乐趣区

关于区块链:经典智能合约案例之发红包

经典智能合约案例:发红包

角色剖析:发红包的人和抢红包的人

功能分析:

  • 发红包:发红包的性能,能够借助构造函数实现,外围是将 ether 打入合约;
  • 抢红包:抢红包的性能,抢胜利须要一些断言判断,外围操作是合约转账给抢红包的人;
  • 退还:当红包有残余的时候,容许发红包的人发出余额,能够用合约销毁来实现;

实现发红包性能

  • 须要一个有领取性能的地址,用于发红包(谁创立合约,谁就是发红包的人)
  • 须要传入一个红包的数量(number),红包的金额从 msg.value 传入
  • 在构造函数中,指定发红包的人和红包数量
  • 须要一个查问红包余额的性能函数(提醒:address(this).balance)

实现抢红包的性能

  • 须要一个给抢红包的人转账的性能函数
  • 函数中须要判断:1. 红包余额大于 0;2. 红包残余个数大于 0;(提醒:断言)
  • 红包数量随着函数执行的次数相应缩小;
  • 抢红包的金额采纳随机的形式(提醒:用 keccak256 函数计算以后工夫戳的哈希),红包的金额是 100 以内的数(提醒:哈希值对 100 取余)
  • 转账性能:msg.sender.transfer(amount)(amount 为金额);

实现退还红包余额

  • 能够借助 selfdestruct 函数,用于销毁合约,其原型如下:

    function selfdestruct(address user)

  • user 代表合约销毁时的受益人;
  • 实现一个 kill 函数,用它来销毁合约,指定发红包的人为受益人;

合约代码:

pragma solidity ^0.6.1;

contract red_pocket{
    uint256 public number;
    address payable public pocket_sender;
    mapping(address => bool) isGot;
    // Send red packets
    // Specify the person and the number of red envelopes
    constructor(uint256 count) public payable{require(msg.value > 0, "msg.value must >0");
        require(count > 0, "count must > 0");
        number = count;
        pocket_sender = msg.sender;
    }

    // Query the balance of the red envelope
    function getBalance() public view returns(uint256){return address(this).balance;
    }

    // GetPocket
    function getPocket() public payable {require(!isGot[msg.sender],"msg.sender must not get");
        require(number > 0, "number must >0");
        require(getBalance() > 0, "getBalance() must > 0");
        uint256 amount = uint256 (keccak256(abi.encode(msg.sender,pocket_sender,now,number)))%100;
        msg.sender.transfer(amount);
        number --;
        isGot[msg.sender] = true;
    }

    // Refund the balance of the red envelope
    function kill() public{selfdestruct(pocket_sender);
    }
}

合约执行截图:

首先 deploy 该红包合约:

在抢红包之前先查问一下相干的信息:

可见总额度为 20230324wei,依照 delpoy,一共是 6 个红包,发送者的地址如下:

而后进行抢红包:

可见,总额度相应缩小,红包的个数也缩小 1。

最初,kill 销毁合约,实现退还红包余额。

退出移动版