0

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);                                                                                                                                                                     
  }
}
Zach_is_my_name
  • 606
  • 4
  • 15

1 Answers1

0

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);
goodvibration
  • 26,003
  • 5
  • 46
  • 86
  • 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 ) – Zach_is_my_name Mar 13 '20 at 22:18
  • @Zach_is_my_name: What is ERC20 in your Truffle test? – goodvibration Mar 13 '20 at 22:40