使用docker并下载必要的文件
FROM ubuntu:16.04
RUN apt-get update \
&& apt-get install -y software-properties-common \
&& add-apt-repository -y ppa:ethereum/ethereum \
&& apt-get update \
&& apt-get install -y ethereum
COPY genesis.json /code/genesis.json
其中genesis.json内容如下:
{
"alloc": {
},
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"nonce": "0x000000000000002a",
"difficulty": "0x001000",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2fefd8"
}
启动2个docker容器
$ docker run -it -p 8545:8545 --name eth_node_1 ymer/ethernum-env:v1
$ docker run -it -p 8546:8545 --name eth_node_2 ymer/ethernum-env:v1
启动之后结果如
$ docker ps
072c1b740f62 ymer/ethernum-env:v1 "/bin/bash" 5 seconds ago Up 9 seconds 0.0.0.0:8547->8545/tcp eth_node_3
65606d9f0257 ymer/ethernum-env:v1 "/bin/bash" About a minute ago Up About a minute 0.0.0.0:8546->8545/tcp eth_node_2
查询节点对应的IP地址
$ docker inspect 072c1b740f62 --format='{{.NetworkSettings.IPAddress}}'
172.17.0.2
$ docker inspect 65606d9f0257 --format='{{.NetworkSettings.IPAddress}}'
172.17.0.3
纪录下查询的信息:
节点 | IP地址 | 映射端口 | 容器ID |
---|---|---|---|
eth_node_1 | 172.17.0.2 | 8545 | 4cd4 |
eth_node_2 | 172.17.0.3 | 8546 | f5d2 |
首先进入docker容器
执行
$ geth init genesis.json`
创建钱包
创建初始节点钱包,用于接收记账奖励,每个节点都需要创建。节点记账(挖矿)程序运行前,必须先建立初始的钱包,用于接收记账奖励,否则会无法启动记账程序。
执行命令
$ geth account new
Address: {acdc8e98d388aae78f2d5937878ad2332297d1c7}
同时再创建一个用户钱包,稍后将用于本节点钱包转账以及不同节点间钱包转账。
在另一个节点上执行同样操作
查看本节点所有账户
$ geth account list
Account #0: {6e56cfd8ca3299abd5604fb7135b79017d72d543} keystore:///root/.ethereum/keystore/UTC--2018-07-30T11-29-23.969093600Z--6e56cfd8ca3299abd5604fb7135b79017d72d543
Account #1: {e1ebed71951203a7079813dacf7ee3af297630b0} keystore:///root/.ethereum/keystore/UTC--2018-07-30T11-31-21.448019100Z--e1ebed71951203a7079813dacf7ee3af297630b0
开始挖矿
节点1上执行
# geth --identity="NODE_1" --networkid="500" --verbosity=1 --mine --minerthreads=1 --rpc --rpcaddr 0.0.0.0 console
Welcome to the Geth JavaScript console!
instance: Geth/NODE_1/v1.8.12-stable-37685930/linux-amd64/go1.10
coinbase: 0xacdc8e98d388aae78f2d5937878ad2332297d1c7
at block: 0 (Thu, 01 Jan 1970 00:00:00 UTC)
datadir: /root/.ethereum
modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
>
参数 | 说明 |
---|---|
--identity | 每个节点必须唯一 |
--networkid | 在集群里面保持一致,所有的节点都相同 |
--verbosity | 有几个级别0=silent, 1=error... (default: 3) |
--mine | 开始启动记账(挖矿)程序 |
--rpc | 允许RPC |
--rpcport | 指定的RPC端口号,演示保持一样,宿主机映射不一样 |
节点2上执行
geth --identity="NODE_2" --networkid="500" --verbosity=1 --mine --minerthreads=1 --rpc --rpcaddr 0.0.0.0 console
执行完之后,开始挖矿
> miner.start()
null
> eth.blockNumber
10
> eth.blockNumber
13
miner.start()
返回null,但是使用eth.blockNumber
可以看到区块在不断增加
查询节点信息IPC RPC 参数
所有的节点都开始记账(挖矿)程序后,我们就需要配置集群的节点信息,让2个节点能够互相发现,并同步信息。
在节点1中
> admin.peers
[]
> admin.nodeInfo.enode
"enode://1c0d3449857f252750945372bf510201b415b2c27999fc462849f6283fd4c7440903049651865bd11d83844cf323cbfd92fcae961c29153a36f894c34899167b@[::]:30303"
将末尾的 [::]替换为我们的内网IP地址,前面有记录,172.17.0.2
然后在node2中执行:
> node1 = "enode://1c0d...4899167b@172.17.0.2:30303"
> admin.addPeer(enode1)
节点1同样操作,在节点1中添加节点2
然后在节点1中执行:
> admin.peers
[{
caps: ["eth/63"],
id: "3d3be057a31d376dddf9a3e8749c8f4639e6dfa748677f7dab86bb369d11b826c84d22641efedf240dc68539390ddb6806e05b16a3d20f13caf27d2b7e040f7a",
name: "Geth/NODE_2/v1.8.12-stable-37685930/linux-amd64/go1.10",
network: {
inbound: false,
localAddress: "172.17.0.2:41518",
remoteAddress: "172.17.0.3:30303",
static: true,
trusted: false
},
protocols: {
eth: {
difficulty: 51633962,
head: "0x92c9c8e402d0e8d9693de8361cc69e3b902e7e941772038e246abdaeac4919f9",
version: 63
}
}
}]
如果节点1中执行> exit
,再次进入挖矿后,需要重新添加。
就是说如果节点1退出挖矿,那么节点2的admin.peers
将为空
删除链
$ geth removedb
查询初始钱包余额
> eth.accounts
["0xa3782d7c6fe47e612db307e48a75fb2e745d9369", "0x13b49f82f4147c7763d4e765250a9875e449e763"]
> node1_w1 = eth.accounts[0]
> eth.getBalance(node1_w1)
3.013125e+21
> web3.fromWei(eth.getBalance(node1_w1))
3037.03125
> node1_w2 = eth.accounts[1]
> web3.fromWei(eth.getBalance(node1_w2))
0
其中,node1_w1是挖矿所得,node1_w2是用户账户。
节点内转账
> eth.sendTransaction({from: node1_w1, to: node1_w2, value: web3.toWei(4, "ether")})
"0x6a4d4d1f2eee528560e363b543921f1167ad54af70091b9f7d218a29ce8320a6"
如果报错,需要解锁
> personal.unlockAccount('0xa3782d7c6fe47e612db307e48a75fb2e745d9369', "123", 300)
123
是创建账户的密码
查看挂起的交易:
> eth.pendingTransactions
[{
blockHash: null,
blockNumber: null,
from: "0xa3782d7c6fe47e612db307e48a75fb2e745d9369",
gas: 90000,
gasPrice: 18000000000,
hash: "0x6a4d4d1f2eee528560e363b543921f1167ad54af70091b9f7d218a29ce8320a6",
input: "0x",
nonce: 0,
r: "0xdf10f9d5caae629041afdf70fb1dabd66bf9c2508419a305558ce0d0607e4e1e",
s: "0x32a359378297b19d86d883f019be6c0785c7d0e4576f69e55a1bed0104f4cd11",
to: "0x13b49f82f4147c7763d4e765250a9875e449e763",
transactionIndex: 0,
v: "0x42",
value: 4000000000000000000
}]
如果转账结束:
> eth.pendingTransactions
[]
> eth.getTransaction("0x6a4d4d1f2eee528560e363b543921f1167ad54af70091b9f7d218a29ce8320a6")
{
blockHash: "0xff907d2dedd7529050bb38dd7373b6cb6e4aedda027690a94ca3eb4ead9dfa0d",
blockNumber: 349,
from: "0xa3782d7c6fe47e612db307e48a75fb2e745d9369",
gas: 90000,
gasPrice: 18000000000,
hash: "0x6a4d4d1f2eee528560e363b543921f1167ad54af70091b9f7d218a29ce8320a6",
input: "0x",
nonce: 0,
r: "0xdf10f9d5caae629041afdf70fb1dabd66bf9c2508419a305558ce0d0607e4e1e",
s: "0x32a359378297b19d86d883f019be6c0785c7d0e4576f69e55a1bed0104f4cd11",
to: "0x13b49f82f4147c7763d4e765250a9875e449e763",
transactionIndex: 0,
v: "0x42",
value: 4000000000000000000
}
节点间转账
通过地址:
> eth.sendTransaction({from: '0xa3782d7c6fe47e612db307e48a75fb2e745d9369', to: '0xdc3b1bc884bca283368f14ee7f577bf777bea464', value: web3.toWei(15, "ether")})