一、环境要求

  1. 需要预先安装好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

二、搭建私有链

  1. 在启动私有链之前, 需要指定一些创世区块的数据, 所以, 预先需要有一个创世区块的配置文件
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