Solidity

如何在 web3js 中部署合約?

  • August 3, 2018

我在 testrpc 中進行了測試,並且已經學會瞭如何通過 geth 命令創建和部署合約,但在 web3js 腳本中總是失敗。我非常簡單的契約:

pragma solidity ^0.4.18;

contract Test {
 string public projName;

 function Test()
 {
   projName = 'Test Proj';
 }

 function getProjName() view public returns(string)
 {
   return projName;
 }
}

我在remix 線上編譯器中遵守了這份契約 這是我下面的 webjs 腳本:

'use strict';
const Web3 = require("web3");
var IcoContractABI = {
 abi :[{"constant":true,"inputs":[],"name":"getProjName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"projName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}],
 contractData : '0x6060604052341561000f57600080fd5b6040805190810160405280600981526020017f546573742050726f6a00000000000000000000000000000000000000000000008152506000908051906020019061005a929190610060565b50610105565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a157805160ff19168380011785556100cf565b828001600101855582156100cf579182015b828111156100ce5782518255916020019190600101906100b3565b5b5090506100dc91906100e0565b5090565b61010291905b808211156100fe5760008160009055506001016100e6565b5090565b90565b6102f3806101146000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635cfa5dee14610051578063e03c69e8146100df575b600080fd5b341561005c57600080fd5b61006461016d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100a4578082015181840152602081019050610089565b50505050905090810190601f1680156100d15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156100ea57600080fd5b6100f2610215565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610132578082015181840152602081019050610117565b50505050905090810190601f16801561015f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101756102b3565b60008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561020b5780601f106101e05761010080835404028352916020019161020b565b820191906000526020600020905b8154815290600101906020018083116101ee57829003601f168201915b5050505050905090565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102ab5780601f10610280576101008083540402835291602001916102ab565b820191906000526020600020905b81548152906001019060200180831161028e57829003601f168201915b505050505081565b6020604051908101604052806000815250905600a165627a7a72305820785c35d48d88e889f29b1689b26e5f5c1385d37bca4dbb2b28242768aae121210029'
}

try {
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log("web3 version: " + web3.version);

var ac = web3.eth.accounts.wallet.add('0x2722c1af21d9129f8c028b64d2a6f76b52e1ca7e4fa2beb293323f94c2b2601b');
console.log("address: " + ac.address);

var mycontract = new web3.eth.Contract(IcoContractABI.abi);

mycontract.deploy({
   data: IcoContractABI.contractData,
}).send({
   from: ac.address,
   gas: '47000000',
   gasPrice: '30000000000000'
}, function (error, transactionHash) {
   console.log("error= " + error.toString() + "; transactionHash=" + transactionHash);
})
   .on('error', function(error){
       console.log("error= " + error.toString());
   })
   .on('transactionHash', function(transactionHash){
       console.log("transactionHash= " + transactionHash.toString());
   })
   .on('receipt', function(receipt){
       console.log(receipt.contractAddress) // contains the new contract address
   })
   .on('confirmation', function(confirmationNumber, receipt){

   })
   .then(function(newContractInstance){
       console.log(newContractInstance.options.address); // instance with the new contract address
   });

} catch (err) {
 console.log("error: " + err.toString());
 console.log(err.stack);
}

然後我執行“node test.js”,總是得到異常:

$ node test_deploy.js 
web3 version: 1.0.0-beta.24
address: 0x440a09de60d308109896179009E0270f1F65b38e
error= Error: Returned error: Error: invalid rlp: total length is larger than the data
at _decode (/usr/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:15040:13)
at Object.exports.decode (/usr/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:14943:17)
at Object.exports.defineProperties (/usr/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:3138:18)
at new Transaction (/usr/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:69871:13)
at new FakeTransaction (/usr/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:16658:5)
at StateManager.queueRawTransaction (/usr/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:83036:12)
at GethApiDouble.eth_sendRawTransaction (/usr/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:82635:14)
at GethApiDouble.handleRequest (/usr/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:82434:10)
at next (/usr/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:52153:18)
at VmSubprovider.handleRequest (/usr/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:59291:12); transactionHash=undefined

我不知道這些異常消息是什麼意思,也不知道如何解決。

任何幫助將不勝感激。

===================================

上面的問題只存在於testrpc。我可以在私有鏈中部署而不會出錯,因此 testrpc 似乎對測試合約並不是那麼完美。如果你想在 web3js 程式碼中測試部署合約,我會建議在私有鏈中測試。

也許您應該嘗試使用 Infura 和 Web3js 對我有用的以下解決方案。

let byteCode = {<YOUR CONTRACT'S BYTE-CODE GOES HERE>};
let contractInstance = new web3.eth.Contract(abiChildContract);
let deploy = contractInstance.deploy({ data: '0x' + byteCode.object,
arguments: [tokenContractAddress, masterAdmin, masterAdmin]
}).encodeABI();

web3.eth.getTransactionCount(masterAdmin, 'pending').then((count) => {
let transactionObject = {
 data: deploy,
 from: senderAddress,
 nonce: count
};
web3.eth.estimateGas(transactionObject, function (err, estimate) {

 transactionObject.gas = estimate;
 web3.eth.accounts.signTransaction(transactionObject, privateKey, 
 function (error, signedTx) {
   if (error) {
     console.log(error);
   } else {
     let tx = web3.eth.sendSignedTransaction(signedTx.rawTransaction)
     tx.on('transactionHash', function (transactionHash) {
 console.log(transactionHash); });

在上面的程式碼中let byteCode儲存了你的合約的字節碼(確保你正確地複制它!)。senderAddress中的是let transactionObject與它簽署合約部署交易的地址(即公共地址)privateKey。最後,如果一切順利,您將獲得transactionHash合約部署交易。有關更多特性/功能,contract.deploy請查看此連結。此外,我強烈建議使用Infura,因為它為與乙太坊網路(即 Mainnet、Ropsten、Rinkeby ……)互動提供了一個可靠的端點。此解決方案與 Infura 完美配合,嘗試一下,如果有幫助,請告訴我。乾杯!

希望下面的連結對您有所幫助: https ://web3js.readthedocs.io/en/1.0/web3-eth-contract.html

您可以閱讀整個文件以獲得更好的理解。

謝謝

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