1

I'm reading the Ethereum book of Gavin Wood right know and the following code example gives an error message when I try to compile it with truffle:

pragma solidity ^0.4.22;

contract calledContract {
    event callEvent(address sender, address origin, address from);
    function calledFunction() public {
        emit callEvent(msg.sender, tx.origin, this);
    }
}

library calledLibrary {
    event callEvent(address sender, address origin,  address from);
    function calledFunction() public {
        emit callEvent(msg.sender, tx.origin, this);
    }
}

contract caller {
    function make_calls(calledContract _calledContract) public {
        // Calling calledContract and calledLibrary directly
        _calledContract.calledFunction();
        calledLibrary.calledFunction();

        // Low-level calls using the address object for calledContract
        require(address(_calledContract).
                call(bytes4(keccak256("calledFunction()"))));
        require(address(_calledContract).
                delegatecall(bytes4(keccak256("calledFunction()"))));
    }
}

https://github.com/ethereumbook/ethereumbook/tree/develop/code/truffle/CallExamples

It gives the following error message:

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type undefined

Any ideas?

1
  • Thank you so much for the help. That wasn't the reason for the error though.
    – Bastin
    Commented Feb 3, 2019 at 7:16

2 Answers 2

1

It compiles perfectly under solidity 0.4.22 but you a probably using a newer one with breaking changes.

Determine your compiler version with

$ truffle version

You should see something like solc: 0.5.x

Most of the breaking changes come with 5.x.

  • line 6: this is not implicitly converted to address anymore. Cast it as address with address(this)
  • line 13: same

I significantly refactored make_calls().

  • functionSig uses abi.encodePacked to handle the explicit converstion from bytes4 fixed length to dynamic bytes. This is quite a lot so I broke it out as a separate concern for readability.
  • require() doesn't work with the responses as they are returning a tuple with an empty bytes. I broke that concern out into a separate step.
  • Added an event emitter to inspect responses.

I'm not certain this is the most elegant want to handle everything. Possibly someone will chime in with another solution. It should compile cleanly under 5.x if you make sure the pragma matches the compiler you are actually using.

pragma solidity 0.5.1;

contract calledContract {
    event callEvent(address sender, address origin, address from);
    function calledFunction() public {
        emit callEvent(msg.sender, tx.origin, address(this));
    }
}

library calledLibrary {
    event callEvent(address sender, address origin,  address from);
    function calledFunction() public {
        emit callEvent(msg.sender, tx.origin, address(this));
    }
}

contract caller {

    event LogLowLevelCalls(address sender, bool success, bytes response);

    function make_calls(calledContract _calledContract) public {
        // Calling calledContract and calledLibrary directly
        _calledContract.calledFunction();
        calledLibrary.calledFunction();

        // Low-level calls using the address object for calledContract
        bool success;
        bytes memory response;

        bytes memory functionSig = abi.encodePacked(bytes4(keccak256("calledFunction()")));
        (success, response) = address(_calledContract).call(functionSig);
        require(success);
        emit LogLowLevelCalls(msg.sender, success, response);
        (success,  response) = address(_calledContract).delegatecall(functionSig);
        require(success);
        emit LogLowLevelCalls(msg.sender, success, response);
    }
}

Here is in Remix to show it compiling and working.

enter image description here

Hope it helps.

0

Thank you so much for the help. That wasn't the reason for the error though, since it doesn't comile under truffle with the config files of the folder on github. But I found a solution thanks to a friend:

Create .env in project root

Put

ROPSTEN_PRIVATE_KEY="your key"
MAINNET_PRIVATE_KEY="your key"`

into it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.