区块链100讲:以太坊开发环境部署(附代码)

Posted by

区块链100讲:以太坊开发环境部署(附代码)

本文作者:HiBlock区块链技术布道群-胡键

原文发布于简书

原文链接:https://www.jianshu.com/p/bec173e6cf73

加微信baobaotalk_com,加入技术布道群

区块链100讲:以太坊开发环境部署(附代码)

注:本文的运行环境为MacOS。

1

安装

brew tap ethereum/ethereumbrew install ethereum

完成之后,通过以下命令验证:

geth version

2

运行

所谓运行,是指运行一个节点并加入以太坊网络,它有两个选择:公链和测试链,这两个网络都在互联网上。

2.1 公链

geth –fast –cache=512 –datadir “你的目录” console

2.2 测试链

geth –testnet –fast –cache=512 –datadir “你的目录” console

这两种方式都需要同步区块,它们存放于datadir指定的目录之下,因此请确保有足够的空间。

3

搭建私链

搭建私链的目的主要是出于测试的目的,不建议搭建以运营为目的的私链。整个步骤如下:

3.1 编写genesis.json,定义初始信息。内容示例如下:

{

“config”: {

“chainId”: 20,

“homesteadBlock”: 0,

“eip155Block”: 0,

“eip158Block”: 0

},

“alloc”: {

“0xeb680f30715f347d4eb5cd03ac5eced297ac5046”: {

“balance”:”100000000000000000000000000000000″

}

},

“coinbase”: “0x0000000000000000000000000000000000000000”,

“difficulty”: “0x01”,

“extraData”: “0x777573686f756865”,

“gasLimit”: “0xffffffff”,

“nonce”: “0x0000000000000001”,

“mixhase”: “0x0000000000000000000000000000000000000000000000000000000000000000”,

“parentHash”: “0x0000000000000000000000000000000000000000000000000000000000000000”,

“timestamp”: “0x00”

}

3.2 初始化

geth –datadir “your dir” init genesis.json

3.3 启动,见到小锤子后,表示已经开始挖矿。

geth –datadir “你的目录” –rpc –rpcaddr=0.0.0.0 –rpcport 8545 –rpccorsdomain “*” –rpcapi “eth,net,web3,personal,admin,shh,txpool,debug,miner” –nodiscover –maxpeers 30 –networkid 1981 –port 30303 –mine –minerthreads 1 –etherbase “0xeb680f30715f347d4eb5cd03ac5eced297ac5046” console

这里需要注意的是,在此命令行下“ctrl-c”并不会终止进程。如果要终止运行,在命令行下输入“exit”。

geth还提供了控制台,输入如下命令可进入:

geth –datadir “你的目录” attach ipc:你的目录/geth.ipc

该控制台提供的接口包括:账户、交易、合约调用、区块。

4

智能合约

本节以vscode为IDE,geth-cli简要说明智能合约的开发过程。

4.1 环境准备

安装语言包

brew install solidity

准备IDE插件

https://github.com/juanfranblanco/vscode-solidity,进入“扩展”,搜索“solidity”,第一个就是。

4.2 合约开发

编辑(simpledata.sol),内容如下:

pragma solidity ^0.4.23;

contract SimpleData {

uint data;

function set(uint x) public{

data = x;

}

function get() view public returns (uint) {

return data;

}

}

编译

echo “var output=`solc –optimize –combined-json abi,bin,interface simpledata.sol`” > simpledata.js

部署(利用前面搭建好的私链)

  • 启动私链

  • 进入控制台,以下所有步骤均在控制台里完成,采用js语法。

  • 加载编译过的js:

loadScript(‘…/simpledata.js’)

  • 获取部署需要的相关参数,其中output为上面“编译”步骤中定义的output:

var contractAbi = output.contracts[‘simpledata.sol:SimpleData’].abi

var contract = eth.contract(JSON.parse(contractAbi))

var binCode = “0x” + output.contracts[‘simpledata.sol:SimpleData’].bin

  • 创建用户,同时让其账户有余额(部署也是要花钱的):

personal.newAccount(“123456”) // 参数为密码

miner.setEtherbase(eth.accounts[0]) // 设置创建的用户为矿工

web3.fromWei(eth.getBalance(eth.accounts[0]), “ether”) // 查看余额

  • 发布

var deployTx = { from: eth.accounts[0], data: binCode, gas: 1000000};

var instance = contract.new(deployTx)

var contractAddress = eth.getTransactionReceipt(instance.transactionHash).contractAddress // 合约地址

调用(仍在同一条私链上,同样在控制台执行)

var simpleData = contract.at(contractAddress)

simpleData.get.call()

personal.unlockAccount(eth.accounts[0]) // 此步必需

simpleData.set.sendTransaction(33, {from: eth.accounts[0], gas: 100000})

simpleData.get.call()

此处需要注意的有两点:

  • 链上的变更通过交易完成,同时执行合约是有代价的,即gas,这是与传统开发很大的不同。也是为何前面在部署之前先创建用户,并将其设置为矿工,获得余额的原因。

    注意:gas和eth不是一类东西,合约最终消耗的eth由:步骤和gasPrice来决定。

  • 执行交易之前需要先解锁账户,这类似咱们在用网银时转账前需要输入“取款密码”。同时,解锁是有时限的,为了避免频繁解锁可以用下面的语句:

