以太坊学习路线——(一)私有链搭建与基本操作

这篇博客演示的基本操作系统环境是CentOS 7,参考书籍:以太坊开发实战——以太坊关键技术与案例分析 第五章(吴寿鹤、冯翔、刘涛、周广益   著)。


文章结构:

一.geth客户端安装

二.搭建一个私有链

1.新建一个geth工作目录

2.创世区块配置文件

3.初始化

4.启动私有链

三.以太坊私有链上的基本操作

1.创建用户

2.查看余额

3.挖矿

4.解锁账户

5.交易

6.区块

7.账户管理

8.区块数据管理

9.远程节点连接

10.通过attach命令连接已启动节点

四.常见问题

1.执行miner.start()返回null


一.geth客户端安装

这篇博客演示的基本操作系统环境是CentOS 7,参考书籍:以太坊开发实战——以太坊关键技术与案例分析(吴寿鹤、冯翔、刘涛、周广益   著)。首先从github上获取go-ethereum源码,然后编译geth。获取源码命令:

[root@localhost opt]# git clone https://github.com/ethereum/go-ethereum.git

    如果git未安装请自行百度安装。

如上图所示,由于之前在本目录中下载过go-ethereum,故显示其已存在。然后进入到go-ethereum目录,进行编译:

[root@localhost opt]# cd go-ethereum/
[root@localhost go-ethereum]# make geth

由于我的客户端编译过了,所以没有显示编译细节,但只要编译成功便会在末尾显示:Run "/opt/go-ethereum/build/bin/geth" to launch geth来提示启动geth,注意双引号之间的内容为你安装时的路径,会有所不同。

二.搭建一个私有链

        1.新建一个geth工作目录

$ mkdir geth
$ cd geth
$ mkdir db
$ touch gensis.json 

//执行完成后目录结构
geth
├── db
└── gensis.json

        2.创世区块配置文件

        gensis. json文件内容如下:

{
        "config": {
                "chainId": 15,
                "homesteadBlock": 0,
                "eip155Block": 0,
                "eip158Block": 0
        },
        "coinbase" : "0x0000000000000000000000000000000000000000",
        "difficulty" : "0x40000",
        "extraData" : "",
        "gasLimit" : "0xffffffff",
        "nonce" : "0x0000000000000042",
        "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
        "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
        "timestamp" : "0x00",
        "alloc": { }

}

 相关参数作用表如下:

chainID指定了独立的区块链网络 ID。网络 ID 在连接到其他节点的时候会用到,以太坊公网的网络 ID 是 1,为了不与公有链网络冲突,运行私有链节点的时候要指定自己的网络 ID。不同 ID 网络的节点无法相互连接
homesteadBlock

取值为0表示正在使用homesteadBlock版本。

以太坊的发展分成了四个阶段:(每个阶段进步到下一个阶段都是通过硬分叉的方式实现的)

        1.Frontier(前沿):2015年7月30日,以太坊发布了Frontier阶段,此时的软件还不太成熟,但可以进行基本的挖矿测试去中心化应用(Dapps),该阶段参与者主要为开发者。

        2.HomesteadBlock(家园):在2016年3月14日(圆周率节),以太坊发布了HomesteadBlock阶段。以太坊开始平稳运行,提供了图形界面的钱包,普通用户也可以体验和使用以太坊。

        3.Metropolis(大都会):Metropolis被分成了两个阶段:Byzantium(拜占庭)和Constantinople (居士坦丁堡)。

           2017.10.16,以太坊拜占庭硬分叉成功,引入了包括:zk-SNARKs(简明非交互零知识证明)、revert功能、return和抽象账户。  

           2019年2月底,以太坊区块链的第7,080,000区块作为激活点正式开启君士坦丁堡硬分叉,点在于将以太坊的共识机制由PoW向PoW+PoS混合机制过渡,从而使整个以太坊网络更加的轻盈、快捷与安全。按官方说法,具体在现有以太坊PoW主网上进行升级的有以下5个方面:

           (1).EIP 145:给EVM增加移位相关指令,包括左移SHL,逻辑右移SHR,算术右移SAR

           (2).EIP 1014:产生合约地址的一种新规则,与状态通道有关。规则为keccak256( 0xff ++ address ++ salt ++ keccak256(init_code)))[12:]

           (3).EIP 1052:为EVM增加EXTCODEHASH指令,这个指令可以获得一个合约bytecode的keccak256的hash值;

           (4).EIP 1283:修改EVM的SSTORE指令gas计算方式,预计会减少许多合约的gas消耗,需要硬分叉支持;

           (5).EIP 1234:将是潜在最有争议的提案,也需要硬分叉支持,它包括难度炸弹(Difficulty Bomb)协议推迟12个月和挖矿奖励调整,难度炸弹使挖矿难度随时间推移越来越高,挖矿奖励调整将挖矿奖励从3个降低到2个;

        4.Serenity(宁静)

eip155Blockeip是ethereum improvement proposal的缩写,你的链不会因为因为这些提议分叉,故设置为“0”即可
eip158Blockeip是ethereum improvement proposal的缩写,你的链不会因为因为这些提议分叉,故设置为“0”即可
mixhsah与nonce配合用于挖矿,由上一个区块的一部分生成的哈希。注意它和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。
noncenonce就是一个64位随机数,用于挖矿,注意它和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。
difficulty设置设置当前区块难度,如果难度过大,CPU挖矿就很难
alloc给某个账户预分配以太币
coinbase矿工帐号
timestamp创世块的时间戳
parentHash上一个区块的哈希值,由于是创世区块,所以值为0
extraData可以写入32Byte大小的任意数据,每个block都会有,由挖出block的miner来决定要不要在里面写什么
gasLimit该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总

       3.初始化

