migración de trufas: cómo implementar un contrato cuyo constructor toma un parámetro

Estoy usando Truffle Versión 4 para desarrollar un contrato inteligente simple y estoy atascado en algo que creo que refleja un malentendido muy básico que simplemente no puedo entender.

Aquí está mi contrato simple, encontracts/BaconSupplier.sol

contract BaconMaker {
    address public pig;
    address public owner;

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

Y mi migración de implementación, enmigrations/2_deploy_contracts.js

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

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

Corro truffle developpara ingresar al entorno de desarrollo estándar de Truffle, luego

compile

=> compila muy bien

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

después

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

Sin embargo , si elimino la línea require(_pig != 0x0);, la migración funciona bien, lo que implica que el proceso de migración en realidad está intentando crear una instancia del BaconMakercontrato.

Supongo que realmente no entiendo qué están haciendo las migraciones aquí o qué está sucediendo realmente con la implementación.

El objetivo a más largo plazo es que haya un Farmcontrato que mantenga un registro propio pigsy para cada cerdo haya un asociado BaconMaker(ignore la lógica de esto por ahora, solo estoy usando cerdos y BaconMakers aquí en lugar de los contratos reales siendo desarrollado.)

Entonces el Farmcontrato se vería como

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);
    }

}

En este caso, ¿realmente necesito deployel BaconMakercontrato durante la migración, o se implementará para mí cuando addPigse llame?

Si no es así, ¿cómo implemento el BaconMakercontrato en la etapa de migración?

Respuestas (1)

Puede agregar los parámetros del constructor como argumentos adicionales a la deploy()llamada

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

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

En su caso, dado que Farm creará BaconMaker a pedido, no tiene que implementar BaconMaker desde los scripts de implementación.

No hay una solución general que se ajuste a todas las situaciones. A veces, crea un contrato único que implementará contratos secundarios. También puede implementar varios contratos y agregarlos a un registro después de la implementación, para que puedan comunicarse entre sí.

Un solo contrato es más fácil, pero está sujeto al límite de gas del bloque. Tener varios contratos es más complejo porque no es fácil comunicarse entre ellos y hay que tener más cuidado con la organización.