Solidity

將 uint 寫入字節以創建更大的字節

  • April 14, 2020

我想採用三個 uint 並將它們連接在一起作為一個字節變數。我能做到這一點的最簡單方法是什麼?我看過很多關於人們編寫完整的程式碼以將兩個字節合併在一起的文章。這很好,但就我而言,如果我想合併 3,我必須呼叫該合併函式兩次,這似乎效率低下。

我熟悉這種方法,它本質上以最簡單的方式將一個 uint 轉換為一個字節。

function toBytes(uint256 x) returns (bytes b) {
   b = new bytes(32);
   assembly { mstore(add(b, 32), x) }
}

我覺得我應該能夠將這種技術應用於我正在嘗試做的事情。但我一直無法弄清楚如何。這種方法基本上是採用一個單一的 uint 並將其視為一個字節,這正是我想要的。除了我想說“前 x 個字節屬於這個 uint,第二個 x 個字節屬於那個 uint,第三個 x 個字節屬於這個最後一個 uint。

編輯: 這是我到目前為止所擁有的。以下程式碼生成此結果。現在我只需要弄清楚如何刪除我不想要的所有額外的 0。

0x000000000000000000000000000000000000000000000000000000000死牛肉死牛肉死牛肉

function testStuff(
   uint256 x1, // 3735928559 -> "0xdeadbeef"
   uint256 x2, // 3735928559 -> "0xdeadbeef"
   uint256 x3 // 3735928559 -> "0xdeadbeef"
   ) public returns (bytes memory b) 
{
   b = new bytes(40);
   assembly 
   { 
       mstore(add(b, 40), x1)
       mstore(add(b, 36), x2)
       mstore(add(b, 32), x3)
   }
}

我想結束

0xdeadbeefdeadbeefdeadbeef

我不確定這是否是正確的方法。但我基本上使用的是大小大於 32 的擴展字節對象,因此我有足夠的空間將每個 uint 佈置為一個字節。根據大小,我將它們彼此相鄰設置。但是現在我最終需要刪除所有這些額外的空間。

function testStuff(
   uint256 x1, // 3735928559 -> "0xdeadbeef"
   uint256 x2, // 3735928559 -> "0xdeadbeef"
   uint256 x3 // 3735928559 -> "0xdeadbeef"
   ) public returns (bytes memory b) 
{
   b = new bytes(40);
   assembly 
   { 
       mstore(add(b, 12), x1)
       mstore(add(b, 8), x2)
       mstore(add(b, 4), x3)
       mstore(b, 12)
   }
}

會給你你正在尋找的結果。數據類型 bytes 將自身的長度儲存為第一個參數。因此,通過添加mstore(b, 12),我們指示 EVM 在字節的開頭儲存 12,這意味著它將包含 12 個字節。

但是,這僅適用於 uint 為 3735928559(或任何低於 2^32 = uint32)的範例。如果您想支持所有 uint256,則必須將其更改為每個 uint 32 字節。對於較低的數字,您當然會得到中間有 0 的空格。

更新:我不知道為什麼我讓它變得如此困難。當然,mstore(b, 12)你也可以只寫b = new bytes(12);

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