//进入geth目录中,执行初始化命令:
$ geth --datadir "./db" init gensis.json

        geth init命令用来初始化区块连,命令可以带有选项和参数,其中--datadir后面跟了一个目录名db,表示指定数据存放目录为db,gensis.json为init命令的参数。初始化成功后,会在db目录中生成geth和keystore两个文件夹,其中,geth/db/geth/chaindata中存放的是区块数据,geth/db/keystore中存放的是账户数据。geth目录结构如下:

[root@localhost geth]# tree ../geth/
../geth/
├── db
│   ├── geth
│   │   ├── chaindata
│   │   │   ├── 000001.log
│   │   │   ├── CURRENT
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000000
│   │   └── lightchaindata
│   │       ├── 000001.log
│   │       ├── CURRENT
│   │       ├── LOCK
│   │       ├── LOG
│   │       └── MANIFEST-000000
│   └── keystore
└── gensis.json

        4.启动私有链


//console 2>>geth.log 表示将日志输出到geth.log,打开另外一个控制台执行tail -f 查看日志
$ geth --datadir "./db" --nodiscover console 2>>geth.log

    geth启动参数详解:

identity区块链的标识,用于标识目前网络的名字
datadir指明当前区块链私钥和网络数据存放的位置
port指定以太坊网络监听端口,默认为30303
rpc开启HTTP-RPC服务,可以进行智能合约的部署和调试
rpcaddr指定HTTP-RPC服务监听地址,默认为“localhost”
rpcapi设置允许连接的rpc的客户端,一般为db、eth、net、web3
rpcport指定HTTP-RPC服务监听端口,默认为8545

networkid

指定以太坊id,其实就是区块链网络的身份标识,共有链为1,测试链为3,默认启动id为1
etherbase指定矿工帐号,默认为keystory中首个帐号
mine

开启挖矿,默认为CPU挖矿

minerthreads挖矿占用CPU线程数,默认为4
nodiscover关闭自动连接节点,但可以手动添加节点,在搭建私有链时,为避免其他节点连入私有链,可使用该命令
maxpeers设置允许最大节点数,默认为25
console启动命令行模式,可以在geth中执行命令

       启动后进入javascript命令行控制台,显示结果如下:

[root@localhost geth]# geth --datadir "./db" --nodiscover console 2>>geth.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.20-unstable/linux-amd64/go1.11
coinbase: 0x1baed334cbf41a94daef7b247beebd6fdc45100c
at block: 112 (Mon, 25 Mar 2019 21:37:17 HKT)
 datadir: /opt/geth/db
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> 

    打开另一个终端,执行 tail -f geth.log可以时刻查看相关日志内容:

[root@localhost geth]# tail -f geth.log 
INFO [03-26|10:20:55.418] Loaded most recent local header          number=112 hash=842b42…2c27da td=28062821 age=12h43m38s
INFO [03-26|10:20:55.418] Loaded most recent local full block      number=112 hash=842b42…2c27da td=28062821 age=12h43m38s
INFO [03-26|10:20:55.418] Loaded most recent local fast block      number=112 hash=842b42…2c27da td=28062821 age=12h43m38s
INFO [03-26|10:20:55.419] Loaded local transaction journal         transactions=0 dropped=0
INFO [03-26|10:20:55.419] Regenerated local transaction journal    transactions=0 accounts=0
WARN [03-26|10:20:55.419] Blockchain not empty, fast sync disabled 
INFO [03-26|10:20:55.584] New local node record                    seq=2 id=c9432d51b9f92fe1 ip=127.0.0.1 udp=0 tcp=30303
INFO [03-26|10:20:55.584] Started P2P networking                   self="enode://688e30b0fd748189b882fb54af5ddf5c2d11555fbf9fd869a96b0f59729cab43b7e6f4c02e59df5ee94a4c2890e54804fa7a2e9476d82e708a903b6b9cc5383a@127.0.0.1:30303?discport=0"
INFO [03-26|10:20:55.587] IPC endpoint opened                      url=/opt/geth/db/geth.ipc
INFO [03-26|10:20:55.786] Etherbase automatically configured       address=0x1Baed334CbF41A94daEF7B247bEebD6fdC45100C

    以太坊的javascript控制台中内置了一些以太坊对象,通过这些对象我们可以很方便的与以太坊交互:

  •         eth:提供了操作区块链相关的方法
  •         net:提供了查看p2p网络状态的方法
  •         admin:提供了管理节点相关的方法
  •         miner:提供启动和停止挖矿的方法
  •         personal:提供了管理账户的方法
  •         txpool:提供了查看交易内存池的方法
  •         web3:除了包含以上对象中有的方法,还包含了一些单位换算的方法

三.以太坊私有链上的基本操作

        1.创建用户

