Go-Ethereum

使用 Azure 乙太坊聯盟部署智能合約不起作用

  • March 9, 2017

我創建了一個 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)並且不得不web3var 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);
       }
   }
})

引用自:https://ethereum.stackexchange.com/questions/12858