Solidity

從 javascript 訪問另一個智能合約中包含的一個智能合約

  • April 19, 2019

我從 Stack Overflow 交叉發布這個,因為這裡似乎有更多的活動。

我正在嘗試使用 Truffle 開發 dApp,並想測試我的智能合約。契約中包含第二個契約,如下所示:

pragma solidity >=0.4.21 <0.6.0;

contract SubContract {
   uint public foo;

   constructor() public {
       foo = 0;
   }
}

contract MainContract {
   SubContract public my_contract;

   constructor() public {
       my_contract = new SubContract();
   }
}

然後我想用 Javascript 測試這個契約,如下所示:

var MainContract = artifacts.require("./MainContract.sol");

contract("MainContract", function(accounts) {

 it("initializes SubContract contract", function() {
   return MainContract.deployed().then(function(instance) {
     return instance.my_contract;
   }).then(function(subContractInstance) {
      return subContractInstance.foo();
   }).then(function(foo) {
     assert.equal(foo.toNumber(), 0);
   });
 });
});

如果我然後嘗試按原樣執行此測試,它會告訴我它無法訪問foo(). undefined如果我在測試中將其從 更改為instance.my_contractinstance.my_contract()它告訴我沒有 function contract(),即使其他欄位是通過 getter 方法訪問的。為了能夠訪問 SubContract 實例,我在這裡缺少什麼?

  • -編輯 - -

根據建議,這是一個工作測試的樣子:

var MainContract = artifacts.require("MainContract");
var SubContract  = artifacts.require("SubContract");

contract("MainContract", async accounts => {
 it("initializes SubContract contract", async() => {
   let instance = await MainContract.deployed();
   let subContractAddress = await instance.my_contract();
   let subContractInstance = await SubContract.at(subContractAddress);
   let foo = await subContractInstance.foo();
   assert.equal(foo.toNumber(), 0);
 });
});

首先,您對contract變數的聲明是錯誤的,contract是 Solidity 中的保留關鍵字。假設您將其重命名為SubContract public my_contract.

其次,my_contract通過自動為其創建的 getter 訪問變數不會返回SubContract實例,而是返回合約的地址。因此,您需要在腳本中進行必要的操作,以便SubContract通過從 獲取其地址MainContract並創建正確的實例來與 互動。

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