Solidity

將數據添加到裝配中的數組以實現穩固性

  • April 22, 2018

嗨,我正在嘗試在彙編中創建一個內聯函式,目的如下:

**給定:**區塊鏈中具有名稱的數組(= bytes32

$$ $$_documentHash)。 **詢問:**查找哪些索引等於我搜尋的名稱(= bytes32 _searchHash)並將它們返回到數組中(= uint

$$ $$結果) 我有以下程式碼,並附有一些註釋來闡明我的邏輯。以下主題幫助我生成了這段程式碼:

function arrMke() public{ // Some test data
   bytes32[] arrMke;
   arrMke.push(0X10);
   arrMke.push(0X20);
   arrMke.push(0x10);
   arrMke.push(0X40);
   uint[] arrResult = search(arrMke,0X10);
}

function search(bytes32[] _documentHashes, bytes32 _searchHash) public returns (uint[] result){
   assembly {
       let len := mload(_documentHashes) // Load the length (first 32 bytes)
       let counter := 0 //count each time data in the _documentHashes == _searchHash
       result := mload(0x40) // 0x40 is the address where next free memory slot is stored in Solidity.
       let i := 0 // uint i for the loop
       loop: //start loop
       let docHash := mload(add(_documentHashes, add(0x20, mul(i, 0x20)))) // docHash = _documentHashes[i], data offset = 0x20 (1st 32 is reserved for size) & i*32 to pickup the right index
       if eq(docHash, _searchHash) { // condition if(docHash == _searchHash)
           counter := add(counter,1) // increment counter by 1
           mstore(add(result, 0x20), counter) // (re)Set size of the result array each time the condtion is true
           mstore(add(result, add(0x20, mul(counter, 0x20))), i) // add data to the array, data offset = 0x20 (1st 32 is reserved for size) & i*32 to pickup the right index 
       }
       i := add(i,1) // increment for loop
       jumpi(loop, lt(i,len)) // stop loop when the lenght of _documenthashes is reached
       mstore(0x40, add(result, add(0x20, mul(counter, 0x20)))) // Update/return the result array ofsset + length of the data (=i*32)
   }
}

問題:

  1. 我沒有讓調試器重新混合執行。“Solidity locals”螢幕為空:

在此處輸入圖像描述

  1. 單位$$ $$arrResult = 搜尋(0x0,arrMke,0X10);不想編譯:

在此處輸入圖像描述

  1. 問題:

1)我如何查看(查看數據)我的變數,尤其是 uint

$$ $$結果?因為我不確定我的彙編程式碼是否正確。2)為什麼我會收到這個編譯錯誤以及如何修復它? 謝謝你的幫助!

時間

我發現了幾個問題

  • 聲明arrResult為記憶體引用(預設為儲存)
  • 數組的長度儲存在result+0,它儲存在result+0x20
  • 不要let在循環中使用它每次都會創建一個新變數(這似乎是編譯器中的一個錯誤)
  • 使用前遞增計數器,結果索引result+0x20+0x20*(counter+1)
  • 最後更新result一次長度以節省一些氣體

這應該按預期工作

function arrMke() public returns (uint[]) { // Some test data
   bytes32[] arrMke;
   arrMke.push(0X10);
   arrMke.push(0X20);
   arrMke.push(0x10);
   arrMke.push(0X40);
   uint[] memory arrResult = search(arrMke,0X40);
   return arrResult;
}

function search(bytes32[] _documentHashes, bytes32 _searchHash) public returns (uint[] result) {
   assembly {
       let len := mload(_documentHashes) // Load the length (first 32 bytes)
       let counter := 0 //count each time data in the _documentHashes == _searchHash
       result := mload(0x40) // 0x40 is the address where next free memory slot is stored in Solidity.
       let i := 0 // uint i for the loop
       let docHash := 0
       loop: //start loop
       docHash := mload(add(_documentHashes, add(0x20, mul(i, 0x20)))) // docHash = _documentHashes[i], data offset = 0x20 (1st 32 is reserved for size) & i*32 to pickup the right index
       if eq(docHash, _searchHash) { // condition if(docHash == _searchHash)
           mstore(add(result, add(0x20, mul(counter, 0x20))), i) // add data to the array, data offset = 0x20 (1st 32 is reserved for size) & i*32 to pickup the right index 
           counter := add(counter, 1) // increment counter by 1
       }
       i := add(i,1) // increment for loop
       jumpi(loop, lt(i,len)) // stop loop when the lenght of _documenthashes is reached
       mstore(result, counter) // (re)Set size of the result array each time the condtion is true
       mstore(0x40, add(result, add(0x20, mul(counter, 0x20)))) // Update/return the result array ofsset + length of the data (=i*32)
   }
}

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