世界杯竞猜项目Dapp-第一章(合约开发)

这篇具有很好参考价值的文章主要介绍了世界杯竞猜项目Dapp-第一章(合约开发)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

最近卡塔尔世界杯如火如荼,让我们一起来尝试利用 solidity 语言做一个世界杯竞猜的 Dapp 实战项目,本次实战学习主要参考:https://github.com/dukedaily/solidity-expert,我会针对原始项目做更详尽的注解,持续更新中…文章来源地址https://www.toymoban.com/news/detail-690478.html

业务需求

  • 参赛球队一经设定不可改变,整个活动结束后无法投票;
  • 全⺠均可参与,无权限控制;
  • 每次投票为 1 ether,且只能选择一支球队;
  • 每个人可以投注多次;
  • 仅管理员公布最终结果,完成奖金分配,开奖后逻辑:
  • winner 共享整个奖金池(一部分是自己的本金,一部分是利润);
  • winner 需自行领取奖金(因为有手续费);
  • 下一期自行开始

基础合约实现

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

import "hardhat/console.sol";

contract WorldCup {
    // 1. 状态变量:管理员、所有玩家、获奖者地址、第几期、参赛球队
    // 2. 核心方法:下注、开奖、兑现
    // 3. 辅助方法:获取奖金池金额、管理员地址、当前期数、参与人数、所有玩家、参赛球队

    // 管理员
    address public admin;
    // 第几期
    uint8 public currRound;

    // 参赛球队
    string[] public countries = ["GERMANY", "FRANCH", "CHINA", "BRIZAL", "KOREA"];
    // 期数 => 玩家
    mapping(uint8 => mapping(address => Player)) players;
    // 期数 => 投注各球队的玩家
    mapping(uint8 => mapping(Country => address[])) public countryToPlayers;
    // 玩家对应赢取的奖金
    mapping(address => uint256) public winnerVaults;

    // 投注截止时间-使用不可变量,可通过构造函数传值,部署后无法改变
    uint256 public immutable deadline;
    // 所有玩家待兑现的奖金
    uint256 public lockedAmts;

    enum Country {
        GERMANY,
        FRANCH,
        CHINA,
        BRAZIL,
        KOREA
    }

    event Play(uint8 _currRound, address _player, Country _country);
    event Finialize(uint8 _currRound, uint256 _country);
    event ClaimReward(address _claimer, uint256 _amt);

    // 验证管理员身份
    modifier onlyAdmin {
        require(msg.sender == admin, "not authorized!");
        _;
    }

    // 玩家投注信息
    struct Player {
        // 是否开奖
        bool isSet;
        // 投注的球队份额
        mapping(Country => uint256) counts;
    }

    constructor(uint256 _deadline) {
        admin = msg.sender;
        require(_deadline > block.timestamp, "WorldCupLottery: invalid deadline!");
        deadline = _deadline;
    }

    // 下注过程
    function play(Country _selected) payable external {
        // 参数校验
        require(msg.value == 1 gwei, "invalid funds provided!");

        require(block.timestamp < deadline, "it's all over!");

        // 更新 countryToPlayers
        countryToPlayers[currRound][_selected].push(msg.sender);
        // 更新 players(storage 是引用传值,修改会同步修改原变量)
        Player storage player = players[currRound][msg.sender];
        // player.isSet = false;
        player.counts[_selected] += 1;

        emit Play(currRound, msg.sender, _selected);
    }

    // 开奖过程
    function finialize(Country _country) onlyAdmin external {
        // 找到 winners
        address[] memory winners = countryToPlayers[currRound][_country];
        // 分发给所有压中玩家的实际奖金
        uint256 distributeAmt;

        // 本期总奖励金额(奖池金额 - 所有玩家待兑现的奖金)
        uint currAvalBalance = getVaultBalance() - lockedAmts;
        console.log("currAvalBalance:", currAvalBalance, "winners count:", winners.length);

        for (uint i = 0; i < winners.length; i++) {
            address currWinner = winners[i];

            // 获取每个地址应该得到的份额
            Player storage winner = players[currRound][currWinner];
            if (winner.isSet) {
                console.log("this winner has been set already, will be skipped!");
                continue;
            }

            winner.isSet = true;
            // 玩家购买的份额
            uint currCounts = winner.counts[_country];

            // (本期总奖励 / 总获奖人数)* 当前地址持有份额
            uint amt = (currAvalBalance / countryToPlayers[currRound][_country].length) * currCounts;
            // 玩家对应赢取的奖金
            winnerVaults[currWinner] += amt;
            distributeAmt += amt;
            // 放入待兑现的奖金池
            lockedAmts += amt;

            console.log("winner:", currWinner, "currCounts:", currCounts);
            console.log("reward amt curr:", amt, "total:", winnerVaults[currWinner]);
        }

        // 未分完的奖励即为平台收益
        uint giftAmt = currAvalBalance - distributeAmt;
        if (giftAmt > 0) {
            winnerVaults[admin] += giftAmt;
        }

        emit Finialize(currRound++, uint256(_country));
    }

    // 奖金兑现
    function claimReward() external {
        uint256 rewards = winnerVaults[msg.sender];
        require(rewards > 0, "nothing to claim!");

        // 玩家领取完奖金置为 0
        winnerVaults[msg.sender] = 0;
        // 从待兑现奖金池中移除该玩家份额
        lockedAmts -= rewards;
        (bool succeed,) = msg.sender.call{value: rewards}("");
        require(succeed, "claim reward failed!");

        console.log("rewards:", rewards);

        emit ClaimReward(msg.sender, rewards);
    }

    // 获取奖池金额
    function getVaultBalance() public view returns(uint256 bal) {
        bal = address(this).balance;
    }

    // 获取当期下注当前球队的人数
    function getCountryPlayers(uint8 _round, Country _country) external view returns(uint256) {
        return countryToPlayers[_round][_country].length;
    }

    // 获取当前玩家当期押注份额
    function getPlayerInfo(uint8 _round, address _player, Country _country) external view returns(uint256 _counts) {
        return players[_round][_player].counts[_country];
    }
}

