从这周开始,我正式开始了以太坊开发的学习。本着利己利人的目的,集结这周的笔记形成了这篇极简入门。它的特点就是:无废话!
注:本文的运行环境为MacOS。
brew tap ethereum/ethereum
brew install ethereum
完成之后,通过以下命令验证:
geth version
所谓运行,是指运行一个节点并加入以太坊网络,它有两个选择:公链和测试链,这两个网络都在互联网上。
geth --fast --cache=512 --datadir "你的目录" console
geth --testnet --fast --cache=512 --datadir "你的目录" console
这两种方式都需要同步区块,它们存放于datadir指定的目录之下,因此请确保有足够的空间。
搭建私链的目的主要是出于测试的目的,不建议搭建以运营为目的的私链。整个步骤如下:
编写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"
}
初始化
geth --datadir "your dir" init genesis.json
启动,见到小锤子后,表示已经开始挖矿。
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
该控制台提供的接口包括:账户、交易、合约调用、区块。
本节以vscode为IDE,geth-cli简要说明智能合约的开发过程。
brew install solidity
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
部署(利用前面搭建好的私链)
loadScript('.../simpledata.js')
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]) // 设置创建的用户为矿工
miner.start() //开始挖矿,产生余额
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()
此处需要注意的有两点:
personal.unlockAccount(eth.accounts[0], 密码, 时限)
这里出现了交易,因此也说明一下安全性的问题:
可以看得出上面的整个过程相当繁琐,Truffle则正是为解决这些问题而生的。
npm install -g truffle
pragma solidity ^0.4.23;
contract Storage {
uint256 storageData;
function set(uint256 data) public {
storageData = data;
}
function get() view public returns (uint256) {
return storageData;
}
}
var Storage = artifacts.require("Storage");
module.exports = function(deployer) {
deployer.deploy(Storage);
}
npm install -g ganache-cli // 安装
ganache-cli //运行
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*" // Match any network id
}
}
};
至此,部署完毕,让我们手动测试一下。
JSON-RPC接口可以用curl完成,其特点在于:合约的方法是rpc请求的数据。如果觉得这有点拗口,不妨将这种方式与利用Java Reflection来调用某个类的方法做类比。
要调用上面的合约,首先需要获得合约方法(get和set)的签名:
curl -X POST -i http://localhost:8545 --data '{
"jsonrpc":"2.0",
"method":"web3_sha3",
"params":["get()"],
"id":1
}'
curl -X POST -i http://localhost:8545 --data '{
"jsonrpc":"2.0",
"method":"web3_sha3",
"params":["set(uint256)"],
"id":1
}'
方法签名利用“web3_sha3”得到,其签名为返回值的0x后的8位。上面两个调用对应的结果如下:
调用合约需要合约的地址,这个值可以从ganache终端中获得。在其终端输出中查找类似下面的语句,其中created之后的即为地址。
Contract created: 0x59322f0c1235719b4c0044b0c67f2437674b8c69
剩下的就是合约调用了(其中from账户直接使用ganache启动时初始化的账户,to为合约地址):
curl -X POST -i http://localhost:8545 --data '{
"jsonrpc":"2.0",
"method":"eth_call",
"params":[
{
"from":"0x2fe84a7fb107ade77adfeb351b92615597b68f52",
"to":"0x59322f0c1235719b4c0044b0c67f2437674b8c69",
"data":"0x6d4ce63c0000000000000000000000000000000000000000000000000000000000000000"
},
"latest"
],
"id":1
}'
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位为对应的方法签名,后面则为实际传入到对应方法的数据。
如果要在js文件中与智能合约交互,则需要相应的包:
truffle支持两类自动化测试:使用javascript和使用solidity,都相当简单,这里不再赘述。测试文件统一放在test目录下,测试命令:
truffle test // 全部测试
truffle test 文件 // 单个测试
truffle install 包名
truffle publish 包名
更多的区块链文章。
觉得有帮助的话,不妨考虑购买付费文章来支持我们 🙂 :
付费文章