2
votes

I want to know how to call a function from already deployed contract in solidity. I tried below one but it's throwing error and require without imorting the deployed contract

 contract B {
    watch_addr = 0x1245689;
    function register(string _text) {
        watch_addr.call(bytes4(keccak256("register(string)")), _text);
    }
}

Can any one please tell me the solution?

error:browser/delegate.sol:14:31: TypeError: Invalid type for argument in function call. Invalid implicit conversion from bytes4 to bytes memory requested. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.
       watch_addr.call(bytes4(keccak256(abi.encode("register(string)"))));
1

1 Answers

2
votes

In version 5.0 Solidity had some breaking changes:

The functions .call() ... now accept only a single bytes argument. Moreover, the argument is not padded. This was changed to make more explicit and clear how the arguments are concatenated. Change ... every .call(signature, a, b, c) to use .call(abi.encodeWithSignature(signature, a, b, c)) (the last one only works for value types). ... Even though it is not a breaking change, it is suggested that developers change x.call(bytes4(keccak256("f(uint256)"), a, b) to x.call(abi.encodeWithSignature("f(uint256)", a, b)).

So, the suggested way to call other contract is like this:

pragma solidity ^0.5.3;

contract test3 {       
    address watch_addr = address(0x1245689);
    function register(string memory _text) public {
        watch_addr.call(abi.encodeWithSignature("register(string)", _text));
    }
}

Also note added memory keyword: you now need to specify data location for function parameters of complex types:

Explicit data location for all variables of struct, array or mapping types is now mandatory. This is also applied to function parameters and return variables.