摘要:
区块链最近炒的沸沸扬扬,作为一名技术开发,也来试一下水,区块链技术还很年轻,网络上没有一篇文章能完全解决mac下以太坊环境配置,所以本人贡献一篇
正文:
本机系统 macOS Sierra 10.12.6
环境配置
(1) 安装python 这步mac是自带python2.7的 直接可以跳过
brew install python
(2) 安装solc(solidity语言编译器) 和solc-cli
sudo npm install -g solc solc-cli --save-dev
(3) 安装ethereum/cpp-ethereum(以太坊客户端geth)
网络上文章一般使用如下步骤官网教程链接
brew update
brew upgrade
brew tag ethereum/ethereum
brew install cpp-ethereum
brew linkapps cpp-ethereum
或者
brew tag ethereum/ethereum
brew install ethereum
这步操作是有问题的 我在命令行中报了一个错误 没有错误提示 让我去github提issue 查找资料 觉得最大可能是不兼容的问题
这时候我们去下载release版本的客户端就好了 不需要从源码编译运行release版本下载地址
小技巧 与本文关系不大 但感觉还是要做的
下载release版本的客户端打开后 需要同步节点 不管是什么网络状态下 自己搭建的私有网络除外 节点数据是很大的 以太坊私有节点的数据近40个G 本人机器内存不够 所以想着把数据放在移动硬盘 本地做个文件夹路径映射 因为以太坊数据是默认放在固定路径(/Users/xxxxx/Library/Ethereum)下的 不能更改路径(本人没找到 谁知道的可以教我下) 所以唯一解决方法就是做文件夹路径映射
方法如下 如果你是将A从B下面转移到C下面
(1) cd B 进入到原始位置
(2) ln -s C/A A 第一个路径是你准备转移去的位置 第二个路径是原始目录名
可能用的时候有出现问题 请保证最后的结果是这样的
我们继续 现在eth开发环境以及配置差不多了(没记错的话)
现在开始初始化我们的私有链以及挖矿交易 这步往后 其实网络上大部分文章都能走通 但有些点还是没有讲到 我总结一下好了 也给自己留个记录 东西总是忘的比较快
区块都是一个接一个的创建 那么创世区块 也就是第一个区块怎么来的? 需要一个配置文件 json格式
(1)创建一个文件夹 放自己的私有链 创建一个json文件
例子:
{
"config": {
"chainId": 666,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc" : {},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x20000",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00"
}
参数名称 | 参数描述 |
---|---|
mixhash | 与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意他和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。 |
nonce | nonce就是一个64位随机数,用于挖矿,注意他和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。 |
difficulty | 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度 |
alloc | 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要预置有币的账号,需要的时候自己创建即可以。 |
coinbase | 矿工的账号,随便填 |
timestamp | 设置创世块的时间戳 |
parentHash | 上一个区块的hash值,因为是创世块,所以这个值是0 |
extraData | 附加信息,随便填,可以填你的个性信息 注意需要0x开头 我把文字转十六进制扔进去了 |
gasLimit | 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。 |
启动私有节点所需参数
参数名称 | 参数描述 |
---|---|
identity | 区块链的标示,随便填写,用于标示目前网络的名字 |
init | 指定创世块文件的位置,并创建初始块 |
datadir | 设置当前区块链网络数据存放的位置 |
port | 网络监听端口 |
rpc | 启动rpc通信,可以进行智能合约的部署和调试 |
rpcapi | 设置允许连接的rpc的客户端,一般为db,eth,net,web3 |
networkid | 设置当前区块链的网络ID,用于区分不同的网络,是一个数字 |
console | 启动命令行模式,可以在Geth中执行命令 |
本人启动eth所在目录为:
/Users/xxxxx/tmpPrivate
目录下放刚刚写好的创世json文件:genesis.json 如果没有特别想法 只是想练手 直接copy我上面那个json就好了
执行命令
geth --datadir "./" init genesis.json
这边有几个常见的错误
Fatal: invalid genesis file: missing 0x prefix for hex data:这个错误信息意思很明白,就是你的json文件中,对于16进制数据,需要加上0x前缀
Fatal: invalid genesis file: hex string has odd length: 从v1.6开始,设置的十六进制数值,不能是奇数位, 比如不能是0x0,而应该是0x00。
Fatal: failed to write genesis block: genesis has no chain configuration :这个错误信息,就是说,你的json文件中,缺少config部分。看到这个信息,我们不需要把geth退回到v1.5版本,而是需要加上config部分。
Error: invalid sender undefined: 这个错误不会导致初始化失败,但是会在以后的转账(eth.sendTransaction),或者部署智能合约的时候产生。解决方法就是chainId 不能设置为0。 如果你完全按照github上给的官方配置文件,就会产生这个错误。
如果成功,这时候目录下会多出geth和keystore两个文件夹 geth保存的是区块链相关数据 keystore中保存的是该链条中的用户信息
初始化创世区块后,我们启动自己的私有链条
geth --datadir "./" --nodiscover --port "35555" console 2>>geth.log
这里又有一个eth的自带bug 由于我们日志输出到geth.log文件中 所以下面我们挖矿的时候 miner.start() 输出是null 不再是正常的ture 这个是eth的bug
这个时候我们可以打开另一个控制台 cd 到我们目录下 我的就是上面的tmpPrivate文件夹 看到是否出现了一个 geth.log文件 如果有的话 我们输入
tail -f geth.log 这句命令可以持续的输出以太坊的日志
回到上一句命令出来的Geth JavaScript console 中
这时候私有链中没有账户 我们需要创建一个账户
输入命令
personal.newAccount("Pcookie1") 该命令创建了一个新的用户,该用户密码是Pcookie1
再次输入命令
eth.accounts 我们发现用户组里已经有一个用户了
我们可以再次创建一个用户 为下面转账做准备
挖矿
这个控制台的语法是js语法 我们可以通过
user1 = eth.accounts[0] 把用户组里的第0位用户赋值给user1变量 类似的
user2 = eth.accounts[1]
我们再执行
eth.getBalance(user1) 可以查看里面的余额
执行
eth.blockNumber 可以查看当前区块高度
我们执行
miner.start() 一般文章中会说输出ture才成功 但是现在都是null 这个bug上面提过
miner.stop() 停止挖矿
挖矿一般都会给默认第0位用户 也可以通过指定选择给哪个账户
miner.setEtherbase(eth.accounts[1])
挖一会儿后可以看看区块高度 以及账户里面是否增加了 以及可以看之前持续输出的控制台的打印日志
转账
以太坊环境 每隔一段时间自动会把账户锁定 所以几乎每次交易转账的时候都需要先解锁
personal.unlockAccount(user2)
输入密码 就是自己之前设定的账户密码
执行
amount = web3.toWei(1) 表示转账一个eth
执行
eth.sendTransaction({from: user2, to: user1, value: amount})
应该不要解释 就是从user2账户转账给user1
这时候有些人会迫不及待用上面查询的语句看看是不是真的变了 结果发现没有变化
这个时候就是缺了个概念 就是挖矿的存在的意义 挖矿就是记账的意思 所以 每次转账 合约部署 之类的时候 需要用挖矿 把账记下来
我们执行miner.start()
成功~
这篇文章本来一周前就要写的。。一直没空。。发现挺多人有困惑的。。还是抽空写了。。后面再写合约部署 合约的代码solidty 版本编译也有很多坑 其实合约这东西 在我看来 只是一个物品交换的规则 就是逻辑 很简单 没什么写的必要 不过写个简单的走个流程 后面研究区块链底层技术 写一个自己的基础链 把btc思想写出来 还是会收获很多的 希望大家都能起飞 本人私人博客