Solidity
映射需要大量的氣體
我正在建構一個允許使用者創建列表的乙太坊智能合約。這是我的契約的一部分,這部分是氣體使用的罪魁禍首:
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 需要大量的氣體;事實上,您將大量數據儲存在一個大對像中。
你應該清楚的一個概念是,當你在乙太坊中儲存數據時,它目前必須由網路中的每個節點(不包括輕節點)儲存。因此,與儲存數據相關的氣體成本會隨著您要儲存的數據量的增加而增加。這個想法是將大量數據分散儲存在鏈上。
潛在的解決方案 以下是一些需要考慮的潛在解決方案:
- 想想你正在使用的數據類型
例如 uint 是 uint256 的別名 - 這將允許您擁有大約 1.1579209e+77 個列表。
您是否預計會有超過 18,446,744,073,709,551,615 個列表?如果不是,那麼也許 uint64 會更合適。
同樣,
condition
更像是一個列舉;您可以儲存 1-2 個字元bytes2
而不是要求所有用於儲存 a 的記憶體string
嗎?
- 將部分數據鏈下儲存
其他合約是否需要讀取所有數據?如果不是,那麼也許數據不必儲存在乙太坊中,並且可以儲存在 IPFS 或類似的鏈下。
也許你可以從ERC-721中獲得一些靈感——它定義了一個
tokenMetadata
函式和儲存標準,用於在鏈下儲存令牌元數據——以及一些實現令牌(例如CrytoKitties)。