Solidity
固定計數數組的問題
使用映射和不使用映射有什麼區別?
我可以用映射聲明門票變數嗎?
Ticket[TOTAL_TICKETS] public tickets;
這是solidity智能合約
pragma solidity >=0.4.22 <0.9.0; uint256 constant TOTAL_TICKETS = 10; contract Tickets { address public owner = msg.sender; struct Ticket { uint256 price; address owner; } //mapping(uint256 => Ticket) public tickets; Ticket[TOTAL_TICKETS] public tickets; constructor() { for (uint256 i = 0; i < TOTAL_TICKETS; i++) { tickets[i].price = 1e17; // 0.1 ETH tickets[i].owner = address(0x0); } } function buyTicket(uint256 _index) external payable { require(_index < TOTAL_TICKETS && _index >= 0); require(tickets[_index].owner == address(0x0)); require(msg.value >= tickets[_index].price); tickets[_index].owner = msg.sender; } }
取票時,松露控制台出現錯誤
truffle(development)> Tickets.deployed().then(function(instance) { app=instance}) undefined truffle(development)> app.tickets() Uncaught Error: Invalid number of parameters for "tickets". Got 0 expected 1!
tickets
state 變數是一個數組,所以你需要發送你想要的票的索引。就像是:app.tickets(0)
但無論如何,
mapping
在這種情況下, a 可能對您更方便。
id
我建議您為該Ticket
結構創建一個成員。每張工單都應該有自己的 id,以便能夠正確辨識、修改等。我建議的方法如下所示:
//SPDX-License-Identifier: MIT pragma solidity ^0.8.15; type TicketId is uint256; contract Tickets { event TicketSold(TicketId id, address ticketOwner); address public owner = msg.sender; struct Ticket { TicketId id; uint256 price; address owner; } mapping(TicketId => Ticket) public tickets; modifier onlyOwner { require(owner == msg.sender); _; } // Maybe you want to be able to add tickets dynamically function addTicket(TicketId id, uint256 price) public onlyOwner { tickets[id] = Ticket(id, price, address(0x0)); } // Maybe you want to be able to remove tickets? function removeTicket(TicketId id) public onlyOwner { delete tickets[id]; } function buyTicket(TicketId id) external payable { require(tickets[id].owner == address(0x0), "Ticket already bought."); require(msg.value >= tickets[id].price, "Not enough balance to buy the ticket"); tickets[id].owner = msg.sender; emit TicketSold(id, msg.sender); } }
也許不再需要 a
TOTAL_TICKETS
了。但是您可以更改邏輯以使用狀態變數來計算總票數,並確保不要添加更多。使用 a
mapping
對於一般查找更有效(與遍歷數組相比,儘管通過索引訪問數組元素與映射一樣有效)。A
mapping
從其中刪除元素更有效。通過數組上的索引刪除元素是有效的,但通常,您希望調整數組的大小,以便數組中沒有空白空間,並且與從映射中刪除元素時的常量相比,其複雜性是線性的.我在實現中使用了自定義類型,以明確映射的關鍵是票證的 id,以使其更具可讀性和類型安全性。