到了这里,关于世界杯竞猜项目Dapp-第一章(合约开发)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • P2719 搞笑世界杯 (期望dp

    考虑一种票全部卖完,另一种有大于等于2 张的所有情况都为合理情况 dp[i][j]  可以 等概率的转移到 dp[i-1][j] 和 dp[j][i-1]

    2024年02月09日
    浏览(39)
  • 【疯狂世界杯】css 动画实现跳动的足球

    💖 作者简介:大家好,我是阿牛,全栈领域优质创作者😜 📝 个人主页:馆主阿牛🔥 🎉 支持我:点赞👍+收藏⭐️+留言📝 📣 系列专栏:前端实用小demo🍁 💬格言:迄今所有人生都大写着失败,但不妨碍我继续向前!🔥 2022卡塔尔世界杯正在如火如荼的进行之中,作为

    2024年02月02日
    浏览(40)
  • 世界杯直播 | 抖音视频编码器优化

    动手点关注 干货不迷路 对于世界杯这样的大型体育赛事而言,视频编码算法既要在高速运动、复杂纹理的场景下确保直播内容的清晰度和流畅度,保障用户的观赛体验,又要兼顾码率、延迟等对网络传输层面尤为敏感的指标。 另外,抖音实现了业界首次的世界杯比赛支持

    2023年04月09日
    浏览(54)
  • 数据分析案例-往届世界杯数据可视化

    目录 1.引言 2.项目简介 2.1数据集介绍 2.2技术工具 3.数据可视化 3.1往届世界杯获奖国家TOP5 3.2往届世界杯比赛数据情况 3.3往届世界杯观众人数情况 3.4往届世界杯主办方情况  3.5往届世界杯冠军队情况 足球是世界上非常受欢迎的运动之一,在全球范围内吸引了众多的参与者。

    2024年02月09日
    浏览(62)
  • 世界杯直播背后的服务器(云计算体系)

    世界杯直播过程中,各大网络平台流媒体app上最大的变化毫无疑问就是零延迟。以前球迷看球是都会发现,网络直播的球赛会比电视播出的球赛延迟40s左右。如果群里有个看电视的兄弟兄弟每个进球他都能提前40秒预告给你,那么所有惊喜荡然无存。 这种情况产生,就是因为

    2023年04月08日
    浏览(38)
  • NFT+体育,卡塔尔世界杯有哪些NFT看点!

    有人说没有冷门的世界杯不是真正的世界杯!11月22日,卡塔尔世界杯小组赛C组第1轮比赛中,沙特爆冷2:1逆转阿根廷队,成了今年世界杯的第一个冷门。世界排名第51位的沙特队战胜了排名第3的阿根廷队,结束了阿根廷队此前的36场国际比赛不败纪录。为庆祝这一胜利,沙特

    2024年02月02日
    浏览(39)
  • 基于Flask+Bootstrap+机器学习的世界杯比赛预测系统

    🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 目录 一、项目介绍 1.1项目简介 1.2技术工具 1.3页面概述  二、项目步骤 2.1首页模块 2.2查看

    2024年02月09日
    浏览(47)
  • 微信小程序|使用小程序制作一个世界杯球员识别工具

    四年一次的世界杯正在卡塔尔进行着,不同的社交圈也在疯狂的刷着世界杯的动态,来自全球各地的三十二支队伍的球员是否让你看的眼花缭乱呢? 当朋友跟你聊起昨晚那场比赛

    2024年01月16日
    浏览(42)
  • 一零六四、世界杯数据可视化分析(阿里云天池赛)

    目录 赛制官方链接 活动背景 活动时间:即日起-12月31日17点 数据说明 世界杯成绩信息表:WorldCupsSummary 世界杯比赛比分汇总表:WorldCupMatches.csv 世界杯球员信息表:WorldCupPlayers.csv  代码实现 赛制官方链接 世界杯数据可视化分析_学习赛_天池大赛-阿里云天池 活动背景 2022世界

    2024年02月16日
    浏览(42)
  • 沉睡者 - 在世界杯之前,看“去中心化Betting协议层”

    2022 年 11 月将临的世界杯赛事,正在给加密领域带来更多期待。 上周 Binance 上线足球粉丝 Token 指数 U 本位永续合约,就是一个很好的信号,合约标的指数用于追踪在该平台现货市场上一系列头部市值的足球粉丝 Token 的表现。 加密领域与世界杯赛事密切相关的不仅仅只有粉丝

    2024年01月16日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包