以太坊搭建私链(二):创建私有区块链、挖矿以及转账

本教程是基于CentOS7.5系统进行的。

区块链是由若干个区块组成的。因此我们首先需要为私有链创建第一个区块(即创世区块),类似于数据结构中链表的头节点。

创建创世区块

首先,你需要创建一个创世区块,这个区块的创建应该让所有节点都知道,并且都同意。

创建创世区块的配置主要存储于一个JSON文件中,这里我们存在一个叫genesis.json的文件中。

为了使结构更加清晰,先创建一个文件夹,专门存放私有链相关数据。

mkdir private_eth
cd private_eth
touch genesis.json

把下面的具体配置拷贝到genesis.json中,并保存

{
  "config": {
    "chainId": 10001,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0
  },
  "alloc": {},
  "coinbase": "0x0000000000000000000000000000000000000000",
  "difficulty": "0x20000",
  "extraData": "",
  "gasLimit": "0x2fefd8",
  "nonce": "0x0000000000000042",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp": "0x00"
}

如果你想为一些账户预先分配一些资金便于测试,那么可以在配置中创建账户并分配一些资金。这时候,你只需要用下面的配置替换掉上面的"alloc":{ }即可:

"alloc": {
  "0x0000000000000000000000000000000000000001": {
    "balance": "111111111"
  },
  "0x0000000000000000000000000000000000000002": {
    "balance": "222222222"
  }
}

 

初始化区块链

启动之前,先进行初始化:

geth init genesis.json --datadir test 

test目录表示保存区块链相关数据的目录,这里的test 与 genesis.json 文件在同一个目录下。

test目录是之前不存在的,执行后会自动生成。

test目录下有两个子目录:

  • geth:存储同步区块链以及相关的数据;
  • keystore:保存了账户文件。由于私链刚创建,此时keystore目录为空。

注意:

如果直接执行

geth init genesis.json

可能会出现如下错误:

Fatal: Failed to write genesis block: database contains incompatible genesis (have d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3, new a3c5c170988f516e00ea3078b2461a149bcd4d0422c8c894923c6cfa22d6926b)

因此记得通过--datadir 设置相应的存储区块链相关数据的目录。

 

启动以太坊客户端

geth --rpc --rpccorsdomain="*"  --nodiscover --allow-insecure-unlock  --datadir './test' console

执行成功之后,如下图所示:

一些常用相关参数总结:

// Ethereum参数
--config value:表示TOML配置文件的目录;
--datadir value:存储区块链相关数据的文件目录,包含geth和keystore两个文件夹(默认为 "/home/ligi/.ethereum"),geth目录存储同步区块链以及相关的数据,keystore存储账户相关数据;
--datadir.ancient value             Data directory for ancient chain segments (default = inside chaindata)
--keystore value                    账户秘钥的存储目录 (默认在datadir里面)
--networkid value                   网络标识符 (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby) (default: 1)
--testnet                           Ropsten network: pre-configured proof-of-work test network
--rinkeby                           Rinkeby network: pre-configured proof-of-authority test network
--syncmode value                    区块链同步模式 ("fast", "full", or "light") (default: fast)
--exitwhensynced                    块同步完成后退出
--identity value                    自定义节点名称


//DEVELOPER CHAIN OPTIONS:
--dev                               拥有一些预先设置了资金的开发者账户的临时权威证明网络,并且可以直接挖矿
--dev.period value                  在开发者模式中使用块(出块)的时间,0表示只有在交易挂起的时候才会挖矿,1表示不用等有了交易才挖矿 (default: 0)


//ACCOUNT OPTIONS:
  --unlock value                      要解锁的账户列表(多个账户用逗号分隔)
  --password value                    用于非交互式密码输入的密码文件


//API AND CONSOLE OPTIONS:
  --ipcdisable                        禁用(关闭)IPC-RPC服务器
  --ipcpath value                     Filename for IPC socket/pipe within the datadir (explicit paths escape it)
  --rpc                               启用HTTP-RPC服务器
  --rpcaddr value                     HTTP-RPC服务器监听的IP地址 (default: "localhost")
  --rpcport value                     HTTP-RPC 服务器监听端口(default: 8545)
  --port:指定和其他节点连接所用的端口号(默认为 30303);
  --rpcapi value                      通过HTTP-RPC接口提供的API
  --rpc.gascap value                  设置可以在eth_call/estimateGas中使用的gas上限(默认值:0) (default: 0)
  --rpccorsdomain value               哪些域名允许访问跨域请求(多个域名用逗号分隔)(浏览器执行),"*"表示允许通过任意域名进行访问
  --rpcvhosts value                   允许哪些虚拟主机名接受请求(多个的时候用逗号分开)(服务器执行). 接受 '*' 通配符. (default: "localhost")
  --ws                                启用WS-RPC服务器
  --wsaddr value                      WS-RPC服务器监听的地址 (default: "localhost")
  --wsport value                      WS-RPC服务器监听的端口号 (default: 8546)
  --wsapi value                       WS-RPC接口提供的API
  --wsorigins value                   接受websockets请求的源


//NETWORKING OPTIONS:
  --nodiscover                        禁用节点发现机制,防止加入有同样初始配置的的陌生节点


--verbosity: 表示设置日志等级,0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 

