Solidity
從數組中檢索時出現問題
我有以下簡單的結構和該結構的數組:
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 進行隨機訪問。如果您不需要列舉鍵,則可以使用更簡單的模式。
希望能幫助到你。