Solidity

內部帶有映射的嵌套結構

  • May 22, 2020

我有以下程式碼:

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.7.0;
pragma experimental ABIEncoderV2; 

contract VenueRegistry{
   struct Queue{
       uint head;
       uint tail;
       mapping(uint => address) queue;
   }

   struct Venue{
       uint id;
       Queue queue;
   }

   mapping (uint => Venue) public venues;

}

我收到以下錯誤:

TypeError:公共狀態變數不允許使用內部或遞歸類型。映射(uint => Venue)公共場所;

所以我做了venues私有並寫了一個吸氣劑:

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.7.0;
pragma experimental ABIEncoderV2; 

contract VenueRegistry{
   struct Queue{
       uint head;
       uint tail;
       mapping(uint => address) queue;
   }

   struct Venue{
       uint id;
       Queue queue;
   }

   mapping (uint => Venue) venues;

   function getVenue(uint _index) public view returns(Venue memory){
       return venues[_index];
   }
}

然後我收到以下錯誤:

僅允許庫在公共或外部函式中使用映射類型。

問題似乎出在struct Queue. 當我刪除映射時,它可以工作。有沒有辦法讓嵌套結構內部帶有映射?

問題是您public在兩個地方使用了不兼容的資料結構。

首先,這一行:

pragma solidity >=0.4.22 <0.7.0;

它使您無法複製您的結果,因為沒有人確定您使用的是什麼編譯器。出於這個原因,最好在主契約中具體說明,強制某個版本。如果繼承的合約、庫等具有更大的靈活性也沒關係,因為主合約仍然會強制執行該問題。

我使用了 Solc 6.6。

在第 16 行:

public對狀態變數做幾件事。這是全有或全無 - 如果您想要所有內容,非常方便,但如果您不想要所有內容,您可以手動編寫程式碼。其中之一是看起來像function variable(args) public returns(....

它適用於標量變數、數組和映射,所以uint public x;可以,uint[] public x;也可以,但myComplexStructWithMoreIndexedStuff[] public x;不兼容。總之,這是因為編譯器不確定如何為您構造 getter。

沒問題。只需將其設為私有或內部並編寫您自己的 getter 函式以請求參數、獲取元素並返迴響應。

所以:

mapping (uint => Venue) private venues;

在第 18 行:

同樣,public您試圖返回一個內部帶有映射的結構。單獨的 struct 就足以與public.

對於結構、數組和映射,函式參數是儲存指針,這意味著對儲存位置的 32 字節引用,而不是實際數據。這適用於合約信任自己的內部和私人環境。但是,儲存指針不能傳入或傳出。

請注意,系統不會迭代數據以產生關於變數值的冗長響應,並且可能永遠不會,因為這將 O(n) 複雜性 - 鏈上的高 CPU 和 I/O 活動,這你不想要。由於它不能返回數組的所有元素,也不能返回指向儲存的簡單指針,所以它無能為力。

您可以重寫它以返回一個元素,以及該元素的任何內容,如下所示:

function getVenueQueueElement(uint id, uint row) public view returns(address) {
 return venues[id].queue[row];
}

您可以考慮一個更好的資料結構,以方便列舉存在的場所和隊列成員,這樣客戶就不應該請求廢話和契約對象,如果他們這樣做的話。

看看這個更新的解釋器,並確保閱讀第 1 部分和第 2 部分以真正了解正在發生的事情和解決的問題:https ://medium.com/robhitchens/solidity-crud-epilogue-e563e794fde

它在內部使用儲存指針。它們是神秘的東西,所以這可能會有所幫助: https ://blog.b9lab.com/storage-pointers-in-solidity-7dcfaa536089

希望能幫助到你。

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