Solidity

從 0.5.x 中的字節轉換?

  • January 8, 2019

我想將字節轉換為任何其他類型。即"0x57D80C61128d608857d5310BB514223Bb6011CAB"進地址0x57D80C61128d608857d5310BB514223Bb6011CAB"5"uint256 5等等。我遵循了所有我能找到的片段,但我無法讓它們中的任何一個在 0.5.0 後工作。我相信罪魁禍首是這裡概述的變化:

由於右側填充和左側填充,現在不允許在不同大小之間進行轉換,bytesX這可能會導致意外的轉換結果。現在必須在轉換之前在類型內調整大小。例如,您可以先將變數轉換為,然後再轉換為,將 a (4 字節)轉換為(8 字節) 。通過 轉換時,您會得到相反的填充。uintY``bytesX``uintY``bytes4``uint64``bytes4``bytes8``uint64``uint32

以 uint 為例,這裡有一些在這個版本的編譯器之前可以工作的程式碼:

function bytesToUInt(string memory _b) public returns (uint256){
 bytes memory b = bytes(_b);
 uint256 number;
 for(uint i=0;i<b.length;i++){
   number = number + uint(b[i])*(2**(8*(b.length-(i+1))));
 }
 return number;
}

但這現在導致了TypeError: Explicit type conversion not allowed,我嘗試移動一些東西並添加額外的轉換,但沒有任何效果。

對於bytesto address,我試過這個:

function bytesToAddress(string memory _b) public returns (address) {
   bytes20 b = bytes20(bytes(_b));
   return address(uint160(b));
}

但是你不能明確地從bytes memoryto轉換bytes20,我也不能讓它工作。

有人可以告訴我這是如何正確完成的嗎?謝謝。

據我所知,您將需要內聯彙編。至少有人已經發布了一些適用於以前的solidity版本的程式碼,儘管通常簡短而正確的內聯彙編應該是相當普遍的。

這是一些將一些字節從記憶體轉換為 bytes20 的程式碼(只有前 20 個,如果超過它,它會被截斷)。

contract t {
   function tb20(bytes memory _b) 
   public
   pure
   returns (bytes20 _result) {
       assembly {
           _result := mload(add(_b, 0x20))
       }
   }

   function bytesToAddress(bytes memory _b) 
   public 
   returns (address) {
       return address(tb20(_b));
   }
}

對程式碼沒有任何保證或保證,但它似乎有效。當然可以更改 tb20 以返回地址,儘管那時您需要輪班。

我之前的回答與將字節類型從記憶體轉換為字節20 有關,因為這就是我如何理解標題中的問題,將動態字節轉換為靜態大小的 1-32 字節,然後再轉換為任何其他派生詞。

關於您體內的實際問題,此答案是為了確認您實際上可以將現有bytesToUInt功能用於 solc 0.5.x。只要它們對應的長度相等,您仍然可以在其他靜態字節之間進行顯式轉換。因此,如果您有一些 bytes32 並希望它是 uint128,您首先必須將其顯式轉換為 bytes16,然後再通過正常的solidity 將其轉換為 uint128。當然,在繼續此操作之前,您需要調試/測試以查看哪些字節 32 可能會被截斷,因為在相反的情況下,先將其轉換為 uint256 然後將其削減為 uint128 可能更有意義.

簡單地說,您可以通過將 轉換bytes1uint8first 來使現有功能正常工作。

function bytesToUInt(string memory _b) public returns (uint256){
 bytes memory b = bytes(_b);
 uint256 number;
 for(uint i=0;i<b.length;i++){
   number = number + uint256(uint8(b[i]))*(2**(8*(b.length-(i+1))));
 }
 return number;
}

添加 uint256 是為了明確性,這可能總是一個好主意,但不需要

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