一、环境要求
- 需要预先安装好golang, 以及 geth客户端环境
geth version # 命令行输入
看到如下输入, 表示安装成功:
Geth
Version: 1.8.3-stable
Git Commit: 329ac18ef617d0238f71637bffe78f028b0f13f7
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10
Operating System: darwin
二、搭建私有链
- 在启动私有链之前, 需要指定一些创世区块的数据, 所以, 预先需要有一个创世区块的配置文件
cd ~/geth_test; cat > genesis.json <<EOF
{
"config": {
"chainID": 1024,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc": {},
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x400",
"extraData": "",
"gasLimit": "0x2fefd8",
"nonce": "0x0000000000000000",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00"
}
EOF
- chainId: 用于标记一条以太链的ID,它必须和你的代码中交易时的chainId一致。
- homesteadBlock: 值为0表示,它使用ethereum homestead release。Homestead是第二个重要的以太坊版本。
- eip155Block/eip158Block: 值0表示,该块支持EIP(ethereum改进建议)155/158
- alloc: 预先指定账户, 和账户对应的账户余额
"alloc":
{
"7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "100000" },
}
- coinbase: 默认的矿工账号,挖矿成功时会默认把所得的挖矿奖励存入这个账号
- difficulty: 设置挖矿难度,私有链在测试时可将该值设置小点,使得区块容易被挖出来,测试效率更高
- extraData: 附加信息,随便填
- gasLimit: GAS 的消耗量限制,用来限制区块能包含的交易信息总和
- nonce: 一个 64 位随机数,用于挖矿
- mixhash: 与 nonce 配合用于挖矿
- parentHash: 上一个区块的 hash 值,创世块的该值为 0
- timestamp: 设置创世块的时间戳
- 以创世区块文件, 进行初始化链, 并且启动节点
# 初始化创世区块
geth --datadir "./peer1" init genesis.json
# 启动节点
geth --datadir "./peer1" --networkid 27 --port 30000 console
- 节点的相关操作:
# 查看账号, 创世文件alloc中可以预先设置
eth.accounts # 此时为 []
# 创建账号
personal.newAccount("123") # 此时 keystore中被写入内容. 并且 eth.accounts 有值
# 获取账户余额
eth.getBalance(eth.accounts[0])
# 挖矿账户
eth.coinbase # 默认会设置成 eth.accounts中第一个账号
# 挖矿
miner.strat() # 使用eth.coinbase进行挖矿
# 停止挖矿
miner.stop()
# 手动设置挖矿账户
miner.setEtherbase(eth.accounts[1]) # 节点重启, 那么会默认设置会 eth.accounts中第一个账户
# 查看节点信息
admin.nodeInfo
# 检测查看所有节点
admin.peers
三、多节点相互转账
3.1 启动第二个节点, 须跟其他节点的networkid相同, 才能进行连接
# 创建私有链
geth --datadir "./peer2" init genesis.json # 基于同一份创世区块产生的节点, 才能连接成功
# 连接
geth --datadir "./peer2" --networkid 27 --port 30001
# 根据ipc 连接
geth attach ipc:node2/geth.ipc
3.2 查看节点2信息
# 节点2
admin.nodeInfo
结果如下:
{
enode: "enode://2cb474dd7ace3cb55d07b3bc5a1bc6b485871ec3be42f6bfb2e32b9ab07782132f122e25529f7a8d0e1fc625a47af6cb3a11928451bbc68514c22b4ee21c7c19@100.104.116.215:30001",
id: "2cb474dd7ace3cb55d07b3bc5a1bc6b485871ec3be42f6bfb2e32b9ab07782132f122e25529f7a8d0e1fc625a47af6cb3a11928451bbc68514c22b4ee21c7c19",
ip: "100.104.116.215",
listenAddr: "[::]:30001",
name: "Geth/v1.8.3-stable-329ac18e/darwin-amd64/go1.10",
ports: {
discovery: 30001,
listener: 30001
},
protocols: {
eth: {
config: {
chainId: 1024,
eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
eip155Block: 0,
eip158Block: 0,
homesteadBlock: 0
},
difficulty: 3675328,
genesis: "0x87cc103e1dec7865c98aee0f12575d70f772833fa449d44895465ec64ac47296",
head: "0x8e13e488fc8d6f18ba50a131775be6af4104bfb657afcfdf388839b7cff71331",
network: 27
}
}
}
- encode: 节点编码, 根据此编码进行添加节点
3.3 节点1进行添加节点, 指定节点2的encode
# 节点1
admin.addPeer("enode://2cb474dd7ace3cb55d07b3bc5a1bc6b485871ec3be42f6bfb2e32b9ab07782132f122e25529f7a8d0e1fc625a47af6cb3a11928451bbc68514c22b4ee21c7c19@100.104.116.215:30001")
# 节点1 节点2中都可以查看到对方
admin.peers
3.4 节点1和节点2进行相互转账
3.4.1给节点2创建账号
# 节点2
personal.newAccount("333")
结果:
"0x6d9001d15cc6ed6738ff5aaac6fa1ae8f5ea7cf0"
3.4.2节点1解锁账号. 账号进行转账, 必须先进行解锁, 输入密码, 才能完成转账.
# 节点1
personal.unlockAccount(eth.accounts[0]) # 解锁账户, 输入密码
# 节点1转账给节点2
eth.sendTransaction({from: eth.accounts[0], to: '0x6d9001d15cc6ed6738ff5aaac6fa1ae8f5ea7cf0', value: web3.toWei('10', 'ether')})
# 查看交易池状态
txpool.status
3.4.3 此时, 转账交易, 已加入交易池, txpool中, 是按照gas费用最高, 交易nonce值越小的进行排序, 打包区块, 全节点本地执行交易,
直到成功挖矿, 广播区块到全网之后, 交易才会真正的被写入区块链
# 进行挖矿
miner.start()
# 再次查看交易池
txpool.status # 此时pending为空
3.4.4 此时转账以完成, 通过查看节点2余额来进行验证
# 查看节点2账户余额
eth.getBalance(eth.accounts[0]) # 查看到转入10个eth