Solidity

從數組中檢索時出現問題

  • July 9, 2017

我有以下簡單的結構和該結構的數組:

struct Document  {
     bytes32 ownerID;
     bytes32 documentID;
     bytes32 name;      
 }

 Document[] public documents;

我有一個填充數組的 storeDoc() 方法:

function storeDocument (bytes32 _ownerID , bytes32 _documentID, bytes32 _name)  {
     Document memory newDoc;

     newDoc.ownerID = _ownerID;
     newDoc.documentID = _documentID;
     newDoc.name = _name;

     documents.push(newDoc);         

   }

最後是吸氣劑。一個 OwenerID 可能有多個條目,因此記憶體數組:

function getDocumentDetailsByID(bytes32 _ownerID) constant public returns (bytes32[], bytes32[], bytes32[]) {
     uint length = documents.length;

     if(registeredCandidates[_ownerID].clientAddress == msg.sender) {

         bytes32[] memory documentIDs = new bytes32[](length);
         bytes32[] memory names = new bytes32[](length);
         bytes32[] memory descriptions = new bytes32[](length);
         bytes32[] memory docYears = new bytes32[](length);


         for(uint i =0; i < length; i++) {

             if(documents[i].ownerID == _ownerID) {

                 Document memory currentDocument;
                 currentDocument = documents[i];

                 documentIDs[i] = currentDocument.documentID;
                 names[i] = currentDocument.name;

           }
         }


       return (documentIDs, names);  

     } else {
         return;
     }
 }

我面臨的問題是,只有 storeDocument() 完成的第一個條目才能正確使用 getDocumentDetailsByID() 返回。

當我第二次呼叫 getDocumentDetailsByID() 時,storeDocument() 完成的第二個後續條目將全部為零!

有人可以指導我我做錯了什麼嗎?謝謝。

這包含一個反模式。

您可能會感覺到它的長度和復雜性在增加。即使發現了邏輯錯誤(真的不確定記憶體陣列的用途)並解決了,你會發現你仍然創建了一個無法擴展的合約。

問題是您的for循環遍歷集合。每次迭代都會消耗一點gas。成本會隨著集合的增長而增加。最終,這將與區塊氣體限制發生衝突,交易將無法完成

您可以使用更有效的內部結構來解決此問題,以避免無界循環。您正在做的事情與此處的 Mapped Structs with Index 模式非常相似:Solidity是否有解決良好且簡單的儲存模式?

那個,或帶有刪除的變體,將為您提供一個可擴展的(任何規模的相同 gas 成本)內部儲存模式,並通過 ID 進行隨機訪問。如果您不需要列舉鍵,則可以使用更簡單的模式。

希望能幫助到你。

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