以太坊私有鏈下智能合約部署


上一篇文章實現了搭建私有鏈,以下進行智能合約的部署

一、 編寫合約

簡單的乘法例子:

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); } }) 

 

 

三、 部署合約

在部署合約前,我們要明確需要以下幾項條件:

  1. 一個有Ether的賬戶;
  2. 該賬戶已解鎖;
  3. 編譯合約得到的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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM