DeclarationError:编译时未声明的标识符



这是投注智能合约,问题是用户/地址需要投注不同的比赛。智能合约只设计一个映射值。完整源代码:https://github.com/laronlineworld/bettingMatch/blob/main/bettingMatch.sol

contract Betting is Ownable {

uint256 public minimumBet;

event EtherTransfer(address beneficiary, uint amount);
//Initialize in 10 matches (It can be improved)
uint256[] public totalBetHome = new uint256[](100);
uint256[] public totalBetAway = new uint256[](100);
uint256[] public totalBetDraw = new uint256[](100);
uint256 public numberOfBets;
uint256 public maxAmountOfBets = 1000;

uint256 devFee = 9500;

address[] public players;
address public owner;

struct Player {
uint256 amountBet;
uint16 matchSelected;
uint16 resultSelected;
}

mapping(uint16 => uint16[]) matchInfo;

mapping(address => bytes32[]) userAdd;

mapping(uint16 => uint16[]) selectedResult;

mapping(uint256 => uint256[]) betAmount;

mapping(uint16 => bool) matchBettingActive;
mapping(address => Player) public playerInfo;
function() public payable {}
constructor() public {
owner = msg.sender;
//The minimum Bet defined as 0.0001 ether
minimumBet = 100000000000000;

}
function kill() public {
if(msg.sender == owner) selfdestruct(owner);
}
function checkIfPlayerExists(address player) public view returns(bool){
for(uint256 i = 0; i < players.length; i++){
if(players[i] == player) return true;
}
return false;
}

function checkIfMatchStatus(uint16 _match) public view returns(bool){
if(matchBettingActive[_match] == true){
return true;
}
else{
return false;
}
}

function _checkBetMatchIsValid(address _user, uint16 _matchId, uint16 _chosenWinner) private view returns (bool) {
//ensure that user hasn't already bet on match 
uint16[] storage addUser = userAdd[_user]; 
if (addUser.length > 0) {
for (uint n = 0; n < addUser.length; n++) {
if (addUser[n] == _matchId) {
//user has already bet on match 
return false;
}
}
}
uint8 participantCount; 
if (_chosenWinner >= participantCount)
return false;
return true;
}
function initializeMatches(uint8 _numberMatches) public onlyOwner{
for(uint256 i = 0; i < _numberMatches; i++){
totalBetHome[i] = 0;
totalBetAway[i] = 0;
totalBetDraw[i] = 0;
}
}

function beginVotingPeriodForMatch(uint16 _match)  public onlyOwner returns(bool) {
matchBettingActive[_match] = true;
return true;
}

function closeVotingForMatch(uint16 _match) public onlyOwner returns (bool) {
// Close the betting period
matchBettingActive[_match] = false;
return true;
}
function bet(uint16  _matchSelected, uint16  _resultSelected) public payable {
require(matchBettingActive[_matchSelected] == true, "Betting: match voting is disabled");
//Check if the player already exist
//   require(!checkIfPlayerExists(msg.sender));

//Check if the value sended by the player is higher than the min value
require(msg.value >= minimumBet);

require(!_checkBetMatchIsValid(msg.sender,_matchSelected, _resultSelected));

matchInfo[] storage idMatch = _matchSelected;
idMatch.push(msg.sender, _matchSelected, _resultSelected);

bytes32[] storage userBets = userAdd[msg.sender];
userBets.push(_matchSelected);


//Set the player informations : amount of the bet, match and result selected
//   playerInfo[msg.sender].amountBet = msg.value;
//   playerInfo[msg.sender].matchSelected = _matchSelected;
//   playerInfo[msg.sender].resultSelected = _resultSelected;



//Add the address of the player to the players array
players.push(msg.sender);

//Finally increment the stakes of the team selected with the player bet
if ( _resultSelected == 1){
totalBetHome[_matchSelected] += msg.value;
}
else if( _resultSelected == 2){
totalBetAway[_matchSelected] += msg.value;
}
else{
totalBetDraw[_matchSelected] += msg.value;
}
}
function distributePrizes(uint16 matchFinished, uint16 teamWinner) public onlyOwner {
address[1000] memory winners;
//Temporary in memory array with fixed size. Let's choose 1000
uint256 count = 0; // This is the count for the array of winners
uint256 loserBet = 0; //This will take the value of all losers bet
uint256 winnerBet = 0; //This will take the value of all winners bet
address add;
uint256 bets;
address playerAddress;

//Check who selected the winner team
for(uint256 i = 0; i < players.length; i++){
playerAddress = players[i];
//If the player selected the winner team, we add his address to the winners array
if(playerInfo[playerAddress].matchSelected == matchFinished &&
playerInfo[playerAddress].resultSelected == teamWinner){
winners[count] = playerAddress;
count++;
}
}
//We define which bet sum is the Loser one and which one is the winner
if ( teamWinner == 1){
loserBet = totalBetAway[matchFinished] + totalBetDraw[matchFinished];
winnerBet = totalBetHome[matchFinished];
}
else if ( teamWinner == 2){
loserBet = totalBetHome[matchFinished] + totalBetDraw[matchFinished];
winnerBet = totalBetAway[matchFinished];
}
else{
loserBet = totalBetHome[matchFinished] + totalBetAway[matchFinished];
winnerBet = totalBetDraw[matchFinished];
}
//We loop through the array of winners, to give ethers to the winners
for(uint256 j = 0; j < count; j++){
//Check that the address in this fixed array is not empty
if(winners[j] != address(0))
add = winners[j];
bets = playerInfo[add].amountBet;
uint256 amountToPlayer = (bets * (10000+(loserBet*devFee/winnerBet))) / 10000;
winners[j].transfer(amountToPlayer);
}
//Reset all variables
delete playerInfo[playerAddress]; 
players.length = 0; 
loserBet = 0; 
winnerBet = 0;
//10 will be the number of matches (To improve this)
for(uint256 k = 0; k < 10; k++){
totalBetHome[k] = 0;
totalBetAway[k] = 0;
totalBetDraw[k] = 0;
}
}

投注智能合约,尝试创建一个映射结构,用户/wallet_address可以投注多个比赛。这个投注合约的问题是每次用户/wallet_address投注时,单个映射的数据被覆盖,如何创建一个值的映射,使用户/wallet_address可以投注不同的比赛。

您可以为此目的使用二维映射,例如mapping(address => mapping(uint256 => Player)) playerInfo,它将映射:玩家地址->matchSelected→玩家结构,你可以修改玩家结构,只保存属性amountBetresultSelected,并适合8个字节,以节省gas成本。