Solidity

truffle migrate:如何部署建構子帶參數的合約

  • November 3, 2017

我正在使用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(暫時忽略這個邏輯,我只是在這裡使用豬和培根製造商來代替實際的合約正在開發中。)

所以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。

沒有適合所有情況的通用解決方案。有時您會創建一個單獨的合約來部署子合約。您還可以部署多個合約並在部署後將它們添加到寄存器中,以便它們可以相互通信。

單一合約是最簡單的,但你會受到區塊氣體限制的約束。擁有多個契約更加複雜,因為它們之間的溝通並不容易,而且您必須對組織更加小心。

引用自:https://ethereum.stackexchange.com/questions/29812