Contract-Design

查詢前端的 Mapping vs looping getter 函式的每個結構?

  • October 7, 2019

我有一個結構映射和一個計數器變數來跟踪映射中儲存了多少結構。

對於前端開發,您是否建議使用自動生成的 getter mymapping 查詢每個結構

$$ mystruct_index $$. 或者創建一個特定的 getter 函式來循環 X 結構並檢索 50 個數組中的結構是否更好。此外,如果我使用 getter 函式只獲取結構的幾行而不是整個結構,它是否會比簡單地為一個結構進行一次查詢帶來更好的效率?您是否有一些與智能合約進行前端互動的經驗,您認為智能合約的效率和長期可行性的最佳設計是什麼?最好的祝福

Solidity 目前不支持返回映射或可變大小的列表,因此您需要按照您描述的那樣實現一個獲取索引的 getter 函式。

我認為您正在描述的方法是在映射旁邊保留第二個列表,並使用它以塊的形式返回映射,如下面的原始碼。

contract SomeContract {

 mapping(address => uint256) public someMapping;
 address[] public addresses;

 function addValue(address _newAddress, uint256 _newValue) public {
   someMapping[_newAddress] = _newValue;
   addresses.push(_newAddress);
 }

 function getAddressCount() public view returns (uint256 _count) {
   return addresses.length;
 }

 function getValueByIndex(uint256 _index) public view returns (uint256 _val) {
   return someMapping[addresses[_index]];
 }

 // Get the values from mapping in chunks of size 10
 // This isn't a feasible solution in my opinion
 function getValuesChunk(uint256 _index) public view returns (uint256[10] memory _chunk) {
   uint256[10] memory vals;
   require(_index < 2^256 - 10, 'Index would wrap around unsafely');
   for (uint256 i = _index; i < _index+10; i++) {
       vals[i] = someMapping[addresses[i]];
   }
   return vals;
 }
}

這些view方法是只讀的並且不消耗gas,因此從技術上講,您可以根據需要多次呼叫它們,以便向前端顯示值。但是,有幾個理由不這樣做。* 它仍然會佔用你的乙太坊節點上的 CPU 資源。如果列表足夠大,您的節點可能會將其視為 DoS 攻擊並限製或禁止您。如果您執行自己的節點,那麼需要大量工作或 AWS 積分來消耗區塊鏈操作。* 在呼叫addValue. 即使您在前端進行了一些記憶體,您每次都將重新進行檢索幾乎相同的值的工作。

相反,我建議使用 Solidity 事件(EVM 日誌),這是一種允許您發出事件的工具,該事件由數據庫檢索,該數據庫允許在鏈下多次讀取一次性索引,例如 Subgraph https://thegraph .com/

這可以讓你保持你的solidity程式碼最小化和乾淨,而不是僅僅為了支持前端功能而在復雜的合約上花費精力,你可以輕鬆地將其解除安裝到為其設計的系統(GraphQL + React + Typescript)

contract SomeContract {

 event NewValue (
     address _address,
     uint256 _value
     );
 mapping(address => uint256) public someMapping;


 function addValue(address _newAddress, uint256 _newValue) public {
   someMapping[_newAddress] = _newValue;
   emit NewValue(_newAddress, _newValue);
 }

}

希望這可以幫助。

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