Puppeth是以太坊go客户端工具中提供的一个实用工具. 通过puppeth可以在自有环境中快速搭建起以太坊私链.

安装Ethereum Go 客户端(geth)

下载并安装Ethereum的Go客户端, 目前最新稳定版为1.7.2

https://ethereum.github.io/go-ethereum/downloads/

安装完成go-ethereum后, go客户端中就带有puppeth

搭建以太坊私有链

本文档搭建3个Ethereum节点, 分别为: node1, node2, node3.

这3个节点可以分别安装在不同电脑上, 也可以安装在同一台电脑上.

以下配置说明都是基于在同一台电脑上, 电脑环境:

环境准备

分别创建3个节点目录, 每个目录下各自保存各节点的账号, 区块链数据

mkdir ethereum
cd ethereum
mkdir node1
mkdir node2
mkdir node3

建立账号

为每个节点各自建立一个账号. 运行命令后会提示输入密码用于保护你的以太坊账号私钥. 这里直接回车跳过密码设置. 生成账号后, 命令返回账号对应的地址.

geth --datadir ./node1/data account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {117b88219433dcbe8d24e961283bf57a800b0e91}

使用相同命令给node2, node3各自创建新账号

geth --datadir ./node2/data account new
geth --datadir ./node3/data account new

记录下新生成的账号, 后续测试私链可以用到. (万一没有记录,也没有关系, 后续可以通过geth console查询)

建立创世块(Genesis Block)

创世块是区块链中第一个区块(唯一无需引用前个区块的区块). 通过运行puppeth, 来生成创世区块. 运行puppeth后首先提示输入私链名称.

puppeth
+-----------------------------------------------------------+
| Welcome to puppeth, your Ethereum private network manager |
|                                                           |
| This tool lets you create a new Ethereum network down to  |
| the genesis block, bootnodes, miners and ethstats servers |
| without the hassle that it would normally entail.         |
|                                                           |
| Puppeth uses SSH to dial in to remote servers, and builds |
| its network components out of Docker containers using the |
| docker-compose toolset.                                   |
+-----------------------------------------------------------+

Please specify a network name to administer (no spaces, please)
>frank-private-chain
Sweet, you can set this via --network=frank-private-chain next time!

输入完私链名称后, 出现选择菜单. 选择2: 配置新创世块

What would you like to do? (default = stats)
 1. Show network stats
 2. Configure new genesis
 3. Track new remote server
 4. Deploy network components

出现子菜单, 选择私链的共识机制(Consensus Protocols).

这里选择PoW的认证方式, 和目前以太坊主链保持一致.(PoA配置方式: 请点击传送门)

Which consensus engine to use? (default = clique)
 1. Ethash - proof-of-work
 2. Clique - proof-of-authority
> 1

选择是否需要初始化就给指定账号ether, 这里可以输入之前建立账号的地址.直接回车结束输入

Which accounts should be pre-funded? (advisable at least one)
> 0x

输入私链ID, 直接输入回车,已默认随机数作为私链ID

Specify your chain/network ID if you want an explicit one (default = random)
>

创世块中可以输入个人个性化信息, 这里可以随便输入字符.

Anything fun to embed into the genesis block? (max 32 bytes)
>This is Frank's private chain.

回到主菜单, 重新选择2

What would you like to do? (default = stats)
 1. Show network stats
 2. Manage existing genesis
 3. Track new remote server
 4. Deploy network components
>

选择导出创世块配置文件

 1. Modify existing fork rules
 2. Export genesis configuration
>2

在提示创世块配置文件位置时, 直接输入回车, 默认当前目录生成创世块配置文件

Which file to save the genesis into? (default = frank-private-chain.json)
>

创世块配置文件生成后, 会回到主菜单, 直接按Ctrl-C退出puppeth.

初始化/启动私链节点

通过如下命令初始化各个节点的数据. 如下命令

geth --datadir node1/data init frank-private-chain.json
geth --datadir node2/data init frank-private-chain.json
geth --datadir node3/data init frank-private-chain.json

开启3个终端, 每个终端中分别启动各自的以太坊节点

geth --datadir ./node1/data --port 2001
geth --datadir ./node2/data --port 2002
geth --datadir ./node3/data --port 2003

参数说明:

添加节点

私链中设置的节点, 默认是无法互相发现并连接, 需要手工添加节点.(以太坊主链则通过在代码中预设了启动节点, 可以启动发现其他节点)

登录node1, 获取节点地址

geth attach ipc:node1/data/geth.ipc

instance: Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9.1
coinbase: 0x117b88219433dcbe8d24e961283bf57a800b0e91
at block: 12 (Tue, 07 Nov 2017 22:59:42 CST)
 datadir: /Users/liuhao/Downloads/ethereum/node1/data
 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

> admin.nodeInfo.enode
"enode://8168f0ffc7b29680c3afaaf5e88c63bf5f89d147fa8a84ca11e5205fc27886bafb6bfc6a1bde78ed2f1c02fd9eea8b53120bc548276d3f7de58e3bf4a02dd643@[::]:2001"

在返回的节点地址中, 地址组成为”enode://<节点id>@IP地址:端口”

