Объединение строк байтов в сборке для входных данных вызова

У меня есть следующий фрагмент кода в моем контракте. Предполагается, что он принимает строку байтов, состоящую из флага uint, за которым следует список переменных чисел uint, и создает вызов, используя эти числа. Например, для строки байтов, состоящей из флага и только одного числа

0x00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000503b65

предполагается построить вызов на предоставленный адрес контракта с входом

0x912610ab0000000000000000000000000000000000000000000000000000000000503b65

который должен возвращать ненулевое значение, за которым следует внутренний вызов handleс флагом 3. Однако, когда я тестирую этот код, во входных данных, предоставляемых вызову контракта, отсутствует первый аргумент:

0x912610ab0000000000000000000000000000000000000000000000000000000000000000

Что я делаю не так? Это проблема со стеком? Я заимствую часть кода из этого вопроса , у которого, похоже, не было этой проблемы.

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

Ответы (1)

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