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

How to deploy factory contract with solidity @0.5.0 on Node.js

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

我有一个 solidity 文件 @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

回购: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.

发现问题出在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 {
...

您可以使用克隆工厂合约而不是新关键字,因为它在 gas 方面非常便宜,这里是 link 供参考:clone-factory and why it is better "Attack Of The Clones — How DDA Contracts Are So Cheap To Deploy"