truffle migrate: как развернуть контракт, конструктор которого принимает параметр

Я использую Truffle версии 4 для разработки простого смарт-контракта и застрял на чем-то, что, как мне кажется, отражает очень простое недоразумение, которое я просто не могу понять.

Вот мой простой контракт, вcontracts/BaconSupplier.sol

contract BaconMaker {
    address public pig;
    address public owner;

    function BaconMaker(address _pig) public {
        require(_pig != 0x0);
        owner = msg.sender;
        pig = _pig;
    }
}

И моя миграция развертывания вmigrations/2_deploy_contracts.js

const BaconMaker = artifacts.require('./BaconMaker.sol')

module.exports = (deployer) => {
  deployer.deploy(BaconMaker)
}

Я бегу truffle develop, чтобы войти в стандартную среду разработки Truffle, затем

compile

=> компилируется просто отлично

Compiling ./contracts/BaconMaker.sol...
Compiling ./contracts/Migrations.sol...
Writing artifacts to ./build/contracts

затем

migrate

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x9e8257089a048815b4593a87ae5ae22af7dab80f74c07a98a0cf0a2ba08234a1
  Migrations: 0xee08e5e6643952b3cb22642d2a04a2992141eddd
Saving successful migration to network...
  ... 0x9845c22c3db695912cb4958c9f8071b9a2ac8853b226367c3f969a0f54510fe9
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying BaconMaker...
  ... 0xdcb442cda2621bbcd648813a567f70761746fb583a502746670f63a558a9a5e8
Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: VM Exception while processing transaction: invalid opcode

Однако, если я удалю эту строку require(_pig != 0x0);, миграция пройдет нормально, что означает, что процесс миграции фактически пытается создать экземпляр BaconMakerконтракта.

Думаю, я не очень понимаю, что здесь делают миграции или что на самом деле происходит с развертыванием.

Долгосрочная цель состоит в том, чтобы был Farmконтракт, который ведет свою собственную запись, pigsи для каждой свиньи есть связанный BaconMaker(пока не обращайте внимания на логику этого, я просто использую свиньи и BaconMakers вместо фактических контрактов). разрабатывается.)

Так Farmдоговор будет выглядеть

import './BaconMaker.sol';

contract Farm {
    address public owner;
    mapping(address => bool) public pigs;
    BaconMaker[] public baconMakers;

    function Farm() {
        owner = msg.sender;
    }

    function addPig(address pig) external {
        require(pig != 0x0);
        require(msg.sender == owner);
        pigs[pig] = true;
        BaconMaker baconMaker = new BaconMaker(pig);
        baconMakers.push(baconMaker);
    }

}

В этом случае мне действительно нужен контракт во deployвремя BaconMakerмиграции, или он будет развернут для меня при addPigвызове?

Если нет, то как мне развернуть BaconMakerконтракт на этапе миграции?

Ответы (1)

Вы можете добавить параметры конструктора в качестве дополнительных аргументов deploy()вызова

const BaconMaker = artifacts.require('./BaconMaker.sol')

module.exports = (deployer, network, accounts) => {
  const userAddress = accounts[3];
  deployer.deploy(BaconMaker, userAddress)
}

В вашем случае, поскольку Farm создаст BaconMaker по запросу, вам не нужно развертывать BaconMaker из сценариев развертывания.

Не существует общего решения, подходящего для всех ситуаций. Иногда вы создаете один контракт, который будет развертывать дочерние контракты. Также вы можете развернуть несколько контрактов и добавить их в реестр после развертывания, чтобы они могли взаимодействовать друг с другом.

Проще всего заключить один контракт, но вы ограничены лимитом блочного газа. Иметь несколько контрактов сложнее, потому что между ними нелегко общаться, и вы должны быть более осторожны с организацией.