0%

私有链部署

环境配置

geth

版本:v1.10.26

作用:作为以太坊客户端,创建创世区块、初始化(启动/添加)节点

remix

https://remix.ethereum.org/

在线智能合约编辑器,并可将编译后的合约部署到私有链。

单节点私有链

初始化创世区块

定义创世区块信息

将以下内容写入一个名为 genesis.json 的文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
"config": {
"chainId": 111,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"ethash": {}
},
"nonce": "0x0",
"timestamp": "0x5ddf8f3e",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x47b760",
"difficulty": "0x000002",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
"0xa4f52e498af8b17F29FcF9F45f7250da0023d7CB": {
"balance": "9999999999999999999"
}
},
"number": "0x00",
"gasUsed": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}

参数说明

参数 作用
coinbase 矿工的账号,可任意填,初始化时先不填
difficulty 设置当前区块的难度,如果难度过大,CPU挖矿就很难,所以设置较小难度
extraData 附加信息,可任意填
gasLimit 设置对Gas的消耗总量限制,用来限制区块能包含的交易信息总和,对于私有链,需要填最大值
nonce nonce是一个64位的随机数,用于挖矿
mixhash 由上一个区块的一部分生成的哈希值,与nonce配合用于挖矿
parentHash 上一个区块的哈希值,因为是创世块,所以这个值是0
timestamp 设置创世块的时间戳
alloc 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以不需要预置有币的账号,需要时自己创建即可

初始化创世区块

geth.exe 目录下运行以下命令

1
geth init --datadir node1 genesis.json

启动私有节点

参数 “networkid” 要对应创世区块中 “chainId”

1
geth --datadir node1 --networkid 111 --http --http.addr "localhost" --http.port "8545" --http.corsdomain "*" --http.api "eth,net,web3,personal" --nodiscover --allow-insecure-unlock --ipcpath "node1/geth.rpc" console

创建账户、交易、挖矿

使用以下命令为当前节点创建一个账户

1
personal.newAccount("123456")		//新建账户(输入账户私钥)

使用 remix 编写并部署合约到当前私有链,即将其打包为一个区块发送到区块链网络。这里以一个简单的转账交易为例,交易会先进入交易池,状态为 pending (表示待确认),矿工从交易池中获取交易进行验证,之后开始挖矿,当一个节点(矿工)成功挖到一个区块时,其将交易打包到该区块中,进而广播给其他节点进行验证,新区块上链后,该交易被从交易池中删除。

1
2
3
4
5
6
7
8
personal.unlockAccount(eth.accounts[0], "123456")
//解锁账户(交易前的准备工作,输入转出账户私钥)
eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(34, "ether")})
//账户0转出34个以太币至账户1,返回交易的hash
txpool.status //查看交易池状态
miner.start();admin.sleepBlocks(1);miner.stop()
//挖到一个区块就停止
txpool.status //查看交易池状态
  • 常用账户管理及交易命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
eth.accounts						//查看当前节点的账户
personal.newAccount("123456") //新建账户(输入账户私钥)
web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
//查看第0个账户的余额,并将单位由Wei换算为ETH
eth.coinbase //查看矿工账户
miner.setEtherbase(eth.accounts[1]) //设置挖矿账户(默认为第0个)
personal.unlockAccount(eth.accounts[0], "123456")
//解锁账户(交易前的准备工作,输入转出账户私钥)
eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(34, "ether")})
//账户0转出34个以太币至账户1,返回交易的hash
txpool.status //查看交易池状态
txpool.inspect.pending //查看待确认交易详情
eth.getBlock("pending", true).transactions
//查看待确认交易所在区块信息
miner.start(2) //开始挖矿(开启2个进程)
miner.start();admin.sleepBlocks(1);miner.stop()
//挖到一个区块就停止
eth.blockNumber //获取区块总数
eth.getBlock('latest') //查看最新区块
eth.getTransaction('latest') //查看最新交易

多节点私有链

初始化创世区块

geth.exe 目录下运行以下命令(相同的创世区块信息)

1
geth init --datadir node2 genesis.json

启动私有节点

  1. 指定参数 —networkid 111 ,即要对应创世区块中 “chainId”
  2. 指定参数 —http.port “8546” ,以避免与 node1 (默认8545)冲突 (HTTP-RPC服务端口)
  3. 添加参数 —port 30304 ,以避免与 node1 (默认30303)冲突 (监听其他节点的端口)
  4. 添加参数 —authrpc.port 8552 ,以避免与 node1 (默认8551)冲突
1
geth --datadir node2 --networkid 111 --http --http.addr "localhost" --http.port "8546" --http.corsdomain "*" --http.api "eth,net,web3,personal" --nodiscover --allow-insecure-unlock --port 30304 --authrpc.port 8552 --ipcpath "node2/geth.rpc" console

添加节点

查看节点信息

输入以下命令,返回当前节点的编码信息

1
admin.nodeInfo.enode

手动添加

在另一节点的终端中,输入以下命令添加指定编码信息的节点

1
admin.addPeer("enode://e6352dc247e2791420c15b9295a22bf8787c2e3272288d2460d9bc78beb9d6dcb03f35d7619fe5b418fb1bb61ab357c29e0d044d020efecdf54fd4157b8616cf@127.0.0.1:30303?discport=0")

查看添加节点的信息

1
admin.peers

查看当前节点一共连接的节点数

1
web3.net.peerCount

Python以太坊交互

调用合约需要合约的 address 和 abi

1
2
3
4
5
from web3 import Web3

# 使用http连接指定节点
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))
...