上一篇文章 详细的说明了如何在 Ubuntu 环境下编译 go-ethereum ,本节内容为 搭建基于 go-ethereum 的以太坊私有链环境
原文链接:ETH开发(二)搭建基于go-ethereum的以太坊的私有链环境
重新加载 profile 文件,加载环境变量到内存,否则会提示 geth 命令未找到
source ~/.profile
测试
geth -h
- 更正系统时间,便于后续日志查看
点击右上角时间–时间设置,然后点击地图设置为 Shanghai
1 以太坊的一些基本命令
同步主网做为节点,需要满足以下条件:
- 空余磁盘 500G 以上。目前,全球交易数据大约在350G 以上
- 需要足够的带宽
创建运行目录
cd ~
mkdir data
cd data
mkdir gethdata
cd gethdata
启动然后监听 geth
学习使用 nohup
nohup 命令:nohup
nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。
- 要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部。
- nohup 是 no hang up 的缩写,就是不挂断的意思。
注意
:nohup 后的命令会执行
什么情况下使用 nohup 命令?
如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用 nohup 命令。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。在缺省情况下该作业的所有输出都被重定向到一个名为 nohup.out 的文件中。
nohup geth --datadir="/data/gethdata" --rpc --rpcaddr=0.0.0.0 --rpcport=8545 --cache=512 --maxpeers 9999 --rpcapi="web3,eth,net,personal,db,admin" --rpccorsdomain="*" > ./geth.log &2>1
命令详解
nohup geth --datadir="/data/gethdata" --rpc --rpcaddr=0.0.0.0 --rpcport=8545 --cache=512 --maxpeers 9999 --rpcapi=“web3,eth,net,personal,db,admin” --rpccorsdomain="*" > ./geth.log &2>1
- 使用 nohup 监听 geth ,配置以下参数后,将其作业的所有输出重定向到当前目录下的 geth.log 文件,
&2>1
表示将错误重定向到标准输出上
参数 | 解释 | 配置 |
---|---|---|
–datadir | 数据库和秘钥存储库 | /data/gethdata |
–rpc | 启用 HTTP-RPC 服务 | |
–rpcaddr | RPC 监听地址 | 0.0.0.0(任何 IP 都可以) |
–rpcport | RPC 监听接口 | 8545(自定义) |
–cache | 内部缓存 | 512 |
–maxpeers | 最大网络对等点数量 | 9999 |
–rpcapi | RPC 接口API | web3,eth,net,personal,db,admin |
rpccorsdomain | 接受的跨源请求域名 |
查看正在运行的程序:
ps -a
可以看到 geth 已经在运行了,查看一下运行日志
vi geth.log
接着,通过加载 .ipc 文件的办法启动 geth 客户端,可以开始挖矿
geth attach ipc:/data/gethdata/geth.ipc
attach: 启动交互式 JavaScript 环境(连接到节点)
显示如下,表示启动了 ETH 节点的模块
Welcome to the Geth JavaScript console!
instance: Geth/v1.9.21-unstable-d54f2f2e-20200908/linux-amd64/go1.14.4 at block: 0 (Wed Dec 31 1969 16:00:00 GMT-0800 (PST))
datadir: /data/gethdata 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 环境
exit
关闭 geth
kill 2067 --pid
2 搭建以太坊私有链节点
创世区块
启动一个区块链网络,需要创建创世区块,然后建立区块节点,才能启动区块链网络,同一个网络中,创世区块必须一样,否则无法连通。
- 如果你的 gethdata 里已经有文件了,则需要删除并重新创建
cd /data
rm -rf gethdata
mkdir gethdata
- 通过配置创世块来创建私有链:新建创世块 json 文件
genesis.json
cd /data/gethdata
vi genesis.json
输入以下内容:
{
"config": {
"chainId": 8888,
"homesteadBlock": 0,
"daoForkBlock": 0,
"daoForkSupport": true,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"ethash": {}
},
"nonce": "0x42",
"timestamp": "0x0",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0xffffffff",
"difficulty": "0x1",
"alloc": {
"093f59f1d91017d30d8c2caa78feb5beb0d2cfaf": {
"balance": "0xffffffffffffffff"
},
"ddf7202cbe0aaed1c2d5c4ef05e386501a054406": {
"balance": "0xffffffffffffffff"
}
}
}
参数解释,详细信息见:以太坊genesis.json配置文件中各参数解释
参数 | 描述 | 配置 |
---|---|---|
chainId | 主网,搭建私有链必须为非 1 | 8888 |
nonce | 64位随机数,用于挖矿 | 0x42 |
timestamp | 创世块的时间戳 | 0x0 |
extraData | 附加信息,随便填 | |
gasLimit | 限制区块能包含的交易信息总和,私有链填最大 | 0xffffffff |
difficulty | 当前区块的难度 | 0x1 |
alloc | 预置账号以及账号的以太币数量 |
启动私有链节点
初始化区块链
geth --datadir "./" init genesis.json
显示如下,说明创世区块成功创建
编写启动脚本
nohup geth --rpc --rpccorsdomain "*" --datadir "./" --port 30304 --rpcapi "db,eth,net,web3,personal,web3" --networkid 8888 --rpcport 8545 --rpcaddr "0.0.0.0" --allow-insecure-unlock > ./geth.log &2>1
该命令如下
nohup geth --rpc --rpccorsdomain “*” --datadir “./” --port 30304 --rpcapi “db,eth,net,web3,personal,web3” --networkid 8888 --rpcport 8545 --rpcaddr “0.0.0.0” --allow-insecure-unlock > ./geth.log &2>1
参数 | 解释 | 配置 |
---|---|---|
–networkid | 8888 | |
–allow-insecure-unlock | 当与帐户相关的rpc被http公开时,允许不安全的帐户解锁 |
- networkid 选项,主网配置为 1 ,其他3、4、5都是以太坊坊社区部署的测试网络,我们是建立自己的私链,定义为8888
- allow-insecure-unlock 选项,方便我们解锁节点账户,如果是主网,不建议配置,否则,你存入节点账户的钱,会瞬间被黑客黑走
注意:此时 geth 已经在运行了
进入Geth JavaScript console
geth attach ipc:/data/gethdata/geth.ipc
输入 eth
会显示与以太坊网络交互的一些方法
eth
看到 accounts: [] 说明,我们还没有创建账户,我们在节点上创建第一个账户
创建账户
- personal.newAccount(“密码”),这个密码,就是我们要操作第一个账户的时候使用的密码
personal.newAccount("111111")
0xfbe2d1668e3ebaa97ca1c117793344a040817343
再次输入 etc
可以看到 accounts 变化了,所有的 accounts 以列表的形式存储,且 coinbase = accounts[0]
{
accounts: ["0xfbe2d1668e3ebaa97ca1c117793344a040817343"],
blockNumber: 0,
coinbase: "0xfbe2d1668e3ebaa97ca1c117793344a040817343",
compile: {
lll: function(),
serpent: function(),
solidity: function()
},
defaultAccount: undefined,
defaultBlock: "latest",
gasPrice: 1000000000,
hashrate: 0,
mining: false,
pendingTransactions: [],
protocolVersion: "0x41",
syncing: false,
call: function(),
chainId: function(),
contract: function(abi),
estimateGas: function(),
fillTransaction: function(),
filter: function(options, callback, filterCreationErrorCallback),
getAccounts: function(callback),
getBalance: function(),
getBlock: function(),
getBlockByHash: function(),
getBlockByNumber: function(),
getBlockNumber: function(callback),
getBlockTransactionCount: function(),
getBlockUncleCount: function(),
getCode: function(),
getCoinbase: function(callback),
getCompilers: function(),
getGasPrice: function(callback),
getHashrate: function(callback),
getHeaderByHash: function(),
getHeaderByNumber: function(),
getMining: function(callback),
getPendingTransactions: function(callback),
getProof: function(),
getProtocolVersion: function(callback),
getRawTransaction: function(),
getRawTransactionFromBlock: function(),
getStorageAt: function(),
getSyncing: function(callback),
getTransaction: function(),
getTransactionCount: function(),
getTransactionFromBlock: function(),
getTransactionReceipt: function(),
getUncle: function(),
getWork: function(),
iban: function(iban),
icapNamereg: function(),
isSyncing: function(callback),
namereg: function(),
resend: function(),
sendIBANTransaction: function(),
sendRawTransaction: function(),
sendTransaction: function(),
sign: function(),
signTransaction: function(),
submitTransaction: function(),
submitWork: function()
}
personal.newAccount() 方法在源码的 go-ethereum/console/bridge.go 中
NewAccount 是对个人信息的包装。使用非回显密码提示符获取密码短语并执行原始 RPC 方法(保存在 jeth.newAccount 中)以实际执行 RPC调用的方法
通过查看源码,可以看到 personal 的各种方法
或者也可以输入 personal 来查看:
personal
显示如下
{
listAccounts: ["0xfbe2d1668e3ebaa97ca1c117793344a040817343", "0xffae391d253d6bad1534af32ad3d7a991a0b3987"],
listWallets: [{
accounts: [{...}],
status: "Locked",
url: "keystore:///data/gethdata/keystore/UTC--2020-09-25T05-30-20.240316132Z--fbe2d1668e3ebaa97ca1c117793344a040817343"
}, {
accounts: [{...}],
status: "Locked",
url: "keystore:///data/gethdata/keystore/UTC--2020-09-25T05-35-07.546078594Z--ffae391d253d6bad1534af32ad3d7a991a0b3987"
}],
deriveAccount: function(),
ecRecover: function(),
getListAccounts: function(callback),
getListWallets: function(callback),
importRawKey: function(),
initializeWallet: function(),
lockAccount: function(),
newAccount: function(),
openWallet: function(),
sendTransaction: function(),
sign: function(),
signTransaction: function(),
unlockAccount: function(),
unpair: function()
}
挖矿
具体参考:ethereum入门-常用命令示例(包括创建用户、挖矿、交易等)
查看挖矿进账的用户,默认为本地账户中的第一个账户
eth.coinbase
设置挖矿的用户
miner.setEtherbase(eth.accounts[0])
- 开始挖矿
- 启用 10 个线程开始挖矿
miner.start(10)
miner.start() 方法在 go-ethereum/miner/miner.go 中
或者通过输入 miner
来查看方法,显示如下
{
getHashrate: function(),
setEtherbase: function(),
setExtra: function(),
setGasPrice: function(),
setRecommitInterval: function(),
start: function(),
stop: function()
}
- 查看挖矿状态
eth.mining
true
- 即使退出了 JavaScript Console,只要 geth 还在后台运行,就会一直在挖矿
- 停止挖矿
miner.stop()
- 查看收益(以太坊币)
eth.getBalance(eth.accounts[0])
352000000000000000000
- 查看日志
tail -f geth.log
或
vi geth.log
以太坊币介绍
Ether 币最小单位是 Wei,1 以太币=1*10^18 Wei
1 e t h e r = 1 × 1 0 3 f i n n e y = 1 × 1 0 6 s z a b o = 1 × 1 0 9 g w e i = 1 × 1 0 12 m w e i = 1 × 1 0 15 k w e i = 1 × 1 0 18 W e i 1 \ ether = 1 \times10^3 \ finney = 1 \times10^6 \ szabo= 1 \times10^9 \ gwei= 1 \times10^{12} \ mwei = 1 \times10^{15} \ kwei= 1 \times10^{18} \ Wei 1 ether=1×103 finney=1×106 szabo=1×109 gwei=1×1012 mwei=1×1015 kwei=1×1018 Wei
- ether 与 Wei 的转换
web3.toWei(1)
“1000000000000000000”
web3.fromWei(1000000000000000000)
“1”
转账操作
先看看有几个账户
eth.accounts
[“0xfbe2d1668e3ebaa97ca1c117793344a040817343”, “0xffae391d253d6bad1534af32ad3d7a991a0b3987”]
创建需要转账的 2 个账户,密码分别为 123 与 456
personal.newAccount("123")
personal.newAccount("456")
查看账户余额
eth.getBalance(eth.accounts[0])
或
web3.fromWei(eth.getBalance(eth.coinbase), "ether")
如果有多个账户,在 /data/gethdata/script
下新建一个 js 文件
cd /data/gethdata
mkdir script
vi getAllBalance.js
输入以下函数:
function checkAllBalances() {
var totalBal = 0;
for (var acctNum in eth.accounts) {
var acct = eth.accounts[acctNum];
var acctBal = web3.fromWei(eth.getBalance(acct), "ether");
totalBal += parseFloat(acctBal);
console.log(" eth.accounts[" + acctNum + "]: \t" + acct + " \tbalance: " + acctBal + " ether");
}
console.log(" Total balance: " + totalBal + " ether");
};
进入Geth JavaScript console
,然后装载该脚本
geth attach ipc:/data/gethdata/geth.ipc
loadScript('script/getAllBalance.js')
使用定义的函数查看账户余额
checkAllBalances()
eth.accounts[0]: 0xfbe2d1668e3ebaa97ca1c117793344a040817343 balance: 0 ether
eth.accounts[1]: 0xffae391d253d6bad1534af32ad3d7a991a0b3987 balance: 0 ether
eth.accounts[2]: 0x57ba41ee26cbbd823b7c544626e660e9220a3ea4 balance: 0 ether
eth.accounts[3]: 0xc5e74ba4b26e2cde7c8800fa4afa7ec4d0a426ad balance: 0 ether
Total balance: 0 ether
由于账户余额没有以太币,因此需要先挖矿
指定账户3 为 coinbase
,并启用 10 个线程挖矿
miner.setEtherbase(eth.accounts[2])
miner.start(10)
查看账户余额(挖矿约 10 分钟)
checkAllBalances()
eth.accounts[0]: 0xfbe2d1668e3ebaa97ca1c117793344a040817343 balance: 0 ether
eth.accounts[1]: 0xffae391d253d6bad1534af32ad3d7a991a0b3987 balance: 0 ether
eth.accounts[2]: 0x57ba41ee26cbbd823b7c544626e660e9220a3ea4 balance: 338 ether
eth.accounts[3]: 0xc5e74ba4b26e2cde7c8800fa4afa7ec4d0a426ad balance: 0 ether
Total balance: 338 ether
可以看到账户 3 有 338 个 以太坊币,现在可以开始转账了(交易)
- 定义转账、收账的用户以及转账金额
acc0=eth.accounts[2]
acc1=eth.accounts[3]
amount=web3.toWei(100)
- 解锁账户(需要密码 123)
personal.unlockAccount(acc0)
- 转账,并生成交易 Hash
eth.sendTransaction({from:acc0,to:acc1,value:amount})
“0xa55ab52b805bab27bbfd4edbd185a68d99e7172a3edbc37de7168fbf978535b7”
- 查询一下是否转到另一个账户里
checkAllBalances()
- 根据交易 Hash 查询
eth.getTransaction("0xa55ab52b805bab27bbfd4edbd185a68d99e7172a3edbc37de7168fbf978535b7")
转账过程如果有错误请看:Stack OverFlow