上一节中我们使用geth搭建了以太坊私有网络,这一次则要在私有网络中建立多节点集群,并互相发现,产生交易.
为了在本地网络运行多个以太坊节点的实例,必须确保以下两点:
- 每个实例都有独立的数据目录
--datadir
- 每个实例运行都有独立的端口.
搭建多节点环境
启动第一个节点
geth --datadir data0 --networkid 1108 console
运行结果如下:
INFO [03-01|10:57:17] Starting peer-to-peer node instance=Geth/v1.7.3-stable/darwin-amd64/go1.9.2
INFO [03-01|10:57:17] Allocated cache and file handles database=/Users/wangsanjun/privatechain/data0/geth/chaindata cache=128 handles=1024
INFO [03-01|10:57:17] Initialised chain configuration config="{ChainID: 10 Homestead: 0 DAO: DAOSupport: false EIP150: EIP155: 0 EIP158: 0 Byzantium: Engine: unknown}"
INFO [03-01|10:57:17] Disk storage enabled for ethash caches dir=/Users/wangsanjun/privatechain/data0/geth/ethash count=3
INFO [03-01|10:57:17] Disk storage enabled for ethash DAGs dir=/Users/wangsanjun/.ethash count=2
INFO [03-01|10:57:17] Initialising Ethereum protocol versions="[63 62]" network=1108
INFO [03-01|10:57:17] Loaded most recent local header number=72 hash=8df4da…335b9f td=9710147
INFO [03-01|10:57:17] Loaded most recent local full block number=72 hash=8df4da…335b9f td=9710147
INFO [03-01|10:57:17] Loaded most recent local fast block number=72 hash=8df4da…335b9f td=9710147
INFO [03-01|10:57:17] Loaded local transaction journal transactions=0 dropped=0
INFO [03-01|10:57:17] Regenerated local transaction journal transactions=0 accounts=0
WARN [03-01|10:57:17] Blockchain not empty, fast sync disabled
INFO [03-01|10:57:17] Starting P2P networking
INFO [03-01|10:57:19] UDP listener up self=enode://c1f6afa8c620b842b6ff36b9321ec2f7dd6a08037a31ee093e9acc4c5a13bcb93b5ce95b10768eedafe144f55c79858a8b8e59f121674dbe267d23dba1df3e7a@[::]:30303
INFO [03-01|10:57:19] RLPx listener up self=enode://c1f6afa8c620b842b6ff36b9321ec2f7dd6a08037a31ee093e9acc4c5a13bcb93b5ce95b10768eedafe144f55c79858a8b8e59f121674dbe267d23dba1df3e7a@[::]:30303
INFO [03-01|10:57:19] IPC endpoint opened: /Users/wangsanjun/privatechain/data0/geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.7.3-stable/darwin-amd64/go1.9.2
coinbase: 0x0416f04c403099184689990674f5b4259dc46bd8
at block: 72 (Wed, 28 Feb 2018 18:33:09 CST)
datadir: /Users/wangsanjun/privatechain/data0
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
获取节点实例的enode url:
> admin.nodeInfo.enode
"enode://c1f6afa8c620b842b6ff36b9321ec2f7dd6a08037a31ee093e9acc4c5a13bcb93b5ce95b10768eedafe144f55c79858a8b8e59f121674dbe267d23dba1df3e7a@[::]:30303"
再打开一个终端,初始化第二个节点:
mkdir data1 //和上一个节点的data0同目录,即在privatechain下面
geth --datadir data1 account new
geth --datadir data1 --networkid 1108 init genesis.json
geth --datadir data1 --networkid 1108 --port 30304 --bootnodes "enode://c1f6afa8c620b842b6ff36b9321ec2f7dd6a08037a31ee093e9acc4c5a13bcb93b5ce95b10768eedafe144f55c79858a8b8e59f121674dbe267d23dba1df3e7a@172.16.70.76:30303" console
上面的命令中,
--bootndoes
是设置当前节点启动后,直接通过设置--bootndoes
的值来链接第一个节点,--bootnoedes
的值可以通过在第一个节的命令行中,输入admin.nodeInfo.enode
命令打印出来,需要注意的是需要把@[::]
换成实际电脑的IP
地址
也可以不设置--bootnodes
, 直接启动,启动后进入命令行, 通过命令admin.addPeer(enodeUrlOfFirst Instance)
把它作为一个peer
添加进来.
为了确认链接成功,第二个节点输入:
> admin.nodeInfo
{
enode: "enode://61eac7f7900bd17cac39ce506cd20c1f67a2a43fb5f5c7a46ace337922a9e325a63a7aa9cb18df12715550ffa0b66c44272132b93245d15825c2ac2c1ddb8cd8@[::]:30304",
id: "61eac7f7900bd17cac39ce506cd20c1f67a2a43fb5f5c7a46ace337922a9e325a63a7aa9cb18df12715550ffa0b66c44272132b93245d15825c2ac2c1ddb8cd8",
ip: "::",
listenAddr: "[::]:30304",
name: "Geth/v1.7.3-stable/darwin-amd64/go1.9.2",
ports: {
discovery: 30304,
listener: 30304
},
protocols: {
eth: {
difficulty: 9972291,
genesis: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
head: "0xbcc9172f244c3c86d15b04451d2d72dca6953cc1838910f35f486149a37ddc87",
network: 1108
}
}
}
第一个节点输入:
> net.peerCount
2
> admin.peers
[{
caps: ["eth/63"],
id: "61eac7f7900bd17cac39ce506cd20c1f67a2a43fb5f5c7a46ace337922a9e325a63a7aa9cb18df12715550ffa0b66c44272132b93245d15825c2ac2c1ddb8cd8",
name: "Geth/v1.7.3-stable/darwin-amd64/go1.9.2",
network: {
localAddress: "172.16.70.76:30303",
remoteAddress: "172.16.70.76:53634"
},
protocols: {
eth: {
difficulty: 131072,
head: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
version: 63
}
}
}]
从得到的结果可以看出,第一个节点有1个peer链接, 链接的node id为:
"61eac7f7900bd17cac39ce506cd20c1f67a2a43fb5f5c7a46ace337922a9e325a63a7aa9cb18df12715550ffa0b66c44272132b93245d15825c2ac2c1ddb8cd8"
这个id,正好就是第二个节点的id.
链接成功后,使用第一个节点挖矿的账户,向第二个节点发送 "ether"
首先查看第二个节点的Wei数量和整个网络的区块号,还有接收货币的账号id:
> eth.getBalance(eth.accounts[0])
0
> eth.blockNumber
73
> eth.accounts[0]
"0x0c7df03a68bd85ef3abcfc63a6b788a2faf8ef27"
>
在第一个节点命令行中,执行下面的操作:
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x0416f04c403099184689990674f5b4259dc46bd8
Passphrase:
true
> eth.sendTransaction({from:"0x0416f04c403099184689990674f5b4259dc46bd8",to:"0x0c7df03a68bd85ef3abcfc63a6b788a2faf8ef27",value:web3.toWei(1, "ether")})
INFO [03-01|15:03:04] Submitted transaction fullhash=0xb92d256b66c336c9ffa5c1872bb5b20b6b704d7fbc4dd7aa3cdb97b8668d407d recipient=0x0C7dF03a68Bd85EF3abcfC63A6b788a2fAf8EF27
"0xb92d256b66c336c9ffa5c1872bb5b20b6b704d7fbc4dd7aa3cdb97b8668d407d"
> eth.pendingTransactions
[{
blockHash: null,
blockNumber: null,
from: "0x0416f04c403099184689990674f5b4259dc46bd8",
gas: 90000,
gasPrice: 18000000000,
hash: "0xb92d256b66c336c9ffa5c1872bb5b20b6b704d7fbc4dd7aa3cdb97b8668d407d",
input: "0x",
nonce: 5,
r: "0xfd4d1b29e0ae3bce53599d4e0f89a093b1b483de2cf85f6acdb66c88dd594242",
s: "0x60b4a92b9a2744b3c2f9cd5c5cd0d406c93b4b18877d4cb6357ec7946019bfe2",
to: "0x0c7df03a68bd85ef3abcfc63a6b788a2faf8ef27",
transactionIndex: 0,
v: "0x37",
value: 1000000000000000000
}]
eth.sendTransaction就是执行发送以太币的操作, 参数from, to分别是发送账户和接收账户, web3.toWei(1, "ether")是将1单位"ether"转换为相应的"Wei"数量.
然后执行挖矿
> miner.start(1);admin.sleepBlocks(1);miner.stop();
INFO [03-01|15:05:47] Updated mining threads threads=1
INFO [03-01|15:05:47] Transaction pool price threshold updated price=18000000000
INFO [03-01|15:05:47] Starting mining operation
INFO [03-01|15:05:47] Commit new mining work number=74 txs=1 uncles=0 elapsed=388.33µs
INFO [03-01|15:06:23] Successfully sealed new block number=74 hash=bcc917…7ddc87
INFO [03-01|15:06:23] mined potential block number=74 hash=bcc917…7ddc87
INFO [03-01|15:06:23] Commit new mining work number=75 txs=0 uncles=0 elapsed=202.123µs
true
再在第二个节点的命令行输入:
> eth.blockNumber
74
> eth.getBalance(eth.accounts[0])
1000000000000000000
可以看到第二个节点中的账户,已经得有了1个"ether", 并且可以看出,以太坊中,1"ether"=1000000000000000000"Wei.
之前输入eth.blockNumber,得到的值为73,现在增加了一个区块变成了74
总结一下:
这次我们完成了以下内容:
1)创建区块链私有网络,并在网络中建立多节点集群
2)在多节点环境中,通过一个节点的账户向网络中的另外一个节点的账户转了1个以太坊币,交易成功.