Tuples, revert, keccak256
memory allows us to deal with data types that are larger than 32 bytes
if we want to return a struct or an array within one function, this would not be possible with a single variable, if that struct/array is larger than 32 bytes
we can do this in Yul by simply denoting the boundaries/area of memory whose values we wish to return (this is what Solidity does under the hood)
function return2and4() external pure returns (uint256, uint256) {
assembly {
mstore(0x00, 2)
mstore(0x20, 4)
return(0x00, 0x40) // beginning and end location in memory of items we want to return
}
}
when we want to revert a statement, we also have to specify an area in memory to store the revert values, just like return
Solidity obscures the fact that in a revert case, data can still be sent so caller can debug it
Most of the time, we want to revert just so that execution stops, and not return a value. we can do this with:
revert(0, 0)
values in
abi.encode
are stored in memory in solidity:
// Solidity example
function hashV1() external pure returns (bytes32) {
bytes memory toBeHashed = abi.encode(1, 2, 3);
return keccak256(toBeHashed);
}
// Yul equivalent version
function hashV2() external pure returns (bytes32) {
assembly {
let freeMemoryPointer := mload(0x40)
// store 1, 2, 3 in memory
mstore(freeMemoryPointer, 1)
mstore(add(freeMemoryPointer, 0x20), 2)
mstore(add(freeMemoryPointer, 0x40), 3)
// update memory pointer to account for 3 32-byte variables
mstore(0x40, add(freeMemoryPointer, 0x60)) // increase memory pointer by 96 bytes
mstore(0x00, keccak256(freeMemoryPointer, 0x60))
return(0x00, 0x60)
}
}
in Yul,
keccak256
takes in the start location in memory of the variables to be hashed, and how many bytes of data (0x60
in this case)
Last updated