Assembly

從裝配轉換為 Solidity

  • June 30, 2019

我正在嘗試將彙編程式碼轉換為連結中給出的 Solidity: 什麼是函式選擇器 程式碼試圖呼叫下面給出的 Contract1 的函式 func(…):

contract Contract1 {
   function func(uint256 x, uint8 y) public returns (uint32, uint32) {...}
}
contract Contract2{
/* .......
*/
       assembly
       {
               let success := call(
                   gas,           // pass the remaining gas to the function
                   dest,          // the address of the contract1 instance
                   0,             // pass 0 wei to the function
                   add(data, 32), // the actual data starts after the length of 'data'
                   mload(data),   // the length of 'data' appears at the first 32 bytes
                   ret,           // the address of the output
                   8              // the size of the output
               )
               if iszero(success) {
                   revert(0, 0)
               }
       }
/*....*/
}

以下陳述是否正確?

(success, errCode, arg1, arg2) =dest.func.value()(  uint256(789), uint8(123));

arg1 和 arg2 將保存 Contract1 的 func() 返回的兩個值。有人請指導我。

祖爾菲。

您需要編寫以下內容:

(bool success, ) = dest.call(data);

正如文件所說:

為了與不遵守 ABI 的合約進行互動,或者為了更直接地控制編碼,提供了calldelegatecall功能staticcall。它們都採用單個 bytes memory參數並返回成功條件(作為 a bool)和返回的數據(bytes memory)。函式abi.encodeabi.encodePacked和可用於對結構化數據進行編碼abi.encodeWithSelectorabi.encodeWithSignature

假設下一個實現func()of Contract1

function func(uint256 x, uint8 y) public returns (uint32, uint32) {
   return(uint32(x), uint32(y));
}

的程式碼Contract2

contract Contract2 {

   Contract1 public contract1 = new Contract1();

   function func() public returns (uint32, uint32) {

       uint32[2] memory ret;

       address dest = address(contract1);

       bytes4 selector = contract1.func.selector;
       //bytes4 selector = bytes4(keccak256("func(uint256,uint8)"));

       bytes memory data = abi.encodeWithSelector(selector, uint256(789), uint8(123));
       (bool success, ) = dest.call(data);
       require(success);

       assembly {
           let size := returndatasize
           returndatacopy(ret, 0, size)
       }
       return (ret[0], ret[1]);
   }
}

這裡使用的彙編是管理函式返回的數據call。如果您使用元組(bool success, bytes memory returnData),您將獲得返回的數據bytes memory,您需要將其轉換為作為兩個uint32值返回。

引用自:https://ethereum.stackexchange.com/questions/72417