Search code examples
ethereumsoliditycontract

How to invoke a pre-installed contract in another contract


First I pre-install a contract A(address(A)). Then I install a contract B (address(B)) to invoke A by using call interface. Lastly I invoke the contract by using his address(x). I meant to use the address(x) to invoke A, but actually the address(B) invoke A. So how can I use address(x) to invoke A?"

pragma solidity ^0.4.21;

contract TransferERC20 {

    event TransferEvent (
        bool _flag,
        string _invoiceId,
        address _erc20ContractHash,
        address indexed _from,
        address indexed _to,
        uint256 _value
    );

    function transfer(string _invoiceId, address _erc20ContractHash,address _from, address _to, uint256 _amount) public returns (bool) {
        bytes4 methodTransfer = bytes4(keccak256("transfer(address,uint256)"));
        if(_erc20ContractHash.call(methodTransfer, _to, _amount)) {
            emit TransferEvent(true, _invoiceId, _erc20ContractHash, _from, _to, _amount);
            return true;
        }
        emit TransferEvent(false, _invoiceId, _erc20ContractHash, _from, _to, _amount);
        return false;
    }
}

The above code intends to call ERC20 contract which is pre-installed on ethereum testnet. However I invoke failed because the address is changed to the the TransferERC20 address. How can I realize the transfer function by using the TransferERC20 callor's address. THKS.


Solution

  • The token holder first needs to set an allowance using approve on the ERC20 token for the TransferERC20 contract and only then can they call transfer on the TransferERC20 contract which should call transferFrom on the ERC20 token.
    This requires two transactions, one for approve and one for transferFrom.

    If you are creating ERC20 tokens you may want to look at the OpenZeppelin Contracts implementation to see if this meets your needs. See the documentation for details: https://docs.openzeppelin.com/contracts/2.x/tokens#ERC20

    Alternatively you could look at creating ERC777 tokens (no need to do approve and transferFrom in two separate transactions). See the documentation for details: https://docs.openzeppelin.com/contracts/2.x/tokens#ERC777

    If you have questions on using OpenZeppelin you can ask in the Community Forum: https://forum.openzeppelin.com/

    Disclosure: I am the Community Manager at OpenZeppelin