如何在 Node.js 上使用solidity @0.5.0 部署工厂合约

Posted

技术标签:

【中文标题】如何在 Node.js 上使用solidity @0.5.0 部署工厂合约【英文标题】:How to deploy factory contract with solidity @0.5.0 on Node.js 【发布时间】:2019-12-10 23:44:19 【问题描述】:

回购:https://github.com/aljmiller87/ethereum-dispute-resolution

我有一个带有工厂合同和子合同的可靠文件@0.5.0。我能够正常编译(尽管您会注意到 ethereum/compile.js 中所有注释掉的行中的试验和错误)。

运行node ethereum/deploy.js 会导致错误。:

Attempting to deploy from account 0xff831110eeA8322639bee543AD1477AD9f472E22 
UnhandledPromiseRejectionWarning: Error: The contract code couldn't be stored, please check your gas limit.
...
...
...
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:24059) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我已确认此合同代码可在混音中使用。 我尝试在 0.0.30.0.5 上使用 truffle-hdwallet-provider(并相应地更新 .deploy() 和 .send() 参数。

我已经在另一个项目@solidity 0.4.17 上使用了这个精确的设置,并且部署工作正常(尽管编译不同)。这是以前项目的回购:https://github.com/aljmiller87/ethereum-kickstart

repo:https://github.com/aljmiller87/ethereum-dispute-resolution

ethereum/deploy.js

const HDWalletProvider = require('truffle-hdwallet-provider');
const Web3 = require('web3');
const compiledContract = require('./build/ThreeJudge.json');

const compiledFactory = compiledContract.ContractFactory
const compiledFactoryABI = compiledFactory.abi;
const compiledFactoryBytecode = compiledFactory.evm.bytecode.object;


const provider = new HDWalletProvider(
    `$process.env.SEED_KEY`,
    'https://rinkeby.infura.io/v3/ad66eb1337e043b2b50abe1323fff5f0'
);

const web3 = new Web3(provider);

const deploy = async () => 
    // Get account to deploy from
    const accounts = await web3.eth.getAccounts();
    console.log('Attempting to deploy from account', accounts[0]);

    // deploy code
    const result = await new web3.eth.Contract(compiledFactoryABI)
    .deploy( data: '0x' + compiledFactoryBytecode )
    .send( gas: '1000000', from: accounts[0] );


    console.log('result address', result.options.address)
;

deploy();


package.json:


  "name": "kickstart",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": 
    "test": "mocha test/ThreeJudge.test.js --timeout 10000",
    "test-local": "mocha test/ThreeJudge-local.test.js --timeout 10000",
    "dev": "node server.js"
  ,
  "author": "",
  "license": "ISC",
  "dependencies": 
    "dotenv": "^8.0.0",
    "fs-extra": "^8.1.0",
    "ganache-cli": "^6.5.0",
    "mocha": "^6.1.4",
    "next": "^4.1.4",
    "next-routes": "^1.4.2",
    "path": "^0.12.7",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "semantic-ui-css": "^2.4.1",
    "semantic-ui-react": "^0.87.3",
    "solc": "0.5.2",
    "truffle-hdwallet-provider": "0.0.5",
    "web3": "^1.0.0-beta.37"
  


运行node ethereum/deploy.js 导致错误。:

Attempting to deploy from account 0xff831110eeA8322639bee543AD1477AD9f472E22
(node:24059) UnhandledPromiseRejectionWarning: Error: The contract code couldn't be stored, please check your gas limit.
    at Object.callback (/Users/alexmiller/Projects/solidity/threejudges/node_modules/web3-core-method/src/index.js:333:46)
    at sendTxCallback (/Users/alexmiller/Projects/solidity/threejudges/node_modules/web3-core-method/src/index.js:484:29)
    at /Users/alexmiller/Projects/solidity/threejudges/node_modules/web3-core-requestmanager/src/index.js:147:9
    at /Users/alexmiller/Projects/solidity/threejudges/node_modules/web3-provider-engine/index.js:172:9
    at /Users/alexmiller/Projects/solidity/threejudges/node_modules/async/internal/once.js:12:16
    at replenish (/Users/alexmiller/Projects/solidity/threejudges/node_modules/async/internal/eachOfLimit.js:61:25)
    at /Users/alexmiller/Projects/solidity/threejudges/node_modules/async/internal/eachOfLimit.js:71:9
    at eachLimit (/Users/alexmiller/Projects/solidity/threejudges/node_modules/async/eachLimit.js:43:36)
    at /Users/alexmiller/Projects/solidity/threejudges/node_modules/async/internal/doLimit.js:9:16
    at end (/Users/alexmiller/Projects/solidity/threejudges/node_modules/web3-provider-engine/index.js:147:5)
    at /Users/alexmiller/Projects/solidity/threejudges/node_modules/web3-provider-engine/subproviders/provider.js:20:5
    at XMLHttpRequest.request.onreadystatechange (/Users/alexmiller/Projects/solidity/threejudges/node_modules/truffle-hdwallet-provider/node_modules/web3/lib/web3/httpprovider.js:118:13)
    at XMLHttpRequest.dispatchEvent (/Users/alexmiller/Projects/solidity/threejudges/node_modules/xhr2/lib/xhr2.js:76:20)
    at XMLHttpRequest._setReadyState (/Users/alexmiller/Projects/solidity/threejudges/node_modules/xhr2/lib/xhr2.js:422:14)
    at XMLHttpRequest._onHttpResponseEnd (/Users/alexmiller/Projects/solidity/threejudges/node_modules/xhr2/lib/xhr2.js:615:14)
    at IncomingMessage._response.on (/Users/alexmiller/Projects/solidity/threejudges/node_modules/xhr2/lib/xhr2.js:567:23)
(node:24059) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:24059) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

【问题讨论】:

也尝试将gas设置为7000000。等待5分钟后,初始console.log Attempting to deploy from account 0x...后没有任何反应 【参考方案1】:

您可以使用克隆工厂合约而不是新关键字,因为它在 gas 方面非常便宜,这是参考链接:clone-factory 以及为什么它更好"Attack Of The Clones — How DDA Contracts Are So Cheap To Deploy"

【讨论】:

【参考方案2】:

发现问题出在solidity代码中。我试图保留合同类型的数组,而不是创建的合同的地址。

原文:

contract ContractFactory 
    ThreeJudge[] public deployedContracts;

    function createContract(address payable _buyer, address payable _seller) public 
        ThreeJudge newContract = new ThreeJudge(_buyer, _seller);
        deployedContracts.push(newContract);
    

    function getDeployedContracts() public view returns (ThreeJudge[] memory) 
        return deployedContracts;
    


contract ThreeJudge 
...

修复:

contract ContractFactory 
    address[] public deployedContracts;

    function createContract(address payable _buyer, address payable _seller) public 
        ThreeJudge newContract = new ThreeJudge(_buyer, _seller);
        deployedContracts.push(address(newContract));
    

    function getCampaignsByAddress() public view returns (address[] memory) 
        return deployedContracts;
    


contract ThreeJudge 
...

【讨论】:

以上是关于如何在 Node.js 上使用solidity @0.5.0 部署工厂合约的主要内容,如果未能解决你的问题,请参考以下文章

Solidity 中的事件触发

如何在不使用 node.js 的情况下添加标准反应应用程序 [关闭]

Solidity编程 二 之Solidity安装

如何在 node.js 上使用邮戳电子邮件?

如何在端口 80 上运行 Node.js?

如何在 Node.js 上建立网站?