1

I get an error in the code below.

function test2(address _t) public { // Owned no deploy address => owned()
        if (!_t.call.value(msg.value)(bytes4(keccak256("test()")))){
            revert();
        }
    }

browser/AccessRestrictionsol.sol:49:39: 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. if (!_t.call.value(msg.value)(bytes4(keccak256("test()")))){ ^-------------------------^
browser/AccessRestrictionsol.sol:49:13: TypeError: Unary operator ! cannot be applied to type tuple(bool,bytes memory) if (!_t.call.value(msg.value)(bytes4(keccak256("test()")))){ ^----------------------------------------------------^
browser/AccessRestrictionsol.sol:49:13: TypeError: Type tuple(bool,bytes memory) is not implicitly convertible to expected type bool. if (!_t.call.value(msg.value)(bytes4(keccak256("test()")))){ ^----------------------------------------------------^

I'm a beginner so I don't know, Is there only two ways, the way using abi.encodeWithSelector () and the above way? How many other ways are there to call a function of other contracts? And which one works as the most generic way to call the contract method? Using the above code as an example, please tell me the difference in the meaning of each way that generally works as a way of calling other functions.

1

Your code:

if (!_t.call.value(msg.value)(bytes4(keccak256("test()")))) {
    revert();
}

Is valid up until solc 0.5.x, where call returns a single boolean value.

Starting from solc 0.6.0, call returns the tuple (bool, bytes memory).

So to begin with, you need to change it to:

(bool success, bytes memory data) = _t.call.value(msg.value)(bytes4(keccak256("test()")));
if (!success) {
    revert();
}

Also note that you may as well change this:

if (!success) {
    revert();
}

To this:

require(success);

Since these two snippets are essentially identical.


Another API breaking change which was introduced in solc 0.6.0, requires that you change this:

call.value(x)

To this:

call{value: x}

So to conclude all of the above, simply do this:

(bool success, bytes memory data) = _t.call{value: msg.value}(bytes4(keccak256("test()")));
require(success);

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.