更多具体的参数解析请看:[Command Line Options](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)

 

开始挖矿

 

(1)使用之前genesis.json中配置的账户进行挖矿

挖矿之前,先将账户和矿工进行绑定。miner是JavaScript控制台中内置的矿工对象,在控制台中可以使用如下的命令将genesis.json文件中的“alloc”中的某个地址与miner对象进行绑定,绑定的目的之一就是为了明确挖矿得到的奖励存到哪个账户去;

miner.setEtherbase("0x0000000000000000000000000000000000000001")

 

开始挖矿之前,我们可以查看一下两个临时账户的余额

eth.getBalance("0x0000000000000000000000000000000000000001")
eth.getBalance("0x0000000000000000000000000000000000000002")

结果如下:

开始挖矿

miner.start()

查看当前区块链中的区块数

eth.blockNumber

再次查询两个临时账户的余额

eth.getBalance("0x0000000000000000000000000000000000000001")
eth.getBalance("0x0000000000000000000000000000000000000002")

由于矿工挖矿得到了一些挖矿的奖励(以太币),所以我们可以发现与矿工绑定的账户的余额变多了。

 

(2)创建一个新的账户用于挖矿

进入JavaScript控制台之后,然后先创建一个新账户,执行下面的命令输入两次密码即可完成新账户的创建:

personal.newAccount()

创建完之后可以查看现有的账户

personal.listAccounts

结果如下图所示,第二个账户就是我们创建的新账户:

将新账户与矿工进行绑定

miner.setEtherbase("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f")

查看新账户的余额

web3.fromWei(eth.getBalance(eth.coinbase), "ether")  //刚开始余额为0
//eth.coinbase直接使用账户的具体地址也可以实现上面一样的效果,比如
web3.fromWei(eth.getBalance("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f"), "ether")

开启挖矿

miner.start()

停止挖矿

miner.stop()

查询账户余额,此时账户余额有所增加,因为矿工挖矿得到了相应的奖励

web3.fromWei(eth.getBalance(eth.coinbase), "ether")
// or
web3.fromWei(eth.getBalance("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f"), "ether")

 

转账

我们可以将A账户的以太币转账给B账户,这里我们用两个账户进行转账操作的展示。

personal.listAccounts

可以发现我们这里有两个账户:

  • 第一个是"0xf157aa0bc8350484171eb0c18e739db03a2f23ce";
  • 第二个是"0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f"(这个是和矿工进行绑定了的);

现在我们用第二个账户向第一个账户转账3个Ether。

  • (1)首先我们查看转账之前,两个账户的余额是多少
web3.fromWei(eth.getBalance("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f"), "ether")   // 22 Ether 
web3.fromWei(eth.getBalance("0xf157aa0bc8350484171eb0c18e739db03a2f23ce"), "ether")  // 542 Ether

  • (2)在转账之前,我们需要先把账户解锁(类似我们在银行转账,要先输密码一样)
personal.unlockAccount("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f", "123456", 300)   //"123456"表示该账户的密码

如果转账之前没有解锁账户,会出现如下错误:

WARN [11-11|16:11:04.940] Served eth_sendTransaction               reqid=35 t=13.912431ms err="authentication needed: password or unlock"
Error: authentication needed: password or unlock
    at web3.js:3143:20
    at web3.js:6347:15
    at web3.js:5081:36
    at <anonymous>:1:1
  • (3)从第二个账户向第一个账户转账3个Ether
eth.sendTransaction({from: '0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f', to: '0xf157aa0bc8350484171eb0c18e739db03a2f23ce', value: web3.toWei(3, "ether")})

执行完成之后,会有如下显示:

INFO [11-11|16:12:35.946] Setting new local account                address=0x7a3F4c28A85eC58F3c8bD862ab201B8a03Dfff5F
INFO [11-11|16:12:35.946] Submitted transaction                    fullhash=0x0fb7355356dc901976c9d996e59bfed1315bdd0546a5dbf9abca2fdabffff35c recipient=0xF157Aa0BC8350484171eb0C18e739DB03A2F2
"0x0fb7355356dc901976c9d996e59bfed1315bdd0546a5dbf9abca2fdabffff35c"

address 表示从哪个账户转出;

fullhash 表示交易hash值;

recipient 表示转入哪个账户;

这个时候我们再次查询两个账户的余额,可以发现这两个账户的余额依然不变。

这是因为交易在挖矿之后才能记入到区块中并上链,所以我们需要进行挖矿。

miner.start(1)

然后再停止挖矿

miner.stop()

最后,查询两个账户的余额

web3.fromWei(eth.getBalance("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f"), "ether")
web3.fromWei(eth.getBalance("0xf157aa0bc8350484171eb0c18e739db03a2f23ce"), "ether")

我们可以发现第一个账户(0xf157aa0bc8350484171eb0c18e739db03a2f23ce)增加了 3 Ether,第二个账户(0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f)之前是22 Ether,现在也增加到了 29 Ether,这是因为第二个账户挖矿得到了 10 Ether的奖励,所以减去转出的 3 Ether,还有29 Ether。

 

参考:

Go Ethereum

以太坊(2):CentOS下以太坊私有链环境下的账户管理操作、挖矿、转账

CentOS 以太坊(Etherum) 环境搭建及挖矿

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值