区块链学习(二)搭建基于go-ethereum的以太坊的私有链环境

上一篇文章 详细的说明了如何在 Ubuntu 环境下编译 go-ethereum ,本节内容为 搭建基于 go-ethereum 的以太坊私有链环境

原文链接:ETH开发(二)搭建基于go-ethereum的以太坊的私有链环境

重新加载 profile 文件,加载环境变量到内存,否则会提示 geth 命令未找到

source ~/.profile

测试

geth -h 
  • 更正系统时间,便于后续日志查看

点击右上角时间–时间设置,然后点击地图设置为 Shanghai

在这里插入图片描述

1 以太坊的一些基本命令

同步主网做为节点,需要满足以下条件:

  1. 空余磁盘 500G 以上。目前,全球交易数据大约在350G 以上
  2. 需要足够的带宽

创建运行目录

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 服务
–rpcaddrRPC 监听地址0.0.0.0(任何 IP 都可以)
–rpcportRPC 监听接口8545(自定义)
–cache内部缓存512
–maxpeers最大网络对等点数量9999
–rpcapiRPC 接口APIweb3,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主网,搭建私有链必须为非 18888
nonce64位随机数,用于挖矿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

参数解释配置
–networkid8888
–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])
  1. 开始挖矿
  • 启用 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()
}
  1. 查看挖矿状态
eth.mining

true

  • 即使退出了 JavaScript Console,只要 geth 还在后台运行,就会一直在挖矿
  1. 停止挖矿
miner.stop()
  1. 查看收益(以太坊币)
eth.getBalance(eth.accounts[0])

352000000000000000000

  1. 查看日志
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

下一篇文章:区块链学习(三)使用以太坊 Truffle 框架并搭建第一个 DApp

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值