基于solidity的抢红包代码

  • chx381
  • 更新于 2022-09-30 21:36
  • 阅读 1514

基于solidity的抢红包代码

基于solidity的抢红包代码

1.实现功能

  1. 发红包人可以设置红包的口令,类型,最多抢红包人数和红包有效时间。
  2. 可以查看某个人的某个红包当前剩余的钱。
  3. 可以查看当前所有红包剩余的钱。
  4. 可以查看当前红包中还有钱的对应的所有发钱包人的地址。
  5. 可以查看某个红包的抢红包结果。
  6. 可以查看某个人(地址)在某个发红包人发的某个红包中抢到了多少钱。
  7. 一个人可以发送多个红包,每个人对同一个红包只能够抢一次。
  8. 好友功能,只有红包拥有者的好友能够抢红包。
  9. 红包需要设置有效期,有效期内好友能够抢红包,有效期过后红包的拥有者能够撤回红包(仅仅在红包的超过有效期后,红包拥有者能够撤回红包)。
  10. 红包合约同时支持存在多个红包,并且任意的人能够调用红包合约不断新添加红包,每个红包对应自己的口令,抢红包的人需要输入该口令才能抢红包。
  11. 支持平分和随机分红包。

    2.原文链接

    题目参考:https://blog.csdn.net/weixin_44858076/article/details/109603051

3.solidity代码

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

contract red_envelope {

    struct redbag {

        uint256 amount;
        uint256 leixing;
        uint256 maxnum;
        uint256 time;
        uint256 left_money;
        bytes32 kouling;
        address sender;
        address[] qiang;
    }

    mapping (address => uint256) countNum;
    mapping (address => mapping(uint256 => redbag)) public whosredbag;

    event Fahongbao(address indexed _sender,uint256 _amount,uint256 _maxnum);
    event BeFriend(address _mine,address _friend);
    event GetRed(address indexed _mine,address _sender,uint256 _whichRB,uint256 _amount);
    event GetRealse(address _sender,uint256 _leftRed,uint256 _nowTime);

    mapping (address => address[]) friend;

    function beFriend(address _friend) public{
        require(!isFriend(_friend,msg.sender),"already friend");
        friend[msg.sender].push(_friend);
        emit BeFriend(msg.sender,_friend);
    }

    function  _countNum(address _Addr) internal returns(uint256 _whichRB){
        countNum[_Addr] += 1;
        _whichRB = countNum[_Addr];
        return _whichRB;
    }

    function getRealse(address _leftRed,uint256 _whichRB) public returns(bool) {
        redbag storage _newSender = whosredbag[_leftRed][_whichRB];
        require(msg.sender == _newSender.sender,"you are not the owner");
        require(_newSender.time < block.timestamp,"time isn't out");
        uint256 _amount = _newSender.left_money;
        _newSender.left_money -= _amount;
        (bool success,) = payable(msg.sender).call{value:_amount}("");
        emit GetRealse(_newSender.sender,_amount,block.timestamp);
        return success;
    }

    function fahongbao(
        uint256 _maxnum,
        uint256 _time,
        bytes32 _kouling,
        uint256 _leixing

    ) public payable
    {
        redbag storage _newSender = whosredbag[msg.sender][_countNum(msg.sender)];
        uint256 _nowTime = block.timestamp;
        _newSender.time = _time + _nowTime;
        _newSender.kouling = _kouling;
        _newSender.amount = msg.value;
        _newSender.sender = msg.sender;
        _newSender.maxnum = _maxnum;
        _newSender.leixing = _leixing;
        _newSender.left_money = msg.value;
        emit Fahongbao(_newSender.sender,_newSender.amount,_newSender.maxnum);
    }

    // 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
    // 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
    // 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db
    // 0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB
    function kouling(string memory _kouling) public pure returns(bytes32 result){
        assembly{
            result := mload(add(_kouling,32))
         }
    }

    function getRed(address _who,bytes32 _kouling,uint256 _whichRB) public returns(bool)  {
        require(isFriend(msg.sender,_who),"not friend");
        redbag storage _newSender = whosredbag[_who][_whichRB];
        require(_kouling == _newSender.kouling);
        require(_newSender.time > block.timestamp,"time is out");
        require(_isqiang(_who,_whichRB));
        if(_newSender.qiang.length == _newSender.maxnum - 1){
            uint256 _amount = _newSender.left_money;
            _newSender.qiang.push(msg.sender);
            _newSender.left_money -= _amount;
            (bool success,) = payable(msg.sender).call{value:_amount}("");
            emit GetRed(msg.sender,_newSender.sender,_whichRB,_amount);
            return success;
        }
        else{uint256 _amount = _perValue(_who,_newSender.leixing,_whichRB);
            _newSender.qiang.push(msg.sender);
            _newSender.left_money -= _amount;
            (bool success,) = payable(msg.sender).call{value:_amount}("");
            emit GetRed(msg.sender,_newSender.sender,_whichRB,_amount);
            return success;
        }

    }

    function _isqiang(address _who,uint256 _whichRB) internal view returns(bool restult) {
        redbag memory _newSender = whosredbag[_who][_whichRB];
        for(uint256 i = 0; i < _newSender.qiang.length;i ++){
            require(msg.sender != _newSender.qiang[i],"you have already done this");
            }
        return true;
    }

    function isFriend(address _mine,address _owner) internal view returns(bool result) {
        for(uint256 i = 0; i < friend[_owner].length;i ++){
            if(_mine == friend[_owner][i]){
                result = true;
            }
        }
        return result;

    }

    function _perValue(address _owner,uint256 _type,uint256 _whichRB) internal view returns(uint256 restult) {
        require(_type < 2,"_type should be 1 or 0");
        redbag memory _newSender = whosredbag[_owner][_whichRB];
        uint256 _amount = _newSender.amount / _newSender.maxnum;
        if(_type == 1){
            return restult = _amount;
        }
        else if(_type == 0){
            return restult = (_random() * _amount) / 50 ;
        }
    }

    function _random() internal view returns(uint256 restult){
        bytes32 randomBytes = keccak256(abi.encodePacked(block.number, msg.sender, blockhash(block.timestamp-1)));
        return restult = (uint(randomBytes) % 100);
    }
}

4.总结

本人为代码小白(刚开始学solidity,求交流和学习途径)+蹩脚英语,目前随机数采用很简单粗暴的途径,也没有对uint256溢出问题进行保护,代码也没有完全参考题目,欢迎各位对代码进行测试,反应存在问题,一起学习交流,谢谢!

点赞 0
收藏 2
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
chx381
chx381
江湖只有他的大名,没有他的介绍。