Solidity

如何在 Solidity 中對字節、字元串和數組進行切片?

  • September 22, 2020

是否可以在 Solidity 中對變數進行切片?

Solidity 0.6.0 及更高版本(2020 年更新)

從 Solidity 0.6.0 開始,Solidity 中內置了數組切片功能。語法類似於現有語言,因為數組採用以下參數x[start:end]。這裡,startendint表示要切片的開始和結束索引的 s。

如果start大於endend大於數組的長度,則拋出異常。

需要注意的是,start或者end(或both)可以從程式碼中排除。start預設為 0,end預設為數組的長度。在以下情況下:

  • start被排除,返回值將是從索引0到指定的切片數組end
  • end被排除,返回值將是從指定start索引到數組末尾的切片數組
  • 兩者都被省略,返回的數組將與輸入數組相同

例子

簡化範例

bytes exampleBytes = '0xabcd'

exampleBytes[2:5];  # 'abc'
exampleBytes[:5];   # '0xabc'
exampleBytes[2:];   # 'abcd'
exampleBytes[:];    # '0xabcd'

完整範例(來自 Solidity 文件)

pragma solidity ^0.6.0;

contract Proxy {
   /// Address of the client contract managed by proxy i.e., this contract
   address client;

   constructor(address _client) public {
       client = _client;
   }

   /// Forward call to "setOwner(address)" that is implemented by client
   /// after doing basic validation on the address argument.
   function forward(bytes calldata _payload) external {
       bytes4 sig = abi.decode(_payload[:4], (bytes4));
       if (sig == bytes4(keccak256("setOwner(address)"))) {
           address owner = abi.decode(_payload[4:], (address));
           require(owner != address(0), "Address of owner cannot be zero.");
       }
       (bool status,) = client.delegatecall(_payload);
       require(status, "Forwarded call failed.");
   }
}

注意:從 Solidity 0.6.0 開始,數組切片僅適用於 calldata 數組



堅固性 < 0.6.0

對於 0.6.0 之前的 Solidity 版本,語言中沒有內置切片功能。但是,考慮到當時可用的語言特性,有一些方法可以執行類似的功能。

要切片 a string,您可以執行以下操作(來自此答案):

pragma solidity 0.4.24;

contract test{

   function getSlice(uint256 begin, uint256 end, string text) public pure returns (string) {
       bytes memory a = new bytes(end-begin+1);
       for(uint i=0;i&lt;=end-begin;i++){
           a[i] = bytes(text)[i+begin-1];
       }
       return string(a);    
   }
}

您還可以使用Arachnid (Nick Johnson)的 stringutils 庫來實現相同的目標。

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