2

I have a wrapper contract that instantiates and calls another contract, and my test cases say the owners (msg.sender)s don't match. Why?

contract A

pragma solidity ^0.4.4;

contract A {

    function A() {
    }

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

contract B

pragma solidity ^0.4.4;

contract B {
    address owner
    string public name;

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

test case

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

Test Results

 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)

EDIT

I have added the address public owner to contract A. And made owner public in contract B.

And now my TestB contract looks like this:

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

You should note that if you call createB like previously:

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

Inside B constructor you will have msg.sender = address(A), because A is creating B.

To make it work as intended you have to send the owner to B constructor like this:

Contract 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);
    }
}
Contract 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;
    }
}
Contract TestB.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");
  }
}

Before Edit

But you never call owner you are comparing the addresses of contract A, and contract B. You should compare

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

But make sure owner is public in contract B.

2
  • I will try this, but I believe I already have tried this. Setting B's owner field to public and trying the assert. Will get back to you.
    – The Nomad
    Aug 26 '17 at 5:21
  • Sending in the owner when creating contract B worked! Thanks a bunch!
    – The Nomad
    Aug 27 '17 at 4:49
2

Ismael is right. Your contracts need public owner variables so you can do something like:

    A a = A(<address where A is deployed);
    address AOwner = a.owner();
...
    assert(AOwner,BOwner,"Owner's should both be the same");

I fiddled with it a little and came up with this:

pragma solidity ^0.4.4;

contract A {

    address public owner; // add this

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

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

pragma solidity ^0.4.4;

contract B {

    address public owner;
    string public name;

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

Hope it helps.

1
  • Just tried this but still getting a failing test. Please see my edited code in OP. Should I not be doing the beforeEach() call? Could that cause some issues with my addresses?
    – The Nomad
    Aug 26 '17 at 8:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.