Solidity

如何讀取結構內的數組?

  • December 4, 2018

作為學習 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;
}

這是我在 Remix 中執行的測試。 在此處輸入圖像描述

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