一. 以太坊私链镜像生成
- 下载以太坊基础镜像
docker pull ethereum/client-go:v1.9.24
- 编写Dockerfile
# vim /opt/docker/images/geth-1.9.24/Dockerfile
FROM ethereum/client-go:v1.9.24
RUN apk update && apk add bash curl
ADD bin /root/bin
RUN chmod a+x /root/bin/*
ENTRYPOINT /root/bin/start.sh
- 新建存放目录bin
mkdir /opt/docker/images/geth-1.9.24/bin
- bin目录下编写执行文件
# vim /opt/docker/images/geth-1.9.24/bin/start.sh
#!/bin/bash
set -e
# Init
echo ""
echo "Init geth"
geth init "/root/files/genesis.json"
sleep 3
# Start geth
echo ""
echo "Start geth"
geth --syncmode "full" --networkid=66666 --gasprice "0" --rpc --rpcapi eth,net,web3,miner,txpool --rpcaddr "0.0.0.0" --rpcport "8545" --mine &
sleep 10
while true; do
sleep 1000000000
done
注:
注意,以上指定了一个名为networkid的参数。这标志着你的以太坊网络的身份。我们在这个例子中使用了66666,应该选择一个随机数来创建你自己的网络并防止其他人无意中连接到你的网络,此ID也必须与下文genesis.json文件中的"chainId"的ID一致
rpcaddr参数,含义为指定rpc服务器地址,如果目前只有这一台矿工发服务器,必须使用0.0.0.0这个地址,不然无法在宿主机外使用curl命令调用rpc远程服务调用协议来查询用户余额
- 为文件赋予执行权限
chmod +x /opt/docker/images/geth-1.9.24/bin/start.sh
- 生成以太坊私链镜像
docker build . -t eth:v1.9.24
注:需要在与Dockerfile同一级目录下执行此命令
二.以太坊私链容器生成
- 新建需要映射给容器存放数据的目录
注:必须创建,此目录下存放着的是所有在此链上的交易信息
mkdir -p /opt/docker/miner/data/bscchain
- 新建需要映射给容器存放DAG数据的目录
注:
必须创建,不然每次启动容器都会先生成DAG数据
mkdir -p /opt/docker/miner/data/ethash
- 新建创始区块文件
注:非常重要!!!此文件是搭建以太坊私链最重要的文件
# vim /opt/docker/miner/genesis.json
{
"config": {
"chainId": 66666,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0
},
"nonce": "0x0000000000000046",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"difficulty": "0x400",
"coinbase": "0x3333333333333333333333333333333333333333",
"timestamp": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x800000000000",
"alloc": {
"0x6e60F5243e1a3F0Be3F407b5AFE9e5395ee82aa2":{
"balance": "6660010000000000000000000000"
}
}
}
注:
1、为了创建我们的私有区块链,我们将创建一个创世块。为此,我们将创建一个自定义的Genesis文件,并要求Geth使用该genesis文件创建我们自己的genesis块,这反过来将成为我们自定义私有区块链的开始。
2、genesis.json文件属性详解
config:配置块定义我们的自定义链的设置,并具有创建私有区块链的某些属性。
chainId :标识我们的区块链,主要的以太坊链有自己的ID,但我们会将它设置为我们私有链的唯一值。
homesteadBlock:Homestead是以太坊平台的第二个主要版本,也是以太坊的第一个生产版本。它包括几个协议更改。由于我们已经在Homestead版本,因此该属性为0。- eip155Block/eip158Block:Homestead版本发布时带有一些向后不兼容的协议更改,因此需要硬分叉。通过以太坊改进提案(EIPs)提出的这些协议变更/改进。然而,我们的链条不会因为这些变化而难以分解,所以保留为0。
difficulty:此值用于控制区块链的块生成时间。难度越高,Miner在发现有效块时必须执行的统计更多计算。在我们的测试网络中,我们将保持此值低以避免在测试期间等待,因为需要生成有效块来执行交易处理区块链。
gasLimit:此值指定每块的“gas”支出的当前链范围限制。gas是以太坊在交易过程中消耗的燃料。我们将在这种情况下将此值标记得足够高,以避免在测试期间受到限制。
alloc:这是你可以创建你的钱包并用假ether预填充的地方。但是对于这篇文章,我们将在本地快速挖掘我们的以太,所以我们不使用这个选项。
- 新建容器启动脚本
# vim /opt/docker/miner/run.sh
#!/bin/bash
cd $(dirname $0)
SCRIPTS_DIR=$(pwd)
docker rm -f eth-miner
docker run --name eth-miner \
-v /etc/localtime:/etc/localtime \
-v /etc/timezone:/etc/timezone \
-v ${SCRIPTS_DIR}/genesis.json:/root/files/genesis.json \
-v ${SCRIPTS_DIR}/data/bscchain:/root/.ethereum \
-v ${SCRIPTS_DIR}/data/ethash:/root/.ethash \
-p 8545:8545 \
-p 30303:30303 \
-p 30303:30303/udp \
-d \
eth:v1.0
docker logs -f eth-miner
- 为脚本赋予执行权限
chmod +x /opt/docker/miner/run.sh
- 启动以太坊私有链容器
bash /opt/docker/miner/run.sh
查看以太坊私有链容器启动日志
docker logs -f eth-miner --tail 10
Init geth
INFO [01-18|18:35:11.145] Maximum peer count ETH=25 LES=0 total=25
INFO [01-18|18:35:11.151] Allocated cache and file handles database=/root/.ethereum/geth/chaindata cache=16 handles=16
INFO [01-18|18:35:11.159] Writing custom genesis block
INFO [01-18|18:35:11.159] Persisted trie from memory database nodes=1 size=152.00B time=55.846µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [01-18|18:35:11.159] Successfully wrote genesis state database=chaindata hash=b8214b…1ee203
INFO [01-18|18:35:11.159] Allocated cache and file handles database=/root/.ethereum/geth/lightchaindata cache=16 handles=16
INFO [01-18|18:35:11.170] Writing custom genesis block
INFO [01-18|18:35:11.171] Persisted trie from memory database nodes=1 size=152.00B time=278.307µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [01-18|18:35:11.171] Successfully wrote genesis state database=lightchaindata hash=b8214b…1ee203
Start geth
INFO [01-18|18:35:14.297] Maximum peer count ETH=25 LES=0 total=25
INFO [01-18|18:35:14.298] Starting peer-to-peer node instance=Geth/v1.9.0-unstable-1636d957/linux-amd64/go1.11.4
WARN [01-18|18:35:14.298] Sanitizing invalid miner gas price provided=0 updated=0
INFO [01-18|18:35:14.298] Allocated cache and file handles database=/root/.ethereum/geth/chaindata cache=512 handles=524288
INFO [01-18|18:35:14.311] Initialised chain configuration config="{ChainID: 66666 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0 Byzantium: <nil> Constantinople: <nil> Engine: unknown}"
INFO [01-18|18:35:14.311] Disk storage enabled for ethash caches dir=/root/.ethereum/geth/ethash count=3
INFO [01-18|18:35:14.311] Disk storage enabled for ethash DAGs dir=/root/.ethash count=2
INFO [01-18|18:35:14.311] Initialising Ethereum protocol versions="[63 62]" network=66666
INFO [01-18|18:35:16.007] Loaded most recent local header number=0 hash=b8214b…1ee203 td=1024 age=49y9mo4d
INFO [01-18|18:35:16.007] Loaded most recent local full block number=0 hash=b8214b…1ee203 td=1024 age=49y9mo4d
INFO [01-18|18:35:16.007] Loaded most recent local fast block number=0 hash=b8214b…1ee203 td=1024 age=49y9mo4d
INFO [01-18|18:35:16.007] Regenerated local transaction journal transactions=0 accounts=0
INFO [01-18|18:35:16.048] New local node record seq=1 id=5ef6e5bd3e67b455 ip=127.0.0.1 udp=30303 tcp=30303
INFO [01-18|18:35:16.049] Started P2P networking self=enode://54fb797b1ab3ac80c20b51ae75d6be5d3d174118b23beb47847d39bc2ba526faebb13e2b78eafa00bace077094ea99299179e91dd5524641d04cbb81810dd9ce@127.0.0.1:30303
INFO [01-18|18:35:16.140] IPC endpoint opened url=/root/.ethereum/geth.ipc
INFO [01-18|18:35:16.140] HTTP endpoint opened url=http://127.0.0.1:8545 cors= vhosts=localhost
Start mining
invalid content type, only application/json is supported
三.以太坊私链相关接口使用
- 以太坊控制台进入
// 进入容器
# docker exec -it eth-miner sh
// 进入控制台
/ # geth attach
Welcome to the Geth JavaScript console!
instance: Geth/v1.9.0-unstable-1636d957/linux-amd64/go1.11.4
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
- 创建账户
personal.newAccount()
Passphrase: 输入账号密码
Repeat passphrase: 再次输入账号密码
"0x8ca7b275cddf82e53a0751b8c3971738cca6e724" 获得账号地址
>
注:此时在容器外的映射目录下,可查看生成的keystore,必须保存好此账户的密码及keystore,因为你需要它来管理你的帐户。
- 查看地址余额
> eth.getBalance("0x8ca7b275cddf82e53a0751b8c3971738cca6e724")
0
>
注:
因为此账户为新生成,所以账户内还没有余额
有两种方法可以让以太币进入你的帐户,或者有人向你发送一些,或者你挖掘交易区块并依次获得以太币奖励
既然你现在独自一人在你的私人网络中,你现在唯一的选择是挖掘一些区块并获得奖励
- 开启挖矿
> miner.start()
null
- 此时可在容器外查看以太坊私有链容器的日志,可查看到如下信息:
# docker logs -f eth-miner
Start mining
invalid content type, only application/json is supported
INFO [01-18|19:51:09.871] Updated mining threads threads=8
INFO [01-18|19:51:09.871] Transaction pool price threshold updated price=0
INFO [01-18|19:51:09.871] Etherbase automatically configured address=0x8Ca7B275Cddf82E53a0751B8c3971738cca6e724
INFO [01-18|19:51:09.871] Commit new mining work number=1 sealhash=124d49…0239cd uncles=0 txs=0 gas=0 fees=0 elapsed=125.377µs
INFO [01-18|19:51:11.241] Generating DAG in progress epoch=0 percentage=0 elapsed=768.498ms
.......................
INFO [01-18|19:52:39.942] Generating DAG in progress epoch=0 percentage=99 elapsed=1m29.468s
INFO [01-18|19:52:39.944] Generated ethash verification cache epoch=0 elapsed=1m29.470s
INFO [01-18|19:52:40.291] Successfully sealed new block number=1 sealhash=124d49…0239cd hash=93190b…ccb7a3 elapsed=1m30.420s
INFO [01-18|19:52:40.291] mined potential block number=1 hash=93190b…ccb7a3
INFO [01-18|19:52:40.292] Commit new mining work number=2 sealhash=00a37d…3583ad uncles=0 txs=0 gas=0 fees=0 elapsed=188.561µs
注:
以上日志第一段信息为:生成DAG数据,作用为:用于共识POW算法的工作量证明
以上日志第二段信息为:出块日志,代表矿工已经成功挖掘到的块
此时:
我们可以再次检查你地址内的余额。
> eth.getBalance("0x8ca7b275cddf82e53a0751b8c3971738cca6e724")
4.905e21
>
哇噢!你的新帐户中会出现大量以太币。
(记住这是假的以太,你不能使用这个以太网在主以太网网络上进行交易)但是你可以用它来测试区块链的几个功能,包括转账,部署合约等。
- 停止挖矿
> miner.stop()
null
注:
如果开启挖矿,日志则会一直输出,此时你搭建的以太坊私链的数据也会越来越大,所以在搭建前,应保证磁盘容量是否充足
- 查询指定用户的最新余额
注:服务一旦搭建完成,我们不可能每次进行交易或查询用户信息时,都进入到以太坊私链容器内进行操作,以下示例为在宿主机命令行或者任意一台与宿主机可通信的命令行内使用curl命令调用rpc远程调用协议进行相关操作
[root@localhost server]# curl -s -H 'Content-Type:application/json;charset=utf-8' -X POST --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x8Ca7B275Cddf82E53a0751B8c3971738cca6e724", "latest"],"id":1}' http://10.20.29.88:8545
{"jsonrpc":"2.0","id":1,"result":"0x10069efb362cda800000"}