Solidity

如何將兩個 int16 打包成一個 byte32?

  • July 1, 2019

我有一個使用笛卡爾座標的契約。我最初的想法是將單個位置(x,y)映射到值/結構。我想用一個byte32可以轉換回座標的座標來定義任何給定的座標對。前任:

int16 x, int16 y;
byte32 key = coordinatesToBytes32(x, y);

反之亦然:

[x, y] = bytes32ToCoordinates(key);

進入之後,solc@^0.5.0我發現您無法再在這些類型之間進行顯式轉換,這使我難以進行強制轉換、屏蔽、移位和執行按位運算。作為參考,這是我做的地方(注意solidity版本):

pragma solidity ^0.4.17;

contract CoordinateUtils {
   function coordinatesToBytes32(int16 x, int16 y) internal pure returns(bytes32) {
       return (bytes32(x) << 16 & 0xFFFFFFFF) | bytes16(y);  // left shift extends negative so we mask out
   }
   function bytes32ToCoordinates(bytes32 b) internal pure returns(int16 x, int16 y) {
       return (int16(b >> 16), int16(b));
   }
}

此外,如果這看起來效率低下,我願意接受有關儲存笛卡爾相關值的其他建議。

首先,int16它只有 2 個字節寬(16 位),而不是 16 個字節。你的意思是int128

其次,您仍然可以在 Solidity 0.5.x 中將兩個int16值打包/解包為單個值,您只需要更多的類型轉換:bytes32

function pack (int16 a, int16 b) public pure returns (bytes32) {
 return bytes32 (bytes2 (a)) >> 16 | bytes2 (b);
}

function unpack (bytes32 x) public pure returns (int16, int16) {
 return (int16 (bytes2 (x << 16)), int16 (bytes2 (x)));
}

注意,轉向的方向。這是因為,bytesN擴展的工作方式與數字不同:

bytes2 a = 0x0102;
bytes4 b = bytes32 (a); // 0x01020000 (padded from right)

int16 c = 0x0102;
int32 d = int32 (c); // 0x00000102 (padded from left)

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