将IP地址部分替换成127.0.0.1(如果是安装在不同电脑上, 则替换成当前节点所在电脑的IP地址)

分别登录node2, node3, 添加链接到node1

geth attach ipc:node2/data/geth.ipc
>admin.addPeer("enode://429dd761506640fd2d581927b969ecdd6876437118a6c14bf8d99096e7d98d1cd2af2da9f93614263a773bf8ec1f6e9cbf9e75b686e113341e4ced78b0673b84@127.0.0.1:2001”)

再次登录node1, 查看是否节点链接正确

geth attach ipc:node1/data/geth.ipc
>net.peerCount
2

也可以获得链接节点的详细信息

geth attach ipc:node1/data/geth.ipc
>admin.peers
[{
    caps: ["eth/63"],
    id: "51fa46b906bbe98a55448d6ec84f20df1ee879123d9cbe3d25ac81982db4fb14a9b42b9f332aa7bd2d1c006f64d15c3740b0e9d1e42bb3858a4fe852d815f860",
    name: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9.1",
    network: {
      localAddress: "127.0.0.1:2001",
      remoteAddress: "127.0.0.1:57710"
    },
    protocols: {
      eth: {
        difficulty: 1048576,
        head: "0x632e6d1e792d4e92e85e717067bb6aa586832db03d79c5decb48d826ff7a715a",
        version: 63
      }
    }
}, {
    caps: ["eth/63"],
    id: "88d8df057ad1c1e863ba91a0f04fd6011bbf91ca9e806a5408a17bf653176064614e78416afbe3227b825f2ddab279e86d348bca1baaa6ae1c30f054a020fa17",
    name: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9.1",
    network: {
      localAddress: "127.0.0.1:2001",
      remoteAddress: "127.0.0.1:57719"
    },
    protocols: {
      eth: {
        difficulty: 1048576,
        head: "0x632e6d1e792d4e92e85e717067bb6aa586832db03d79c5decb48d826ff7a715a",
        version: 63
      }
    }
}]

测试私链

挖矿

使用node3节点进行挖矿, 挖矿前可以看到account3账户余额为0.

使用miner.start()开始挖矿(geth采用CPU算力挖矿). 等待10到20秒后, 可以使用miner.stop()停止挖矿.

再次查询余额就可以看到挖矿获得的ether

geth attach ipc:node3/data/geth.ipc
>eth.getBalance(eth.accounts[0])
0
>miner.start()
null
>miner.stop()
true
>eth.getBalance(eth.accounts[0])
45000000000000000000

转账

完成挖矿后, 可以将挖到的ether转账给其他账户.

登录node3 console, 首先解锁account3账号, 然后将指定金额的ether转账给其他账号(例子中为转账给account1账号, 如果没有在之前记录account1账号地址, 则可以通过”eth.accounts”获取账号地址信息).

转账命令运行后会返回transaction id, 通过该transaction id可以查询到转账交易相关信息

geth attach ipc:node3/data/geth.ipc
>personal.unlockAccount(eth.accounts[0])
>eth.sendTransaction({from:eth.accounts[0], to:"117b88219433dcbe8d24e961283bf57a800b0e91", value:20000})
"0x9da356310da637a8b9856098d95cf08fd9feb687991abbf9bcfc4f1d7b9a08ab"
>eth.getTransaction("0x9da356310da637a8b9856098d95cf08fd9feb687991abbf9bcfc4f1d7b9a08ab")

注:

其他说明

PoA说明

建立创世块时, 也可以选择采用PoA方式的共识算法(不消耗计算力, 可以用于私链测试开发)

Which consensus engine to use? (default = clique)
 1. Ethash - proof-of-work
 2. Clique - proof-of-authority
> 2

选择PoA后, 会提示选择出块的间隔时间. 由于是用于内部测试的私链, 可以将出块时间设置较少, 这里配置5秒.

How many seconds should blocks take? (default = 15)
> 5

设置那个账号作为权威来生成块, 这里输入account3账号作为权威账号

Which accounts are allowed to seal? (mandatory at least one)
> 0x7fa7dff92c1a0a3384975f7c5dd8272ec5349712
> 0x

之后的配置和PoW的配置相同

挖矿注意:

PoA共识算法下, 在挖矿之前,需要保持账号unlock.

geth attach ipc:node3/data/geth.ipc
> personal.unlockAccount(eth.accounts[0])
> miner.start()

链接节点参数

可以将启动链接节点添加到命令行参数中, 而不需要再在geth控制台中通过admin.addPeer添加节点

geth --datadir ./node2/data --port 2002 --bootnodes enode://7b9d6c06ea731c4e3c990472fccf41e80e1f10699c526c3d02b1adf8a5bd1ca51861f10f8d55b95c666e5df607efc21063d81e9e21dbaec800865efdcbfcbe9b@127.0.0.1:2001
geth --datadir ./node3/data --port 2003 --bootnodes enode://7b9d6c06ea731c4e3c990472fccf41e80e1f10699c526c3d02b1adf8a5bd1ca51861f10f8d55b95c666e5df607efc21063d81e9e21dbaec800865efdcbfcbe9b@127.0.0.1:2001