Assembly
在裝配中……無法讓委託呼叫工作
Delegatecall 可以在solidity 或assembly 中使用。
在solidity中,我可以使用以下程式碼使其工作:
bytes memory payload = abi.encodeWithSignature ("get_value(uint16,uint16)", var1, var2); bool success; bytes memory result; (success, result) = my_contract.delegatecall (payload);
上面的程式碼呼叫
my_contract.get_value(var1, var2)
.我怎樣才能在裝配中做同樣的事情?函式定義如下:
delegatecall (gas, address, in, insize, out, outsize)
如果我在一個組裝塊中,假設
address
應該是包含被呼叫函式的合約的地址,它怎麼會知道我打算呼叫哪個函式?當我使用solidity 執行此操作時,它會從我傳遞給它的編碼有效負載數據中知道這一點。但是彙編函式只需要一個地址。它總是返回 0。我無法在 Internet 上的任何地方找到任何關於 EVM 組裝的好的文件。
編輯:以下是我所做的嘗試之一,使用來自 Internet 的範例。
let freememstart := mload (0x40) calldatacopy (freememstart, 0, calldatasize ()) success := delegatecall (not (0), my_contract, freememstart, calldatasize (), freememstart, 32)
編輯 2:我做了另一次嘗試,沒有使用 calldatacopy。
bytes memory payload = abi.encodeWithSignature ("get_value(uint16,uint16)", var1, var2); uint payload_size = payload.length * 8; assembly { let freememstart := mload (0x40) mstore (0x40, add (freememstart, payload_size)) mstore (freememstart, payload) let output := mload (0x40) mstore (0x40, add (output, 0x20)) success := delegatecall (not (0), contract_addr, freememstart, payload_size, output, 0x20) }
您應該注意的幾件事:
- 不需要將記憶體複製到空閒指針,可以使用任何記憶體指針。EVM 會將記憶體複製到目標,因此不會被修改。
- 有效載荷的前 32 個字節是數組的長度。傳遞該記憶體時可能希望跳過這些字節。這就是背後的原因
add(payload, 32)
。像這樣的東西應該適用於你的情況
bytes memory payload = abi.encodeWithSignature ("get_value(uint16,uint16)", var1, var2); uint ret; bool success; assembly { let output := mload (0x40) success := delegatecall(gas(), contract_addr, add(payload, 32), mload(payload), output, 0x20) ret := mload(output) }