personal.unlockAccount(eth.accounts[0], 密码, 时限)

这里出现了交易,因此也说明一下安全性的问题:

  • 以太坊上所有的交易都是公开可查看的,所有交易历史可以通过Etherscan看到。

  • 所有交易执行都是要用发起者的私钥签名的,因此只要私钥能得到妥善保存,就不会有什么大问题。在上面的步骤中没有出现用私钥签名,这是因为账户本身是由控制台创建的,在创建的同时也创建了相应的公钥和私钥。

5

Truffle框架

可以看得出上面的整个过程相当繁琐,Truffle则正是为解决这些问题而生的。

安装

npm install -g truffle

开发部署

  • mkdir dapp

  • cd dapp

  • truffle init

  • 进入contracts目录,创建下面的文件

pragma solidity ^0.4.23;

contract Storage {

uint256 storageData;

function set(uint256 data) public {

storageData = data;

}

function get() view public returns (uint256) {

return storageData;

}

}

  • truffle compile

  • 合约的部署通过migration完成,假如用过诸如liquidbase之类的dbmigration工具,对此应该不陌生。进入migrations目录,创建相应的文件,以“数字_”开头,如“2_deploy_storage.js”。内容如下:

var Storage = artifacts.require(“Storage”);

module.exports = function(deployer) {

deployer.deploy(Storage);}

  • 搭建开发用的测试链,ganache,因为它的速度比前面自行搭建的私链更快。

npm install -g ganache-cli // 安装

ganache-cli //运行

  • 在部署之前,修改truffle.js内容(其中networks可定义各种网络,其客观上起到了类似“环境”的作用):

module.exports = {

networks: {

development: {

host: “127.0.0.1”,

port: 8545,

network_id: “*” // Match any network id

}

}

};

  • truffle migrate

至此,部署完毕,让我们手动测试一下。

6

利用JSON-RPC手工调用合约

JSON-RPC接口可以用curl完成,其特点在于:合约的方法是rpc请求的数据。如果觉得这有点拗口,不妨将这种方式与利用Java Reflection来调用某个类的方法做类比。

要调用上面的合约,首先需要获得合约方法(get和set)的签名:

get方法

curl -X POST -i http://localhost:8545 –data ‘{

“jsonrpc”:”2.0″,

“method”:”web3_sha3″,

“params”:[“get()”],

“id”:1

}’

set方法

curl -X POST -i http://localhost:8545 –data ‘{

“jsonrpc”:”2.0″,

“method”:”web3_sha3″,

“params”:[“set(uint256)”],

“id”:1

}’

方法签名利用“web3_sha3”得到,其签名为返回值的0x后的8位。上面两个调用对应的结果如下:

  • get:6d4ce63c

  • set:60fe47b1

调用合约需要合约的地址,这个值可以从ganache终端中获得。在其终端输出中查找类似下面的语句,其中created之后的即为地址。

Contract created: 0x59322f0c1235719b4c0044b0c67f2437674b8c69

剩下的就是合约调用了(其中from账户直接使用ganache启动时初始化的账户,to为合约地址):

get方法

curl -X POST -i http://localhost:8545 –data ‘{

“jsonrpc”:”2.0″,

“method”:”eth_call”,

“params”:[

{ “from”:”0x2fe84a7fb107ade77adfeb351b92615597b68f52″, “to”:”0x59322f0c1235719b4c0044b0c67f2437674b8c69″,

“data”:”0x6d4ce63c0000000000000000000000000000000000000000000000000000000000000000″

},

“latest”

],

“id”:1

}’

set方法

curl -X POST -i http://localhost:8545 –data ‘{

“jsonrpc”:”2.0″,

“method”:”eth_sendTransaction”,

“params”:[

{ “from”:”0x2fe84a7fb107ade77adfeb351b92615597b68f52″, “to”:”0x59322f0c1235719b4c0044b0c67f2437674b8c69″, “gas”:”0xc350″,

“gaslimit”:”0xc350″, “data”:”0x60fe47b10000000000000000000000000000000000000000000000000000000000000005″

}

],

“id”:1

}’

注意两次调用的“method”的不同。同时,“data”参数中的0x后的前8位为对应的方法签名,后面则为实际传入到对应方法的数据。

7

编程接口

如果要在js文件中与智能合约交互,则需要相应的包:

  • web3.js,其封装了json-rpc接口

  • truffle-contract模块,truffle的合约抽象

8

自动化测试

truffle支持两类自动化测试:使用javascript和使用solidity,都相当简单,这里不再赘述。测试文件统一放在test目录下,测试命令:

truffle test // 全部测试truffle test 文件 // 单个测试

9

包管理

js包用普通的npm,略

智能合约的包用ethpm

truffle install 包名truffle publish 包名

10

参考

Truffle(https://truffleframework.com/)

solidity(https://solidity.readthedocs.io/en/v0.4.24/)

区块链开发实战:以太坊关键技术与案例分析,部分内容过时,比如TestRPC目前已经被Ganache替代。

— 线下活动推荐–

技术工坊|如何利用ERC875协议开发世界杯区块链门票?(北京)

— 线上课程推荐–

区块链课堂|猜想区块链数字货币交易所的未来进化(线上免费)

始发于微信公众号: 区块链社区HiBlock