//查看帐户,可以看到有我之前创建的三个账户,若没有创建过账户则显示: []
> eth.accounts
["0x1baed334cbf41a94daef7b247beebd6fdc45100c", "0xdb3d4ae8e3624d1ec75bba5c4da024c5984e3b17", "0x115b0ba0ffddb13cd513ec38679e1089c252c839"]
> 
//建帐户的方式有两种,第一种创建帐户时直接初始化密码
//如下创建的账户为“0xeed50d745a67eaa2a2eaf9e08a2485d1c1145103”,密码为“444444”
> personal.newAccount("444444")
"0xeed50d745a67eaa2a2eaf9e08a2485d1c1145103"
> 
//第二种方法是先创建账户,然后输入密码"555555"
> personal.newAccount()
Passphrase: 
Repeat passphrase: 
"0x6ccfd99b17da037d7f974aa9bd9bd65a04f514d1"
> 
//此时查看已创建的用户,有5个
> eth.accounts
["0x1baed334cbf41a94daef7b247beebd6fdc45100c", "0xdb3d4ae8e3624d1ec75bba5c4da024c5984e3b17", "0x115b0ba0ffddb13cd513ec38679e1089c252c839", "0xeed50d745a67eaa2a2eaf9e08a2485d1c1145103", "0x6ccfd99b17da037d7f974aa9bd9bd65a04f514d1"]
> 

   

//账户创建成功后会返回账户地公钥,生成的账户文件在keystore文件夹下:
db/keystore/
├── UTC--2019-03-25T13-11-16.002140069Z--1baed334cbf41a94daef7b247beebd6fdc45100c
├── UTC--2019-03-25T13-15-38.206845483Z--db3d4ae8e3624d1ec75bba5c4da024c5984e3b17
├── UTC--2019-03-25T13-28-30.957174224Z--115b0ba0ffddb13cd513ec38679e1089c252c839
├── UTC--2019-03-26T02-47-59.331021277Z--eed50d745a67eaa2a2eaf9e08a2485d1c1145103
└── UTC--2019-03-26T02-52-31.434967091Z--6ccfd99b17da037d7f974aa9bd9bd65a04f514d1

        2.查看余额

    以太币的最小单位为wei1 ether = _1_0{18} wei

//由于我的账户挖过矿,且发生过交易,故前三个账户有余额,单位为wei
//而新创建的两个账户未发生过交易,故余额为0
> eth.getBalance(eth.accounts[0])
557000021000000000000
> eth.getBalance(eth.accounts[1])
999979000000000000
> eth.getBalance(eth.accounts[2])
2000000000000000000
> eth.getBalance(eth.accounts[3])
0
> eth.getBalance(eth.accounts[4])
0
> 

        3.挖矿

//在挖矿之前要先设置挖矿奖励地址,默认为创建的第一个账户地址,即eth.accounts[0]
> miner.setEtherbase(eth.accounts[0])
true
> 
//设置完成后,查看是否设置成功,返回结果为设置后的挖矿奖励地址
> eth.coinbase
"0x1baed334cbf41a94daef7b247beebd6fdc45100c"
> 
//开始挖矿
> miner.start()
null
//在之前打开的另一个终端中可以看到挖矿日志记录
INFO [03-26|13:05:36.057] Updated mining threads                   threads=4
INFO [03-26|13:05:36.057] Transaction pool price threshold updated price=1000000000
INFO [03-26|13:05:36.059] Commit new mining work                   number=113 sealhash=527c2b…95e338 uncles=0 txs=0 gas=0 fees=0 elapsed=746.685µs
INFO [03-26|13:06:55.500] Successfully sealed new block            number=113 sealhash=527c2b…95e338 hash=0b5a7f…5202bb elapsed=1m19.441s
INFO [03-26|13:06:55.500] ? mined potential block                  number=113 hash=0b5a7f…5202bb
INFO [03-26|13:06:55.501] Commit new mining work                   number=114 sealhash=20a5a4…07fb8c uncles=0 txs=0 gas=0 fees=0 elapsed=137.993µs
INFO [03-26|13:06:56.895] Successfully sealed new block            number=114 sealhash=20a5a4…07fb8c hash=5bae51…cca193 elapsed=1.394s
INFO [03-26|13:06:56.895] ? mined potential block                  number=114 hash=5bae51…cca193
INFO [03-26|13:06:56.895] Commit new mining work                   number=115 sealhash=75cdcb…42129c uncles=0 txs=0 gas=0 fees=0 elapsed=187.946µs
INFO [03-26|13:07:00.470] Successfully sealed new block            number=115 sealhash=75cdcb…42129c hash=52352a…4e6153 elapsed=3.574s
INFO [03-26|13:07:00.470] ? mined potential block                  number=115 hash=52352a…4e6153
INFO [03-26|13:07:00.470] Commit new mining work                   number=116 sealhash=8590f9…10690f uncles=0 txs=0 gas=0 fees=0 elapsed=138.993µs
INFO [03-26|13:07:01.796] Successfully sealed new block            number=116 sealhash=8590f9…10690f hash=2bc9b7…1d7a1c elapsed=1.326s
INFO [03-26|13:07:01.796] ? mined potential block                  number=116 hash=2bc9b7…1d7a1c
INFO [03-26|13:07:01.797] Commit new mining work                   number=117 sealhash=4f171e…976b8e uncles=0 txs=0 gas=0 fees=0 elapsed=208.115µs
INFO [03-26|13:07:02.863] Successfully sealed new block            number=117 sealhash=4f171e…976b8e hash=89b748…8abebc elapsed=1.066s
INFO [03-26|13:07:02.864] ? mined potential block                  number=117 hash=89b748…8abebc
INFO [03-26|13:07:02.864] Commit new mining work                   number=118 sealhash=d23ff5…1ee086 uncles=0 txs=0 gas=0 fees=0 elapsed=173.425µs
INFO [03-26|13:07:06.387] Successfully sealed new block            number=118 sealhash=d23ff5…1ee086 hash=573e64…31050e elapsed=3.522s
INFO [03-26|13:07:06.387] ? mined potential block                  number=118 hash=573e64…31050e
INFO [03-26|13:07:06.387] Commit new mining work                   number=119 sealhash=c8840a…c9c0af uncles=0 txs=0 gas=0 fees=0 elapsed=228.028µs
INFO [03-26|13:07:12.455] Successfully sealed new block            number=119 sealhash=c8840a…c9c0af hash=dae780…86c027 elapsed=6.068s
INFO [03-26|13:07:12.455] ? mined potential block                  number=119 hash=dae780…86c027
INFO [03-26|13:07:12.455] Commit new mining work                   number=120 sealhash=f89e85…f46780 uncles=0 txs=0 gas=0 fees=0 elapsed=134.293µs
INFO [03-26|13:07:12.851] Successfully sealed new block            number=120 sealhash=f89e85…f46780 hash=b034c6…e2c5fc elapsed=395.460ms
INFO [03-26|13:07:12.851] ? block reached canonical chain          number=113 hash=0b5a7f…5202bb
INFO [03-26|13:07:12.851] ? mined potential block                  number=120 hash=b034c6…e2c5fc

        4.解锁账户

