使用 Go-Ethereum 1.7.2搭建以太坊私有链
转自:https://mshk.top/2017/11/go-ethereum-1-7-2/
1、什么是Ethereum(以太坊)
以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统,以太坊从诞生到2017年5月,短短3年半时间,全球已有200多个以太坊应用诞生。以太坊是一个平台和一种编程语言,使开发人员能够建立和发布下一代分布式应用。 以太坊可以用来编程,分散,担保和交易任何事物:投票,域名,金融交易所,众筹,公司管理, 合同和大部分的协议,知识产权,还有得益于硬件集成的智能资产。
以太坊的白皮书:https://github.com/ethereum/wiki/wiki/White-Paper
1.2、以太坊的几个基本概念:
以太坊简单来说就是区块链与智能合约的结合,是基于solidity
语言实现的。在以太坊中,智能合约也有一个帐户地址。
- EVM
以太坊虚拟机(EVM)是以太坊中智能合约的运行环境。它不仅被沙箱封装起来,事实上它被完全隔离,运行在EVM内部的代码不能接触到网络、文件系统或者其它进程。甚至智能合约之间也只有有限的调用。
- accounts
以太坊账户,是以太坊技术的核心概念。与传统意义上的账户相比,以太坊账户分为外部账户(Externally Owned Accounts)和合约账户(Contract
Accounts)两种类型:外部账户是用户可见的部分,具有账户余额的账户状态;合约账户是非用户可见的部分,具有账户余额和合约代码(Contract Code)的账户状态。在每一次交易执行过程中,余额和合约代码等信息随着交易执行发生变化,因此也可以认为交易的执行与账户状态的变化同时发生。在以太坊网络中,以太坊账户被定义为20个字节的地址。
- block
区块,是以太坊区块链的基本数据结构,每个区块包括(0个或多个交易的)交易信息,父区块、叔伯区块的散列码(hash code),其他可选数据信息等。通过父区块的散列码,可以遍历前向区块,获取历史交易信息。
- block header
区块头,指区块的头数据,包含父区块、叔伯区块、交易根、状态根、交易回执的散列码(hash code),以及其他交易要素,如挖矿账户地址、区块数量、奖励等构成。通过父区块的散列码,可以遍历前向的区块,获取交易历史信息。
- currency(Eth and ETC)
以太坊货币是以太坊网络的原生货币(称为ETH),被用于奖励矿工的挖矿操作。著名的DAO黑客事件发生后,为了解决黑客攻击的影响,硬分叉被提出,即将一部分区块从经典区块链分离出来,形成新的区块链,经典区块链采用数字货币称为ETC,新区块链沿用数字货币ETH,并接受后续的版本升级。
- contract
合约,表示一组可执行代码(合约功能)和数据(账户状态)的集合。合约驻留在以太坊区块链的特定地址中,由合约账户通过消息传递的方式促发合约运行,具有图灵完备的计算效果。合约在以太坊区块链的形态是一串编译成二进制的可执行代码,被称为EVM(Ethereum Virtual Machine)。已知编写合约脚本的典型高阶语言是solidity,具有图灵完备的性质,用高级语言编写的脚本要经过编译器(如solc)编译,生成二进制代码后,才能上载到以太坊区块链向全网发布。
- Ethash
在以太坊区块链中,指原生支持工作量证明(POW)的散列算法。该算法常采用SHA3-256或SHA3-512版本,也称为keccak-256或keccak-512。
- ether
以太币,以太坊区块链的有价代币,其在加密货币交易所上市的货币符号是ETH。ether具有市场价格,支持在加密货币市场交易,也可作为货币价值在以太坊账户之间自由转移,为合约执行支付交易费用。
- gas
向矿工支付的交易费用。在以太坊中,记账需要消耗计算资源,为激励矿工参与记账,交易发起方要支付一定数量的交易费用,对成功打出区块的矿工实施奖励。
- gas limit
交易费用上限,交易和区块的设置参数。对个人交易,指用户指定的交易费用(gas)上限,保护用户在执行有缺陷或恶意合约时,不至于损失过多的以太币。对区块,指区块中所有交易费用的累积值。
- gas price
一个单位gas的价格。在以太坊的Homestead版本中,一个gas的价格是20shannon(指以太币单位)。
- Hard fork
硬分岔,指区块链被分割成两条独立运行的区块链,两条区块链分别采用不同管控规则的形态。硬分岔通常是由于代码缺陷,引起黑客攻击所致,主要作为平衡各方利益采取的不得已而为之的手段。
- light client
轻量级的客户端程序,允许在较低配置的环境中执行和检查执行交易,却无需执行全网的节点程序(如Geth)。
- mining
挖矿,形象地指在以太坊区块链上,通过不断执行区块发现指令以验证交易和智能合约执行的合法性,从矿池打包交易,从而获取报酬的竞争性行为。
- mining pool
矿池,形象地表示矿工的资源池。矿工平等地分享计算能力,并通过所提供的计算能力的多少获取相应报酬,多劳多得。
- nonce
一种随时间流逝而发生变化的数码,常常被用于特定的技术场景,如会话证明的校验码,工作量证明生成散列码等。
- RLP
递归长度前缀编码,用于封装任意嵌套的二进制队列结构,在以太坊,RLP是主要的序列化对象的编码方法,适用于封装复杂结构体,特殊的高阶协议的数据结构等。
- receipt
交易回执。执行智能合约是验证过程的重要环节,设想通过函数调用智能合约,由于交易是异步执行的,并没有交易的反馈信息。因此,以太坊网络通过向其他节点广播事件日志,实现消息通信,该事件日志作为交易回执的组成部分,是执行交易的返回结果。交易回执以merkle树结构存储,其作为区块头的一部分,与账户状态根,交易根一起,共同保证着以太坊区块链的完整性
- Transactions
以太坊交易,指经由发起人签名的数据包,该数据包存储了交易信息,其包的信息有:交易回执,交易签名,交易金额,交易费用,交易费用价格,以及一些可选参数等。当交易发生时在不同外部账户之间传递。
- Uncle
叔伯块,与最新插入的区块具有相同的父区块。叔伯块的产生归因于两个或多个矿工同时发现区块,但矿工网络连接条件不佳和区块产生时间窗口较少等因素的影响,致所产生的区块到达其他节点延迟,该节点已经打上新区块,故只能允许后通知的区块作为较早发现区块的兄弟存在。与比特币的策略不同,以太坊奖励发现叔伯块的矿工,对网络条件不佳的挖矿节点予以补偿,确保更多的计算力集中起来统一管理。
- wallet
以太坊钱包,与传统意义的钱包类似,用于保存以太币或其他加密货币。以太坊钱包管理一组公私密钥对,在加密货币应用中实现加密货币的管理和认证。
- world state
世界状态,表示以太坊区块链的全局状态,与20位字节的以太坊地址构成映射关系。地址表示为20个字节的长度值,全局状态被封装成RLP的编码格式。
1.3、以太坊周边的常用工具
2、什么是 Go-Ethereum?
Go-Ethereum
是由以太坊基金会提供的官方客户端软件。它是用Go编程语言编写的,简称Geth
。其中以下几个组件是值得了解的:
- Geth 客户端
当你开始这个客户程序,它连接到其他客户端(也称为节点)的网络下载同步区块。它将不断地与其他节点进行通信来保持它的副本是最新的。它还具有挖掘区块并将交易添加到块链的能力,验证并执行区块中的交易。它还可以充当服务器,您可以通过RPC来访问暴露的API接口。
- Geth 终端
这是一个命令行工具,可以让您连接到正在运行的节点,并执行各种操作,如创建和管理帐户,查询区块链,签署并将交易提交给区块链等等。更多介绍 点击这里
3、Go-Ethereum的开源地址在哪里?
https://github.com/ethereum/go-ethereum
4、如何安装Go-Ethereum 1.7.2
本文中使用的方法是通过Git
下载源码,本地编译Go-Ethereum 1.7.2
git clone https://github.com/ethereum/go-ethereum.git
cd go-ethereum
git checkout v1.7.2
make all
4.1、控制台命令
geth
ethereum网络的主入口程序,默认执行会连接到共同以太网络,接受全网节点数据同步。
abigen
以太坊源码转换器,支持将智能合约定义脚本(.abi,.sol)转换为类型安全的go语言包。
bootnode
以太坊客户端的精简版本,仅参与执行网络节点发现协议。
evm
提供给开发者使用的以太坊虚拟机(EVM),可方便运行和调试字节码命令。
gethrpctest
提供给开发者使用的rpc测试工具,支持在Ethereum/rpc-test项目中执行。
rlpdump
提供给开发者使用的RLP(递归长度前缀编码)转换工具,支持将RLP转换成层次结构分明的数据结构体。
swarm
swarm工具,也是swarm网络的入口程序。
puppeth
CLI向导程序,指导快速创建新的以太坊网络。
查看安装好的geth
版本号
>geth version
Geth
Version: 1.7.2-stable
Git Commit: 1db4ecdc0b9e828ff65777fb466fc7c1d04e0de9
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.9.1
...
5、开始创建以太坊私有链
5.1、初始化一个创世区块
初始化创世区块时,要先创建一个genesis.json
文件,内容如下:
genesis.json:
{
"config": {
"chainId": 10,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x00400",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00",
"alloc" : {}
}
参数名称 | 参数描述 |
---|---|
mixhash | 与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意他和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。 |
nonce | nonce就是一个64位随机数,用于挖矿,注意他和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。 |
difficulty | 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度 |
alloc | 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要预置有币的账号,需要的时候自己创建即可以。 |
coinbase | 矿工的账号,随便填 |
timestamp | 设置创世块的时间戳 |
parentHash | 上一个区块的hash值,因为是创世块,所以这个值是0 |
extraData | 附加信息,随便填,可以填你的个性信息 |
gasLimit | 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。 |
接下来,我们使用命令来进行创世区块的初始化,当前区块链网络数据存放的位置会保存在./chain
目录中:
./geth --datadir "./chain" init ./genesis.json
效果如下:
WARN [10-22|14:49:09] No etherbase set and no accounts found as default
INFO [10-22|14:49:09] Allocated cache and file handles database=/xxx/chaindata cache=16 handles=16
INFO [10-22|14:49:09] Writing custom genesis block
INFO [10-22|14:49:09] Successfully wrote genesis state database=chaindata hash=5e1fc7…d790e0
INFO [10-22|14:49:09] Allocated cache and file handles database=/xxx/lightchaindata cache=16 handles=16
INFO [10-22|14:49:09] Writing custom genesis block
INFO [10-22|14:49:09] Successfully wrote genesis state database=lightchaindata hash=5e1fc7…d790e0
5.2、启用私有链
执行geth可以启动私有链,但需要配置一些参数,将区块链数据目录指向data,同时还要配置端口,网络id等一系列参数。下表列出了通过geth启动私有链所涉及的参数:
参数名称 | 参数描述 |
---|---|
datadir | 设置当前区块链网络数据存放的位置 |
console | 启动命令行模式,可以在Geth中执行命令 |
nodiscover | 私有链地址,不会被网上看到 |
networkid | 区块链网络ID,用于区分不同的网络(以太坊公网的网络ID是1) |
port | 网络监听端口,默认值:30303 |
rpc | Http-rpc通信侦听端口(默认值8485),智能合约部署和调试 |
rpcapi | 设置允许连接的rpc的客户端,一般为db,eth,net,web3 |
启用私有链(--dev
参数可以省略5.1初始化操作,并分配一个默认账户):
./geth --datadir "./chain" --rpc --rpcaddr="0.0.0.0" --rpcapi="db,eth,net,web3,personal,admin" --nodiscover console 2>> geth.log
console,表示启动节点并进入交互式控制台,运行上面的命令后,就启动了区块链节点并进入了Javascript Console,是一个交互式的Javascript执行环境,如下欢迎信息提示后,输出了提示符“>”。
console运行环境内置了一些命令,用以操作以太坊的Javascript对象,用户可以直接使用这些对象。这些对象主要包括:
eth
区块链网络相关的操作net
查看网络状态的方法admin
管理节点的方法miner
启动和停止挖矿的操作personal
管理账户的方法txpool
查看交易内存和内容的方法web3
该对象包含上述方法
在当前目录执行tail -f geth.log
,可以看到输出日志。
>tail -f geth.log
INFO [10-22|14:50:04] Bloom-bin upgrade completed elapsed=149.285µs
INFO [10-22|14:50:04] Initialising Ethereum protocol versions="[63 62]" network=1
INFO [10-22|14:50:04] Database conversion successful
INFO [10-22|14:50:04] Loaded most recent local header number=0 hash=5e1fc7…d790e0 td=131072
INFO [10-22|14:50:04] Loaded most recent local full block number=0 hash=5e1fc7…d790e0 td=131072
INFO [10-22|14:50:04] Loaded most recent local fast block number=0 hash=5e1fc7…d790e0 td=131072
INFO [10-22|14:50:04] Starting P2P networking
INFO [10-22|14:50:04] RLPx listener up self="enode://bcc414219b7423f56da261857508771c229a5ee370e2d5bee7a9d1a3886ae9c207956a80e03f7ba44ed5f9f7777ac64db9b6939d18f3f44786dc6fc5690035b1@[::]:30303?discport=0"
INFO [10-22|14:50:04] IPC endpoint opened: /xxx/chain/geth.ipc
INFO [10-22|14:50:05] Mapped network port proto=tcp extport=30303 intport=30303 interface=NAT-PMP(10.0.0.1)
后面章节中的命令,都是在启动私有链后的
Geth javascript console
中操作
5.2.1、帐户的添加和查看
查看帐户,可以看到当前帐户是空的
> web3.eth.accounts
[]
创建帐户的方式有两种,第一种创建帐户时直接初始化密码
> web3.personal.newAccount("123456")
"0xbe323cc4fde114269a9513a27d3e985f82b9e25d"
其中返回的
0xbe323cc4fde114269a9513a27d3e985f82b9e25d
是帐户,123456
是帐户的密码
第二种方法是先创建账户,然后输入密码
> web3.personal.newAccount()
Passphrase:
Repeat passphrase:
"0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70"
这时我们再查看帐户,能够看到刚才创建的两个帐户已经存在了
> web3.eth.accounts
["0xbe323cc4fde114269a9513a27d3e985f82b9e25d", "0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70"]
5.2.2、开始挖矿和停止挖矿
挖矿执行以下命令:
> miner.start(1)
执行以后,通过刚才查看日志的方法tail -f geth.log
,能够看到类似下面的日志,说明挖矿已经在进行.
INFO [10-22|15:01:32] Commit new mining work number=70 txs=0 uncles=0 elapsed=2.000s
INFO [10-22|15:01:34] Successfully sealed new block number=70 hash=a0cfd2…f99c06
INFO [10-22|15:01:34] block reached canonical chain number=65 hash=3f6d16…586aba
INFO [10-22|15:01:34] mined potential block number=70 hash=a0cfd2…f99c06
INFO [10-22|15:01:34] Commit new mining work number=71 txs=0 uncles=0 elapsed=163.977µs
INFO [10-22|15:01:34] Successfully sealed new block number=71 hash=f84b8a…7468e1
INFO [10-22|15:01:34] block reached canonical chain number=66 hash=6ca3b9…e959e8
INFO [10-22|15:01:34] mined potential block number=71 hash=f84b8a…7468e1
挖矿会默认保存到创建的第一个帐户
0xbe323cc4fde114269a9513a27d3e985f82b9e25d
中。
block number=66,说明我们已经创建了66个区块
在以太坊官方的网络上,平均每15秒产生一个区块
停止挖矿执行以下命令:
> miner.stop()
停止挖矿后,以太币则不会产生,同样智能合约、转帐等操作也不会起作用。
5.2.3、查看帐户余额
查看帐户余额的方法如下:
> web3.eth.getBalance("0xbe323cc4fde114269a9513a27d3e985f82b9e25d")
1.245e+21
> web3.eth.getBalance("0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70")
0
每次记一长串的地址很麻烦,我们可以通过设置变量来acc0
表示帐户10xbe323cc4fde114269a9513a27d3e985f82b9e25d
,acc1
表示帐户20x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70
.
> acc0 = web3.eth.accounts[0]
"0xbe323cc4fde114269a9513a27d3e985f82b9e25d"
> acc1 = web3.eth.accounts[1]
"0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70"
> web3.eth.getBalance(acc0)
1.245e+21
> web3.eth.getBalance(acc1)
0
## 使用这个方法可以查看格式化的以太币
> web3.fromWei(web3.eth.getBalance(acc0))
1245
以太币最小的单位是wei(18个0)
因为geth javascript console
是基于javascript的,所以也可以创建js函数,查看所有帐户余额
> function checkAllBalances() {
var totalBal = 0;
for (var acctNum in eth.accounts) {
var acct = eth.accounts[acctNum];
var acctBal = web3.fromWei(eth.getBalance(acct), "ether");
totalBal += parseFloat(acctBal);
console.log(" eth.accounts[" + acctNum + "]: \t" + acct + " \tbalance: " + acctBal + " ether");
}
console.log(" Total balance: " + totalBal + " ether");
};
> checkAllBalances()
eth.accounts[0]: 0xbe323cc4fde114269a9513a27d3e985f82b9e25d balance: 1245 ether
eth.accounts[1]: 0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70 balance: 0 ether
Total balance: 1245 ether
如果命令较多,可以保存到一个脚本里,使用命令载入脚本:loadScript(‘/path/script/here.js’)
5.2.4、转帐操作
从帐户0xbe323cc4fde114269a9513a27d3e985f82b9e25d
转3个以太币到0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70
,如果不指定单位ether,默认转的是wei。
> web3.eth.sendTransaction({from:acc0,to:acc1,value:web3.toWei(3,"ether")})
Error: authentication needed: password or unlock
at web3.js:3104:20
at web3.js:6191:15
at web3.js:5004:36
at <anonymous>:1:1
当直接执行此方法时会抛出异常,显示帐号被锁
解锁转帐帐户
> acc0 = web3.eth.accounts[0]
> web3.personal.unlockAccount(acc0,"123456")
true
解锁完成之后,即可执行转账操作。
> web3.eth.sendTransaction({from:acc0,to:acc1,value:web3.toWei(3,"ether")})
"0x472f26a00d244b91fea9ff05d9cd5ff5259d8618301bb14af4499827eb159056"
但此时查看时会发现接收账户依旧为原来数值。此时需要执行挖矿命令,才会把转账真正完成。
> checkAllBalances()
eth.accounts[0]: 0xbe323cc4fde114269a9513a27d3e985f82b9e25d balance: 1245 ether
eth.accounts[1]: 0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70 balance: 0 ether
Total balance: 1245 ether
undefined
> miner.start()
null
> checkAllBalances()
eth.accounts[0]: 0xbe323cc4fde114269a9513a27d3e985f82b9e25d balance: 1257 ether
eth.accounts[1]: 0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70 balance: 3 ether
Total balance: 1260 ether
undefined
> miner.stop()
true
5.2.5、查看交易和区块
eth
对象封装了查看交易和区块信息的方法。
查看当前区块总数:
> eth.blockNumber
33
通过交易hash查看交易:
> eth.getTransaction("0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825")
{
blockHash: "0xf5d3da50065ce5793c9571a031ad6fe5f1af326a3c4fb7ce16458f4d909c1613",
blockNumber: 33,
from: "0xc232e2add308136571bb8f9197ba4ae4e5ba9836",
gas: 90000,
gasPrice: 20000000000,
hash: "0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825",
input: "0x",
nonce: 0,
r: "0x433fe5845391b6da3d8aa0d2b53674e09fb6126f0070a600686809b57e4ef77d",
s: "0x6b0086fb76c46024f849141074a5bc79c49d5f9a658fd0fedbbe354889c34d8d",
to: "0x814d39aa21f3eed069f2b21da7b5f857f7343afa",
transactionIndex: 0,
v: "0x1b",
value: 5000000000000000000
}
通过区块号查看区块:
> eth.getBlock(33)
{
difficulty: 132928,
extraData: "0xd783010506846765746887676f312e372e33856c696e7578",
gasLimit: 3244382,
gasUsed: 21000,
hash: "0xf5d3da50065ce5793c9571a031ad6fe5f1af326a3c4fb7ce16458f4d909c1613",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0xc232e2add308136571bb8f9197ba4ae4e5ba9836",
mixHash: "0x09849dff7c8b8467812fa80d1fa2a27bc61f1cf16d5b2c05a6ce1b77ee18f3f1",
nonce: "0x5b3939449dbdbea0",
number: 33,
parentHash: "0xeca34637642f56f7cfe5b699031c7ddbc43aee00fb10c7f054e0a9719cf226da",
receiptsRoot: "0xd5f5b7ee944e57cbff496f7bdda7ceffd5eedffe6d5be5320008190502adc07a",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 649,
stateRoot: "0xc7add6b756980ab9e482766e455597ef1583e747ad62e2924a8e66c6f9170112",
timestamp: 1490183209,
totalDifficulty: 4358016,
transactions: ["0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825"],
transactionsRoot: "0x7335a362b2c3925e7ba1b41bf7772aa9645a13d4f9c12edd5892b87887264232",
uncles: []
}
5.2.6、连接到其他节点
可以通过admin.addPeer()
方法连接到其他节点,两个节点要想联通,必须保证网络是相通的,并且要指定相同的networkid。
假设有两个节点:节点一和节点二,networkid都是1108,通过下面的步骤就可以从节点一连接到节点二。
首先要知道节点二的enode
信息,在节点二的js console中执行下面的命令查看enode
信息:
> admin.nodeInfo.enode
"enode://9e86289ea859ca041f235aed87a091d0cd594b377cbe13e1c5f5a08a8a280e62d4019ac54063ed6a1d0e3c3eaedad0b73c40b99a16a176993f0373ffe92be672@[::]:30304"
然后在节点一的js console中执行admin.addPeer()
,就可以连接到节点二:
> admin.addPeer("enode://9e86289ea859ca041f235aed87a091d0cd594b377cbe13e1c5f5a08a8a280e62d4019ac54063ed6a1d0e3c3eaedad0b73c40b99a16a176993f0373ffe92be672@127.0.0.1:30304")
addPeer()
的参数就是节点二的enode
信息,注意要把enode
中的[::]
替换成节点二的IP地址。连接成功后,节点二就会开始同步节点一的区块,同步完成后,任意一个节点开始挖矿,另一个节点会自动同步区块,向任意一个节点发送交易,另一个节点也会收到该笔交易。
通过admin.peers
可以查看连接到的其他节点信息,通过net.peerCount
可以查看已连接到的节点数量。
除了上面的方法,也可以在启动节点的时候指定--bootnodes
选项连接到其他节点。
===================================
编译遇到错误:
vendor/github.com/karalabe/hid/hidapi/libusb/hid.c:444:对‘libiconv_open’未定义的引用
vendor/github.com/karalabe/hid/hidapi/libusb/hid.c:456:对‘libiconv’未定义的引用
vendor/github.com/karalabe/hid/hidapi/libusb/hid.c:471:对‘libiconv_close’未定义的引用
collect2: error: ld returned 1 exit status
解决方法:
安装libiconv,并添加链接参数:-liconv
编辑:go-ethereum-1.8.1/vendor/github.com/karalabe/hid/hid_enabled.go,修改如下:
#cgo linux,!android LDFLAGS: -lrt -liconv