Solidity

映射需要大量的氣體

  • January 5, 2018

我正在建構一個允許使用者創建列表的乙太坊智能合約。這是我的契約的一部分,這部分是氣體使用的罪魁禍首:

struct LiveListing {
    uint id;
    string name;
    string description;
    string condition;
    uint price;
    address buyer;
    address seller;       
}

mapping(uint => LiveListing) public liveListingsMapping;
uint id;

    function createListing(string _name, string _description, string _condition, uint _price) public  { 
        id++;
        LiveListing memory listing = LiveListing({name: _name, 
        description: _description, 
        condition: _condition, 
        price: _price, 
        seller: msg.sender, 
        id: id,
        buyer: 0x0,
        });
        liveListingsMapping[id] = listing;
   }

當映射和我將列表分配到 id 被註釋掉時,gas 從超過 1,000,000 變為 300,000。此外,創建列表從 300,000 到大約 21,000-22,000。有什麼建議嗎?謝謝!

不是 Mapping 需要大量的氣體;事實上,您將大量數據儲存在一個大對像中。

你應該清楚的一個概念是,當你在乙太坊中儲存數據時,它目前必須由網路中的每個節點(不包括輕節點)儲存。因此,與儲存數據相關的氣體成本會隨著您要儲存的數據量的增加而增加。這個想法是將大量數據分散儲存在鏈上。

潛在的解決方案 以下是一些需要考慮的潛在解決方案:

  1. 想想你正在使用的數據類型

例如 uint 是 uint256 的別名 - 這將允許您擁有大約 1.1579209e+77 個列表。

您是否預計會有超過 18,446,744,073,709,551,615 個列表?如果不是,那麼也許 uint64 會更合適。

同樣,condition更像是一個列舉;您可以儲存 1-2 個字元bytes2而不是要求所有用於儲存 a 的記憶體string嗎?

  1. 將部分數據鏈下儲存

其他合約是否需要讀取所有數​​據?如果不是,那麼也許數據不必儲存在乙太坊中,並且可以儲存在 IPFS 或類似的鏈下。

也許你可以從ERC-721中獲得一些靈感——它定義了一個tokenMetadata函式和儲存標準,用於在鏈下儲存令牌元數據——以及一些實現令牌(例如CrytoKitties)。

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