I have the following piece of code in my contract. It's supposed to take in a byte string composed of a uint flag that is followed by a variable list of uint numbers and contruct a call using those numbers. For example, for a byte string made up of the flag and just one number
0x00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000503b65
it is supposed to construct a call to the the provided contract address with the input
0x912610ab0000000000000000000000000000000000000000000000000000000000503b65
which should return a nonzero value, followed by an internal call to handle
with a flag of 3
. However, when I test this code, the input that is provided to the contract call is missing the first argument:
0x912610ab0000000000000000000000000000000000000000000000000000000000000000
What am I doing wrong? Is this an issue with the stack? I am borrowing some of the code from this question, which did not seem to have this problem.
function record(bytes script, address contract) public {
bytes4 sig = bytes4(0x912610ab);
uint256 flag = uint256At(script, 0);
uint256 location = 0x20;
while (location < script.length) {
uint256 id = uint256At(script, location);
assembly {
let x := mload(0x40)
mstore(x,sig)
mstore(add(x,0x04),id)
switch call(sub(gas, 5000), contract, 0, x, 0x24, 0, 0)
case 0 {
revert(0, 0)
}
}
location += 0x20;
}
handle(flag);
}
function uint256At(bytes data, uint256 location) pure internal returns (uint256 result) {
assembly {
result := mload(add(data, add(0x20, location)))
}
}