如何讀取結構內的數組?
作為學習 Solidity 和智能合約開發的一部分,我正在開發一個簡單的零件管理/跟踪系統。我有一個結構和一個元件列表的映射,如下所示:
struct Part { uint pNumber; string pName; string pDesc; string pManuf; string[] owners; } mapping(uint => Part) public part_store; uint public partsCount;
我正在使用以下方法向映射添加新部分:
function createPart (string _pName, string _pDesc, string _pManuf) public { partsCount++; part_store[partsCount].pNumber = partsCount; part_store[partsCount].pName = _pName; part_store[partsCount].pDesc = _pDesc; part_store[partsCount].pManuf = _pManuf; part_store[partsCount].owners.push(_pManuf); /* Trigger event */ emit partCreatedEvent(partsCount); }
一切都在編譯,沒有錯誤,我可以通過 Truffle 送出這個交易。當我創建新元件時,我會得到一個交易 ID。
現在我正在嘗試讀取元件內部的數據,但我沒有看到我推送數據的數組。似乎對像中的最後一個數據是製造商。但這並不表明我已經推動了原始製造商成為該零件的所有者。
> contract.part_store(1) Result: [ BigNumber { s: 1, e: 0, c: [1] }, 'part name', 'part desc', 'part Manuf' ] >
我沒有正確定義數組並將數據推送到它嗎?如何讀取該數組中的數據?我需要一個數組,因為這是一種儲存元件所有者的簡單方法,因為所有者可以更改(即通過將新所有者推送到特定元件的數組來定義新所有者)。
謝謝大家。
編輯:似乎如果我在結構之外定義一個數組並且
public
,我能夠讀取該值:string[] public test1; string[] test2; function writeElem() public { test1.push("t1"); test2.push("t2"); }
結果:
> contract.writeElem() ...tx: 0x88... ...txHas: 0x88... > contract.test1(0) 't1' > contract.test2(0) TypeError: app.test2 is not a function > contract.test2 undefined
我認為我不能在 struct public 或 private 中定義變數,所以也許這就是我無法讀取該數據的原因?是否可以在 Solidity 中對數組進行數據訪問?
發生的事情是您使用的“免費”吸氣劑不支持索引值,因此它只是將其排除在外。來自的“免費”吸氣劑
public
mapping
大致是function part_store(uint index) public view returns(uint, string, string, string) { Part storage p = part_store[index]; return (p.pNumber, p.pName, p.pDesc, p.pManu); }
您必須創建一個函式來獲取失去的資訊。你有緯度。您可以簡單地繼續我開始的操作並添加陣列,但由於規模問題和 gas 成本,我不是它的忠實粉絲。
你可以改為
function getProductOwnerCount(uint part) public view returns(uint) { return prod_store[part].owners.length; } function getProductOwnerAtIndex(uint part, uint index) public view returns(address) { return prod_store[part].owners[index]; }
這兩個函式允許任何觀察者建立數組長度(這樣他們就不會離開最後)並獲取他們感興趣的任何行。或者,客戶端可以遍歷所有行以獲取所有行。值得注意的是,如果客戶一直在查看事件日誌,並且每次添加所有者(應該)時都已發出事件,那麼他們可能已經知道大多數所有者。
希望能幫助到你。
能夠找到我的問題的答案。只要使用
memory
關鍵字,就可以返回字元串。function getProductOwner() public view returns(string memory) { return part_store[1].owners[0]; }
同樣對字元串數組執行相同的操作,但還需要在源頁面頂部添加新的編譯指示定義才能做到這一點。您將收到警告但沒有錯誤,我假設這是因為它是一項新功能,最終將在 Solidity 中完全發揮作用。
pragma experimental ABIEncoderV2; function getProductOwners() public view returns(string[] memory) { return part_store[1].owners; }