​

//方式一,参数中只传入要解锁的账户地址,控制台提示输入密码时请输入密码,成功后返回true
> personal.unlockAccount(eth.accounts[2])
Unlock account 0x115b0ba0ffddb13cd513ec38679e1089c252c839
Passphrase: 
true
> 

//方式二,参数中传入账户地址和密码
> personal.unlockAccount(eth.accounts[2],"333333")
true
> 

//方式三,参数中传入账户地址、密码、账户解锁状态持续时间
> personal.unlockAccount(eth.accounts[2],"333333",300)
true
> 

        5.交易

//发起交易,内容为accounts[2]账户向accounts[3]账户发送1 ether以太币,返回值为交易hash
//此时的交易正在矿工的交易池中等待被打包
> eth.sendTransaction({from: eth.accounts[2], to: eth.accounts[3],value: web3.toWei(1,"ether")})
"0x28f7e6989893d6e8b1cd26d5d7a285654f5a3c8eff7d6b2029817496deb8bda0"


//查看accounts[2]用户和accounts[3]用户的余额如下:
> eth.getBalance(eth.accounts[2])
2000000000000000000
> eth.getBalance(eth.accounts[3])
0


//查看交易池等待被打包的交易,其中有一条pending的交易,表示已提交但还未被处理的交易
> txpool.status
{
  pending: 1,
  queued: 0
}


//查看pending交易详情
> txpool.inspect.pending
{
  0x115B0ba0ffDdB13Cd513ec38679E1089C252C839: {
    0: "0xeed50D745A67EaA2A2EAf9e08A2485D1c1145103: 1000000000000000000 wei + 90000 gas × 1000000000 wei"
  }
}
//要使交易被处理,必须要挖矿,启动挖矿后,等待挖到一个区块之后就可以停止挖矿了
> miner.start(1);admin.sleepBlocks(1);miner.stop();
null
> 
//在日志显示终端可以看到正常执行后的挖矿日志
INFO [03-26|14:37:06.377] Updated mining threads                   threads=1
INFO [03-26|14:37:06.377] Transaction pool price threshold updated price=1000000000
INFO [03-26|14:37:06.378] Commit new mining work                   number=418 sealhash=14f834…2c37a4 uncles=0 txs=0 gas=0 fees=0 elapsed=376.473µs
INFO [03-26|14:37:06.381] Commit new mining work                   number=418 sealhash=f1a1e0…13c185 uncles=0 txs=1 gas=21000 fees=2.1e-05 elapsed=3.129ms
INFO [03-26|14:37:06.537] Successfully sealed new block            number=418 sealhash=f1a1e0…13c185 hash=a79ae1…4cce3e elapsed=158.086ms
INFO [03-26|14:37:06.537] ? block reached canonical chain          number=411 hash=8de5b1…25b9e2
INFO [03-26|14:37:06.537] ? mined potential block                  number=418 hash=a79ae1…4cce3e
INFO [03-26|14:37:06.537] Commit new mining work                   number=419 sealhash=58dcdb…adddbf uncles=0 txs=0 gas=0     fees=0       elapsed=217.251µs
//此时交易已经成功打包,并且加入区块链中了,此时查看余额:
> eth.getBalance(eth.accounts[2])
999979000000000000
> eth.getBalance(eth.accounts[3])
1000000000000000000
>

        accounts[3]余额正确为1 ether,而accounts[2]似乎应该由2 ether变为1 ether,但结果并不是,这其中的原由便需要好好解释一下。

        在以太坊中一个比较重要的概念就是gas,当你调用一个智能合约的时候,整个网络中的每个矿工会分别执行你调用的合约程序,这会消耗矿工的CPU、内存、与硬盘空间,在合约中执行每个命令的消耗会用单位gas计数。

        gasPrice是你愿意为单位gas支付的费用,以gwei为单位表示。1 gwei = 1 000 000 000 wei,在交易中gasPrice是由发起交易的人规定的,每个矿工接收到交易请求时,会根据gasPrice的高低来决定是否要打包进区块中。

        如果你希望矿工运行你的合约,你最好提供高一点的gasPrice。在某种程度上,这是一场基于合约运行,有多意愿付费驱动下的竞价。

        在每个交易中必须包含gasLimit和gasPrice的值。gasLimit代表这个交易在执行过程中最多被允许消耗的gas数量。gasLimit和gasPrice就代表了交易发送者愿意为执行交易支付的wei的最大值。其最多可能付款金额 =  gasLimit   X  gasPrice  (wei)。

        在交易完成后,如果实际消耗的gas小于gasLimit,那么剩余的gas会返回给交易发起者,交易实际法非金额计算方式:

                                                    实际交易费 = gasUsed   X   gasPrice

        回到本例子中,通过查看下文中本交易被发起时的交易详情可以知道,本例子的转账交易发起时的gas = 90000,gasPrice = 1 000 000 000。而交易完成后被打包进区块后,该交易的详细信息中gasUsed: = 21 000 。

        故这次交易的花费了:21 000 X 1 000 000 000 = 21 000 000 000 000 wei

        accounts[2]向accounts[3]转账了1 ether后剩余1 ether = 1 000 000 000 000 000 000 wei,但还要承担交易费,故:

        1    0 0 0    0 0 0    0 0 0    0 0 0    0 0 0    0 0 0

