分红派息型智能合约其实很好理解,就是给予持币用户或者LP用户一部分的分红,这个分红大多是USDT。在区块链的世界里,可以将每个人分红的比例提前写入智能合约,然后由合约自动分配,这样就大大提高分红的公平性和便利性。具体应该如何创建一个这样的LP分红USDT合约呢?分红合约逻辑分红合约(Pa
<!--StartFragment-->
分红派息型智能合约其实很好理解,就是给予持币用户或者LP用户一部分的分红,这个分红大多是USDT。在区块链的世界里,可以将每个人分红的比例提前写入智能合约,然后由合约自动分配,这样就大大提高分红的公平性和便利性。
具体应该如何创建一个这样的LP分红USDT合约呢? <!--EndFragment-->
<!--StartFragment-->
分红合约(PaymentSplit)具有以下几个特点:
<!--StartFragment-->
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /\*\* \* 分红合约 \* @dev 这个合约会把收到的ETH按事先定好的份额分给几个账户。收到ETH会存在分红合约中,需要每个受益人调用release()函数来领取。 \*/ contract PaymentSplit{
<!--EndFragment-->
分红合约事件
分红合约中共有3个事件:
// 事件 event PayeeAdded(address account, uint256 shares);
// 增加受益人事件 event PaymentReleased(address to, uint256 amount);
// 受益人提款事件 event PaymentReceived(address from, uint256 amount);
// 合约收款事件
<!--StartFragment-->
分红合约中共有5个状态变量,用来记录受益地址、份额、支付出去的ETH等变量:
uint256 public totalShares;
// 总份额
uint256 public totalReleased;
// 总支付 mapping(address => uint256) public shares;
// 每个受益人的份额 mapping(address => uint256) public released;
// 支付给每个受益人的金额 address\[] public payees;
// 受益人数组
<!--StartFragment-->
分红合约中共有6个函数:
<!--EndFragment-->
/**
* @dev 初始化受益人数组_payees和分红份额数组_shares
* 数组长度不能为0,两个数组长度要相等。_shares中元素要大于0,_payees中地址不能为0地址且不能有重复地址
*/
constructor(address[] memory _payees, uint256[] memory _shares) payable {
// 检查_payees和_shares数组长度相同,且不为0
require(_payees.length == _shares.length, "PaymentSplitter: payees and shares length mismatch");
require(_payees.length > 0, "PaymentSplitter: no payees");
// 调用_addPayee,更新受益人地址payees、受益人份额shares和总份额totalShares
for (uint256 i = 0; i < _payees.length; i++) {
_addPayee(_payees[i], _shares[i]);
}
}
/**
* @dev 回调函数,收到ETH释放PaymentReceived事件
*/
receive() external payable virtual {
emit PaymentReceived(msg.sender, msg.value);
}
/**
* @dev 为有效受益人地址_account分帐,相应的ETH直接发送到受益人地址。任何人都可以触发这个函数,但钱会打给account地址。
* 调用了releasable()函数。
*/
function release(address payable _account) public virtual {
// account必须是有效受益人
require(shares[_account] > 0, "PaymentSplitter: account has no shares");
// 计算account应得的eth
uint256 payment = releasable(_account);
// 应得的eth不能为0
require(payment != 0, "PaymentSplitter: account is not due payment");
// 更新总支付totalReleased和支付给每个受益人的金额released
totalReleased += payment;
released[_account] += payment;
// 转账
_account.transfer(payment);
emit PaymentReleased(_account, payment);
}
/**
* @dev 计算一个账户能够领取的eth。
* 调用了pendingPayment()函数。
*/
function releasable(address _account) public view returns (uint256) {
// 计算分红合约总收入totalReceived
uint256 totalReceived = address(this).balance + totalReleased;
// 调用_pendingPayment计算account应得的ETH
return pendingPayment(_account, totalReceived, released[_account]);
}
/**
* @dev 根据受益人地址`_account`, 分红合约总收入`_totalReceived`和该地址已领取的钱`_alreadyReleased`,计算该受益人现在应分的`ETH`。
*/
function pendingPayment(
address _account,
uint256 _totalReceived,
uint256 _alreadyReleased
) public view returns (uint256) {
// account应得的ETH = 总应得ETH - 已领到的ETH
return (_totalReceived * shares[_account]) / totalShares - _alreadyReleased;
}
/**
* @dev 新增受益人_account以及对应的份额_accountShares。只能在构造器中被调用,不能修改。
*/
function _addPayee(address _account, uint256 _accountShares) private {
// 检查_account不为0地址
require(_account != address(0), "PaymentSplitter: account is the zero address");
// 检查_accountShares不为0
require(_accountShares > 0, "PaymentSplitter: shares are 0");
// 检查_account不重复
require(shares[_account] == 0, "PaymentSplitter: account already has shares");
// 更新payees,shares和totalShares
payees.push(_account);
shares[_account] = _accountShares;
totalShares += _accountShares;
// 释放增加受益人事件
emit PayeeAdded(_account, _accountShares);
}
<!--StartFragment-->
<!--EndFragment--> <!--StartFragment-->
在构造函数中,输入两个受益人地址,份额为1和3。
<!--EndFragment-->
<!--StartFragment-->
<!--EndFragment-->
<!--StartFragment-->
<!--EndFragment-->
<!--StartFragment-->
<!--EndFragment--> <!--StartFragment-->
以上是以太坊及兼容链的分红合约实战演练,相关的代码在文章中也已经给出。学会了以太坊的合约逻辑,那么再开发币安智能链、火币智能链等合约的时候就很方便了。
<!--EndFragment-->
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!