Solidity投注合约编译Undeclared identifier错误与多赛事投注映射改造问题
投注智能合约修复方案
一、编译DeclarationError报错修复
触发报错的核心原因有3处语法/变量错误,直接对应修改即可:
- 移除
_checkBetMatchIsValid函数中未初始化的uint8 participantCount变量,该变量无实际作用,直接用_resultSelected有效值判断即可 - 修正
userAdd映射的类型定义,原定义为mapping(address => bytes32[]) userAdd,实际存储的是uint16类型的赛事ID,修改为mapping(address => uint16[]) public userAdd,解决类型不匹配报错 - 删除
bet函数中错误写法matchInfo[] storage idMatch = _matchSelected; idMatch.push(msg.sender, _matchSelected, _resultSelected);,原matchInfo映射结构设计错误,无法同时存储地址、赛事ID、投注结果三类数据,后续用新的存储结构替代即可
二、存储结构调整支持单地址多赛事下注
原有单层级mapping(address => Player) public playerInfo会导致新投注覆盖旧投注,直接调整为双层嵌套映射即可实现单地址多赛事投注:
// 原结构(删除) // mapping(address => Player) public playerInfo; // 新结构:地址 => 赛事ID => 投注信息 mapping(address => mapping(uint16 => Player)) public playerInfo;
同时配套调整相关业务逻辑:
1. 投注校验逻辑优化
_checkBetMatchIsValid函数无需遍历数组校验,直接通过双层映射判断即可,更节省gas:
function _checkBetMatchIsValid(address _user, uint16 _matchId, uint16 _chosenWinner) private view returns (bool) { // 校验是否已投注该赛事 if(playerInfo[_user][_matchId].amountBet > 0) { return false; } // 校验投注结果有效值(1=主场胜,2=客场胜,3=平局) if(_chosenWinner <1 || _chosenWinner>3) { return false; } return true; }
2. 投注存储逻辑调整
bet函数中存储投注信息的逻辑修改为:
// 存储当前地址对应赛事的投注信息 playerInfo[msg.sender][_matchSelected].amountBet = msg.value; playerInfo[msg.sender][_matchSelected].matchSelected = _matchSelected; playerInfo[msg.sender][_matchSelected].resultSelected = _resultSelected;
3. 奖金发放逻辑调整
distributePrizes函数中读取投注信息的逻辑修改为:
if(playerInfo[playerAddress][matchFinished].resultSelected == teamWinner){ winners[count] = playerAddress; count++; } // 计算奖金时读取对应赛事的投注金额 bets = playerInfo[add][matchFinished].amountBet;
4. 冗余映射清理
原代码中设计混乱的matchInfo、selectedResult、betAmount映射无实际作用,可直接删除,减少不必要的存储消耗。
内容的提问来源于stack exchange,提问作者Lloyd Ramos
相关产品推荐
相关产品推荐