—                          2 1    0 0 0    0 0 0    0 0 0    0 0 0

——————————————————————

             9 9 9    9 7 9    0 0 0    0 0 0    0 0 0     0 0 0         

        所以accounts[2]账户的余额为999 979 000 000 000 000

        6.区块

//查看指定交易哈希值 所对应交易 被发起时的交易详情:
> eth.getTransaction("0x28f7e6989893d6e8b1cd26d5d7a285654f5a3c8eff7d6b2029817496deb8bda0")
{
  blockHash: "0xa79ae173965c379d7fd75e865faf955e65d55feb1b3afe840a18fbe8f04cce3e",
  blockNumber: 418,
  from: "0x115b0ba0ffddb13cd513ec38679e1089c252c839",
  gas: 90000,
  gasPrice: 1000000000,
  hash: "0x28f7e6989893d6e8b1cd26d5d7a285654f5a3c8eff7d6b2029817496deb8bda0",
  input: "0x",
  nonce: 0,
  r: "0xb7579b66aa0e051b7ec7e8dad8f4d07454d415df6d7a2497a76f76b7e4bb0b62",
  s: "0x53357a3b80e1e478012b89df718be16613f4f3a20141393acb16538dd3b02d23",
  to: "0xeed50d745a67eaa2a2eaf9e08a2485d1c1145103",
  transactionIndex: 0,
  v: "0x42",
  value: 1000000000000000000
}
> 

    其中参数详情 :

blockHash交易所在区块的哈希值。当这个区块处于pending时将会返回null
blockNumber交易所在区块的区号。当这个区块处于pending时将会返回null
from交易发起的地址
gas交易发起者提供的gas数量
gasPrice交易发起者提供的gasPrice,单位为wei
hash交易的哈希值
input交易附带的数据
nonce交易的发起者在之前发起过的交易数量
transactionIndex交易在区块中的序号。当这个区块处于pending时将会返回null
value交易附带的货币量,单位为wei
to交易接受者的地址
//查看指定交易哈希值 所对应交易 被打包进区块时的详细信息:
> eth.getTransactionReceipt("0x28f7e6989893d6e8b1cd26d5d7a285654f5a3c8eff7d6b2029817496deb8bda0")
{
  blockHash: "0xa79ae173965c379d7fd75e865faf955e65d55feb1b3afe840a18fbe8f04cce3e",
  blockNumber: 418,
  contractAddress: null,
  cumulativeGasUsed: 21000,
  from: "0x115b0ba0ffddb13cd513ec38679e1089c252c839",
  gasUsed: 21000,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x45ddc0ef9a33a1e97acdd4b966ad631278f15a5744699ff7672f13f07d60e2e3",
  to: "0xeed50d745a67eaa2a2eaf9e08a2485d1c1145103",
  transactionHash: "0x28f7e6989893d6e8b1cd26d5d7a285654f5a3c8eff7d6b2029817496deb8bda0",
  transactionIndex: 0
}
> 

        其中参数详情 :

blockHash交易所在区块的哈希值。
blockNumber交易所在区块的区号。
contractAddress创建的合约地址。如果是一个合约创建交易,则返回合约地址,其他情况返回null
cumulativeGasUsed当前交易执行后累计花费的gas总值
from交易发送者的地址
gasUsed执行当前这个交易单独花费的gas
logs这个交易产生的日志对象数组
logsBloomlogsBloom由logs中的address与topics共同决定,详细请看以太坊黄皮书,作用是便于快速查找监听的事件是否在该交易中产生
root交易执行后的stateroot
to交易接收者的地址。如果是一个合约创建的交易,返回null
transactionHash交易的哈希值
transationIndex交易在区块里面的序号

        常用查询区块命令:

  •                 查看当前区块总数:eth.blockNumber
  •                 查询最新区块:eth.getBlock("latest")  返回该区块的详细信息,eth.getBlock(blockNumber/blockHash)根据区块   Number或Hash查询区块
    //查看当前区块链节点中第Number为1的区块详情
    > eth.getBlock(1)
    {
      difficulty: 249472,
      extraData: "0xd683010814846765746886676f312e3131856c696e7578",
      gasLimit: 4290772993,
      gasUsed: 0,
      hash: "0xc18e6263be514c9c79b822d1d1fa9c17f25c148f4e71fb876da2c676eb19df2a",
      logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      miner: "0x1baed334cbf41a94daef7b247beebd6fdc45100c",
      mixHash: "0xf67374106da53196fe47cd9002ea0e18415d209efae336619c8fa4fab1359455",
      nonce: "0x1f7390e1d36e28fd",
      number: 1,
      parentHash: "0xa0e580c6769ac3dd80894b2a256164a76b796839d2eb7f799ef6b9850ea5e82e",
      receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
      size: 535,
      stateRoot: "0xbb491beccc4865b5728c8cec43bc46846591d54ba2a87dbd86aa03af18bcdbfd",
      timestamp: 1553519563,
      totalDifficulty: 511616,
      transactions: [],
      transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      uncles: []
    }
    > 
    
                    参数含义如下:
    difficulty挖矿难度,后面区块难度会随着区块高度升高而提高
    extraData当前区块链附加信息,若创世区块该值为空,则在第二个区块中会保存创建该私有链时的geth、go,以及操作系统版本,保存的信息为第一个挖到该区块的矿工信息
    gasLimit该区块允许的最大gas数
    GasUsedgas花费,在以太坊中交易和部署智能合约会消耗gas
    hash当前区块哈希值
    logsBloomlogsBloom由logs中的address与topics共同决定,详细请看以太坊黄皮书,作用是便于快速查找监听的事件是否在该交易中产生

    miner

    挖到该区块的矿工地址
    mixHash与nonce配合用于挖矿,由上一个区块的一部分生成的hash
    nonce工作量证明
    number当前区块链高度
    parentHash上一个区块链哈希值
    receiptsRoot区块receipt trie的根
    sha3Uncles对叔区块进行hash运算的结果
    size区块大小,以字节为单位
    stateRoot块的状态树根结果
    timestamp时间戳
    totalDifficulty达到该区块的难度综总数
    transactions以数组的形式保存交易的tx值
    transactionsRoot交易的默尔克树根
    uncles当前区块引用的束缚区块的哈希值

