前言
- CentOS Linux release 7.4.1708 (Core)
- geth Version: 1.8.17-stable (【Get 以太坊技能】CentOS 7 Geth安装)
为啥搭建私链
在以太坊的共有链上部署智能合约、发起交易需要花费以太币。而通过修改配置,可以在本机搭建一套以太坊私有链,因为与公有链没关系,既不用同步公有链庞大的数据,也不用花钱购买以太币,很好地满足了智能合约开发和测试的要求,开发好的智能合约也可以很容易地切换接口部署到以太坊公有链上。
搭建说明
- 官方的搭建说明:https://github.com/ethereum/go-ethereum#operating-a-private-network
- 非官方的搭建说明:自行搜索,很多!
- 我的搭建说明:往下看。
Step1:选好位置
- 工作目录设定为:/data/sde/geth_priv
- 数据目录设定为:/data/sde/geth_priv/data
Step2:创建第1个 Account 作为 coinbase
shell> cd /data/sde/geth_priv && geth --datadir ./data account new
INFO [11-27|16:30:11.007] Maximum peer count ETH=50 LES=0 total=50
INFO [11-27|16:30:11.007] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
Your new account is locked with a password. Please give a password. Do not forget this password.
Password:
Repeat password:
Your new key was generated
Public address of the key: 0xf6ce09760a136833A1574aea1C6Bc75EaC514652
Path of the secret key file: data/keystore/UTC--2019-11-27T08-30-18.297342351Z--f6ce09760a136833a1574aea1c6bc75eac514652
- You can share your public address with anyone. Others need it to interact with you.
- You must NEVER share the secret key with anyone! The key controls access to your funds!
- You must BACKUP your key file! Without the key, it's impossible to access account funds!
- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!
得到第1个 Account : 0xf6ce09760a136833A1574aea1C6Bc75EaC514652
Step3:再创建2个 Account ,在初始化私链时分配Ether
创建方法参考Step2。
得到第2个 Account : 0x95f86CeaE604A969005B18b8A2e7542Ea8043ded
得到第3个 Account : 0x92857592a2D96894a45F400D86fe9cbE0d72F199
Step4:编辑genesis.json
- genesis.json文件放置位置:/data/sde/geth_priv/genesis.json
- genesis.json文件内容。一定要去官网拷贝该文件的内容。geth是不停在升级的,genesis.json的内容也会有变化。血的教训:我在网上找了个文章,就跟着做了,结果genesis.json的内容不匹配geth版本,浪费了好久。
- genesis.json文件内容举例(内置了两个地址,并分配了Ether):
shell> vim /data/sde/geth_priv/genesis.json
{
"config": {
"chainId": 12345,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0
},
"alloc": {
"0x95f86CeaE604A969005B18b8A2e7542Ea8043ded": {
"balance": "10000000000000000000000000000"
},
"0x92857592a2D96894a45F400D86fe9cbE0d72F199": {
"balance": "10000000000000000000000000"
}
},
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x10000",
"extraData": "",
"gasLimit": "0x2fefd8",
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00"
}
说明参考这里:https://blog.csdn.net/scau_lth/article/details/79570886
Step5:初始化
shell> cd /data/sde/geth_priv && geth init ./genesis.json --datadir ./data
INFO [11-27|16:37:29.844] Maximum peer count ETH=50 LES=0 total=50
INFO [11-27|16:37:29.844] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [11-27|16:37:29.847] Allocated cache and file handles database=/data/sde/geth_priv/data/geth/chaindata cache=16.00MiB handles=16
INFO [11-27|16:37:29.855] Writing custom genesis block
INFO [11-27|16:37:29.856] Persisted trie from memory database nodes=3 size=416.00B time=109.651µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [11-27|16:37:29.856] Successfully wrote genesis state database=chaindata hash=188825…e50e76
INFO [11-27|16:37:29.856] Allocated cache and file handles database=/data/sde/geth_priv/data/geth/lightchaindata cache=16.00MiB handles=16
INFO [11-27|16:37:29.865] Writing custom genesis block
INFO [11-27|16:37:29.866] Persisted trie from memory database nodes=3 size=416.00B time=684.975µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [11-27|16:37:29.866] Successfully wrote genesis state database=lightchaindata hash=188825…e50e76
看到 Successfully 就OK了。
此时,目录结构如下:
shell> cd /data/sde/geth_priv && tree
.
├── data
│ ├── geth
│ │ ├── chaindata
│ │ │ ├── 000001.log
│ │ │ ├── CURRENT
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── MANIFEST-000000
│ │ └── lightchaindata
│ │ ├── 000001.log
│ │ ├── CURRENT
│ │ ├── LOCK
│ │ ├── LOG
│ │ └── MANIFEST-000000
│ └── keystore
│ ├── UTC--2019-11-27T08-30-18.297342351Z--f6ce09760a136833a1574aea1c6bc75eac514652
│ ├── UTC--2019-11-27T08-33-31.098513082Z--95f86ceae604a969005b18b8a2e7542ea8043ded
│ └── UTC--2019-11-27T08-33-48.994523046Z--92857592a2d96894a45f400d86fe9cbe0d72f199
└── genesis.json
5 directories, 14 files
Step6 : 第一次启动
第一次启动geth时,按照下面的命令进行输入,体验geth。
# 启动 geth
shell> cd /data/sde/geth_priv && geth --nodiscover --datadir ./data --identity "gethPriv" --networkid 12345 --port 30305 console
# 查看 geth 的节点信息
geth shell> admin.nodeInfo
# 退出 geth
geth shell> exit
体验过程:
shell> cd /data/sde/geth_priv && geth --nodiscover --datadir ./data --identity "gethPriv" --networkid 12345 --port 30305 console
INFO [11-27|16:38:55.218] Maximum peer count ETH=50 LES=0 total=50
INFO [11-27|16:38:55.218] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [11-27|16:38:55.221] Starting peer-to-peer node instance=Geth/gethPriv/v1.9.8-stable-d62e9b28/linux-amd64/go1.13.4
INFO [11-27|16:38:55.221] Allocated trie memory caches clean=256.00MiB dirty=256.00MiB
INFO [11-27|16:38:55.221] Allocated cache and file handles database=/data/sde/geth_priv/data/geth/chaindata cache=512.00MiB handles=32767
INFO [11-27|16:38:55.253] Opened ancient database database=/data/sde/geth_priv/data/geth/chaindata/ancient
INFO [11-27|16:38:55.253] Initialised chain configuration config="{ChainID: 12345 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: 0 EIP155: 0 EIP158: 0 Byzantium: 0 Constantinople: 0 Petersburg: 0 Istanbul: <nil> Engine: unknown}"
INFO [11-27|16:38:55.253] Disk storage enabled for ethash caches dir=/data/sde/geth_priv/data/geth/ethash count=3
INFO [11-27|16:38:55.253] Disk storage enabled for ethash DAGs dir=/root/.ethash count=2
INFO [11-27|16:38:55.253] Initialising Ethereum protocol versions="[64 63]" network=12345 dbversion=<nil>
WARN [11-27|16:38:55.253] Upgrade blockchain database version from=<nil> to=7
INFO [11-27|16:38:55.255] Loaded most recent local header number=0 hash=188825…e50e76 td=65536 age=50y7mo2w
INFO [11-27|16:38:55.255] Loaded most recent local full block number=0 hash=188825…e50e76 td=65536 age=50y7mo2w
INFO [11-27|16:38:55.255] Loaded most recent local fast block number=0 hash=188825…e50e76 td=65536 age=50y7mo2w
INFO [11-27|16:38:55.256] Regenerated local transaction journal transactions=0 accounts=0
INFO [11-27|16:38:55.265] Allocated fast sync bloom size=512.00MiB
INFO [11-27|16:38:55.272] Initialized fast sync bloom items=3 errorrate=0.000 elapsed=5.464ms
INFO [11-27|16:38:55.279] New local node record seq=1 id=019ce63e78996e1c ip=127.0.0.1 udp=0 tcp=30305
INFO [11-27|16:38:55.279] Started P2P networking self="enode://09c25d97f8d5ef391838469cf3558f4bf8aea3332c933b48a5aa0263fabc8746e20328d26fcfa8d372ddfbad0af5c069408a10fbf0538cad10bd20ca110bb92e@127.0.0.1:30305?discport=0"
INFO [11-27|16:38:55.279] IPC endpoint opened url=/data/sde/geth_priv/data/geth.ipc
INFO [11-27|16:38:55.356] Etherbase automatically configured address=0xf6ce09760a136833A1574aea1C6Bc75EaC514652
Welcome to the Geth JavaScript console!
instance: Geth/gethPriv/v1.9.8-stable-d62e9b28/linux-amd64/go1.13.4
coinbase: 0xf6ce09760a136833a1574aea1c6bc75eac514652
at block: 0 (Thu, 01 Jan 1970 08:00:00 CST)
datadir: /data/sde/geth_priv/data
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
geth shell> admin.nodeInfo
{
enode: "enode://09c25d97f8d5ef391838469cf3558f4bf8aea3332c933b48a5aa0263fabc8746e20328d26fcfa8d372ddfbad0af5c069408a10fbf0538cad10bd20ca110bb92e@127.0.0.1:30305?discport=0",
enr: "enr:-JC4QKN7CPyL0M4lvJzUnSreIr7hbHPQ8y7j6oai4cKVUsjhMjNl3L6NQNLDDXb36hInOC2fv2ZhwtPBDSrOOztGhM4Bg2V0aMfGhEKv3-mAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQIJwl2X-NXvORg4RpzzVY9L-K6jMyyTO0ilqgJj-ryHRoN0Y3CCdmE",
id: "019ce63e78996e1c6eb0137bcb9d49018660522805d8f9e16412a937deb6f7ca",
ip: "127.0.0.1",
listenAddr: "[::]:30305",
name: "Geth/gethPriv/v1.9.8-stable-d62e9b28/linux-amd64/go1.13.4",
ports: {
discovery: 0,
listener: 30305
},
protocols: {
eth: {
config: {
byzantiumBlock: 0,
chainId: 12345,
constantinopleBlock: 0,
eip150Block: 0,
eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
eip155Block: 0,
eip158Block: 0,
homesteadBlock: 0,
petersburgBlock: 0
},
difficulty: 65536,
genesis: "0x18882519e8a38ec1ab9516c1cef14f064827ec8160cb0b76821300dd9ce50e76",
head: "0x18882519e8a38ec1ab9516c1cef14f064827ec8160cb0b76821300dd9ce50e76",
network: 12345
}
}
}
geth shell> exit
INFO [11-27|16:40:18.780] IPC endpoint closed url=/data/sde/geth_priv/data/geth.ipc
INFO [11-27|16:40:18.780] Blockchain manager stopped
INFO [11-27|16:40:18.780] Stopping Ethereum protocol
INFO [11-27|16:40:18.780] Ethereum protocol stopped
INFO [11-27|16:40:18.780] Transaction pool stopped
Step7:查看账号
启动方式参考Step6.
# 查看当前节点下有多少account
geth shell> eth.accounts
# 查看coinbase。挖矿得到的Ether会进入coinbase account
geth shell> eth.coinbase
# 查看第一个账号的余额,单位:Wei。账号下标从0开始。
geth shell> eth.getBalance(eth.accounts[0])
geth shell> eth.getBalance(eth.accounts[1])
geth shell> eth.getBalance(eth.accounts[2])
geth shell> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether");
geth shell> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether");
geth shell> web3.fromWei(eth.getBalance(eth.accounts[2]), "ether");
geth 执行结果:
# 查看当前节点下有多少account。下标从0开始。
geth shell> eth.accounts
["0xf6ce09760a136833a1574aea1c6bc75eac514652", "0x95f86ceae604a969005b18b8a2e7542ea8043ded", "0x92857592a2d96894a45f400d86fe9cbe0d72f199"]
# 查看coinbase。挖矿得到的Ether会进入coinbase account
geth shell> eth.coinbase
"0xf6ce09760a136833a1574aea1c6bc75eac514652"
# 查看第1个账号的余额,单位:Wei。账号下标从0开始。
geth shell> eth.getBalance(eth.accounts[0])
0
# 查看第2个账号的余额,单位:Wei。账号下标从0开始。
geth shell> eth.getBalance(eth.accounts[1])
1e+28
# 查看第3个账号的余额,单位:Wei。账号下标从0开始。
geth shell> eth.getBalance(eth.accounts[2])
1e+25
# 查看第0个账号的余额,单位:Ether。账号下标从0开始。
geth shell> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether");
0
# 查看第1个账号的余额,单位:Ether。账号下标从0开始。
geth shell> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether");
10000000000
# 查看第2个账号的余额,单位:Ether。账号下标从0开始。
geth shell> web3.fromWei(eth.getBalance(eth.accounts[2]), "ether");
10000000
Step8:退出 Geth Console
geth shell> exit
最后
判断 Geth 私链是否搭好:依据 Step6 中的方法查看账户及余额。能够查到账户和余额,就表示搭建好了。
Geth 私链搭建好后,总结一下。通过 Geth 私链搭建,get 到了以下东西:
- 一个可以启动/关闭的 Geth 私链
- 新建了3个账号
- 2个账号很富有
接下来要做:
- 挖矿。给新建的账号一些创业资本。
- 转账。各种花式转账。
- 操作智能合约。
分享个心得体会:一次搭不好,多搭建几次就行了。
说明
经过测试,发现geth需要至少512M内存。如果操作系统内存不足512M时,会提示fatal error: runtime: out of memory
参考
https://github.com/ethereum/go-ethereum
https://ethereum.gitbooks.io/frontier-guide/content/index.html