Similar to How do you call a function of a deployed contract from another contract? (first answer), but because Truffle has access to the ABI's of compiled contracts thought I could avoid low-level call

Want to call a public function timeProtectTokens on token variable representing ERC20 contract within Escrow contract. Intuitively I thought to do:

 let token = await ERC20.new()
 let escrow = await Escrow.new(token.address)
 let result = await escrow.token.timeProtectTokens(initialAccount, 5)

..but fails

contract ERC20 is Protected {

import "./ERC20.sol";                                                                                                                                                                                                                         

contract Escrow {
  ERC20 public token;                                                                                                                                                                                                                         
  constructor(ERC20 _token) public {
    token = _token;

contract Protected {
  mapping (address => uint256) public protectedTokens;                                                                                                                                                                                       

  function timeProtectTokens(address _address, uint256 _amount) public **onlyEscrow** {
    protectedTokens[_address] = protectedTokens[_address].add(_amount);                                                                                                                                                                     

1 Answer 1


You cannot do it this way.

First, you need to do const tokenAddress = await escrow.token();.

Then, you need to use this address in order to create a contract object.

If you're on Truffle v4.x (web3.js v0.x), then you can do:

const tokenContract = web3.eth.contract(<Your ERC20 ABI Array>).at(tokenAddress);

If you're on Truffle v5.x (web3.js v1.x), then you can do:

const tokenContract = new web3.eth.Contract(<Your ERC20 ABI Array>, tokenAddress);

But I believe that you might experience problems interacting with your contract within Truffle tests.

So alternatively, you should probably use @truffle/contract.

Following that, you should finally be able to do:

const result = await tokenContract.timeProtectTokens(initialAccount, 5);
  • Syntax I'm using (ie ERC20.new()) is truffle-contract... I'd prefer to use truffle-contract because this for a test issue (timeProtectTokens uses OZ's Roles contract modifier, requiring that the call originate from the Escrow Contract, not a user account ) Mar 13, 2020 at 22:18
  • @Zach_is_my_name: What is ERC20 in your Truffle test? Mar 13, 2020 at 22:40

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.