一、下载及安装客户端工具:geth
官网下载地址:https://geth.ethereum.org/downloads/(有一丢丢慢) 国内镜像下载地址:https://ethfans.org/wikis/Ethereum-Geth-Mirror
二、搭建私有链
1、准备创世区块配置文件
要运行私有链,我们就需要定义自己的创世区块,创世区块信息写在一个json格式的配置文件中。首先将下面的内容保存到一个json文件中,例如genesis.json。
{
"config": {
"chainId": 921,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0
},
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x400",
"extraData": "",
"gasLimit": "0xffffffff",
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00",
"alloc": {}
}
参数 | 解释 |
---|
chainId | 自定义私链的网络ID,不同的网络ID无法互联通讯,以太坊公链ID 为1,我们设置为921以防止与网络中其他私链冲突。 | homesteadBlock | 是否为HomeStead版本的区块,设置为0表明是。 | eip155Block | EIP155 [1] 是一个以太坊分叉提议,为了和以前的以太坊经典ETC 链条分叉而存在,我们私链不需要它,设为0。 | eip158Block | EIP158 [2] 是一个以太坊分叉提议,为了解决之前以太坊空账户造成效率低下的协议漏洞而分叉,我们私链不需要它,设为0。 | difficulty | 设置当前区块难度,若难度过大挖矿就很慢,我们设置较小值。 | gasLimit | 单一区块最大 gas 消耗上限,用来限制能够打包进入块的交易数量与信息总和,我们在学习中可以设置为最大。 | coinbase | 打包该块的矿工的奖励地址,因为是创世块,可设为0地址。 | console | 启动命令行模式,可以在Geth中执行命令 | extraData | 打包该块时矿工记录的笔记。 | nonce | 打包该块时矿工挖矿所用到的Ethash输入参数nonce。 | mixHash | 与nonce配合用于挖矿,创世区无前一个区块,可不填。 | parentHash | 前一个区块头的哈希值,创世区块无前一个区块,设为0。 | timestamp | 打包该块的时间戳,符合Unix Timestamp标准,设为0。 | alloc | 创世时各账户分配以太币的数量,不想分配则忽略。 |
2、初始化创世区块配置
我们已经准备好了创世的配置,接下来就是将该链条的配置初始化,形成区块链的起点,初始化之后我们就有了第一个区块,接下来就可以根据第一个区块来挖掘第二个区块了。
初始化命令 | 作用 |
---|
identity | 区块链的标示,随便填写,用于标示目前网络的名字 | init | 指定创世块文件的位置,并创建初始块 | datadir | 设置当前区块链网络数据存放的位置 | rpc | 启动rpc通信,可以进行智能合约的部署和调试 | rpcport | HTTP-RPC服务器监听端口(default: 8545) | rpcapi | 设置允许连接的rpc的客户端,默认只有eth,net,web3 | networkid | 设置当前区块链的网络ID,用于区分不同的网络,是一个数字 | console | 启动命令行模式,可以在Geth中执行命令 | rpccorsdomain | 指定一个可以接收请求来源的以逗号间隔的域名列表(浏览器访问的话,要强制指定该选项) |
进入 ether-test (自己新建的) 目录,执行初始化。
> geth --datadir data init genesis.json
上面的命令的主体是geth init,表示初始化区块链,命令可以带有选项和参数,其中–datadir选项后面跟一个目录名,这里为data,表示指定数据存放目录为data,genesis.json是init命令的参数。
运行上面的命令,会读取genesis.json文件,根据其中的内容,将创世区块写入到区块链中。如果看到以下的输出内容,说明初始化成功了。
Successfully wrote genesis state…
初始化成功后,会在数据目录data中生成geth和keystore两个文件夹,此时目录结构如下:
ether-test ├── data │ ├── geth │ │ └── chaindata │ │ ├── 000001.log │ │ ├── CURRENT │ │ ├── LOCK │ │ ├── LOG │ │ └── MANIFEST-000000 │ └── keystore └── genesis.json
其中 geth/chaindata中存放的是区块数据,keystore中存放的是账户数据。
3、启动私有链节点
执行启动区块链节点命令进入了Javascript Console:
> geth --datadir data --networkid 1108 console
这是一个交互式的Javascript执行环境,在这里面可以执行Javascript代码,其中>是命令提示符。在这个环境里也内置了一些用来操作以太坊的Javascript对象,可以直接使用这些对象。这些对象主要包括:
模块 | 解释 |
---|
personal | 账户相关操作–新建账户、锁定账户、发送签名交易等。 | admin | 节点管理相关–节点数据存储、网络状况、API 开放状况等。 | txpool | 交易池相关–交易池等待情况,查看某交易详情等。 | debug | 开发调试相关–追踪区块状况,分析区块详情、CPU 状况检测等。 | miner | 挖矿相关–更改奖励收款地址、开启/关闭挖矿功能、设置 gas 费用等。 | web3 | 包含了以上模块的总入口,还包含单位换算函数。 | eth | 提供了操作区块链的相关方法。 | shh | 提供了分布式网络 P2P Whisper通信协议的相关方法 |
其中常用命令有:
personal.newAccount():创建账户;
personal.unlockAccount():解锁账户;
eth.accounts:枚举系统中的账户;
eth.getBalance():查看账户余额,返回值的单位是 Wei(Wei - 是以太坊中最小货币面额单位,类似比特币中的聪,1 ether = 10^18 Wei);
eth.blockNumber:列出区块总数;
eth.getTransaction():获取交易;
eth.getBlock():获取区块;
miner.start():开始挖矿;
miner.stop():停止挖矿;
web3.fromWei():Wei 换算成以太币;
web3.toWei():以太币换算成 Wei;
txpool.status:交易池中的状态;
admin.addPeer():连接到其他节点;
三、接收挖矿奖励
1、创建账户
前面只是搭建了私有链,并没有自己的账户,可以在js console中输入personal对象来创建一个账户,123为设定的密码,eth.accounts查看账户数量。
账户默认会保存在数据目录的keystore文件夹中。查看目录结构,发现data/keystore中多了几个个文件,这两个文件就对应刚才创建的几个账户,这是json格式的文本文件,可以打开查看,里面存的是私钥经过密码加密后的信息。
2、查看账户余额
我们用eth功能模块来检查一下这两个账户的以太币余额。
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
0
我们用 web3 功能模块的 fromWei() 换算功能帮助我们换算了账户余额,如我们所预料的,账户余额为 0 。在以太坊的世界里没有浮点数小数点,只有整数。所以形如 3.1415 的小数在以太坊里是无法表示的,这里采用了 Wei 为单位表示以太坊不可分割的最小单位,将所有小数转化为大整数运算,
我们用 web3 库的换算功能帮助我们换算了账户余额,如我们所预料的,账户余额为 0 。
3、启动&停止挖矿
通过miner.start()来启动挖矿 通过miner.stop()来停止挖矿
其中start的参数表示挖矿使用的线程数。第一次启动挖矿会先生成挖矿所需的DAG文件,这个过程有点慢,等进度达到100%后,就会开始挖矿,此时屏幕会被挖矿信息刷屏。
矿工账户: 挖到一个区块会奖励5个以太币,挖矿所得的奖励会进入矿工的账户,这个账户叫做coinbase,默认情况下coinbase是本地账户中的第一个账户,通过miner.setEtherbase()可将其他账户设置成coinbase。
number表示出块数量
4、转账与收款
同样在控制台上我们解锁的转账方的账户,输入解锁密码,以及解锁时长 300秒 。
> personal.unlockAccount(eth.accounts[0], '123', 300)
解锁账户的真正解锁的对象是存储于硬盘的keystore文件。 用户输入密码解锁后将私钥解出,暂存于内存。 在使用签名过后或者解锁时长到达规定后再从内存中移除私钥。这是设计上安全性的考量。不签名直接发送交易,将导致交易异常,无法成功发出。
好,接下来我们发送一笔 10 个以太币的转账,转账接收方是另一个我们持有的账户。
> eth.sendTransaction({from:eth.accounts[0],to:"0xdb799cb611f49eb3435fdfe642b28b8ac50e51f",value: web3.toWei(10, 'ether')})
查看转账状态
之前我们已经命令挖矿停止。此时我们可以暂停查看全网状态。让我们深入研究此时刚发出去的交易处在什么阶段。
> txpool.status
{
pending: 1,
queued: 0
}
此时交易尚处在 待打包 (pending)的状态,它的具体内容又是什么呢?我们用交易的哈希值来查询一下它。
eth.getTransaction(“0x45b6be881cf86b79dc7ad8bf4d9cbfafc9aa191062411d6606a086bbc42042ed”) { blockHash: “0x0000000000000000000000000000000000000000000000000000000000000000”, blockNumber: null, from: “0x657abe37b32aaee7b34f602868a6387b7559a91e”, gas: 90000, gasPrice: 18000000000, hash: “0x45b6be881cf86b79dc7ad8bf4d9cbfafc9aa191062411d6606a086bbc42042ed”, input: “0x”, nonce: 1, r: “0x9b372d58eb5acce93a8aa742ce3af179576c17208835eaf356c270db24df448c”, s: “0x5990b41a4f0f8103f4786f785e47f797b83428c96c251ee89bc10cef1d143b35”, to: “0xdb799cb611f49eb3435fdfe642b28b8ac50e51f”, transactionIndex: 0, v: “0x7d9”, value: 10000000000000000000 }
from/to 字段指明了交易的发送方和接收方; gas/gasPrice 指明了交易方愿意支付的交易费;value 指明了本次转账的以太币金额(wei 为单位);由于我们不是调用合约的交易,所以 input 所代表的数据区域是空的 0x ; nonce 是账户曾经发出过的交易笔数的值;因为尚未被打包入区块,所以 blockHash/blockNumber 都是 0 或者不确定状态。 让矿工运行!让这条交易被打包吧!
> miner.start(1); admin.sleepBlocks(1); miner.stop();
以上代码将会让挖矿节点重启挖矿,稍等片刻,并在出块1个以后暂停挖矿。停止后区块链再次停止出块,给我们一个机会再观察一下交易池。
> txpool.status
{
pending: 0,
queued: 0
}
交易已经成功被矿工捕获并打包,我们再查看收款账户余额。
>web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
10
到这里就结束啦。码字不易,快去给博主点赞吧~
|