7.账户管理

(1).创建新帐号

[root@localhost geth]# geth --datadir "./db1" account new
INFO [03-29|20:39:53.169] Maximum peer count                       ETH=25 LES=0 total=25
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase: 
Repeat passphrase: 
Address: {b1d70e94ffcba142fd024ece374e0be3cd9c08ad}

(2).列举已存在帐号

[root@localhost geth]# geth --datadir "./db1" account list
INFO [03-29|20:46:02.607] Maximum peer count                       ETH=25 LES=0 total=25
Account #0: {c4e87bb87064c40ecc07ed8955f35533c92a82f0} keystore:///opt/geth/db1/keystore/UTC--2019-03-28T13-07-34.305959164Z--c4e87bb87064c40ecc07ed8955f35533c92a82f0
Account #1: {70083e2f06da81015c1ee24b60a53fde4f30bddb} keystore:///opt/geth/db1/keystore/UTC--2019-03-28T14-08-09.815911074Z--70083e2f06da81015c1ee24b60a53fde4f30bddb
Account #2: {da66a23edbec03deef9eea953c1a2d865bf3acb3} keystore:///opt/geth/db1/keystore/UTC--2019-03-28T14-21-37.216641721Z--da66a23edbec03deef9eea953c1a2d865bf3acb3
Account #3: {b1d70e94ffcba142fd024ece374e0be3cd9c08ad} keystore:///opt/geth/db1/keystore/UTC--2019-03-29T12-40-09.120020587Z--b1d70e94ffcba142fd024ece374e0be3cd9c08ad

(3).修改账户密码

[root@localhost geth]# geth --datadir "./db1" account update b1d70e94ffcba142fd024ece374e0be3cd9c08ad
INFO [03-29|20:48:53.009] Maximum peer count                       ETH=25 LES=0 total=25
Unlocking account b1d70e94ffcba142fd024ece374e0be3cd9c08ad | Attempt 1/3
Passphrase: 
INFO [03-29|20:48:58.466] Unlocked account                         address=0xB1d70e94FfCBa142FD024ecE374e0bE3Cd9C08ad
Please give a new password. Do not forget this password.
Passphrase: 
Repeat passphrase:

(4).导入密钥文件

[root@localhost geth]# geth --datadir "./db1" account import ecc.key 
INFO [03-29|21:06:10.906] Maximum peer count                       ETH=25 LES=0 total=25
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase: 
Repeat passphrase: 
Address: {fc563cb4086c1c9621c72b1a9f8d3b487fe438e9}
//其中ecc.key是ECDSA[椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟]的私钥
[root@localhost geth]# cat ecc.key 
25066ae7675c08bdafded1c1403cc5d1431597149eac21261c5a3002339a007b

8.区块数据管理

(1).导出区块数据

//将db1目录中的区块数据导入到bak文件中:
[root@localhost geth]# geth --datadir "./db1" export ./bak
INFO [03-29|21:14:53.492] Maximum peer count                       ETH=25 LES=0 total=25
INFO [03-29|21:14:53.496] Allocated cache and file handles         database=/opt/geth/db1/geth/chaindata cache=512 handles=1024
INFO [03-29|21:14:53.810] Disk storage enabled for ethash caches   dir=/opt/geth/db1/geth/ethash count=3
INFO [03-29|21:14:53.810] Disk storage enabled for ethash DAGs     dir=/root/.ethash             count=2
INFO [03-29|21:14:53.870] Loaded most recent local header          number=35 hash=7f2f97…73ba58 td=4603649 age=23h9m8s
INFO [03-29|21:14:53.870] Loaded most recent local full block      number=35 hash=7f2f97…73ba58 td=4603649 age=23h9m8s
INFO [03-29|21:14:53.870] Loaded most recent local fast block      number=35 hash=7f2f97…73ba58 td=4603649 age=23h9m8s
INFO [03-29|21:14:53.870] Exporting blockchain                     file=./bak
INFO [03-29|21:14:53.870] Exporting batch of blocks                count=36
INFO [03-29|21:14:53.873] Exported blockchain                      file=./bak
Export done in 3.070252ms
//导入成功好会在当前目录下生成一个bak文件
[root@localhost geth]# ll
total 48
-rwxr-xr-x. 1 root root 19230 Mar 29 21:14 bak
drwx------. 4 root root    49 Mar 28 22:06 db1
-rw-r--r--. 1 root root    65 Mar 29 21:06 ecc.key
-rw-r--r--. 1 root root   605 Mar 28 20:11 gensis.json
-rw-r--r--. 1 root root 20377 Mar 28 22:06 geth.log

 (2).移除区块数据

