Я использую 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
контракт на этапе миграции?
Вы можете добавить параметры конструктора в качестве дополнительных аргументов deploy()
вызова
const BaconMaker = artifacts.require('./BaconMaker.sol')
module.exports = (deployer, network, accounts) => {
const userAddress = accounts[3];
deployer.deploy(BaconMaker, userAddress)
}
В вашем случае, поскольку Farm создаст BaconMaker по запросу, вам не нужно развертывать BaconMaker из сценариев развертывания.
Не существует общего решения, подходящего для всех ситуаций. Иногда вы создаете один контракт, который будет развертывать дочерние контракты. Также вы можете развернуть несколько контрактов и добавить их в реестр после развертывания, чтобы они могли взаимодействовать друг с другом.
Проще всего заключить один контракт, но вы ограничены лимитом блочного газа. Иметь несколько контрактов сложнее, потому что между ними нелегко общаться, и вы должны быть более осторожны с организацией.