5

I tried to use the function "Call", as described here: Calling function from deployed contract

But seems it is not working at all.

How can I call a function from an existing deployed smart contract?

I'm trying to call a simple function from an existing address that receives an address as parameter.

This is the code I'm using to call the external function:

Contract A:

function CallExternalFunction(address externalContractAddress) { externalContractAddress.call(bytes4(sha3("FunctionX(address)")),0xfffff); //sends 0xfffff as input parameter to the external contract } 

The source code of the already deployed contract is like this:

Contract B:

contract test { mapping (address => uint256) public balanceOf; function test() { } function FunctionX(address _address) { balanceOf[_address] = 50000; } } 
3
  • 1
    Do you have the source code or ABI of the contract to call? Commented Apr 19, 2017 at 12:39
  • I updated the question with the source code Commented Apr 19, 2017 at 12:47
  • There doesn't seem to be anything wrong with this approach; it's just a lower level call to the external contract. There are just a few caveats. With call all of your gas (minus ~30k) will be forwarded to the external contract to do with it what it pleases, which is a vulnerability especially if the call fails and defaults to the fallback function. call also breaks type-safety for function arguments and will still transfer ether if an exception is emitted on execution, so make sure to place the call in a require() in order to revert transactions that don't behave as expected. Commented Sep 26, 2018 at 19:51

1 Answer 1

4

Try this. Deploy the caller, and it will deploy the test contract to simplify matters.

contract Caller { test public t; function Caller() { t = new test(); } function callIt(address theAddress) public returns(bool success) { t = test(t); <===== here the other contract address can be called t = test([OtherContractAddress]); example: test(0x12345); bool result = t.FunctionX(theAddress); return result; } } contract test { mapping (address => uint256) public balanceOf; function FunctionX(address _address) public returns(bool success) { balanceOf[_address] = 50000; return true; } } 

In Remix to show it working.

enter image description here

You can use a similar structure for a contract that is already if you have the source code, by using and Interface contract. Here "Caller" compiler can see just enough of test {} to manage the interface.

contract Caller { test public t; // where test is deployed and the address is known // Pass in the address for test {}. function Caller(address tAddress) { t = test(tAddress); // address of contract t } function callIt(address theAddress) public returns(uint bal) { return t.FunctionX(theAddress); } } // This interface constant includes the function interfaces (exactly as in the "real" contract" with the fynctions undefined // This tells the compiler how to communicate with the ABI in test{}. contract test { function FunctionX(address _address) public returns(uint balanceOf) {} } 
3
  • The example you displayed seems to be the 2 contracts in the same deployed address right? In my case the Contract A and B are deployed in different addresses (I updated the description with contract A and B). Do you know how to make it work when the contracts are deployed in different addresses? Commented Apr 19, 2017 at 13:19
  • 1
    No. Two contracts at one address is not possible. Two contracts in a single source file, with the first contract deploying an instance of the other (one way for it to know the address of the other). Caller at 0xb872, test at 0x22e6.t = new test(); deploys a new instance of test. For already deployed test{} you can pass in the address or hard code the address. Caller will need to know it to make the call. The single source file gives the compiler a view of the test contract so it) understands the test{} interface and has the bytecode it needs to deploy a new test{}. Commented Apr 19, 2017 at 14:33
  • I like the forward-declaration idea. Note the compiler (solcjs) generates "Unused local variable" warning for _address in the above example. Commented Oct 9, 2017 at 0:06

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.