[root@localhost geth]# geth --datadir "./db1" removedb
INFO [03-29|21:18:16.562] Maximum peer count                       ETH=25 LES=0 total=25
/opt/geth/db1/geth/chaindata
Remove this database? [y/N] y
Remove this database? [y/N] y
INFO [03-29|21:18:23.975] Database successfully deleted            database=chaindata elapsed=1.166ms
/opt/geth/db1/geth/lightchaindata
Remove this database? [y/N] y
Remove this database? [y/N] y
INFO [03-29|21:18:26.355] Database successfully deleted            database=lightchaindata elapsed=1.276ms

(3).导入区块数据

//导入区块数据之前要用gensis.json文件执行初始化
[root@localhost geth]# geth --datadir "./db1" init gensis.json 
INFO [03-29|21:19:30.372] Maximum peer count                       ETH=25 LES=0 total=25
INFO [03-29|21:19:30.374] Allocated cache and file handles         database=/opt/geth/db/geth/chaindata cache=16 handles=16
INFO [03-29|21:19:30.464] Writing custom genesis block 
INFO [03-29|21:19:30.464] Persisted trie from memory database      nodes=0 size=0.00B time=21.737µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [03-29|21:19:30.464] Successfully wrote genesis state         database=chaindata                   hash=1ef75f…d1799a
INFO [03-29|21:19:30.464] Allocated cache and file handles         database=/opt/geth/db/geth/lightchaindata cache=16 handles=16
INFO [03-29|21:19:30.548] Writing custom genesis block 
INFO [03-29|21:19:30.548] Persisted trie from memory database      nodes=0 size=0.00B time=6.821µs  gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [03-29|21:19:30.549] Successfully wrote genesis state         database=lightchaindata                   hash=1ef75f…d1799a
//初始化完成后就可以导入区块数据le
[root@localhost geth]# geth --datadir "./db1" import ./bak 
INFO [03-29|21:21:32.802] Maximum peer count                       ETH=25 LES=0 total=25
INFO [03-29|21:21:32.805] Allocated cache and file handles         database=/opt/geth/db1/geth/chaindata cache=512 handles=1024
INFO [03-29|21:21:32.990] Writing default main-net genesis block 
INFO [03-29|21:21:33.440] Persisted trie from memory database      nodes=12356 size=1.88mB time=72.102914ms gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [03-29|21:21:33.440] Disk storage enabled for ethash caches   dir=/opt/geth/db1/geth/ethash count=3
INFO [03-29|21:21:33.440] Disk storage enabled for ethash DAGs     dir=/root/.ethash             count=2
INFO [03-29|21:21:33.468] Loaded most recent local header          number=0 hash=d4e567…cb8fa3 td=17179869184 age=49y11mo2w
INFO [03-29|21:21:33.468] Loaded most recent local full block      number=0 hash=d4e567…cb8fa3 td=17179869184 age=49y11mo2w
INFO [03-29|21:21:33.468] Loaded most recent local fast block      number=0 hash=d4e567…cb8fa3 td=17179869184 age=49y11mo2w
INFO [03-29|21:21:33.469] Importing blockchain                     file=./bak
ERROR[03-29|21:21:33.471] 
########## BAD BLOCK #########
Chain config: {ChainID: 1 Homestead: 1150000 DAO: 1920000 DAOSupport: true EIP150: 2463000 EIP155: 2675000 EIP158: 2675000 Byzantium: 4370000 Constantinople: <nil> Engine: ethash}

Number: 1
Hash: 0xa5144c4a46a7047492371bdee8459785d09ae44e32d06a8a96c7409dfd35013a


Error: unknown ancestor
##############################
 
ERROR[03-29|21:21:33.471] Import error                             err="invalid block 35: unknown ancestor"
INFO [03-29|21:21:33.471] Blockchain manager stopped 
Import done in 2.573417ms.

Compactions
 Level |   Tables   |    Size(MB)   |    Time(sec)  |    Read(MB)   |   Write(MB)
-------+------------+---------------+---------------+---------------+---------------

Read(MB):0.00000 Write(MB):2.38956
Trie cache misses:  0
Trie cache unloads: 0

Object memory: 268.085 MB current, 267.908 MB peak
System memory: 334.967 MB current, 334.967 MB peak
Allocations:   1.118 million
GC pause:      396.612µs

Compacting entire database...
Compaction done in 786.903722ms.

Compactions
 Level |   Tables   |    Size(MB)   |    Time(sec)  |    Read(MB)   |   Write(MB)
-------+------------+---------------+---------------+---------------+---------------
   0   |          0 |       0.00000 |       0.59842 |       0.00000 |       1.91527
   1   |          1 |       1.91526 |       0.13436 |       1.91527 |       1.91526

Read(MB):1.88542 Write(MB):6.22033
INFO [03-29|21:21:34.304] Database closed                          database=/opt/geth/db1/geth/chaindata

(4).dump

//从区块链中dump制定区块数据,geth命令后可以传入区块编号或区块hash值
$ geth --datadir "./db1" dump 0
​

