Truffle

幫助繼承和松露測試

  • May 16, 2018

我有兩個都繼承自OpenZeppelin 的 Whitelist 的合約。部署兩個合約後,我使用第一個合約的實例將“受信任”地址添加到白名單。由於兩個合約都繼承自同一個白名單,我假設第二個合約也看到“受信任”被列入白名單。但是,我在執行測試時看不到這一點。我的問題在程式碼下方。

契約AB

pragma solidity ^0.4.23;
import "openzeppelin-solidity/contracts/ownership/Whitelist.sol";

contract A is Whitelist {   
}

contract B is Whitelist {   
}

遷移2_deploy.js

var A = artifacts.require("./A.sol");
var B = artifacts.require("./B.sol");

module.exports = function(deployer, network, accounts) {
   var owner = accounts[0];
   var trusted = accounts[1];

   deployer.deploy(A, {from: owner})
   .then(function(){
       console.log("A deployed");  
       return; 
   });

   deployer.deploy(B, {from: owner})
   .then(function(){
       console.log("B deployed");      
       return;
   });

   A.deployed()
   .then(function(instance) {
       instance.addAddressToWhitelist(trusted, {from: owner})
       .then(function() {
           return;
       });
   });
};

測試.js

const A = artifacts.require("A");
const B = artifacts.require("B");

contract('A', async (accounts) => {
   let owner = accounts[0];
   let trusted = accounts[1];

   a = await A.deployed();
   b = await B.deployed();

   let isWhitelistedA = await a.whitelist(trusted); 
   let isWhitelistedB = await b.whitelist(trusted); 
   console.log("before adding trusted, contract A: "+isWhitelistedA); 
   console.log("before adding trusted, contract B: "+isWhitelistedB); 

   await a.addAddressToWhitelist(trusted, {from: owner});
   isWhitelistedA = await a.whitelist(trusted); 
   isWhitelistedB = await b.whitelist(trusted); 
   console.log("after adding trusted to A, contract A: "+isWhitelistedA);
   console.log("after adding trusted to A, contract B: "+isWhitelistedB);

   await b.addAddressToWhitelist(trusted, {from: owner});
   isWhitelistedA = await a.whitelist(trusted); 
   isWhitelistedB = await b.whitelist(trusted); 
   console.log("after adding trusted to B, contract A: "+isWhitelistedA);
   console.log("after adding trusted to B, contract B: "+isWhitelistedB);  
})

松露測試輸出:

before adding trusted, contract A: false
before adding trusted, contract B: false
after adding trusted to A, contract A: true
after adding trusted to A, contract B: false
after adding trusted to B, contract A: true
after adding trusted to B, contract B: true

問題:

  1. 為什麼 trust 在被添加到 Test 之前沒有被列入白名單?遷移應該添加它。
  2. 當trusted通過A的實例被列入白名單時,為什麼它沒有根據B被列入白名單?繼承應該解決這個問題。

筆記:

  • 這可能是我不理解“部署”和實例是如何工作的,所以請告訴我發生了什麼:)。
  • test.js 顯然不是一個適當的松露測試(因為沒有真正測試過),但它是我面臨的問題的簡化範例。

其他資訊:

  • 松露 v4.1.8(核心:4.1.8)
  • Solidity v0.4.23 (solc-js)
  • 在 localhost 中使用 Ganache

簡短回答:兩個合約都在創建Whitelist. 他們不共享同一個實例。

要共享同一個實例——它們都需要引用單個部署的相同地址Whitelist

事實上,通過部署這兩個合約,你會浪費(無論大小)gas,因為這兩個合約都有冗餘程式碼。

我的建議(可能適合也可能不適合您的案例)是:

  • 只有合約A繼承Whitelist
  • 創建一個新interface合約,列出該Whitelist合約B需要使用的功能。契約B將具有此interface契約的可變類型。
  • 將合約的地址設置為合約A的變數,B因此B現在可以引用Whitelist

對於您的問題,它們可能是更好的架構設計 - 但這將使您的沙箱範例正常工作。

Code snippets:

WhitelistInterface.sol

契約B

import "./WhitelistInterface.sol";

WhitelistInterface whitelistInstance;

B的建構子:

require(_whitelistAddress != address(0));
whitelistInstance = WhitelistInterface(_whitelistAddress);

B的白名單函式呼叫

bool isWhitelisted = whitelistInstance.whitelist(addressToTest);

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