From 0e807a2115ef09669c9187e2d65befd75e3f78de Mon Sep 17 00:00:00 2001 From: yekai1003 Date: Wed, 16 Jun 2021 21:27:38 +0800 Subject: [PATCH 1/6] add redpacket --- .../business_template/redpacket/IERC20.sol | 20 ++++ .../business_template/redpacket/SafeMath.sol | 65 +++++++++++++ .../business_template/redpacket/mytoken.sol | 95 +++++++++++++++++++ .../business_template/redpacket/proxy.sol | 36 +++++++ .../business_template/redpacket/redpacket.sol | 72 ++++++++++++++ 5 files changed, 288 insertions(+) create mode 100644 contracts/business_template/redpacket/IERC20.sol create mode 100644 contracts/business_template/redpacket/SafeMath.sol create mode 100644 contracts/business_template/redpacket/mytoken.sol create mode 100644 contracts/business_template/redpacket/proxy.sol create mode 100644 contracts/business_template/redpacket/redpacket.sol diff --git a/contracts/business_template/redpacket/IERC20.sol b/contracts/business_template/redpacket/IERC20.sol new file mode 100644 index 00000000..d4c7a28f --- /dev/null +++ b/contracts/business_template/redpacket/IERC20.sol @@ -0,0 +1,20 @@ +pragma solidity^0.6.0; + +//定义接口 +interface IERC20 { + + function name() external view returns (string memory); + function symbol() external view returns (string memory); + function totalSupply() external view returns (uint256); + function balanceOf(address _owner) external view returns (uint256 balance); + function transfer(address _to, uint256 _value) external returns (bool success); + function approve(address _spender, uint256 _value) external returns (bool success); + function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); + function allowance(address _owner, address _spender) external view returns (uint256 remaining); + + + + event Transfer(address indexed _from, address indexed _to, uint256 _value); + event Approval(address indexed _owner, address indexed _spender, uint256 _value); + +} \ No newline at end of file diff --git a/contracts/business_template/redpacket/SafeMath.sol b/contracts/business_template/redpacket/SafeMath.sol new file mode 100644 index 00000000..27b391bc --- /dev/null +++ b/contracts/business_template/redpacket/SafeMath.sol @@ -0,0 +1,65 @@ +pragma solidity ^0.6.0; + +/** + * @title SafeMath + * @dev Math operations with safety checks that revert on error + */ +library SafeMath { + + /** + * @dev Multiplies two numbers, reverts on overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b); + + return c; + } + + /** + * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + require(b > 0); // Solidity only automatically asserts when dividing by 0 + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + + return c; + } + + /** + * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + require(b <= a); + uint256 c = a - b; + + return c; + } + + /** + * @dev Adds two numbers, reverts on overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a); + + return c; + } + + /** + * @dev Divides two numbers and returns the remainder (unsigned integer modulo), + * reverts when dividing by zero. + */ + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + require(b != 0); + return a % b; + } +} \ No newline at end of file diff --git a/contracts/business_template/redpacket/mytoken.sol b/contracts/business_template/redpacket/mytoken.sol new file mode 100644 index 00000000..13c5b2e4 --- /dev/null +++ b/contracts/business_template/redpacket/mytoken.sol @@ -0,0 +1,95 @@ +pragma solidity^0.6.0; + +import "./IERC20.sol"; +import "./SafeMath.sol"; + + +//定义接口 +contract mytoken is IERC20 { + using SafeMath for uint256; + //定义name + string tokenName; + string tokenSymbol; + uint256 tokenTotalSupply; + address owner; + //user's balance + mapping(address=>uint256) balances; + // A->B = 100 A->C 200 + mapping(address=>mapping(address=>uint256)) allows; + + constructor(string memory n, string memory s) public { + tokenName = n; + tokenSymbol = s; + owner = msg.sender; + } + + function mint(address _to, uint256 _value) external returns (bool success) { + require(_value > 0, "_value must > 0"); + require(address(0) != _to, "to must a valid address"); + require(msg.sender == owner, "only owner can do"); + + //balances[_to] += _value; + balances[_to] = balances[_to].add(_value); + //tokenTotalSupply += _value; + tokenTotalSupply = tokenTotalSupply.add(_value); + emit Transfer(address(0), _to, _value); + success = true; + } + + function name() override external view returns (string memory) { + return tokenName; + } + function symbol() override external view returns (string memory) { + return tokenSymbol; + } + function totalSupply() override external view returns (uint256) { + return tokenTotalSupply; + } + function balanceOf(address _owner) override external view returns (uint256 balance) { + return balances[_owner]; + } + function transfer(address _to, uint256 _value) override external returns (bool success) { + require(_value > 0, "_value must > 0"); + require(address(0) != _to, "to must a valid address"); + require(balances[msg.sender] >= _value, "user's balance must enough"); + + //balances[msg.sender] -= _value; + balances[msg.sender] = balances[msg.sender].sub(_value); + //balances[_to] += _value; + balances[_to] = balances[_to].add(_value); + + emit Transfer(msg.sender, _to, _value); + return true; + } + function approve(address _spender, uint256 _value) override external returns (bool success) { + success = false; + require(_value > 0, "_value must > 0"); + require(address(0) != _spender, "_spender must a valid address"); + require(balances[msg.sender] >= _value, "user's balance must enough"); + + allows[msg.sender][_spender] = _value; + + emit Approval(msg.sender, _spender, _value); + success = true; + return true; + } + function transferFrom(address _from, address _to, uint256 _value) override external returns (bool success) { + require(_value > 0, "_value must > 0"); + require(address(0) != _to, "to must a valid address"); + require(balances[_from] >= _value, "user's balance must enough"); + + //balances[_from] -= _value; + balances[_from] = balances[_from].sub(_value); + //balances[_to] += _value; + balances[_to] = balances[_to].add(_value); + //allows[_from][msg.sender] -= _value; + allows[_from][msg.sender] = allows[_from][msg.sender].sub(_value); + + success = true; + emit Transfer(_from, _to, _value); + } + function allowance(address _owner, address _spender) override external view returns (uint256 remaining) { + return allows[_owner][_spender]; + } + +} \ No newline at end of file diff --git a/contracts/business_template/redpacket/proxy.sol b/contracts/business_template/redpacket/proxy.sol new file mode 100644 index 00000000..2c728229 --- /dev/null +++ b/contracts/business_template/redpacket/proxy.sol @@ -0,0 +1,36 @@ +pragma solidity^0.6.0; +import "./IERC20.sol"; + +//负责接受token合约的授权,以完成token转移 +contract proxy { + IERC20 token; + address owner; + constructor() public { + owner = msg.sender; + } + + modifier onlyOwner() { + require(msg.sender == owner, "only owner can do"); + _; + } + + function setTokenAddr(address _addr) public onlyOwner { + token = IERC20(_addr); + } + + function transfer(address _from, address _to, uint256 _value) external returns (bool success) { + token.transferFrom(_from, _to, _value); + } + + function allowance(address _from) public view returns (uint256) { + return token.allowance(_from, address(this)); + } + + function balanceOf(address _who) public view returns (uint256) { + return token.balanceOf(_who); + } + + function addr() public view returns (address) { + return address(this); + } +} \ No newline at end of file diff --git a/contracts/business_template/redpacket/redpacket.sol b/contracts/business_template/redpacket/redpacket.sol new file mode 100644 index 00000000..e062939b --- /dev/null +++ b/contracts/business_template/redpacket/redpacket.sol @@ -0,0 +1,72 @@ +pragma solidity^0.6.0; +import "./proxy.sol"; + +contract redpacket { + //定义土豪 + address theRich; + //定义红包的数据 + uint256 public totalAmount;//红包金额 + uint256 public leftAmount;//剩余金额 + uint256 public count;//红包数量 + bool isEqual;//是否等额 + proxy proxyContract;//红包的合约地址 + using SafeMath for uint256; + //抢过了不能再抢 + mapping(address=>bool) isGrabed; + + //构造函数:土豪执行,顺带将红包也发了 + constructor() public { + proxyContract = new proxy();//创建代理合约对象 + + } + + //调用前,用户需要先调用token合约的授权给本合约 + function sendRedPacket(uint256 c, bool ok, address addr, uint256 amount) public { + require(count == 0, "the red packet already exists"); + require(address(0) != addr, "addr is 0"); + require(amount > 0, "amount is 0"); + require(c > 0, "c is 0"); + isEqual = ok; + count = c; + proxyContract.setTokenAddr(addr);//绑定要发送的token合约地址 + require(proxyContract.balanceOf(msg.sender) > 0, "user's balance not enough"); + leftAmount = totalAmount = amount; + theRich = msg.sender; + + + } + + //抢红包 + function grabRedpacket() public { + require(count > 0, "count must > 0"); + require(leftAmount > 0, "leftAmount must > 0"); + require(!isGrabed[msg.sender], "msg.sender must has not grabed"); + isGrabed[msg.sender] = true; + + //如果是最后一个红包-- 直接拿走 + if(count == 1) { + proxyContract.transfer(theRich, msg.sender, leftAmount); + leftAmount = 0; + } else { + //是否为等额 + if(isEqual) { + uint256 amount = leftAmount / count; + leftAmount = leftAmount.sub(amount); + proxyContract.transfer(theRich, msg.sender, amount); + } else { + //计算一个10以内的随机值 + uint256 random = uint256(keccak256(abi.encode(msg.sender, theRich, count, leftAmount, now))) % 8 + 1; + uint256 amount = totalAmount * random / 10; + proxyContract.transfer(theRich, msg.sender, amount); + leftAmount = leftAmount.sub(amount); + + } + } + count --; + + } + + function getProxy() public view returns (address) { + return proxyContract.addr(); + } +} \ No newline at end of file From a3cf8025e504d0f14dc295cd3d4c8d219bda133e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E9=87=8E?= Date: Thu, 17 Jun 2021 11:54:53 +0800 Subject: [PATCH 2/6] add redpacket.md --- docs/business_template/redpacket.md | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 docs/business_template/redpacket.md diff --git a/docs/business_template/redpacket.md b/docs/business_template/redpacket.md new file mode 100644 index 00000000..9f2f3922 --- /dev/null +++ b/docs/business_template/redpacket.md @@ -0,0 +1,41 @@ +## 土豪发红包背景说明 + +发红包是现实中常见的一种生活方式,本方案是将原本发红包使用的现金,替换成了ERC20标准的token。 + +## 场景说明 + +具体业务场景也可以是商家发放的优惠券,代金券等等。 + +## 接口 + +提供了3+2个合约:其中3个合约为目前标准化合约,分别是IERC20接口,mytoken(token的一个模拟实现),SafeMath(安全计算库),另外2个合约是主要逻辑合约,redpacket合约和proxy合约。其中proxy合约是对外接受统一的token授权服务,为辅助合约,redpacket为发红包合约。 + +proxy合约:接受外部token授权的唯一接口。包含: + - setTokenAddr(address _addr): 设置token合约地址,_addr为一个已经部署的token合约地址 + - transfer(address _from, address _to, uint256 _value): 转账合约,完成抢红包动作时的转账操作 + - addr():返回本合约地址 + - balanceOf(address _who): 获取用户的token余额 + - allowance(address _from): 获取_from授权给本合约的额度 + +redpacket合约:红包合约。包含: + - getProxy(): 获取proxy地址 + - transfer(address _from, address _to, uint256 _value): 转账合约,完成抢红包动作时的转账操作 + - sendRedPacket(uint256 c, bool ok, address addr, uint256 amount):发红包动作,c代表数量,ok代表是否等额,addr为要发送的红包token地址,amount代表红包数量 + - grabRedpacket(): 抢红包动作 + + +## 使用示例 + +假如现在要执行一个发红包、抢红包动作,整个过程如下: + +合约初始化: + + - token合约已经部署,并且“土豪”用户已经拥有一定数量的token + - 部署redpacket合约 + + +合约调用: + + - 利用redpacket合约获取proxy地址,在token合约中“土豪”调用approve给proxy地址 + - “土豪”在redpacket合约中执行sendRedPacket,指定红包的数量、方式、token地址以及金额 + - 其他用户执行grabRedpacket抢红包 \ No newline at end of file From 95359e325f9c34a988b44f2457001c9d51731dab Mon Sep 17 00:00:00 2001 From: yekai1003 Date: Thu, 17 Jun 2021 11:58:48 +0800 Subject: [PATCH 3/6] solc change to 0.6.10 --- contracts/business_template/redpacket/IERC20.sol | 2 +- contracts/business_template/redpacket/SafeMath.sol | 2 +- contracts/business_template/redpacket/mytoken.sol | 2 +- contracts/business_template/redpacket/proxy.sol | 2 +- contracts/business_template/redpacket/redpacket.sol | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/business_template/redpacket/IERC20.sol b/contracts/business_template/redpacket/IERC20.sol index d4c7a28f..1ce7afc7 100644 --- a/contracts/business_template/redpacket/IERC20.sol +++ b/contracts/business_template/redpacket/IERC20.sol @@ -1,4 +1,4 @@ -pragma solidity^0.6.0; +pragma solidity^0.6.10; //定义接口 interface IERC20 { diff --git a/contracts/business_template/redpacket/SafeMath.sol b/contracts/business_template/redpacket/SafeMath.sol index 27b391bc..f6b807ed 100644 --- a/contracts/business_template/redpacket/SafeMath.sol +++ b/contracts/business_template/redpacket/SafeMath.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.6.0; +pragma solidity ^0.6.10; /** * @title SafeMath diff --git a/contracts/business_template/redpacket/mytoken.sol b/contracts/business_template/redpacket/mytoken.sol index 13c5b2e4..0769b083 100644 --- a/contracts/business_template/redpacket/mytoken.sol +++ b/contracts/business_template/redpacket/mytoken.sol @@ -1,4 +1,4 @@ -pragma solidity^0.6.0; +pragma solidity^0.6.10; import "./IERC20.sol"; import "./SafeMath.sol"; diff --git a/contracts/business_template/redpacket/proxy.sol b/contracts/business_template/redpacket/proxy.sol index 2c728229..6bdb1f2a 100644 --- a/contracts/business_template/redpacket/proxy.sol +++ b/contracts/business_template/redpacket/proxy.sol @@ -1,4 +1,4 @@ -pragma solidity^0.6.0; +pragma solidity^0.6.10; import "./IERC20.sol"; //负责接受token合约的授权,以完成token转移 diff --git a/contracts/business_template/redpacket/redpacket.sol b/contracts/business_template/redpacket/redpacket.sol index e062939b..f8a8ac3a 100644 --- a/contracts/business_template/redpacket/redpacket.sol +++ b/contracts/business_template/redpacket/redpacket.sol @@ -1,4 +1,4 @@ -pragma solidity^0.6.0; +pragma solidity^0.6.10; import "./proxy.sol"; contract redpacket { From 97c7baa231066819add1ac5332860d61d16be398 Mon Sep 17 00:00:00 2001 From: yekai1003 Date: Thu, 17 Jun 2021 16:44:30 +0800 Subject: [PATCH 4/6] modity token->point --- .../redpacket/{mytoken.sol => mypoints.sol} | 23 +++++++++---------- .../business_template/redpacket/proxy.sol | 14 +++++------ .../business_template/redpacket/redpacket.sol | 5 ++-- docs/business_template/redpacket.md | 18 +++++++-------- 4 files changed, 30 insertions(+), 30 deletions(-) rename contracts/business_template/redpacket/{mytoken.sol => mypoints.sol} (89%) diff --git a/contracts/business_template/redpacket/mytoken.sol b/contracts/business_template/redpacket/mypoints.sol similarity index 89% rename from contracts/business_template/redpacket/mytoken.sol rename to contracts/business_template/redpacket/mypoints.sol index 0769b083..054b52ad 100644 --- a/contracts/business_template/redpacket/mytoken.sol +++ b/contracts/business_template/redpacket/mypoints.sol @@ -5,12 +5,12 @@ import "./SafeMath.sol"; //定义接口 -contract mytoken is IERC20 { +contract mypoints is IERC20 { using SafeMath for uint256; //定义name - string tokenName; - string tokenSymbol; - uint256 tokenTotalSupply; + string pointName; + string pointSymbol; + uint256 pointTotalSupply; address owner; //user's balance mapping(address=>uint256) balances; @@ -18,8 +18,8 @@ contract mytoken is IERC20 { mapping(address=>mapping(address=>uint256)) allows; constructor(string memory n, string memory s) public { - tokenName = n; - tokenSymbol = s; + pointName = n; + pointSymbol = s; owner = msg.sender; } @@ -28,22 +28,21 @@ contract mytoken is IERC20 { require(address(0) != _to, "to must a valid address"); require(msg.sender == owner, "only owner can do"); - //balances[_to] += _value; + balances[_to] = balances[_to].add(_value); - //tokenTotalSupply += _value; - tokenTotalSupply = tokenTotalSupply.add(_value); + pointTotalSupply = pointTotalSupply.add(_value); emit Transfer(address(0), _to, _value); success = true; } function name() override external view returns (string memory) { - return tokenName; + return pointName; } function symbol() override external view returns (string memory) { - return tokenSymbol; + return pointSymbol; } function totalSupply() override external view returns (uint256) { - return tokenTotalSupply; + return pointTotalSupply; } function balanceOf(address _owner) override external view returns (uint256 balance) { return balances[_owner]; diff --git a/contracts/business_template/redpacket/proxy.sol b/contracts/business_template/redpacket/proxy.sol index 6bdb1f2a..a4a08350 100644 --- a/contracts/business_template/redpacket/proxy.sol +++ b/contracts/business_template/redpacket/proxy.sol @@ -1,9 +1,9 @@ pragma solidity^0.6.10; import "./IERC20.sol"; -//负责接受token合约的授权,以完成token转移 +//负责接受积分合约的授权,以完成积分转移 contract proxy { - IERC20 token; + IERC20 point; address owner; constructor() public { owner = msg.sender; @@ -14,20 +14,20 @@ contract proxy { _; } - function setTokenAddr(address _addr) public onlyOwner { - token = IERC20(_addr); + function setPointAddr(address _addr) public onlyOwner { + point = IERC20(_addr); } function transfer(address _from, address _to, uint256 _value) external returns (bool success) { - token.transferFrom(_from, _to, _value); + point.transferFrom(_from, _to, _value); } function allowance(address _from) public view returns (uint256) { - return token.allowance(_from, address(this)); + return point.allowance(_from, address(this)); } function balanceOf(address _who) public view returns (uint256) { - return token.balanceOf(_who); + return point.balanceOf(_who); } function addr() public view returns (address) { diff --git a/contracts/business_template/redpacket/redpacket.sol b/contracts/business_template/redpacket/redpacket.sol index f8a8ac3a..0e8d0799 100644 --- a/contracts/business_template/redpacket/redpacket.sol +++ b/contracts/business_template/redpacket/redpacket.sol @@ -1,4 +1,5 @@ pragma solidity^0.6.10; +import "./SafeMath.sol"; import "./proxy.sol"; contract redpacket { @@ -20,7 +21,7 @@ contract redpacket { } - //调用前,用户需要先调用token合约的授权给本合约 + //调用前,用户需要先调用积分合约的授权给本合约 function sendRedPacket(uint256 c, bool ok, address addr, uint256 amount) public { require(count == 0, "the red packet already exists"); require(address(0) != addr, "addr is 0"); @@ -28,7 +29,7 @@ contract redpacket { require(c > 0, "c is 0"); isEqual = ok; count = c; - proxyContract.setTokenAddr(addr);//绑定要发送的token合约地址 + proxyContract.setPointAddr(addr);//绑定要发送的积分合约地址 require(proxyContract.balanceOf(msg.sender) > 0, "user's balance not enough"); leftAmount = totalAmount = amount; theRich = msg.sender; diff --git a/docs/business_template/redpacket.md b/docs/business_template/redpacket.md index 9f2f3922..aed8ecc3 100644 --- a/docs/business_template/redpacket.md +++ b/docs/business_template/redpacket.md @@ -1,6 +1,6 @@ ## 土豪发红包背景说明 -发红包是现实中常见的一种生活方式,本方案是将原本发红包使用的现金,替换成了ERC20标准的token。 +发红包是现实中常见的一种生活方式,本方案是将原本发红包使用的现金,替换成了ERC20标准的积分。 ## 场景说明 @@ -8,19 +8,19 @@ ## 接口 -提供了3+2个合约:其中3个合约为目前标准化合约,分别是IERC20接口,mytoken(token的一个模拟实现),SafeMath(安全计算库),另外2个合约是主要逻辑合约,redpacket合约和proxy合约。其中proxy合约是对外接受统一的token授权服务,为辅助合约,redpacket为发红包合约。 +提供了3+2个合约:其中3个合约为目前标准化合约,分别是IERC20接口,mypoints(积分的一个模拟实现),SafeMath(安全计算库),另外2个合约是主要逻辑合约,redpacket合约和proxy合约。其中proxy合约是对外接受统一的积分授权服务,为辅助合约,redpacket为发红包合约。 -proxy合约:接受外部token授权的唯一接口。包含: - - setTokenAddr(address _addr): 设置token合约地址,_addr为一个已经部署的token合约地址 +proxy合约:接受外部积分授权的唯一接口。包含: + - setPointAddr(address _addr): 设置积分合约地址,_addr为一个已经部署的积分合约地址 - transfer(address _from, address _to, uint256 _value): 转账合约,完成抢红包动作时的转账操作 - addr():返回本合约地址 - - balanceOf(address _who): 获取用户的token余额 + - balanceOf(address _who): 获取用户的积分余额 - allowance(address _from): 获取_from授权给本合约的额度 redpacket合约:红包合约。包含: - getProxy(): 获取proxy地址 - transfer(address _from, address _to, uint256 _value): 转账合约,完成抢红包动作时的转账操作 - - sendRedPacket(uint256 c, bool ok, address addr, uint256 amount):发红包动作,c代表数量,ok代表是否等额,addr为要发送的红包token地址,amount代表红包数量 + - sendRedPacket(uint256 c, bool ok, address addr, uint256 amount):发红包动作,c代表数量,ok代表是否等额,addr为要发送的红包积分地址,amount代表红包数量 - grabRedpacket(): 抢红包动作 @@ -30,12 +30,12 @@ redpacket合约:红包合约。包含: 合约初始化: - - token合约已经部署,并且“土豪”用户已经拥有一定数量的token + - 积分合约已经部署,并且“土豪”用户已经拥有一定数量的积分 - 部署redpacket合约 合约调用: - - 利用redpacket合约获取proxy地址,在token合约中“土豪”调用approve给proxy地址 - - “土豪”在redpacket合约中执行sendRedPacket,指定红包的数量、方式、token地址以及金额 + - 利用redpacket合约获取proxy地址,在积分合约中“土豪”调用approve给proxy地址授权 + - “土豪”在redpacket合约中执行sendRedPacket,指定红包的数量、方式、积分地址以及金额 - 其他用户执行grabRedpacket抢红包 \ No newline at end of file From 5495e4625aed739b836f3778301b88d5dab690fe Mon Sep 17 00:00:00 2001 From: yekai1003 Date: Fri, 18 Jun 2021 20:19:20 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=90=88=E7=BA=A6?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=AD=A5=E9=AA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/business_template/redpacket.md | 256 ++++++++++++++++++++++++++-- 1 file changed, 238 insertions(+), 18 deletions(-) diff --git a/docs/business_template/redpacket.md b/docs/business_template/redpacket.md index aed8ecc3..99230281 100644 --- a/docs/business_template/redpacket.md +++ b/docs/business_template/redpacket.md @@ -1,41 +1,261 @@ ## 土豪发红包背景说明 + + 发红包是现实中常见的一种生活方式,本方案是将原本发红包使用的现金,替换成了ERC20标准的积分。 + + ## 场景说明 + + 具体业务场景也可以是商家发放的优惠券,代金券等等。 + + ## 接口 + + 提供了3+2个合约:其中3个合约为目前标准化合约,分别是IERC20接口,mypoints(积分的一个模拟实现),SafeMath(安全计算库),另外2个合约是主要逻辑合约,redpacket合约和proxy合约。其中proxy合约是对外接受统一的积分授权服务,为辅助合约,redpacket为发红包合约。 + + proxy合约:接受外部积分授权的唯一接口。包含: - - setPointAddr(address _addr): 设置积分合约地址,_addr为一个已经部署的积分合约地址 - - transfer(address _from, address _to, uint256 _value): 转账合约,完成抢红包动作时的转账操作 - - addr():返回本合约地址 - - balanceOf(address _who): 获取用户的积分余额 - - allowance(address _from): 获取_from授权给本合约的额度 + +- setPointAddr(address _addr): 设置积分合约地址,_addr为一个已经部署的积分合约地址 + +- transfer(address _from, address _to, uint256 _value): 转账合约,完成抢红包动作时的转账操作 + +- addr():返回本合约地址 + +- balanceOf(address _who): 获取用户的积分余额 + +- allowance(address _from): 获取_from授权给本合约的额度 + + redpacket合约:红包合约。包含: - - getProxy(): 获取proxy地址 - - transfer(address _from, address _to, uint256 _value): 转账合约,完成抢红包动作时的转账操作 - - sendRedPacket(uint256 c, bool ok, address addr, uint256 amount):发红包动作,c代表数量,ok代表是否等额,addr为要发送的红包积分地址,amount代表红包数量 - - grabRedpacket(): 抢红包动作 + +- getProxy(): 获取proxy地址 + +- transfer(address _from, address _to, uint256 _value): 转账合约,完成抢红包动作时的转账操作 + +- sendRedPacket(uint256 c, bool ok, address addr, uint256 amount):发红包动作,c代表数量,ok代表是否等额,addr为要发送的红包积分地址,amount代表红包数量 + +- grabRedpacket(): 抢红包动作 + + + ## 使用示例 + + +当前控制台视图下,可以看到redpacket目录内文件如下: + +```sh +parallels@parallels-vm:~/fisco/newconcole/console-0.6$ tree contracts/solidity/redpacket/ +contracts/solidity/redpacket/ +├── IERC20.sol +├── mypoints.sol +├── proxy.sol +├── redpacket.sol +└── SafeMath.sol +``` + + + 假如现在要执行一个发红包、抢红包动作,整个过程如下: -合约初始化: - - 积分合约已经部署,并且“土豪”用户已经拥有一定数量的积分 - - 部署redpacket合约 - - -合约调用: - - 利用redpacket合约获取proxy地址,在积分合约中“土豪”调用approve给proxy地址授权 - - “土豪”在redpacket合约中执行sendRedPacket,指定红包的数量、方式、积分地址以及金额 - - 其他用户执行grabRedpacket抢红包 \ No newline at end of file +### 1. 合约初始化: + +需要先部署积分合约,再部署redpacket合约。 + + + +####1.1 需要先部署积分合约,并且给“土豪”发一点积分 + +部署积分合约 + +```sh +[group:1]> deploy contracts/solidity/redpacket/mypoints.sol ykc ykc +transaction hash: 0x8c7914c8023955690b2519e3b571d6bba7a47ca7a54c499f065a3161876aea08 +contract address: 0xdc9f277d4b706f0e8e4ce4c3b94a726ee716368f +currentAccount: 0x126235d39382170c8aafacfd1f430610190d8de9 +``` + +给“土豪”发一点积分 + +```sh +[group:1]> listAccount +0x126235d39382170c8aafacfd1f430610190d8de9(current account) <= +0xf6e254e6bd8c7d6799dd72d30fa440a8bf06a39f + +[group:1]> call contracts/solidity/redpacket/mypoints.sol 0xdc9f277d4b706f0e8e4ce4c3b94a726ee716368f mint 0x126235d39382170c8aafacfd1f430610190d8de9 100000 +transaction hash: 0x80838424fdfe33d69bafc6d67f185b2a7a754f8697b567f373697e1274e6d365 +--------------------------------------------------------------------------------------------- +transaction status: 0x0 +description: transaction executed successfully +--------------------------------------------------------------------------------------------- +Receipt message: Success +Return message: Success +Return value size:1 +Return types: (BOOL) +Return values:(true) +--------------------------------------------------------------------------------------------- +Event logs +Event: {"Transfer":[[100000]]} +``` + + + + + +####1.2 部署redpacket合约 + +部署redpacket合约 + +```sh +[group:1]> deploy contracts/solidity/redpacket/redpacket.sol +transaction hash: 0x6df39b0423a48b9cf89518b90623a796be1d36bb36c559ad9045af55e7106310 +contract address: 0x8f671f69efab33437123b02701560ee80546b9e8 +currentAccount: 0x126235d39382170c8aafacfd1f430610190d8de9 +``` + + + +### 2. 合约调用 + + + +#### 2.1 获取proxy地址 + +```sh +[group:1]> call contracts/solidity/redpacket/redpacket.sol 0x8f671f69efab33437123b02701560ee80546b9e8 getProxy +--------------------------------------------------------------------------------------------- +Return code: 0 +description: transaction executed successfully +Return message: Success +--------------------------------------------------------------------------------------------- +Return value size:1 +Return types: (ADDRESS) +Return values:(0x66e6fbb2cf7bf635653db398de624c09c2cd52cf) +--------------------------------------------------------------------------------------------- +``` + +#### 2.2 土豪调用积分授权合约 + +在这里要用到前一步获得的proxy合约地址,土豪将自己的积分授权给proxy合约。 + +```sh +[group:1]> call contracts/solidity/redpacket/mypoints.sol 0xdc9f277d4b706f0e8e4ce4c3b94a726ee716368f approve 0x66e6fbb2cf7bf635653db398de624c09c2cd52cf 1000 +transaction hash: 0xc8b0e6b93630751e68f6ae7a20e61ae0df1b22b8548944ea9e0806950b7a2deb +--------------------------------------------------------------------------------------------- +transaction status: 0x0 +description: transaction executed successfully +--------------------------------------------------------------------------------------------- +Receipt message: Success +Return message: Success +Return value size:1 +Return types: (BOOL) +Return values:(true) +--------------------------------------------------------------------------------------------- +Event logs +Event: {"Approval":[[1000]]} +``` + + + +#### 2.3 土豪执行发红包动作 + +这里说的“土豪”实际上是控制台的默认账户。 + +这一步,需要调用redpacket合约中的sendRedPacket,需要传给它的参数是:红包数量,是否等值红包,积分合约地址,红包总金额 + +```sh +[group:1]> call contracts/solidity/redpacket/redpacket.sol 0x8f671f69efab33437123b02701560ee80546b9e8 sendRedPacket 4 true 0xdc9f277d4b706f0e8e4ce4c3b94a726ee716368f 1000 +transaction hash: 0x0416c14b18fac4b3cebbf07d4e85b2146002f97e95d16eb7411cc1a92ba540c2 +--------------------------------------------------------------------------------------------- +transaction status: 0x0 +description: transaction executed successfully +--------------------------------------------------------------------------------------------- +Receipt message: Success +Return message: Success +Return values:[] +--------------------------------------------------------------------------------------------- +Event logs +Event: {} +``` + +#### 2.4 切换另外一个用户抢红包 + +先切换一下调用用户,使用loadAccount可以完成此操作。 + +```sh +[group:1]> listAccount +0x126235d39382170c8aafacfd1f430610190d8de9(current account) <= +0xf6e254e6bd8c7d6799dd72d30fa440a8bf06a39f + +[group:1]> loadAccount 0xf6e254e6bd8c7d6799dd72d30fa440a8bf06a39f +Load account 0xf6e254e6bd8c7d6799dd72d30fa440a8bf06a39f success! + +[group:1]> listAccount +0xf6e254e6bd8c7d6799dd72d30fa440a8bf06a39f(current account) <= +0x126235d39382170c8aafacfd1f430610190d8de9 +``` + +查询当前账户的余额 + +```sh +[group:1]> call contracts/solidity/redpacket/mypoints.sol 0xdc9f277d4b706f0e8e4ce4c3b94a726ee716368f balanceOf 0xf6e254e6bd8c7d6799dd72d30fa440a8bf06a39f +--------------------------------------------------------------------------------------------- +Return code: 0 +description: transaction executed successfully +Return message: Success +--------------------------------------------------------------------------------------------- +Return value size:1 +Return types: (UINT) +Return values:(0) +--------------------------------------------------------------------------------------------- + +``` + +此时,可以调用抢红包方法grabRedpacket + +```sh +[group:1]> call contracts/solidity/redpacket/redpacket.sol 0x8f671f69efab33437123b02701560ee80546b9e8 grabRedpacket +transaction hash: 0x856ee929442b6b7eb6e0d884df63330db59a2ccbcd37ccf3ea15c53821205225 +--------------------------------------------------------------------------------------------- +transaction status: 0x0 +description: transaction executed successfully +--------------------------------------------------------------------------------------------- +Receipt message: Success +Return message: Success +Return values:[] +--------------------------------------------------------------------------------------------- +Event logs +Event: {} + +``` + +再次查看当前账户的余额,发现变为了250。 + +```sh +[group:1]> call contracts/solidity/redpacket/mypoints.sol 0xdc9f277d4b706f0e8e4ce4c3b94a726ee716368f balanceOf 0xf6e254e6bd8c7d6799dd72d30fa440a8bf06a39f +--------------------------------------------------------------------------------------------- +Return code: 0 +description: transaction executed successfully +Return message: Success +--------------------------------------------------------------------------------------------- +Return value size:1 +Return types: (UINT) +Return values:(250) +--------------------------------------------------------------------------------------------- + +``` + From 9b5dc6a361b7d6b438d625c76a33b836a524e99c Mon Sep 17 00:00:00 2001 From: yekai1003 Date: Fri, 18 Jun 2021 20:23:50 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=90=88=E7=BA=A6?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=AD=A5=E9=AA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/business_template/redpacket.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/business_template/redpacket.md b/docs/business_template/redpacket.md index 99230281..8d90cc35 100644 --- a/docs/business_template/redpacket.md +++ b/docs/business_template/redpacket.md @@ -78,7 +78,7 @@ contracts/solidity/redpacket/ -####1.1 需要先部署积分合约,并且给“土豪”发一点积分 +#### 1.1 需要先部署积分合约,并且给“土豪”发一点积分 部署积分合约 @@ -116,7 +116,7 @@ Event: {"Transfer":[[100000]]} -####1.2 部署redpacket合约 +#### 1.2 部署redpacket合约 部署redpacket合约