1

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)))
    }
}
benhorne
  • 11
  • 2

1 Answers1

0
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)
        }
    }
}