Go-Ethereum
使用 Azure 乙太坊聯盟部署智能合約不起作用
我創建了一個 Azure 乙太坊聯盟。部署的乙太坊網路在負載均衡器後面有 2 個事務節點。通過 Putty,我連接到其中一個交易節點。
然後我進入
geth attach
現在控制台已打開。安裝了solidity編譯器。然後我解鎖要使用的帳戶:
personal.unlockAccount(eth.accounts[1], "{your password}");
賬戶餘額為:
400000000000000000000
然後我編譯程式碼:
var greeterSource = 'pragma solidity ^0.4.9; /** @title Mortal.*/ contract mortal { /* Define variable owner of the type address*/ address owner; /**@dev this function is executed at initialization and sets the owner of the contract. */ function mortal() { owner = msg.sender; } /**@dev Function to recover the funds on the contract. */ function kill() { if (msg.sender == owner) { selfdestruct(owner); } } } /** @title Greeter.*/ contract greeter is mortal { /* define variable greeting of the type string */ string greeting; /**@dev This function runs when the contract is executed. * @param _greeting Greeting message. */ function greeter(string _greeting) public { greeting = _greeting; } /* main function */ /**@dev This function returns the greeting message. * @return greeting The greeting message. */ function greet() constant returns (string) { return greeting; } }'; var greeterCompiled = web3.eth.compile.solidity(greeterSource);
結果:
{ <stdin>:greeter: { code: "0x6060604052341561000c57fe5b6040516102f03803806102f0833981016040528051015b5b60008054600160a060020a03191633600160a060020a03161790555b805161005390600190602084019061005b565b505b506100fb565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061009c57805160ff19168380011785556100c9565b828001600101855582156100c9579182015b828111156100c95782518255916020019190600101906100ae565b5b506100d69291506100da565b5090565b6100f891905b808211156100d657600081556001016100e0565b5090565b90565b6101e68061010a6000396000f300606060405263ffffffff60e060020a60003504166341c0e1b5811461002c578063cfae32171461003e575bfe5b341561003457fe5b61003c6100ce565b005b341561004657fe5b61004e610110565b604080516020808252835181830152835191928392908301918501908083838215610094575b80518252602083111561009457601f199092019160209182019101610074565b505050905090810190601f1680156100c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000543373ffffffffffffffffffffffffffffffffffffffff9081169116141561010d5760005473ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b6101186101a8565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561019d5780601f106101725761010080835404028352916020019161019d565b820191906000526020600020905b81548152906001019060200180831161018057829003601f168201915b505050505090505b90565b604080516020810190915260008152905600a165627a7a72305820da570cb755561def0ccbb0f3c265ec5dd9dd5aeaca595bf15ff4a3673d9d2e8d0029", info: { abiDefinition: [{...}, {...}, {...}], compilerOptions: "--combined-json bin,abi,userdoc,devdoc --add-std --optimize", compilerVersion: "0.4.9", developerDoc: { methods: {...}, title: "Greeter." }, language: "Solidity", languageVersion: "0.4.9", source: "pragma solidity ^0.4.9; /** @title Mortal.*/ contract mortal { /* Define variable owner of the type address*/ address owner; /**@dev this function is executed at initialization and sets the owner of the contract. */ function mortal() { owner = msg.sender; } /**@dev Function to recover the funds on the contract. */ function kill() { if (msg.sender == owner) { selfdestruct(owner); } } } /** @title Greeter.*/ contract greeter is mortal { /* define variable greeting of the type string */ string greeting; /**@dev This function runs when the contract is executed. * @param _greeting Greeting message. */ function greeter(string _greeting) public { greeting = _greeting; } /* main function */ /**@dev This function returns the greeting message. * @return greeting The greeting message. */ function greet() constant returns (string) { return greeting; } }", userDoc: { methods: {} } } }, <stdin>:mortal: { code: "0x6060604052341561000c57fe5b5b60008054600160a060020a03191633600160a060020a03161790555b5b609c806100386000396000f300606060405263ffffffff60e060020a60003504166341c0e1b581146020575bfe5b3415602757fe5b602d602f565b005b6000543373ffffffffffffffffffffffffffffffffffffffff90811691161415606d5760005473ffffffffffffffffffffffffffffffffffffffff16ff5b5b5600a165627a7a723058200a9fb13e0c7088d8b8834e9dacd090047f7173bbd4b22b8a2c06a00681b5631d0029", info: { abiDefinition: [{...}, {...}], compilerOptions: "--combined-json bin,abi,userdoc,devdoc --add-std --optimize", compilerVersion: "0.4.9", developerDoc: { methods: {...}, title: "Mortal." }, language: "Solidity", languageVersion: "0.4.9", source: "pragma solidity ^0.4.9; /** @title Mortal.*/ contract mortal { /* Define variable owner of the type address*/ address owner; /**@dev this function is executed at initialization and sets the owner of the contract. */ function mortal() { owner = msg.sender; } /**@dev Function to recover the funds on the contract. */ function kill() { if (msg.sender == owner) { selfdestruct(owner); } } } /** @title Greeter.*/ contract greeter is mortal { /* define variable greeting of the type string */ string greeting; /**@dev This function runs when the contract is executed. * @param _greeting Greeting message. */ function greeter(string _greeting) public { greeting = _greeting; } /* main function */ /**@dev This function returns the greeting message. * @return greeting The greeting message. */ function greet() constant returns (string) { return greeting; } }", userDoc: { methods: {} } } } }
然後我定義輸入變數:
var _greeting = "Hello World!";
然後我創建契約:
var greeterContract = web3.eth.contract(greeterCompiled["<stdin>:greeter"].info.abiDefinition);
結果是:
{ <stdin>:greeter: { code: "0x6060604052341561000c57fe5b6040516102f03803806102f0833981016040528051015b5b60008054600160a060020a03191633600160a060020a03161790555b805161005390600190602084019061005b565b505b506100fb565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061009c57805160ff19168380011785556100c9565b828001600101855582156100c9579182015b828111156100c95782518255916020019190600101906100ae565b5b506100d69291506100da565b5090565b6100f891905b808211156100d657600081556001016100e0565b5090565b90565b6101e68061010a6000396000f300606060405263ffffffff60e060020a60003504166341c0e1b5811461002c578063cfae32171461003e575bfe5b341561003457fe5b61003c6100ce565b005b341561004657fe5b61004e610110565b604080516020808252835181830152835191928392908301918501908083838215610094575b80518252602083111561009457601f199092019160209182019101610074565b505050905090810190601f1680156100c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000543373ffffffffffffffffffffffffffffffffffffffff9081169116141561010d5760005473ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b6101186101a8565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561019d5780601f106101725761010080835404028352916020019161019d565b820191906000526020600020905b81548152906001019060200180831161018057829003601f168201915b505050505090505b90565b604080516020810190915260008152905600a165627a7a72305820da570cb755561def0ccbb0f3c265ec5dd9dd5aeaca595bf15ff4a3673d9d2e8d0029", info: { abiDefinition: [{...}, {...}, {...}], compilerOptions: "--combined-json bin,abi,userdoc,devdoc --add-std --optimize", compilerVersion: "0.4.9", developerDoc: { methods: {...}, title: "Greeter." }, language: "Solidity", languageVersion: "0.4.9", source: "pragma solidity ^0.4.9; /** @title Mortal.*/ contract mortal { /* Define variable owner of the type address*/ address owner; /**@dev this function is executed at initialization and sets the owner of the contract. */ function mortal() { owner = msg.sender; } /**@dev Function to recover the funds on the contract. */ function kill() { if (msg.sender == owner) { selfdestruct(owner); } } } /** @title Greeter.*/ contract greeter is mortal { /* define variable greeting of the type string */ string greeting; /**@dev This function runs when the contract is executed. * @param _greeting Greeting message. */ function greeter(string _greeting) public { greeting = _greeting; } /* main function */ /**@dev This function returns the greeting message. * @return greeting The greeting message. */ function greet() constant returns (string) { return greeting; } }", userDoc: { methods: {} } } }, <stdin>:mortal: { code: "0x6060604052341561000c57fe5b5b60008054600160a060020a03191633600160a060020a03161790555b5b609c806100386000396000f300606060405263ffffffff60e060020a60003504166341c0e1b581146020575bfe5b3415602757fe5b602d602f565b005b6000543373ffffffffffffffffffffffffffffffffffffffff90811691161415606d5760005473ffffffffffffffffffffffffffffffffffffffff16ff5b5b5600a165627a7a723058200a9fb13e0c7088d8b8834e9dacd090047f7173bbd4b22b8a2c06a00681b5631d0029", info: { abiDefinition: [{...}, {...}], compilerOptions: "--combined-json bin,abi,userdoc,devdoc --add-std --optimize", compilerVersion: "0.4.9", developerDoc: { methods: {...}, title: "Mortal." }, language: "Solidity", languageVersion: "0.4.9", source: "pragma solidity ^0.4.9; /** @title Mortal.*/ contract mortal { /* Define variable owner of the type address*/ address owner; /**@dev this function is executed at initialization and sets the owner of the contract. */ function mortal() { owner = msg.sender; } /**@dev Function to recover the funds on the contract. */ function kill() { if (msg.sender == owner) { selfdestruct(owner); } } } /** @title Greeter.*/ contract greeter is mortal { /* define variable greeting of the type string */ string greeting; /**@dev This function runs when the contract is executed. * @param _greeting Greeting message. */ function greeter(string _greeting) public { greeting = _greeting; } /* main function */ /**@dev This function returns the greeting message. * @return greeting The greeting message. */ function greet() constant returns (string) { return greeting; } }", userDoc: { methods: {} } } } } > ^C > var _greeting = "Hello World!"; undefined > var greeterContract = web3.eth.contract(greeterCompiled["<stdin>:greeter"].info.abiDefinition); undefined > greeterContract { abi: [{ constant: false, inputs: [], name: "kill", outputs: [], payable: false, type: "function" }, { constant: true, inputs: [], name: "greet", outputs: [{...}], payable: false, type: "function" }, { inputs: [{...}], payable: false, type: "constructor" }], eth: { accounts: ["0xd44470753171e1b22dc9e5ffd9ac50e0427f49ca", "0x7dc65a6db5de74ace26ab27dd822dab0fcb36851"], blockNumber: 15544, coinbase: "0xd44470753171e1b22dc9e5ffd9ac50e0427f49ca", compile: { lll: function(), serpent: function(), solidity: function() }, defaultAccount: undefined, defaultBlock: "latest", gasPrice: 20000000000, hashrate: 0, mining: false, pendingTransactions: [], protocolVersion: "0x3f", syncing: false, call: function(), contract: function(abi), estimateGas: function(), filter: function(fil, callback), getAccounts: function(callback), getBalance: function(), getBlock: function(), getBlockNumber: function(callback), getBlockTransactionCount: function(), getBlockUncleCount: function(), getCode: function(), getCoinbase: function(callback), getCompilers: function(), getGasPrice: function(callback), getHashrate: function(callback), getMining: function(callback), getPendingTransactions: function(callback), getProtocolVersion: function(callback), getRawTransaction: function(), getRawTransactionFromBlock: function(), getStorageAt: function(), getSyncing: function(callback), getTransaction: function(), getTransactionCount: function(), getTransactionFromBlock: function(), getTransactionReceipt: function(), getUncle: function(), getWork: function(), iban: function(iban), icapNamereg: function(), isSyncing: function(callback), namereg: function(), resend: function(), sendIBANTransaction: function(), sendRawTransaction: function(), sendTransaction: function(), sign: function(), signTransaction: function(), submitTransaction: function(), submitWork: function() }, at: function(address, callback), getData: function(), new: function() }
現在我要部署合約:
var greeter = greeterContract.new(_greeting,{from:web3.eth.accounts[1], data: greeterCompiled["<stdin>:greeter"].code, gas: 45000000000}, function(e, contract){ if(!e) { if(!contract.address) { console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); } else { console.log("Contract mined! Address: " + contract.address); console.log(contract); } } })
結果是:
{ abi: [{ constant: false, inputs: [], name: "kill", outputs: [], payable: false, type: "function" }, { constant: true, inputs: [], name: "greet", outputs: [{...}], payable: false, type: "function" }, { inputs: [{...}], payable: false, type: "constructor" }], address: undefined, transactionHash: null }
如您所見,應該包含足夠的氣體。但隨後什麼也沒有發生,也不會分配任何地址。賬戶餘額也保持不變。我沒有正確連接(當我執行 admin.peers 時,我看到所有其他連接的節點)或者可能是什麼問題?
現在有一個解決方案(感謝幫助我解決這個問題的同事 :) 但這有點令人不滿意,因為我不知道為什麼它現在有效而不是以前有效。
我的同事使用了不同的氣體值(1000000 而不是 45000000000)並且不得不
web3
從var greeter = greeterContract.new(_greeting,{from:web3.eth.accounts[1], ...
我只需要更改氣體值,但可以使用
web3
…所以現在對我有用的程式碼如下所示:
var greeter = greeterContract.new(_greeting,{from:web3.eth.accounts[1], data: greeterCompiled["<stdin>:greeter"].code, gas: 1000000}, function(e, contract){ if(!e) { if(!contract.address) { console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); } else { console.log("Contract mined! Address: " + contract.address); console.log(contract); } } })
和我的同事
var greeter = greeterContract.new(_greeting,{from:eth.accounts[1], data: greeterCompiled["<stdin>:greeter"].code, gas: 1000000}, function(e, contract){ if(!e) { if(!contract.address) { console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); } else { console.log("Contract mined! Address: " + contract.address); console.log(contract); } } })