2

So I have multiple contracts that use the same modifier.

contract Token is ERC20Basic {

using SafeMath for uint256;

mapping(address => uint256) balances;

Owned private owned;

/// @dev `owner` is the only address that can call a function with this
/// modifier
modifier onlyOwner() {
    require(msg.sender == owned.getOwner());
    _;
}

function Token(address _owned) {

  owned = Owned(_owned);

}

function changeOwnerContract(address _owned) onlyOwner {

  owned = Owned(_owned);

}


function transfer(address _to, uint256 _value) public returns (bool) {

require(_to != address(0));

balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value);
return true;

}

 /**
 * @dev Gets the balance of the specified address.
 * @param _owner The address to query the the balance of.
 * @return An uint256 representing the amount owned by the passed address.
 */
function balanceOf(address _owner) public constant returns (uint256 balance) {
return balances[_owner];
}

function increaseTotal(uint256 _amount) public onlyOwner {

totalSupply = totalSupply.add(_amount);

}

function addToBalance(address _to, uint256 _amount) public onlyOwner {

balances[_to] = balances[_to].add(_amount);

}

}

And the second one:

contract TokenController {

Token private token;

Owned private owned;

event Mint(address indexed to, uint256 amount);

/// @dev `owner` is the only address that can call a function with this
/// modifier
modifier onlyOwner() {
    require(msg.sender == owned.getOwner());
    _;
}

function TokenController(address _sapien, address _owned) {

    token = token(_sapien);
    owned = Owned(_owned);

}

function changeBasicToken(address _sapien) onlyOwner {

    token = Token(_sapien);

}

function changeOwnerContract(address _owned) onlyOwner {

    owned = Owned(_owned);

}


function mint(address _to, uint256 _amount) onlyOwner returns (bool) {
    token.increaseTotal(_amount);
    token.addToBalance(_to, _amount);
    Mint(_to, _amount);
    return true;
}

}

Here is the Owned contract:

contract Owned {

address private owner;

/// @notice The Constructor assigns the message sender to be `owner`
function Owned() {
    owner = msg.sender;
}

address private newOwner;

/// @notice `owner` can step down and assign some other address to this role
/// @param _newOwner The address of the new owner. 0x0 can be used to create
///  an unowned neutral vault, however that cannot be undone
function changeOwner(address _newOwner) {

    if (msg.sender != owner)
        revert();

    newOwner = _newOwner;

}

function getOwner() public returns (address) {

    return owner;

}


function acceptOwnership() {
    if (msg.sender == newOwner) {
        owner = newOwner;
        newOwner = 0x0000000000000000000000000000000000000000;
    }
}
}

If I try to deploy on Mist (all contracts from the same address) and then call "mint" from TokenController, I get an error saying that the function can't be executed. If I don't put onlyOwner in Token at "increaseTotal" and "addToBalance", it works. But it should also work if I have the modifier there, because I basically call from the same address that deployed Owned, Token and TokenController....

Do you know why it doesn't work?

  • Just to confirm - you are setting the _owned parameter of each correctly, right? Also, have you stepped through the transaction to see where it's failing? – K. Fichter Nov 5 '17 at 3:19
  • @K.Fichter yes I tried multiple times and put the correct address of the Owned contract; it's failing on the check of onlyOwner on increaseTotal and addToBalance Btw, I deploy from win 64 – Steve Nov 5 '17 at 12:25
1

Your problem is that calling another contract changes msg.sender.

Let's say we have two contracts

contract A {
  B b;
  function foo() {
    // Here msg.sender is owner
    b.bar();
  }
}

contract B {
  function bar() { 
    // Here msg.sender is A
  }
}

If you execute a transaction A.foo({ from: owner }). Then inside A.foo() call we have msg.sender is equal to owner.

Now contract A calls function bar from contract B. Inside B.bar() we have msg.sender is equal to address of A.

  • Genius. Can't think that I missed that. Thank you! – Steve Nov 5 '17 at 19:01

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.