以太坊私链搭建
安装
系统:Ubuntu
环境
GO
下载go包,安装并加入环境变量
成功标志:
Ethereum
|
|
成功标志:
参考文档:
区块链技术指南: 地址
初始化
新建项目目录
|
|
ethereum是项目目录,新建目录data用以存放databases和keystore,新建文件init.json用于初始化的配置。以上目录文件名称等可以自定。
init配置
配置内容参考官网
init.json内容如下:
如果需要初始化的时候添加账户,可以在alloc中注明
mixhash:
与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意他和nonce的设置需要满足以太坊的Yellow Paper,Block Header Validity(44)章节中所描述的条件nonce:
nonce就是一个64位的随机数,用于挖矿,注意他和mixhash的设置需要满足以太坊的Yellow Paper,Block Header Validity(44)章节中所描述的条件difficulty:
设置当前区块的难度,如果难度过大,cpu挖矿就困难。私有链设置的小一些。alloc:
用于预设值账号已经账号的以太币数量。coinbase:
矿工的账号,随意填timestamp:
创世块的时间戳parentHash:
上一个区块的hash值,因为是创世块,所以这个值为0extraData:
附加信息gasLimit:
该值设置对gas的消耗总量限制,用来限制区块能包含的交易信息的总和。私有链填最大。
具体的key的含义参考官网文档即可。
使用中发现extraData不为空时,会报错
Fatal: invalid genesis file: json: cannot unmarshal hex string without 0x prefix into Go struct field Genesis.extraData of type hexutil.BytesAttention: chainId不能为0,为0时,在后续转账是无法成功。报错
Error: insufficient funds for gas * price + valueAttention: chainId 和 后续的networkid 保持一致,否则报错Error: insufficient funds for gas * price + value。 见issue。
创世操作
执行以下命令初始化系统
正常结果如下:
接着执行以下命令 启动运行
参数的含义请参考Command文档.
参数 | 参数说明 |
---|---|
datadir | 设置当前区块链网络数据存放的位置 |
console | 启动命令行模式,可以在geth里执行命令 |
nodiscover | 关闭p2p网络的自动发现,不会被网上看到 |
networkid | 网络标识,用于区分不同的网络,私有链取一个大于4的随意的值 |
identity | 区块链的标示,随便填写,用于标示目前网络的名字 |
init | 指定创世块文件的位置,并创建初始块 |
rpc | 启动rpc通信,可以进行智能合约的部署和调试 |
rpcapi | 设置允许连接的rpc的客户端,一般为db,net,eth,web3 |
正常结果返回Welcome to the Geth JavaScript console!
|
|
操作到现在,私有链已经搭建好了,只是现在还没有账户,也没有交易,只有一个环境。
最终的ethereum目录结构如下:
挖矿
写在前面的话:如果是像我一样跑在虚拟机上的童鞋,请先调高你的虚拟机配置,初始的Ubuntu我的是1C1G,通过5h的挖矿探索,发现调高配置到4C2G,分分钟挖到了。血泪史。
接着上面的geth命令行,执行以下命令查询账户和新建账户。listAccounts为[],表示当前没有账户;newAccount(),输入密码就会新建一个账户,这时候再listAccounts就会显示刚才创建的用户。
personal.listAccounts 等同于eth.accounts,说明有很多包的方法有重复
geth的命令行支持的操作参见文档
现在有了第一个账户,可以开始挖矿了。
geth命令行执行以下命令,查当前账户的钱包。当前为0以太币
接着输入
语法是:miner.start(threadCount),返回true表示开始挖矿
一次挖矿完整的记录如下
分析一下:
Generating DAG in progress
正在生成DAG,参考DAGRegenerated local transaction journal
重新生成本地事务日志Successfully sealed new block
成功密封新块mined potential block
挖掘潜在的块Commit new mining work
提交新的采矿工作block reached canonical chain
块达到了规范链epoch
纪元elapsed
过去uncles
叔链
这个时候我再查一下账户,发现已经有钱啦。这就是挖矿得来的奖励。
我查了下总共有11次success的标识,钱包是55 ether,那每次挖矿会奖励5个以太币了。(显示的单位是wei)
注意:ethereum中的最小交易单位是wei,所有的交易都已Wei为单位进行。换算方法如下:
Unit | Wei Value | Wei |
---|---|---|
wei | 1 | 1 wei |
Kwei (babbage) | 1e3 wei | 1,000 |
Mwei (lovelace) | 1e6 wei | 1,000,000 |
Gwei (shannon) | 1e9 wei | 1,000,000,000 |
microether (szabo) | 1e12 wei | 1,000,000,000,000 |
milliether (finney) | 1e15 wei | 1,000,000,000,000,000 |
ether | 1e18 wei | 1,000,000,000,000,000,000 |
交易
为了模拟交易,我们新建一个用户。
新账户的钱包:
我们要互相转多少钱呢?由于wei的单位太小,直接使用起来不方便,我们可以执行以下命令:
web3.toWei(number, unit) 是把数值转换为wei的单位
web3.toWei(1,’ether’) === 1 ether (默认)
web3.toWei(1,’kWei’)=== 1 kWei
web3的用法参照文档.
web3 console里内置了一些用来操作以太坊的Javascript对象。主要有:
- eth:包含一些跟操作区块链相关的方法
- net:包含以下查看p2p网络状态的方法
- admin:包含一些与管理节点相关的方法
- miner:包含启动&停止挖矿的一些方法
- personal:主要包含一些管理账户的方法
- txpool:包含一些查看交易内存池的方法
- web3:包含了以上对象,还包含一些单位换算的方法
我们把钱从第一个账户转到第二个账户,金额是1 ether。
命令很好理解(命令省去了一些参数)。报错也很常见,账户被锁。这是ethereum的安全机制,每隔一段时间就会锁定账户。交易前先解锁账户(发起交易的账户)。
|
|
解锁完成,直接操作
执行到这一步如果报错Error:insufficient funds for gas * price + value的报错,回到init时的attention处找一下原因。我做到这一步报错,停掉重新init,重新启动,账户还在,余额也在,转账正常。原理还未知。
这个时候,查看两个账户的余额,发现还没有变化。这是因为交易要记录在通过挖矿找到的块上才算生效。所以我们继续挖矿。
最终结果如下:挖到矿后,两个账户的金额有了变动,账户1:55+5(挖矿)-1(交易) ;账户2:1(交易)