原文地址: 石匠的bloggit
为了测试以太坊智能合约,最方便的是在本地搭建一个以太坊私有链。在mac上搭建环境主要须要如下步骤。github
geth是go-ethereum的简写,是一个用go语言编写的以太坊客户端,是在以太坊智能合约开发中最经常使用的命令行工具。
在mac上能够经过brew工具直接安装:web
brew tap ethereum/ethereum brew install ethereum
详细的安装说明也能够查看官方文档。json
安装完成后,能够再mac的terminal中,用如下命令测试工具是否正常:api
geth -h
为了建立一个本身测试的私有链,须要首先建立一个创世区块,能够自定义创世区块信息信息genesis.json:安全
{ "config": { "chainId": 10, "homesteadBlock": 0, "eip155Block": 0, "eip158Block": 0 }, "alloc": {}, "coinbase": "0x0000000000000000000000000000000000000000", "difficulty": "0x20000", "extraData": "", "gasLimit": "0x2fefd8", "nonce": "0x0000000000000042", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp": "0x00" }
区块参数释义:网络
chainId: 指定了独立的区块链网络ID。网络ID在链接到其余节点的时候会用到,以太坊公网的网络ID是 1,为了避免与公有链网络冲突,运行私有链节点的时候要指定本身的网络ID。不一样ID网络的节点没法相互链接。 HomesteadBlock: 当设置为0表示使用Homestead发布该链。 nonce: 一个64位随机数,用于挖矿,注意它和mixhash的设置须要知足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。 mixhash: 与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意它和nonce的设置须要知足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。 difficulty: 设置设置当前区块的难度,值越大挖矿就越难。 alloc: 用来预置帐号以及帐号的以太币数量。 coinbase: 矿工帐号 timestamp: 设置创世块的时间戳 parentHash: 上一个区块的hash,创世块就为0 extraData: 附加信息,本身能够填写任意信息 gasLimit: 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和
找一个合适的目录,执行命令,建立创世区块:cors
geth --datadir "./" init genesis.json
运行成功后会在当前目录建立geth和keystore两个文件夹dom
前面创建创世区块成功后,启动区块链程序:ide
geth --datadir "./" --nodiscover console 2>>geth.log
相关参数:
--nodiscover 使用这个参数,你的节点就不会被其余人发现,除非手动添加你的节点。不然,就只有一个被无心添加到一个陌生区块链上的机会,那就是跟你有相同的genesis文件和networkID。 --maxpeers 0 若是你不想有人连上你的测试链,就用maxpeers 0。或者,你能够调整参数,当你确切的知道有几个节点要链接上来的时候。 --rpc 容许RPC操做你的节点。这个参数在Geth上是默认的。 --rpcapi "db,eth,net,web3" 这个命令指示了容许经过RPC访问的命令。默认状况下,Geth容许web3。 --rpcport "8080" --rpccorsdomain "http://chriseth.github.io/browser-solidity/" --datadir "/home/TestChain1" 私有链存放路径(最好跟公有链路径不一样) --port "30303" 网络监听端口,用来和其余节点手动链接 --identity “TestnetMainNode" 用来标识你的节点的,方便在一大群节点中识别出本身的节点
console指定了启动成功后进入命令行界面,2>>将日志重定向到geth.log中,否则日志也会输出到界面上,会和命令行界面混在一块儿,不方便命令行测试。
在命令行中建立帐号:
>personal.newAccount()
而后会提示输入帐号密码,成功后会返回一个帐号地址,好比:0xc7ca64442b98cbfdb6f056841ccd40f8b7f054bb
也能够经过给newAccount传递密码做为参数,一次性完成建立:
>personal.newAccount("123456")
查看帐户的余额:
>eth.getBalance("0xc7ca64442b98cbfdb6f056841ccd40f8b7f054bb")
开始挖矿:
>miner.start()
开始后,能够tailf geth.log看看挖矿初始化是否成功,以及挖矿过程细节。
中止挖坑:
>miner.stop()
将一个帐户的代币转移到另一个帐户,须要经过事务接口完成 eth.sendTransaction({from: acc0, to: acc1, value: amount}),好比:
>eth.sendTransaction({from: "0x01b5ecbcd8d46c1a9ee52e8b8a30bb6426dffb1b", to: "0xe6e4e20c95abc11dca8b3e9c292a34725bf89930", value: 20})
转出的帐户须要密码解锁,否则会发生相似如下错误:
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
很好理解,若是转出别人帐户的代币,不须要密码验证,那就毫无安全可言了,能够经过如下方式,解锁帐户后继续转帐:
>personal.unlockAccount("0xab04698365ed79ef22921edad8f6f516ca40cecb")
转帐完成后,能够经过eth.getBalance()查看余额,可是立刻查询却发现并无变化,这是由于sendTransaction这是发起了一笔交易事务,尚未获得确认,只是将这个事务放到了待提交池中。区块链的机制中是新建立区块的时候,会就从事务池中找出全部事务,进行有效性验证,验证成功后进行挖矿并将全部相关事务打包到区块中,待新的去区块成功加入到区块链中后,以前的转帐就获得了最终的确认和永久固话。
因此,sendTransaction成功后,须要调用挖矿命令miner.start()建立区块,而后再查看余额会发现转帐金额变化已经生效。