本文所搭建的环境是在 Mac 上的开发环境,其余操做系统上与此很是类似,依然有参考价值。
做为一枚区块链开发工程师,本地的开发环境是必不可少的。咱们首先看看须要哪些工具:git
这些工具的安装在官方文档上都有很是详细的讲解,这边就很少赘述了。github
下文中的文件均已该目录为当前路径。
先新建好以下初始目录,web
. ├── data └── genesis.json
genesis.json
:初始化私有链的配置文件。data
:存放区块链数据的目录。以太坊支持自定义创世区块,要运行私有链那么就必须定义本身的创世区块。创世区块的信息就写在 genesis.json
中,内容以下:json
{ "config": { "chainId": 15, "homesteadBlock": 0, "eip155Block": 0, "eip158Block": 0 }, "alloc": {}, "nonce": "0x0000000000000042", "difficulty": "0x020000", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "timestamp": "0x00", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", "gasLimit": "0x4c4b40" }
大概解释下其中的几个参数:浏览器
接下来咱们就须要将创世区块的初始信息写入区块链中,使用 geth init
命令。网络
# geth --datadir "./data" --networkid 31415926 --rpc --rpccorsdomain "*" init ./genesis.json
大体会输出以下信息:app
INFO [03-12|19:36:02] Allocated cache and file handles INFO [03-12|19:36:02] Writing custom genesis block INFO [03-12|19:36:02] Persisted trie from memory database INFO [03-12|19:36:02] Successfully wrote genesis state
此时的目录结构就变成以下:cors
. ├── data │ ├── geth │ │ ├── chaindata │ │ │ ├── 000001.log │ │ │ ├── CURRENT │ │ │ ├── LOCK │ │ │ ├── LOG │ │ │ └── MANIFEST-000000 │ │ └── lightchaindata │ │ ├── 000001.log │ │ ├── CURRENT │ │ ├── LOCK │ │ ├── LOG │ │ └── MANIFEST-000000 │ └── keystore └── genesis.json
其中 keystore
目录用来保存帐户信息,geth
目录用来保存区块信息。dom
让咱们接下来启动私有链吧!工具
# geth --datadir data --networkid 31415926 --rpc --rpccorsdomain "*" --nodiscover console
输出以下即表示成功进入 geth
的控制台:
Welcome to the Geth JavaScript console! instance: Geth/v1.8.2-stable/darwin-amd64/go1.10 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 >
先别急着去挖矿,咱们得先建立一个帐户,否则挖出的 ether 塞哪里去呢!
ether 也就是咱们说的以太币(ETH)。
先来看看是否已存在帐户了,
> eth.accounts []
那咱们新建两个(用于后面帐户间的转帐演示),
> personal.newAccount() Passphrase: Repeat passphrase: "0x880004bb64282fb01a3a2500ddf1f4bb5ad4b64a" > personal.newAccount() Passphrase: Repeat passphrase: "0x29a079bdbc6d4d122178fbe01558e5df2d008523"
如今咱们就有两个帐户了,
> eth.accounts ["0x880004bb64282fb01a3a2500ddf1f4bb5ad4b64a", "0x29a079bdbc6d4d122178fbe01558e5df2d008523"]
多说一句,咱们此时去看看 keystore
目录,多出了两个文件,也就是咱们刚才建立的两个帐户密钥(丢了它,你就等于丢了币)
. ├── UTC--2018-03-12T11-46-09.722094891Z--880004bb64282fb01a3a2500ddf1f4bb5ad4b64a └── UTC--2018-03-12T11-48-04.771328116Z--29a079bdbc6d4d122178fbe01558e5df2d008523
这时候让咱们看看帐户里有没有 ether,
> eth.getBalance(eth.accounts[0]) 0
一开始你们的帐户里都没有 ether,那么都须要经过挖矿来获取。使用 miner.start()
命令开启挖矿,默认挖出的 ether 是存到 eth.coinbase
帐户中的,也就是第一个帐户。
> eth.coinbase INFO [03-12|19:55:13] Etherbase automatically configured address=0x880004Bb64282fb01A3A2500DDF1F4bB5AD4b64A "0x880004bb64282fb01a3a2500ddf1f4bb5ad4b64a"
若是咱们想要把挖到的矿存入其余帐户,能够这样:
> miner.setEtherbase(eth.accounts[1]) true
好了,咱们开始挖吧~
> miner.start(1) > INFO [03-12|20:00:44] Commit new mining work number=1 txs=0 uncles=0 elapsed=513.188µs INFO [03-12|20:00:47] Generating DAG in progress epoch=0 percentage=0 elapsed=1.668s INFO [03-12|20:00:49] Generating DAG in progress epoch=0 percentage=1 elapsed=3.368s
等到 percentage 达到100就能挖出来了,请耐心等待~
INFO [03-12|20:04:15] Successfully sealed new block number=4 hash=81db99…4db568 INFO [03-12|20:04:15] 🔨 mined potential block number=4 hash=81db99…4db568
出现小锤头的时候意味着你挖到了!
那么咱们先暂停挖矿,
> miner.stop() true
而后看看帐户余额,
> eth.getBalance(eth.accounts[0]) 85000000000000000000
不要被这个零的个数吓到,这里默认显示的以 wei
为单位的,而 1 ether = 10^18 wei
,因此咱们转换一下单位立马就清晰了,
> web3.fromWei(eth.getBalance(eth.accounts[0]), 'ether') 85
嗯,其实咱们目前就挖了 85 个 ether~
既然手头有了钱,分点给好朋友吧!
记得在转帐前把本身解锁,类比银行卡转帐,你得先输入密码才能转帐。
> personal.unlockAccount(eth.accounts[0]) Unlock account 0x880004bb64282fb01a3a2500ddf1f4bb5ad4b64a Passphrase: true
我决定转给好朋友 8 个 ether!
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(8,'ether')}) INFO [03-12|20:24:15] Submitted transaction fullhash=0x996a3037b75585415ece5b1dc28181833691760176b3f24066c93e7093a967e5 recipient=0x29a079BdbC6D4d122178FBe01558E5DF2D008523 "0x996a3037b75585415ece5b1dc28181833691760176b3f24066c93e7093a967e5"
咱们能够看到目前只是向区块链提交了这笔转帐交易,谁来执行这笔交易呢?矿工
咱们仍是得开启挖矿模式,把这笔转帐交易执行掉。而后咱们再来看看好朋友的帐户里面有多少 ether 了,
> eth.getBalance(eth.accounts[1]) 8000000000000000000
遥想当初第一次安装以太坊钱包的时候,为了下载以太坊主网络的全节点数据,整整下了5天,而后卡在最后几个区块死活动不了,最后弃疗。。。
这段磨人的经历想一想都心塞,不事后来用了 Ethfans 的星火节点计划,导入了超级节点,peers 一会儿增多,下载确实快多了。说回正题,此次咱们须要让 Ethereum Wallet 连上咱们的私有链,而后利用钱包的 UI 界面快速开发部署智能合约。
/Applications/Ethereum\ Wallet.app/Contents/MacOS/Ethereum\ Wallet --rpc "/path/to/data/geth.ipc"
注意这里的 --ipc
参数值是刚才项目里面 data
目录下的 geth.ipc
,就是让钱包链接上本地的私有链。
若是出现 miner.start() 直接返回 null 的状况,请先查看是否还未建立过帐户。
若是以前有搭建过本地私有链,那么请先将以前的 .ethash 目录删除,该目录在当前登陆用户的家目录下。
笔者一开始是选择最简单的开发流程去实践的:下载官方的 Ethereum Wallet 而后同步主网全节点,而后开发合约并部署。可是下载全节点的经历实在是不想回想,没日没夜同步了好几天还没同步全(离当前最新区块老是差那么几块同步不了,固然后来是解决了)。后来请教技术群友告知了我可使用 Remix + MetaMask 这种轻量级开发流程,确实方便不少,调试开发用基于浏览器的 Remix IDE,部署合约用基于浏览器插件的 MetaMask。
可是有时候 Remix 加载很慢,并且这个解决方案没网络就不行了(大部分都有 WIFI 能够连,可是有的时候真的是没网络。。。)私有链挺好的解决了上述两个困扰个人问题,并且在搭建和使用私有链的过程,就是一次比较完整的区块链体验~
欢迎关注公众号:『比特扣』,与我一块儿探索区块链的世界。