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

bumped to the homepage by Community 12 hours ago

This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.

  • I try your contract with remix and it worked correctly. – Ismael Oct 9 '18 at 5:02
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)
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.