9.远程节点连接

(1).查看节点信息

> admin.nodeInfo
{
  enode: "enode://4b13086b294f1b7b0801ff78eb62cd9b1bf2991819ccc2b69df9a0371a031c0d8f25e84aa92781cb590a20b4ed25d4c67184c44470e008a77dfbe9ec4fedfe20@127.0.0.1:38690?discport=0",
  enr: "0xf895b8407a227a916f7016b5dec567b0ecb41d6452fb41130b69bf861fae9ed271ff9c46607ae835137bf7b5508dfdd86a8df8ce859c61d044513ed707d72f5a58e272a50183636170ccc5836574683fc58373686806826964827634826970847f00000189736563703235366b31a1024b13086b294f1b7b0801ff78eb62cd9b1bf2991819ccc2b69df9a0371a031c0d83746370829722",
  id: "d0bd4223d5c476927e34787e99179c27da96f4e1dee7913a345d445c89a164dd",
  ip: "127.0.0.1",
  listenAddr: "[::]:38690",
  name: "Geth/v1.8.20-unstable/linux-amd64/go1.11",
  ports: {
    discovery: 0,
    listener: 38690
  },
  protocols: {
    eth: {
      config: {
        byzantiumBlock: 0,
        chainId: 1337,
        clique: {...},
        constantinopleBlock: 0,
        eip150Block: 0,
        eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
        eip155Block: 0,
        eip158Block: 0,
        homesteadBlock: 0
      },
      difficulty: 37,
      genesis: "0x004680c14f64dd409489eb632569fb1440bffbfbbc4996263e3f3cadb10e37a1",
      head: "0x782e496b3110c566136549d7dfbc2cf7700b6414fcc3aa9d74eb5984ab076f39",
      network: 1337
    },
    shh: {
      maxMessageSize: 1048576,
      minimumPoW: 0.2,
      version: "6.0"
    }
  }
}

(2).添加其他节点

可以通过admin.addPeer()方法连接到其他节点,两个接节点想要联通,必须保证网络时相通的,并且要指定相同的networkid。我的第一个节点时我的本机节点,另一个节点时远程服务器节点,两个节点的gensis.json文件相同。

首先通过在远程服务器节点获取其encode信息,注意要把encode中的[::]替换成该机器的IP地址。

> admin.nodeInfo.enode
"enode://e5b417b09f971fc06a4a413ed4ed2d431cd303e286e44b01cf6c126c51708bde44cf6f692f611e441ba22f0ebce1b384d3f418af338589358daacd322f9df966@207.246.103.126:30303"
//在本机连接远程服务器节点
> admin.addPeer("enode://e5b417b09f971fc06a4a413ed4ed2d431cd303e286e44b01cf6c126c51708bde44cf6f692f611e441ba22f0ebce1b384d3f418af338589358daacd322f9df966@207.246.103.126:30303")
true
​

(3).查看已连接的远程节点

> admin.peers
[{
    caps: ["eth/63"],
    enode: "enode://e5b417b09f971fc06a4a413ed4ed2d431cd303e286e44b01cf6c126c51708bde44cf6f692f611e441ba22f0ebce1b384d3f418af338589358daacd322f9df966@207.246.103.126:30303",
    id: "f40c748606f81f3d600584b70e4425165ed68ed47484d20afe5051655e509719",
    name: "Geth/v1.8.23-stable/linux-amd64/go1.10.3",
    network: {
      inbound: false,
      localAddress: "192.168.124.48:48550",
      remoteAddress: "207.246.103.126:30303",
      static: true,
      trusted: false
    },
    protocols: {
      eth: {
        difficulty: 1,
        head: "0x1ef75f7ced81aa0ff14865c59117439c6ae6760468d64e46e06311190dd1799a",
        version: 63
      }
    }
}]

10.通过attach命令连接已启动节点 

当通过geth命令启动了一个以太坊私有链时,会在数据目录下生成一个geth.ipc文件,在本例子中即为“./db/geth.ipc”。通过attach命令可以连接这个已经启动的节点,来启动一个Js命令环境:

[root@localhost geth]# geth --datadir "./db" attach ipc:./db/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/v1.9.0-unstable-acbb8a14/linux-amd64/go1.11
coinbase: 0x8c7ae59ab7e5d510ae3f09a9544978f50315b5f5
at block: 107 (Sat, 06 Apr 2019 15:27:50 HKT)
 datadir: /opt/geth/db
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> 

四.常见问题

1.执行miner.start()返回null

解决方案借鉴自:https://blog.csdn.net/billwzf/article/details/83145111

geth版本更新之后,–dev模式(回归测试模式)下新增了一个参数项:

--dev               Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled
--dev.period value  Block period to use in developer mode (0 = mine only if transaction pending) (default: 0)

–dev是我们常用的参数,之前版本中我们只用使用–dev然后执行miner.start()就可以挖矿,但是在后面的版本中,当我们会发现只有发送交易了才会挖一个块。引起此问题的原因就是新增了–dev.period value配置项。此配置默认值为0,也就是说只有pending中存在交易才会挖矿。所以–dev参数依旧使用,然后再在后面添加–dev.period 1,即设置dev.period的参数为1。

由于此参数的存在,使得存在两种启动模式:

1.dev模式

//该模式下需要在pending中先存在交易才可以挖矿
geth --networkid 15 --dev console 2>>geth.log

2.dev自动挖矿模式

geth --networkid 15 --dev --dev.period 1 console 2>>geth.log

 

  • 7
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值