Solidity

可靠性測試:合約呼叫另一個合約和地址不同

  • August 26, 2017

我有一個包裝契約,它實例化並呼叫另一個契約,我的測試案例說所有者(msg.sender)不匹配。為什麼?

契約A

pragma solidity ^0.4.4;

contract A {

   function A() {
   }

   function createB(string name) {
       return new B(msg.sender, name);
   }
}

契約乙

pragma solidity ^0.4.4;

contract B {
   address owner
   string public name;

   function B(address _owner, string _name) {
       owner = _owner;
       name = _name;
   }
}

測試案例

pragma solidity ^0.4.0;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/B.sol";

contract TestB {
   B testB;
   A testA;

   function beforeEach() {
       A = A(DeployedAddresses.A());
       B = testA.createB("test");
   }

   function testOwnerIsSet() {
       Assert.equal(address(A), address(B), "Owner's address does not match");
   }
}

測試結果

1) TestB testOwnerIsSet:
    Error: Owner's address does not match
     at /Users/xxx/.config/yarn/global/node_modules/truffle/build/cli.bundled.js:214233:17
     at Array.forEach (native)
     at processResult (/Users/xxx/.config/yarn/global/node_modules/truffle/build/cli.bundled.js:214231:19)
     at process._tickCallback (internal/process/next_tick.js:109:7)

編輯

我已經添加address public ownercontract A. 並ownercontract B.

現在我的 TestB 契約看起來像這樣:

pragma solidity ^0.4.0;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/B.sol";

contract TestB {
   B testB;
   A testA;

   function beforeEach() {
       A = A(DeployedAddresses.A());
       B = testA.createB("test");
   }

   function testOwnerIsSet() {
       address aOwner = A.owner();
       address bOwner = B.owner();
       Assert.equal(aOwner, bOwner, "Owner's address does not match");
   }
}

您應該注意,如果您createB像以前一樣呼叫:

function createB(string name) public returns (address) {
 return new B(name)
}

在 B 建構子中,您將擁有msg.sender = address(A),因為 A 正在創建 B。

為了使其按預期工作,您必須將所有者發送給 B 建構子,如下所示:

契約A.sol

pragma solidity ^0.4.13;

import "./B.sol";

contract A {
   address public owner;
   function A() {
       owner = msg.sender;
   }

   function createB(string name) public returns (address) {
       return new B(owner, name);
   }
}

契約 B.sol

pragma solidity ^0.4.13;

contract B {
   address public owner;
   string public name;
   function B(address _owner, string _name) {
       owner = _owner;
       name = _name;
   }
}

合約測試B.sol

pragma solidity ^0.4.13;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/A.sol";
import "../contracts/B.sol";

contract TestB {
 B testB;
 A testA;

 function beforeEach() {
   testA = A(DeployedAddresses.A());
   testB = B(testA.createB("test"));
 }

 function testIsOwnerIsSet() {
   address aOwner = testA.owner();
   address bOwner = testB.owner();
   Assert.equal(aOwner, bOwner, "Owner's address does not match");
 }
}

編輯前

但是你永遠不會打電話給所有者,你正在比較合約 A 和合約 B 的地址。你應該比較

Assert.equal(address(A), address(B.owner), "Owner's address does not match") 

但要確保所有者在契約 B 中是公開的。

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