您的位置:首页 > 其它

【区块链】以太坊私有链下智能合约部署

2017-09-16 10:59 731 查看

以太坊私有链下智能合约部署

上一篇文章实现了搭建私有链,以下进行智能合约的部署

一、 编写合约

简单的乘法例子:

pragma solidity ^0.4.2;
contract test {

function multiply(uint a) returns(uint d) {
return a * 7;
}
}


二、 编译合约

推荐网站:here

得到:Interface 和 Bytecode 和 Web3 deploy

Bytecode: 6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a723058206f9974e7f2c8329cbc09530d06d001018bfeca369c7cd8f9d565298adbdd2a9c0029

Interface: [{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]

Web3 deploy:
var browser_ballot_sol_testContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]);
var browser_ballot_sol_test = browser_ballot_sol_testContract.new(
{
from: web3.eth.accounts[0],
data: '0x6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a723058206f9974e7f2c8329cbc09530d06d001018bfeca369c7cd8f9d565298adbdd2a9c0029',
gas: '4300000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})


三、 部署合约

在部署合约前,我们要明确需要以下几项条件:

一个有Ether的账户;

该账户已解锁;

编译合约得到的abi和code。

所以首先需要做以下工作:

//创建账户
personal.newAccount('密码')

//挖矿,获得ether
miner.start()
miner.stop()

//账户解锁
personal.unlockAccount("第一个账户地址", "密码")


第一步: 获取abi信息,即上述编译得到的interface

abi = [{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]


得到结果:

[{
constant: false,
inputs: [{
name: "a",
type: "uint256"
}],
name: "multiply",
outputs: [{
name: "d",
type: "uint256"
}],
payable: false,
stateMutability: "nonpayable",
type: "function"
}]
>


第二步:

multiplyContract = web3.eth.contract(abi)


得到结果:

{
abi: [{
constant: false,
inputs: [{...}],
name: "multiply",
outputs: [{...}],
payable: false,
stateMutability: "nonpayable",
type: "function"
}],
eth: {
accounts: ["0xbe98c12f918275591c9a43ec3c7bc44cfca50d2f"],
blockNumber: 7,
coinbase: "0xbe98c12f918275591c9a43ec3c7bc44cfca50d2f",
compile: {
lll: function(),
serpent: function(),
solidity: function()
},
defaultAccount: undefined,
defaultBlock: "latest",
gasPrice: 18000000000,
hashrate: 0,
mining: false,
pendingTransactions: [],
protocolVersion: "0x3f",
syncing: false,
call: function(),
... (一堆function)
}


第三步: 复制 Web3 deploy 到命令行

multiply = multiplyContract.new(
{
from: web3.eth.accounts[0],
data: '0x6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a723058206f9974e7f2c8329cbc09530d06d001018bfeca369c7cd8f9d565298adbdd2a9c0029',
gas: '4300000'  //改为300000
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})


得到结果

{
abi: [{
constant: false,
inputs: [{...}],
name: "multiply",
outputs: [{...}],
payable: false,
stateMutability: "nonpayable",
type: "function"
}],
address: undefined,
transactionHash: "0x87400471a0e32edcfa9e1ca621d08a318e9abb85299d280deb8bc199e118427f"
}


==> 在这一步,可能你会得到一条错误信息:

invalid sender undefined


解决方法: 在genesis.json文件中,chainId 不能设置为0。 如果你完全按照github上给的官方配置文件,就会产生这个错误

==> 在这一步,可能你会得到一条错误信息:

Error: authentication needed: password or unlock undefined


解决方法:先解锁账户啦

personal.unlockAccount("第一个账户地址", "密码")


==> 在这一步,可能你还会遇到这个问题:

Error: exceeds block gas limit undefined
The contract code couldn't be stored, please check your gas amount. undefined


解决方法:把gas改为300000。直接从那个网站的Web3 deploy 复制可能是4300000,然后改成300000,就没问题了。

猜测原因:

eth.getBlock("pending").gasLimit
web3.eth.estimateGas({data: bytecode})

可以先输入这两条来预判一下范围,取中间值。


第四步:然后我们需要挖矿确认

miner.start()

等待一会,你会得到一条信息:
Contract mined! address: 0xdb385bc97ed9fbac62920102d5edc7c4bf993c79 transactionHash: 0x87400471a0e32edcfa9e1ca621d08a318e9abb85299d280deb8bc199e118427f
==> 就代表部署成功啦。

miner.stop()


四、合约交互

第一步:获取合约对象

MyContract = eth.contract(abi)


得到结果:

{
abi: [{
constant: false,
inputs: [{...}],
name: "multiply",
outputs: [{...}],
payable: false,
stateMutability: "nonpayable",
type: "function"
}],
eth: {
accounts: ["0xd88ad6d115ed640b69f01e24ff1433f75d5c8f87"],
blockNumber: 4,
coinbase: "0xd88ad6d115ed640b69f01e24ff1433f75d5c8f87",
compile: {
lll: function(),
serpent: function(),
solidity: function()
},
defaultAccount: undefined,
defaultBlock: "latest",
gasPrice: 18000000000,
hashrate: 612,
mining: false,
pendingTransactions: [],

...(一堆function)
}


第二步:实例化合约

myContract = MyContract.at(multiply.address)


得到结果:

{
abi: [{
constant: false,
inputs: [{...}],
name: "multiply",
outputs: [{...}],
payable: false,
stateMutability: "nonpayable",
type: "function"
}],
address: "0xdb385bc97ed9fbac62920102d5edc7c4bf993c79",
transactionHash: null,
allEvents: function(),
multiply: function()
}


第三步:调用合约

myContract.multiply.call(5)


得到结果:

35


五、在电脑B调用该合约

确定两台电脑已成功连接。电脑B上新建账户,并解锁。

1. abi = [{constant:false,inputs:[{name:'a',type:'uint256'}],name:'multiply',outputs:[{name:'d',type:'uint256'}],type:'function'}]  //合约的abi
2. address = 0xdb385bc97ed9fbac62920102d5edc7c4bf993c79  // 合约地址
3. myContract = web3.eth.contract(abi).at(address)

==> 然后就可以调用使用了 myContract.multiply.call(5)
得到结果:35


参考博客:hereherehere
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息