function here:
function encodeAmount(
uint256 amount,
bytes memory data
) public pure returns(bytes memory){
bytes memory amountToEncode = abi.encode(amount);
assembly {
mstore(add(add(data, 32), 68), mload(add(amountToEncode, 32)))
}
return data;
}
amount: 1000000
data: 0xe5b07cdb0000000000000000000000003416cf6c708da44db2624d63ea0aaef7113527c60000000000000000000000000000000000000000000000000000000000000001
The fn should change the last 32bytes in data, but the function returns the data unchanged.
So how to get the actually changed data?
Best Answer
There is a depper issue with your code. The provided data seems composed of :
For a total length of 68 bytes.
Now on this line :
You effectively skip the length field with
add(data, 32)
but then you write the amount after the provided data without changing the length field or updating the free memory pointer. Additionally, this is not necessary :Since amount is already a 32 bytes value (uint256) and abi.encoding it just yields a 32 bytes byte array with the very same value. You should also make sure that the data is formatted the way you expect it, that is 68 bytes long. Let me know if you are looking for a more generic approach, able to deal with byte arrays of variable length.
Since it's unclear what exactly you want to do between add data to the existing one or overwrite the last 32 bytes, here's what you need to do in both cases :
Adding data to the existing byte array (use the 2nd version)
This version is flawed, do not use it. I left it only because I believe it can be informative.
Which yields
0xe5b07cdb0000000000000000000000003416cf6c708da44db2624d63ea0aaef7113527c6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000f4240
EDIT: I figured that this version has a flaw if
data
is not the result of the last memory allocation.mstore(0x40, add(data, add(mload(data), 32)))
may take the free memory pointer back and leave the memory in an inconsistent state.This example that illustrate the flaw :
It's therefore better to use the following version that creates a new byte array and ensure memory consistency for previously allocated data.
I strongly advise using that version and not the previous one due to the flaw I mentioned before.
Overwriting the last 32 bytes of the byte array
There is no need to update the length or the free memory pointer in that case since we did not change anything to the memory layout, only the memory content of already allocated memory space.
Which yields
0xe5b07cdb0000000000000000000000003416cf6c708da44db2624d63ea0aaef7113527c600000000000000000000000000000000000000000000000000000000000f4240
I hope that answers your question.