Tengo el siguiente código en mi contrato. Se supone que debe tomar una cadena de bytes compuesta por un indicador uint seguido de una lista variable de números uint y realizar una llamada usando esos números. Por ejemplo, para una cadena de bytes formada por la bandera y solo un número
0x00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000503b65
se supone que debe construir una llamada a la dirección del contrato proporcionada con la entrada
0x912610ab0000000000000000000000000000000000000000000000000000000000503b65
que debería devolver un valor distinto de cero, seguido de una llamada interna a handle
con un indicador de 3
. Sin embargo, cuando pruebo este código, a la entrada que se proporciona a la llamada de contrato le falta el primer argumento:
0x912610ab0000000000000000000000000000000000000000000000000000000000000000
¿Qué estoy haciendo mal? ¿Es esto un problema con la pila? Estoy tomando prestado parte del código de esta pregunta , que no parecía tener este problema.
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)))
}
}
function callByBytes(bytes4 _func, bytes _param) public {
address _tmpAddr = addr;
uint paramLen = _param.length;
uint allLen = 4 + paramLen;
assembly {
let p := mload(0x40)
mstore(p, _func)
for { let i := 0 } lt(i, paramLen) { i := add(i, 32) } {
mstore(add(p, add(4,i)), mload(add(add(_param, 0x20), i)))
}
let success := call(not(0), _tmpAddr, 0, p, allLen, 0, 0)
let size := returndatasize
returndatacopy(p, 0, size)
switch success
case 0 {
revert(p, size)
}
default {
return(p, size)
}
}
}