0

I need to call mint() function in MyNFToken.sol via MyContract.sol.

Ownable.sol

pragma solidity ^0.4.20;

contract Ownable {

address public owner;

function Ownable()
public
{
  owner = msg.sender;

}


 modifier onlyOwner() {

  require(msg.sender == owner);
_;
  }


}

MyNFToken.sol

pragma solidity ^0.4.20;

import "../tokens/NFTokenMetadata.sol";
import "../../node_modules/@0xcert/ethereum-utils/contracts/ownership/Ownable.sol";


contract MyNFToken is
  NFTokenMetadata,
  Ownable

{

function MyNFToken(
    string _name,
    string _symbol
)
public
{
     nftName = _name;
     nftSymbol = _symbol;
  }

function mint(
    address _owner,
    uint256 _id
)
 onlyOwner
 external
{
    super._mint(_owner, _id);
 }

}

MyContract.sol

pragma solidity ^0.4.20;

import "../tokens/MyNFToken.sol";


 contract MyContract{

address nftaddress;

function MyContract (address _nftaddress) public {
    nftaddress = _nftaddress;

}

 function createToken(address _owner,uint256 _tokenId) onlyOwner public payable returns(bool){

    MyNFToken instance = MyNFToken(nftaddress);
    instance.mint(_owner,_tokenId);
    return true;
}

I'm able to execute mint() directly from MYNFToken.sol by accurately checking the owner of contract(Ownable.sol). But not able call mint() via MyContract.sol. Is there something missing or beyond my understanding?..Please help to resolve this issue.

1 Answer 1

1

When you call mint() in MyNFToken.sol, msg.sender is your address since you call it directly. When calling it from MyContract.sol - the sender is MyContract.sol contract and it is not the owner of MyNFToken.sol so onlyOwner modifier reverts.
If you want it work you should take address parameter mint(address _caller) and pass msg.sender from MyContract.sol, then check if _caller is owner in MYNFToken.sol, either in function or in modifier.

EDIT. You could do it like this if you call mint() from other contract:

MyNFToken.sol

function mint(address _sender, address _owner, uint256 _id) external
{
    require(_sender == owner);
    super._mint(_owner, _id);
}

MyContract.sol

function createToken(address _owner,uint256 _tokenId) onlyOwner public payable returns(bool){

    MyNFToken instance = MyNFToken(nftaddress);
    instance.mint(msg.sender, _owner,_tokenId);
    return true;
}

Also consider using interfaces if you are only using function or two of other contract, as it will save gas when creating contract and allow to have more code in current contract.

EDIT EDIT. Alternatively you could do this to avoid passing address:

MyNFToken.sol

address myContract;
function mint(address _owner, uint256 _id) external
{
    require(msg.sender == owner || msg.sender == myContract);
    super._mint(_owner, _id);
}

MyContract.sol

function createToken(address _owner,uint256 _tokenId) onlyOwner public payable returns(bool){

    MyNFToken instance = MyNFToken(nftaddress);
    instance.mint(_owner,_tokenId);
    return true;
}
2
  • Thanks...You meant the parameter of mint(_owner, _tokenid). Here _owner is passed from js which is given same value of msg.sender . Also MyContract.sol and MYNFToken.sol is deployed by same wallet address hence, the owner of both contracts is same...right? Can you please explain a bit more
    – angelmaria
    Commented Jul 11, 2018 at 10:30
  • Edited my answer.
    – Maxpeinas
    Commented Jul 11, 2018 at 10:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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