0

I was wondering how to decode the data payload received on a function

At first, I thought it would be enough with knowing the order of the variables and the exact data type of them at the moment of encoding, but when I tried to decode the msg.data as follows (var1,var2,var3) = abi.decode(msg.data,(dataType1,dataType2,dataType3));, the operation was failing and the entire tx was reverted.

1 Answer 1

2

After digging down on this topic, I found an interesting discussion about this exact same topic on Solidity's GitHub repository.(https://github.com/ethereum/solidity/issues/6012)

Short long story, the reason why the msg.data can't be decoded is:

  • The purpose of abi.decode is ABI decoding. msg.data is not ABI encoded, so it cannot be used there.

Workaround

  • As of the date of publishing this question (February 14th 2023), the suggested workaround is to slice the first 4 bytes of the msg.data which are the bytes of the function signature.
abi.decode(msg.data[4:], (...));
  • The above workaround seems to make the trick and allows the msg.data to be decoded, of course, you need to follow the rules of abi.decode!

Example

Function sending msg.data to the decodeMsgData for further decoding

// Decodes the payload on the called function and returnes the decoded data!

function decodeMsgData_ExternalFunction(
    address to,
    uint256 value,
    address origSender
) public  returns (address _to, uint _value, address _origSender) {
    (_to, _value, _origSender) = decodeMsgData(msg.data);
}

Decoding function

// Decodes the msgData and returns the exact data that was encoded on the msgData!
    // address to,
    // uint256 value,
    // address origSender

function decodeMsgData(bytes calldata msgData) external pure returns (address to, uint value, address origSender) {
    // The first 4 bytes on the msgData are the function signature, in order to decode the payload it is required to skip those bytes of the function signature!
        // reference: "abi.decode cannot decode msg.data" <===> https://github.com/ethereum/solidity/issues/6012
    (to, value, origSender) = abi.decode(msgData[4:],(address,uint,address));
}

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.