You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity使用Mapping/Struct实现玩家持多票时6位数组绑定彩票问题

彩票智能合约问题修复说明

以下是代码中存在的问题及对应修复方案:

主要问题

    1. 定长数组长度不匹配
      你在结构体Picket中定义的ticket字段是长度为6的uint定长数组,但赋值时仅填入了5个元素[1,2,3,4,5],类型不匹配导致赋值失败,需要补全为6个元素。
    1. 内存修改未同步到链上存储
      你在BuyTicket函数中用memory关键字声明的picket变量是存储数据的临时内存拷贝,修改该变量的值不会自动同步到链上存储,必须在修改完成后重新赋值给hope[_address]才会生效。
    1. 数据结构不支持单用户多购
      当前的mapping (address => Picket) hope是一个地址对应单张彩票的结构,用户多次购买会直接覆盖之前的彩票记录,不符合单用户可购买多张彩票的需求,需要改为mapping(address => Picket[])结构,即一个地址对应一个彩票数组。
    1. 其他语法与逻辑缺陷
    • address pool = addresshere;中的addresshere是未定义变量,需要替换为实际的资金池地址,且pool需要声明为address payable类型才能接收转账
    • BuyTicket函数的_address参数冗余,直接使用交易发起者msg.sender即可,避免出现代买错付的问题
    • 标识彩票是否开启的startinglottery变量使用bool类型比uint256语义更清晰
    • 转账逻辑建议使用call而非transfer,避免gas限制导致转账失败

修复后代码示例

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";

contract Lottery is Ownable {
    uint256 public constant TICKET_PRICE = 1 ether;
    address payable public immutable pool;
    uint public nextTicketId = 0;
    bool public isLotteryOpen;

    struct Ticket { 
        uint id;
        uint[6] number;
    }

    // 单个地址对应多张彩票
    mapping (address => Ticket[]) public userTickets;
    address[] public allPlayers;

    constructor(address payable _pool) {
        pool = _pool;
        isLotteryOpen = false;
    }

    function startLottery() public onlyOwner {
        isLotteryOpen = true;  
    }

    function endLottery() public onlyOwner {
        isLotteryOpen = false;
    }

    function buyTicket(uint[6] calldata ticketNumbers) public payable {
        // 校验条件
        require(msg.value >= TICKET_PRICE, "not enough money!");
        require(isLotteryOpen == true, "lottery isn't started.");
        
        // 转账到资金池
        (bool success, ) = pool.call{value: msg.value}("");
        require(success, "transfer to pool failed");

        // 存储彩票信息
        Ticket memory newTicket = Ticket({
            id: nextTicketId,
            number: ticketNumbers
        });
        userTickets[msg.sender].push(newTicket);
        allPlayers.push(msg.sender);
        nextTicketId++;
    }

    // 获取用户所有彩票
    function getUserTickets(address user) public view returns(Ticket[] memory) {
        return userTickets[user];
    }
}

内容的提问来源于stack exchange,提问作者Tryneed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 16:57:03