Solidity
將數據添加到裝配中的數組以實現穩固性
嗨,我正在嘗試在彙編中創建一個內聯函式,目的如下:
**給定:**區塊鏈中具有名稱的數組(= 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) } }
問題:
- 我沒有讓調試器重新混合執行。“Solidity locals”螢幕為空:
- 單位$$ $$arrResult = 搜尋(0x0,arrMke,0X10);不想編譯:
- 問題:
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) } }