上一篇博客介绍了如何搭建私链并在私链上创建账户、挖矿、查看余额,本篇将介绍在私链上部署合约并与之交互。本篇开发环境为MacOS 10.12,建议读者使用macOS系统或者Ubuntu系统。
第一步,进入geth客户端
启动私链,进入geth客户端。启动终端,进入你的私链所在目录。输入:
geth --datadir "./" console 2>>geth.log
第二步,编写智能合约
合约代码我们使用出自以太坊官网的一段最简单的合约代码:
pragma solidity ^0.4.9;
contract Test{
function f(uint a) returns (uint b){
uint result = a*8;
return result;
}
}
如果你有过编程经验,一定能够猜测出这段代码的功能:输入一个数字,返回它的8倍的值。
第一行代码表示该合约支持solidity0.4.9及以上版本。contract Test可以看做是面向对象语言(如JAVA)中的类,f是这个合约的一个函数,returns指定返回值类型为uint,uint代表无符整型。将这段代码键入到Remix中。
第三步,编译合约
点击Remix右侧的start to compile(如果勾选了auto compile则不需要点击),如果没有报错,点击Details(这个按钮在start to compile的下面一行),此时会弹出一个信息框,里面有一块叫做WEB3DEPLOY,复制这段代码,代码如下:
var testContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"f","outputs":[{"name":"b","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]);
var test = testContract.new(
{
from: web3.eth.accounts[0],
data: '0x6060604052341561000f57600080fd5b60b68061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b3de648b146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b600080600883029050809150509190505600a165627a7a7230582098308aba54ec83fa77e460bbb939783c32c67727e90e560c6e1975affac1b3f80029',
gas: '4700000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
这是一段js代码,这段代码的作用是将合约部署到当前链上,使用的账户是accounts[0]。gas是燃料的意思。在以太坊中,对链每进行一次“写”操作,都要付出“代价”,这个代价就是gas,消耗gas意味着消耗以太坊。如果你是跟着前一篇博客读过来的,此时你可以回头看看genesis.json文件,这个文件中有一项叫做gasLimit,这个属性定义了链单次消耗gas的上限。
第四步,部署合约
回到geth终端,如果此时你将复制的代码粘贴进geth中,并按下回车,会报错,报错信息大致如下:
这是因为账户accounts[0]处于锁住状态,输入:
personal.unlockAccount(eth.accounts[0],"password")
第一个参数是要解锁的账户地址,这里我们是accounts[0],第二个参数是账户的密码,按下回车返回true代表解锁成功。接着,输入挖矿指令,如果私链不挖矿就产生不了新的区块,合约是不能够成功部署的,
miner.start(1)
当私链开始挖矿后,把之前的代码复制进来,按下回车。等待片刻,当终端返回信息Contract mined,合约即部署成功!
第五步,与合约交互
观察WEB3DEPLOY可以发现,部署后的合约被赋值给了test,输入指令:
test.f.call(8)
回车得返回值64。通过这条指令,我们从geth终端调用了合约中的函数f,并获得了正确的结果!我们完成了与合约的第一次交互!指令中的call()表示调用函数进行“只读”操作,不会消耗gas。