您的位置:首页 > 运维架构 > Linux

【区块链学习】以Linux为例,通过控制台部署和运行智能合约

2017-06-07 13:29 1001 查看

安装环境

安装以太坊环境

(1)
sudo apt-get install software-properties-common






(2)
sudo add-apt-repository -y ppa:ethereum/ethereum




(3)
sudo add-apt-repository -y ppa:ethereum/ethereum-dev




(4)
sudo apt-get update




(5)
sudo apt-get install ethereum
,如果这一步失败,一直重试安装




安装solidity语言编译器

(1)Chrome里面插件安装

打开Chrome网上应用商店,搜索
solidity




安装后打开,一般solidity语言编写的智能合约代码会自动编译,然后在右边显示,如果没有,说明solidity代码语法错误

例如,solidity智能合约代码编译通过



例如,solidity智能合约代码编译失败



(2)solidity语言在线编译器

Solidity IDE

私有链搭建

(1)打开终端(Ctrl+Alt+T)



(2)打开测试网控制台:
geth --datadir "~/ethdev" --dev console 2>> geth.log




(3)查看personal的属性:
personal




(4)创建账户:
personal.newAccount('123456')
,123456是密码,
0xe9f350a2c250fa26b7eb3db6f28d858668b7e45b
是账户地址



(5)查看账户余额:
web3.eth.getBalance(personal.listAccounts[0])
,
personal.listAccounts[0]
就是我们第一账户,当前账户余额为0



(6)启动挖矿:
miner.start()
, 如果感觉占用CPU,可以启动一个CPU挖矿
miner.start(1)




(7)打开另一终端,查看挖矿信息(如果一直挖矿,会不断刷屏,正常,这个终端用来观察挖矿信息),查看挖矿信息:
tail -f geth.log




(8)停止挖矿:
miner.stop()
,如果觉得CPU被占用觉得还行,忽略这一步,后面交易确认需要挖矿一直进行



(9)查看余额:
web3.eth.getBalance(personal.listAccounts[0])
或者
web3.fromWei(eth.getBalance("0xe9f350a2c250fa26b7eb3db6f28d858668b7e45b"), "ether")






(10)解锁发起智能合约的账户:
personal.unlockAccount("0xe9f350a2c250fa26b7eb3db6f28d858668b7e45b")
,
0xe9f350a2c250fa26b7eb3db6f28d858668b7e45b
是我们发起智能合约账户的地址



部署智能合约

(1)编写智能合约:

contract Rating {
function setRating(bytes32 _key, uint256 _value) {
ratings[_key] = _value;
}
mapping (bytes32 => uint256) public ratings;
}


(2)复制编译后得到
Web3 deploy
, 从代码上看,定义了2个变量:
ratingContract
rating


var ratingContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"_key","type":"bytes32"},{"name":"_value","type":"uint256"}],"name":"setRating","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ratings","outputs":[{"name":"","type":"uint256"}],"type":"function"}]);
var rating = ratingContract.new(
{
from: web3.eth.accounts[0],
data: '606060405260c88060106000396000f360606040526000357c01000000000000000000000000000000000000000000000000000000009004806350b7b7a21460415780636c71d01d14606057603f565b005b605e6004808035906020019091908035906020019091905050608a565b005b6074600480803590602001909190505060ad565b6040518082815260200191505060405180910390f35b8060006000506000848152602001908152602001600020600050819055505b5050565b6000600050602052806000526040600020600091509050548156',
gas: 3000000
}, function(e, contract){
console.log(e, contract);
if (typeof contract.address != 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})




(3)复制上面的代码到控制台上,从内容看,里面是2个变量的定义,所以分开复制更好看一些。



(4)这时,我们可以检查一下交易池,查看当前交易的待处理状况:
txpool.status
,如果pending=1,说明我们的合约还没得到确认,因为我们刚才停止挖矿。



(5)从上面,我们可以看到当前的交易池中有一个交易正在等待确认。然后,我们查看待确认交易的详细内容:
eth.getBlock("pending",true).transactions




我们从显示出来的结果可以看出当前交易的一些内容。例如,from数据项就是我们发送交易的地址,input就是合约编译完成的字节码,这些内容均与我们之前的设定相同。而且,我们可以看到新的交易创建在第2016号区块中。

与此同时,我们也可以查看一下刚才在新的终端中创建的挖矿日志。我们在日志中找到这样的一行信息:



这说明交易已经发送到区块链中了,正在等待矿工的确认。

(6)启动挖矿:
miner.start()




控制台提示
Contract mined
,则合约被创建成功,并返回合约的地址(address)和此次交易的散列值。可通过这两个数值在区块链上寻找合约的信息。

(7)我们发现交易池已经没有待确认的交易了。我们使用
eth.getBlock(2016)
命令查看第2016号区块的信息:
eth.getBlock(2016)




我们发现hash值为
0xa20f32030e6114002da1e8c8645023ee02ad43a18dde34f43c916bddc886bc5e
的交易确实在第2016号区块中。

调用智能合约

(1)在部署合约所使用的控制台窗口下,可直接使用合约名和函数名调用合约。假设一个用户想为1号商品打3分,需要调用rating合约的setRating函数,需要执行以下命令:(我这里是rating,是因为我上面编译合约的代码赋值给rating,这里这里要根据自己编译完合约的代码而定)

rating.setRating.sendTransaction(1, 3, {from: personal.listAccounts[0]})


如果出现下面红色的错误,重新解锁账户



由于用户需要发起一个交易并改变区块链的状态,因此需要用到合约对象的
sendTransaction()
方法来发起交易。该方法的前几个参数为
setRating
函数的参数,最后一个参数为发起交易的地址,也就是需要为本次交易支付费用的账户的地址。这里
personal.listAccounts[0]
代表钱包内的第1个账户,即基准账户
MAIN ACCOUNT
:

"0x3c194bcba9c3b90028fdd22aaad4f4c8973781835c15c57d3879dc5c1c743760"


(2)经过一段时间的确认,该交易被保存到区块链中,此时可使用rating合约中的ratings数组来显示1号商品的打分,其命令如下:
rating.ratings(1)




这时将会显示3,表示1号商品被打了3分。由于此时并不需要改变区块链系统的状态,因此不需要使用sendTransaction方法,也就不需要支付任何费用。

(3) 如果想在其他以太坊节点通过控制台调用合约,则需知道合约的地址和接口。执行以下命令实例化合约对象:
var NewRatingContract = eth.contract(interface).at(“address”)
这里,interface的信息可从Solidity在线编辑器上获得,而address在合约部署之后返回得到。之后,使用NewRatingContract.ratings(1)命令就可查找到1号商品的打分。例如我的:

var NewRatingContract = eth.contract([{"constant":false,"inputs":[{"name":"_key","type":"bytes32"},{"name":"_value","type":"uint256"}],"name":"setRating","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ratings","outputs":[{"name":"","type":"uint256"}],"type":"function"}]).at("0x133e80139ce46615a777ba26f5ee2a39ee709df1")


找到interface信息:



找到address信息:



(3)查询打分:



参考

如何开发编译部署调用智能合约
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: