Docker搭建以太坊私有链

3,030 阅读15分钟

获取geth镜像

docker pull ethereum/client-go:v1.9.25

启动(默认启动是公链)

  • 普通方式启动
sudo docker run -it --name eth_miner -p 30303:30303 ethereum/client-go:v1.9.25 
  • 控制台交互式启动
sudo docker run -it --name eth_miner -p 30303:30303 ethereum/client-go:v1.9.25 console
  • 可远程交互式启动

"0.0.0.0" 参数会在8548端口上接受所有主机发送的请求,公用网络慎用

sudo docker run -it --name eth_miner -p 8545:8545 -p 30303:30303 ethereum/client-go:v1.9.25 --rpc --rpcaddr "0.0.0.0"
  • 制定存储位置启动
sudo docker run -it --name geth_miner -p 30303:30303 -v /ethereum/dapp/geth_miner:/root  ethereum/client-go:v1.9.25 

进入容器

sudo docker exec -it geth_miner /bin/sh

或者

sudo docker exec -it d96e618104a6 /bin/sh

新建需要映射给容器存放数据的目录

  • 创建目录(容器内被映射目录:/root
[root@localhost ~]# mkdir -p /dapp/private_chain_data

私有链搭建

  • 创建/dapp/private_chain_data/genesis.json具体内容在下面创始区块文件

  • 运行私有链

 docker run \
    -itd \
    --name geth_miner \
    -v /etc/localtime:/etc/localtime \
    -v /etc/timezone:/etc/timezone   \
    -v /dapp/private_chain_data/genesis.json:/dapp/genesis.json \
    -v /dapp/private_chain_data:/dapp \
    -p 8545:8545 \
    -p 30303:30303 \
    -p 30303:30303/udp \
    --entrypoint /bin/sh \
    ethereum/client-go:v1.9.25 \

--entrypoint:这里替换了geth这个默认命令,只创建创建容器,没有运行geth,就不会默认连接主链启动了

创世区块

  • 创始区块文件(容器目录:/dapp/genesis.json

注:非常重要!!!此文件是搭建以太坊私链最重要的文件

使用上述JSON文件中定义的创始状态,您需要在启动每个geth节点之前对其进行初始化,以确保正确设置所有区块链参数

应为容器/dapp/genesis.json挂载到了/dapp/private_chain_data/genesis.json可以直接查看:

/ # cat /dapp/genesis.json
{
	"config": {
		"chainId": 88,
		"homesteadBlock": 0,
		"eip150Block": 0,
		"eip155Block": 0,
		"eip158Block": 0,
		"byzantiumBlock": 0,
		"constantinopleBlock": 0,
		"petersburgBlock": 0,
		"istanbulBlock": 0
	},
	"alloc": {
		"0x0000000000000000000000000000000000000001": {
			"balance": "666666666666666666666666"
		},
		"0x0000000000000000000000000000000000000002": {
			"balance": "888888888888888888888888"
		}
	},
	"coinbase": "0x0000000000000000000000000000000000000000",
	"difficulty": "0x2000",
	"extraData": "0x",
	"gasLimit": "0x800000000000",
	"nonce": "0x0000000000000042",
	"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
	"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
	"timestamp": "0x00"
}

config:配置块定义我们的自定义链的设置,并具有创建私有区块链的某些属性。

chainId:标识我们的区块链,主要的以太坊链有自己的ID,但我们会将它设置为我们私有链的唯一值。注意:这里需要不能使用字符串"88",后面初始化会报错

homesteadBlock:Homestead是以太坊平台的第二个主要版本,也是以太坊的第一个生产版本。它包括几个协议更改。由于我们已经在Homestead版本,因此该属性为0。

eip155Block/eip158Block:Homestead版本发布时带有一些向后不兼容的协议更改,因此需要硬分叉。通过以太坊改进提案(EIPs)提出的这些协议变更/改进。然而,我们的链条不会因为这些变化而难以分解,所以保留为0。

difficulty:此值用于控制区块链的块生成时间。难度越高,Miner在发现有效块时必须执行的统计更多计算。在我们的测试网络中,我们将保持此值低以避免在测试期间等待,因为需要生成有效块来执行交易处理区块链。

gasLimit:此值指定每块的“gas”支出的当前链范围限制。gas是以太坊在交易过程中消耗的燃料。我们将在这种情况下将此值标记得足够高,以避免在测试期间受到限制。

alloc:这是你可以创建你的钱包并用假ether预填充的地方。

coinbase:矿工的账号

  • 初始化genesis
geth init --datadir /dapp /dapp/genesis.json
INFO [01-19|05:21:48.607] Maximum peer count                       ETH=50 LES=0 total=50
INFO [01-19|05:21:48.607] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
ERROR[01-19|05:21:48.609] Failed to enumerate USB devices          hub=ledger vendor=11415 failcount=1 err="failed to initialize libusb: libusb: unknown error [code -99]"
ERROR[01-19|05:21:48.609] Failed to enumerate USB devices          hub=trezor vendor=21324 failcount=1 err="failed to initialize libusb: libusb: unknown error [code -99]"
ERROR[01-19|05:21:48.609] Failed to enumerate USB devices          hub=trezor vendor=4617  failcount=1 err="failed to initialize libusb: libusb: unknown error [code -99]"
ERROR[01-19|05:21:48.609] Failed to enumerate USB devices          hub=ledger vendor=11415 failcount=2 err="failed to initialize libusb: libusb: unknown error [code -99]"
ERROR[01-19|05:21:48.610] Failed to enumerate USB devices          hub=trezor vendor=21324 failcount=2 err="failed to initialize libusb: libusb: unknown error [code -99]"
ERROR[01-19|05:21:48.610] Failed to enumerate USB devices          hub=trezor vendor=4617  failcount=2 err="failed to initialize libusb: libusb: unknown error [code -99]"
INFO [01-19|05:21:48.610] Set global gas cap                       cap=25000000
INFO [01-19|05:21:48.611] Allocated cache and file handles         database=/root/privtedata/geth/chaindata cache=16.00MiB handles=16
INFO [01-19|05:21:48.619] Writing custom genesis block 
INFO [01-19|05:21:48.621] Persisted trie from memory database      nodes=3 size=411.00B time="254.089µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [01-19|05:21:48.622] Successfully wrote genesis state         database=chaindata                       hash="1c93ff…32eb9b"
INFO [01-19|05:21:48.622] Allocated cache and file handles         database=/root/privtedata/geth/lightchaindata cache=16.00MiB handles=16
INFO [01-19|05:21:48.627] Writing custom genesis block 
INFO [01-19|05:21:48.629] Persisted trie from memory database      nodes=3 size=411.00B time="187.026µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [01-19|05:21:48.629] Successfully wrote genesis state         database=lightchaindata    

--datadir:私有链的数据存储位置

启动私有链,进入控制台

  • 启动私有链
geth --identity "miner_node" --datadir /dapp --networkid 88 --rpc --rpcaddr 0.0.0.0 --rpcport "8545" --port "30303" --rpcapi "db,eth,net,web3" --nodiscover console

后面遇到问题添加了--allow-insecure-unlock

geth --identity "miner_node" --datadir /dapp --networkid 88 --rpc --rpcaddr 0.0.0.0 --rpcport "8545" --port "30303" --rpcapi "db,eth,net,web3" --nodiscover --allow-insecure-unlock console
  • 日志信息

WARN [01-19|06:18:07.401] Sanitizing cache to Go's GC limits       provided=1024 updated=606
INFO [01-19|06:18:07.402] Maximum peer count                       ETH=50 LES=0 total=50
WARN [01-19|06:18:07.402] The flag --rpc is deprecated and will be removed in the future, please use --http 
WARN [01-19|06:18:07.402] The flag --rpcport is deprecated and will be removed in the future, please use --http.port 
INFO [01-19|06:18:07.402] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
ERROR[01-19|06:18:07.403] Failed to enumerate USB devices          hub=ledger vendor=11415 failcount=1 err="failed to initialize libusb: libusb: unknown error [code -99]"
ERROR[01-19|06:18:07.403] Failed to enumerate USB devices          hub=trezor vendor=21324 failcount=1 err="failed to initialize libusb: libusb: unknown error [code -99]"
ERROR[01-19|06:18:07.403] Failed to enumerate USB devices          hub=trezor vendor=4617  failcount=1 err="failed to initialize libusb: libusb: unknown error [code -99]"
ERROR[01-19|06:18:07.403] Failed to enumerate USB devices          hub=ledger vendor=11415 failcount=2 err="failed to initialize libusb: libusb: unknown error [code -99]"
ERROR[01-19|06:18:07.403] Failed to enumerate USB devices          hub=trezor vendor=21324 failcount=2 err="failed to initialize libusb: libusb: unknown error [code -99]"
ERROR[01-19|06:18:07.404] Failed to enumerate USB devices          hub=trezor vendor=4617  failcount=2 err="failed to initialize libusb: libusb: unknown error [code -99]"
INFO [01-19|06:18:07.404] Set global gas cap                       cap=25000000
INFO [01-19|06:18:07.404] Allocated trie memory caches             clean=150.00MiB dirty=151.00MiB
INFO [01-19|06:18:07.404] Allocated cache and file handles         database=/root/privtedata/geth/chaindata cache=303.00MiB handles=524288
INFO [01-19|06:18:07.422] Opened ancient database                  database=/root/privtedata/geth/chaindata/ancient
INFO [01-19|06:18:07.423] Initialised chain configuration          config="{ChainID: 88 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: 0 EIP155: 0 EIP158: 0 Byzantium: 0 Constantinople: 0 Petersburg: 0 Istanbul: 0, Muir Glacier: <nil>, YOLO v2: <nil>, Engine: unknown}"
INFO [01-19|06:18:07.423] Disk storage enabled for ethash caches   dir=/root/privtedata/geth/ethash count=3
INFO [01-19|06:18:07.424] Disk storage enabled for ethash DAGs     dir=/root/.ethash                count=2
INFO [01-19|06:18:07.424] Initialising Ethereum protocol           versions="[65 64 63]" network=88 dbversion=8
INFO [01-19|06:18:07.435] Loaded most recent local header          number=0 hash="1c93ff…32eb9b" td=8192 age=51y9mo2w
INFO [01-19|06:18:07.435] Loaded most recent local full block      number=0 hash="1c93ff…32eb9b" td=8192 age=51y9mo2w
INFO [01-19|06:18:07.435] Loaded most recent local fast block      number=0 hash="1c93ff…32eb9b" td=8192 age=51y9mo2w
INFO [01-19|06:18:07.436] Loaded local transaction journal         transactions=0 dropped=0
INFO [01-19|06:18:07.436] Regenerated local transaction journal    transactions=0 accounts=0
INFO [01-19|06:18:07.458] Allocated fast sync bloom                size=301.00MiB
INFO [01-19|06:18:07.461] Starting peer-to-peer node               instance=Geth/miner_node/v1.9.25-stable-e7872729/linux-amd64/go1.15.6
INFO [01-19|06:18:07.462] Initialized fast sync bloom              items=3 errorrate=0.000 elapsed="315.381µs"
INFO [01-19|06:18:07.487] New local node record                    seq=4 id=c47064f6b8ab3823 ip=127.0.0.1 udp=0 tcp=30303
INFO [01-19|06:18:07.487] Started P2P networking                   self="enode://e2a4d84ae2c319751b372fd41e2ce09a60398d56dc60f47d8b86b2fd366d79ced6a9f3e6195f6b47a7f179337079c56bb017a78f1468cc3cab3b8f120412a9fe@127.0.0.1:30303?discport=0"
INFO [01-19|06:18:07.490] IPC endpoint opened                      url=/root/privtedata/geth.ipc
INFO [01-19|06:18:07.491] HTTP server started                      endpoint=127.0.0.1:8545 cors= vhosts=localhost
WARN [01-19|06:18:07.589] Served eth_coinbase                      reqid=3 t="30.955µs" err="etherbase must be explicitly specified"
Welcome to the Geth JavaScript console!

instance: Geth/miner_node/v1.9.25-stable-e7872729/linux-amd64/go1.15.6
at block: 0 (Thu Jan 01 1970 08:00:00 GMT+0800 (CST))
 datadir: /root/privtedata
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d
>

geth --identity "miner_node" --datadir /dapp --networkid 88 --rpc --rpcaddr 0.0.0.0 --rpcport "8545" --port "30303" --rpcapi "db,eth,net,web3" --nodiscover console

--identity:自定义节点名

--datadir:数据库和keystore密钥的数据目录

--networkid:网络标识符(整型, 1=Frontier, 2=Morden (弃用), 3=Ropsten, 4=Rinkeby) (默认: 1)

--rpc:启用HTTP-RPC服务器

--rpcport:HTTP-RPC服务器监听端口(默认值:8545)

--port:监听端口(默认值:30303)

--nodiscover:禁用节点发现机制(手动添加节点),日志就不会出现 Looking for peers

  • JavaScript console
/ # geth attach

Welcome to the Geth JavaScript console!

instance: Geth/v1.9.25-stable-e7872729/linux-amd64/go1.15.6
at block: 0 (Thu Jan 01 1970 00:00:00 GMT+0000 (UTC))
 datadir: /root/.ethereum
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d
> 

  • 创建账户
# 创建账号
# 输入密码
#获得账号地址

>personal.newAccount()

Passphrase: 
Repeat passphrase: 

INFO [01-19|06:22:35.833] Your new key was generated               address=0x046c9A712c6c82579cf4F05379b157BAba760e6E
WARN [01-19|06:22:35.833] Please backup your key file!             path=/root/privtedata/keystore/UTC--2021-01-18T22-22-32.826039142Z--046c9a712c6c82579cf4f05379b157baba760e6e
WARN [01-19|06:22:35.833] Please remember your password! 
"0x046c9a712c6c82579cf4f05379b157baba760e6e"


注:此时在容器外的映射目录下,可查看生成的keystore,必须保存好此账户的密码及keystore,因为你需要它来管理你的帐户。

  • 查看地址余额
> eth.getBalance("0x046c9a712c6c82579cf4f05379b157baba760e6e")
0
> 

此账户为新生成,所以账户内还没有余额

  • 获取以太币

有两种方法可以让以太币进入你的帐户,或者有人向你发送一些,或者你挖掘交易区块并依次获得以太币奖励

现在独自一人在你的私人网络中,你现在唯一的选择是挖掘一些区块并获得奖励

  • 开启挖矿
> miner.start()

INFO [01-19|06:25:02.328] Updated mining threads                   threads=8
INFO [01-19|06:25:02.328] Transaction pool price threshold updated price=1000000000
INFO [01-19|06:25:02.328] Etherbase automatically configured       address=0x046c9A712c6c82579cf4F05379b157BAba760e6E
null
> INFO [01-19|06:25:02.329] Commit new mining work                   number=1 sealhash="a14903…a8920b" uncles=0 txs=0 gas=0 fees=0 elapsed="353.38µs"
INFO [01-19|06:25:04.318] Generating DAG in progress               epoch=0 percentage=0 elapsed=1.055s
INFO [01-19|06:25:05.398] Generating DAG in progress               epoch=0 percentage=1 elapsed=2.135s
INFO [01-19|06:25:06.452] Generating DAG in progress               epoch=0 percentage=2 elapsed=3.189s
INFO [01-19|06:25:07.727] Generating DAG in progress               epoch=0 percentage=3 elapsed=4.464s
INFO [01-19|06:25:08.802] Generating DAG in progress               epoch=0 percentage=4 elapsed=5.539s
INFO [01-19|06:25:09.920] Generating DAG in progress               epoch=0 percentage=5 elapsed=6.657s
INFO [01-19|06:25:11.077] Generating DAG in progress               epoch=0 percentage=6 elapsed=7.814s
INFO [01-19|06:25:12.366] Generating DAG in progress               epoch=0 percentage=7 elapsed=9.103s
INFO [01-19|06:25:13.857] Generating DAG in progress               epoch=0 percentage=8 elapsed=10.595s
INFO [01-19|06:25:14.963] Generating DAG in progress               epoch=0 percentage=9 elapsed=11.700s
INFO [01-19|06:25:16.023] Generating DAG in progress               epoch=0 percentage=10 elapsed=12.760s
INFO [01-19|06:25:17.370] Generating DAG in progress               epoch=0 percentage=11 elapsed=14.107s
INFO [01-19|06:25:18.688] Generating DAG in progress               epoch=0 percentage=12 elapsed=15.425s
INFO [01-19|06:25:19.994] Generating DAG in progress               epoch=0 percentage=13 elapsed=16.731s
INFO [01-19|06:25:21.245] Generating DAG in progress               epoch=0 percentage=14 elapsed=17.983s
INFO [01-19|06:25:22.474] Generating DAG in progress               epoch=0 percentage=15 elapsed=19.211s

  • 挖到矿了

直到percentage到100时,计算完毕就挖到矿了


INFO [01-19|06:31:50.709] Generating DAG in progress               epoch=1 percentage=97 elapsed=4m29.670s
INFO [01-19|06:31:54.026] Generating DAG in progress               epoch=1 percentage=98 elapsed=4m32.987s
INFO [01-19|06:31:57.452] Generating DAG in progress               epoch=1 percentage=99 elapsed=4m36.414s

INFO [01-19|06:31:57.479] Generated ethash verification cache      epoch=1 elapsed=4m36.420s
INFO [01-19|06:34:45.039] Successfully sealed new block            number=1 sealhash="a14903…a8920b" hash="9ff2b2…bb5c8b" elapsed=9m42.710s
INFO [01-19|06:34:45.076] 🔨 mined potential block                  number=1 hash="9ff2b2…bb5c8b"
INFO [01-19|06:34:45.056] Commit new mining work                   number=2 sealhash="e438e6…ff51c4" uncles=0 txs=0 gas=0 fees=0 elapsed=17.093ms
INFO [01-19|06:34:45.141] Successfully sealed new block            number=2 sealhash="e438e6…ff51c4" hash="d70210…3bca0d" elapsed=84.626ms
INFO [01-19|06:34:45.141] 🔨 mined potential block                  number=2 hash="d70210…3bca0d"
INFO [01-19|06:34:45.141] Commit new mining work                   number=3 sealhash="6a98b3…4bdc80" uncles=0 txs=0 gas=0 fees=0 elapsed="367.472µs"
INFO [01-19|06:34:51.295] Successfully sealed new block            number=3 sealhash="6a98b3…4bdc80" hash="78d6cb…c033f5" elapsed=6.153s
INFO [01-19|06:34:51.324] 🔨 mined potential block                  number=3 hash="78d6cb…c033f5"
INFO [01-19|06:34:51.296] Commit new mining work                   number=4 sealhash="51be0d…46f2e8" uncles=0 txs=0 gas=0 fees=0 elapsed="642.359µs"
INFO [01-19|06:35:02.689] Successfully sealed new block            number=4 sealhash="51be0d…46f2e8" hash="6086ce…98c928" elapsed=11.393s
INFO [01-19|06:35:02.828] 🔨 mined potential block                  number=4 hash="6086ce…98c928"
INFO [01-19|06:35:02.824] Commit new mining work                   number=5 sealhash="297750…ece4fb" uncles=0 txs=0 gas=0 fees=0 elapsed=134.563ms
INFO [01-19|06:35:12.483] Successfully sealed new block            number=5 sealhash="297750…ece4fb" hash="addb2f…85c1ac" elapsed=9.659s
INFO [01-19|06:35:12.527] 🔨 mined potential block                  number=5 hash="addb2f…85c1ac"
INFO [01-19|06:35:12.500] Commit new mining work                   number=6 sealhash="284733…e3cbab" uncles=0 txs=0 gas=0 fees=0 elapsed=16.081ms




>  eth.getBalance("0x046c9a712c6c82579cf4f05379b157baba760e6e")
58000000000000000000
>

  • 查看日志命令
[root@localhost ~]#  docker logs -f  geth_miner  --tail 10


INFO [01-19|06:27:49.959] Generating DAG in progress               epoch=1 percentage=10 elapsed=28.921s
INFO [01-19|06:27:52.422] Generating DAG in progress               epoch=1 percentage=11 elapsed=31.384s
INFO [01-19|06:27:54.912] Generating DAG in progress               epoch=1 percentage=12 elapsed=33.874s
INFO [01-19|06:27:57.294] Generating DAG in progress               epoch=1 percentage=13 elapsed=36.255s
INFO [01-19|06:27:59.939] Generating DAG in progress               epoch=1 percentage=14 elapsed=38.900s
INFO [01-19|06:28:02.773] Generating DAG in progress               epoch=1 percentage=15 elapsed=41.735s
INFO [01-19|06:28:05.576] Generating DAG in progress               epoch=1 percentage=16 elapsed=44.538s
INFO [01-19|06:28:08.257] Generating DAG in progress               epoch=1 percentage=17 elapsed=47.219s
INFO [01-19|06:28:10.785] Generating DAG in progress               epoch=1 percentage=18 elapsed=49.747s
INFO [01-19|06:28:13.201] Generating DAG in progress               epoch=1 percentage=19 elapsed=52.163s

INFO [01-19|06:28:16.145] Generating DAG in progress               epoch=1 percentage=20 elapsed=55.106s

INFO [01-19|06:28:18.599] Generating DAG in progress               epoch=1 percentage=21 elapsed=57.561s
INFO [01-19|06:28:21.353] Generating DAG in progress               epoch=1 percentage=22 elapsed=1m0.314s


  • 停止挖矿
> miner.stop()
null
> 

问题

  • 账号解锁失败
personal.unlockAccount(eth.accounts[1])

Unlock account 0x76eb31fe42019b8aca3ec0b15ee50a6105c28fc3
Passphrase: 
WARN [01-20|14:24:35.625] Served personal_unlockAccount            reqid=133              t="41.711µs"  err="account unlock with HTTP access is forbidden"
GoError: Error: account unlock with HTTP access is forbidden at web3.js:6347:37(47)
	at native
	at <eval>:1:24(6)

> 

解决方案

如果已经了解打开此功能的风险,可通启动命令中添加参数:

--allow-insecure-unlock

示例:

geth --identity "miner_node" --datadir /dapp --networkid 88 --rpc --rpcaddr 0.0.0.0 --rpcport "8545" --port "30303" --rpcapi "db,eth,net,web3" --nodiscover --allow-insecure-unlock console