Solidity
如何在 web3js 中部署合約?
我在 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
您可以閱讀整個文件以獲得更好的理解。
謝謝