Solidity使用Mapping/Struct实现玩家持多票时6位数组绑定彩票问题
彩票智能合约问题修复说明
以下是代码中存在的问题及对应修复方案:
主要问题
- 定长数组长度不匹配
你在结构体Picket中定义的ticket字段是长度为6的uint定长数组,但赋值时仅填入了5个元素[1,2,3,4,5],类型不匹配导致赋值失败,需要补全为6个元素。
- 定长数组长度不匹配
- 内存修改未同步到链上存储
你在BuyTicket函数中用memory关键字声明的picket变量是存储数据的临时内存拷贝,修改该变量的值不会自动同步到链上存储,必须在修改完成后重新赋值给hope[_address]才会生效。
- 内存修改未同步到链上存储
- 数据结构不支持单用户多购
当前的mapping (address => Picket) hope是一个地址对应单张彩票的结构,用户多次购买会直接覆盖之前的彩票记录,不符合单用户可购买多张彩票的需求,需要改为mapping(address => Picket[])结构,即一个地址对应一个彩票数组。
- 数据结构不支持单用户多购
- 其他语法与逻辑缺陷
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
相关产品推荐
相关产品推荐

