LOADING

如何开发分红派息合约:附完整代码及实现思路

技术博客1年前 (2023)发布 Dexnav
0

如何开发分红派息合约:附完整代码及实现思路

电报学习交流:DexDao

分红派息型智能合约是一种可以自动分配持币用户或LP用户一部分分红的智能合约,这样做可以提高分红的公平性便利性。在创建合约时,可以将每个受益人的比例提前写入合约,并由合约自动分配。分红合约遵循 Pull Payment 模式,即付款不会自动转入账户,而是保存在此合约中,受益人通过调用 release() 函数触发实际转账。合约的代码和教程也可以在相关网站上找到。

1.创建分红合约
创建分红合约的第一步是在 Solidity IDE 中编写智能合约代码。以下是一个简单的例子,它创建了一个可以在支付时将资金分配给多个受益人的合约。

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

contract PaymentSplit {
    address payable[] payees;
    uint[] shares;

    constructor(address payable[] memory _payees, uint[] memory _shares) payable {
        require(_payees.length == _shares.length, "Payees and shares length mismatch");

        uint totalShares = 0;
        for (uint i = 0; i < _payees.length; i++) {
            require(_payees[i] != address(0), "Payee address cannot be 0");
            require(_shares[i] > 0, "Share must be greater than 0");

            totalShares += _shares[i];
            payees.push(_payees[i]);
            shares.push(_shares[i]);
        }

        require(totalShares == 100, "Total shares must equal 100");
    }

    function release() public {
        for (uint i = 0; i < payees.length; i++) {
            uint payment = address(this).balance * shares[i] / 100;
            payees[i].transfer(payment);
        }
    }

    fallback() external payable {}
}

在这个例子中,我们定义了一个名为 PaymentSplit 的合约,该合约具有一个构造函数和一个名为 release() 的函数。

构造函数接收两个参数:一个 payees 数组和一个 shares 数组,这两个数组都需要是地址和无符号整数的数组。payees 数组中的每个地址都是受益人的地址,而 shares 数组中的每个整数表示相应受益人应获得的份额

在构造函数中,我们首先检查传入参数的有效性,然后计算所有份额的总和,如果不等于 100,则会引发异常。

release() 函数是在受益人要求取款时调用的,它会按照每个受益人的份额从该合约的余额中向他们发送 ETH

2..部署和测试合约
完成智能合约代码后,我们需要在以太坊上部署该合约。有几种方法可以完成这个任务,包括使用 Remix 或 Truffle 等 Solidity IDE。

在合约部署后,我们可以通过在 Remix 或任何以太坊区块链浏览器中调用合约函数来测试它的功能。

分红派息型智能合约为持币用户和 LP 用户提供了一种收入分配的途径,这是一个非常有用的功能。虽然实现一个分红合约需要一些编程知识,但这个过程非常值得。因为这个合约能够自动分配收入,这将大大提高分红的公平性和便利性。

这是一个分红合约,它会按照预先设定的比例将接收到的以太币分配给几个账户。合约将接收到的以太币保存在内部,直到每个受益人调用 release()函数来领取他们的份额。这个合约具有三个事件:PayeeAdded,PaymentReleased和PaymentReceived,用来跟踪合约中增加受益人、受益人提款和收款的情况。此外,这个合约有五个状态变量:totalShares,totalReleased,payees,shares和released,用来记录受益人地址、份额、支付出去的以太币等信息。totalShares代表份额总和,totalReleased代表已支付的总金额,payees是一个地址数组,用来记录受益人地址,shares是一个地址到uint256的映射,记录每个受益人的份额,released也是一个地址到uint256的映射,记录分红合约支付给每个受益人的金额。

// 受益人地址数组 address[] public payees; // 地址到份额的映射 mapping(address => uint256) public shares; // 地址到已支付金额的映射 mapping(address => uint256) public released;分红合约构造函数构造函数用来初始化分红合约的受益人和份额。// 构造函数 constructor(address[] memory _payees, uint256[] memory _shares) payable { require(_payees.length == _shares.length); require(_payees.length > 0); for (uint256 i = 0; i < _payees.length; i++) { addPayee(_payees[i], _shares[i]); } }分红合约函数分红合约中有 3 个函数,addPayee()、release() 和 fallback()。其中 addPayee() 和 release() 只能由受益人调用,fallback() 函数用于接收 ETH。addPayee():增加受益人。函数签名为:function addPayee(address account, uint256 shares) public onlyPayees;release():受益人提款。函数签名为:function release(address payable account) public onlyPayees;fallback():用于接收 ETH。函数签名为:fallback() external payable {}addPayee()函数addPayee() 函数用来增加受益人,并计算总份额。在增加新的受益人时,需要保证合约的余额足够支付所有受益人的份额。// 增加受益人 function addPayee(address account, uint256 shares) public onlyPayees { require(account != address(0)); require(shares > 0); totalShares = totalShares + shares; require(totalShares <= address(this).balance); if (shares > 0) { if (shares[account] == 0) { payees.push(account); } shares[account] = shares[account] + shares; emit PayeeAdded(account, shares); } }release()函数release() 函数用来让受益人提取分红。该函数只能由受益人调用,并且需要确保分红合约余额足够支付受益人提取的金额。// 受益人提款 function release(address payable account) public onlyPayees { require(account != address(0)); uint256 payment = (address(this).balance * shares[account]) / totalShares – released[account]; require(payment != 0); require(address(this).balance >= payment); released[account] = released[account] + payment; totalReleased = totalReleased + payment; account.transfer(payment); emit PaymentReleased(account, payment); }fallback()函数fallback() 函数用来接收 ETH,并记录到分红合约中。// 接收 ETH fallback() external payable { emit PaymentReceived(msg.sender, msg.value); }注意事项分红合约需要预先将受益人的地址和份额写入合约中,这样才能确保分红合约能够自动分配 ETH 给每个受益人。受益人可以通过调用 release() 函数来领取自己的分红。在调用 release() 函数之前,受益人需要确保分分红合约函数分析

下面是分红合约中的几个函数:

  1. 构造函数

constructor(address[] memory _payees, uint256[] memory _shares) public payable { require(_payees.length == _shares.length, “PaymentSplit: payees and shares length mismatch”); require(_payees.length > 0, “PaymentSplit: no payees”);

for (uint256 i = 0; i < _payees.length; i++) {
    addPayee(_payees[i], _shares[i]);
}

}

构造函数用于初始化合约,传入受益人地址和份额,调用 addPayee() 函数来增加受益人。

  1. addPayee() 函数

function addPayee(address account, uint256 shares_) internal { require(account != address(0), “PaymentSplit: account is the zero address”); require(shares_ > 0, “PaymentSplit: shares is 0”); require(shares[account] == 0, “PaymentSplit: account already has shares”);

payees.push(account);
shares[account] = shares_;
totalShares = totalShares.add(shares_);
emit PayeeAdded(account, shares_);

}

addPayee() 函数用于增加受益人,传入受益人地址和份额,将受益人地址和份额添加到 payees 和 shares 中,并更新 totalShares 的值。

  1. release() 函数

function release(address payable account) public { require(shares[account] > 0, “PaymentSplit: account has no shares”); uint256 payment = totalReleased.mul(shares[account]).div(totalShares).sub(released[account]); require(payment != 0, “PaymentSplit: no payment”);

released[account] = released[account].add(payment);
totalReleased = totalReleased.add(payment);

account.transfer(payment);
emit PaymentReleased(account, payment);

}

release() 函数用于释放受益人的分红,传入受益人地址,根据 totalShares 和 shares 计算出该受益人应该得到的金额 payment,更新 released 和 totalReleased 的值,最后将 payment 转入受益人账户中,并触发 PaymentReleased 事件。

  1. fallback() 函数

fallback() 函数用于接收 ETH,将 ETH 存入分红合约中,并触发 PaymentReceived 事件。

function () external payable { totalReleased = totalReleased.add(msg.value); emit PaymentReceived(msg.sender, msg.value); }

分红合约的实现逻辑比较简单,通过构造函数来初始化合约,使用 addPayee() 函数来增加受益人,使用 release() 函数来释放受益人的分红。分红合约遵循 Pull Payment 模式,付款不会自动转入账户,而是保存在此合约中,受益人通过调用 release()函数触发实际转账。

分红合约包含六个函数,构造函数、receive()、release()、releasable()、pendingPayment()、_addPayee()。构造函数用于初始化受益人数组_payees和分红份额数组_shares,两个数组长度要相等且不为0,_shares中元素要大于0,_payees中地址不能为0地址且不能有重复地址。receive()是回调函数,在分红合约收到ETH时释放PaymentReceived事件。release()是分红函数,为有效受益人地址_account分配相应的ETH,任何人都可以触发该函数,但ETH会转给受益人地址account。releasable()用于计算一个受益人地址应领取的ETH,调用了pendingPayment()函数。pendingPayment()根据受益人地址_account、分红合约总收入_totalReceived和该地址已领取的钱_alreadyReleased,计算该受益人现在应分的ETH。_addPayee()是新增受益人函数及其份额函数,在合约初始化的时候被调用,之后不能修改。

release():分红函数,为有效受益人地址_account 分配相应的 ETH。任何人都可以触发这个函数,但 ETH 会转给受益人地址 account。调用了 releasable()函数。

releasable():计算一个受益人地址应领取的 ETH。调用了 pendingPayment()函数。

pendingPayment():根据受益人地址_account, 分红合约总收入_totalReceived 和该地址已领取的钱_alreadyReleased,计算该受益人现在应分的 ETH。

_addPayee():新增受益人函数及其份额函数。在合约初始化的时候被调用,之后不能修改。

/**

  • @dev 为某个受益人添加一份份额。
  • @param _account 受益人地址。
  • @param _shares 受益人分红份额。

release():分红函数,为有效受益人地址_account 分配相应的 ETH。任何人都可以触发这个函数,但 ETH 会转给受益人地址 account。调用了 releasable()函数。

releasable():计算一个受益人地址应领取的 ETH。调用了 pendingPayment()函数。

pendingPayment():根据受益人地址_account, 分红合约总收入_totalReceived 和该地址已领取的钱_alreadyReleased,计算该受益人现在应分的 ETH。

_addPayee():新增受益人函数及其份额函数。在合约初始化的时候被调用,之后不能修改。

/**

  • @dev 为某个受益人添加一份份额。
  • @param _account 受益人地址。
  • @param _shares 受益人分红份额。
*/

function _addPayee(address _account, uint256 _shares) internal {

require(_account != address(0), "PaymentSplitter: account is zero address");

require(_shares > 0, "PaymentSplitter: shares are 0");

require(shares[_account] == 0, "PaymentSplitter: account already has shares");

payees.push(_account);

shares[_account] = _shares;

totalShares = totalShares.add(_shares);

emit PayeeAdded(_account, _shares);

}

其中,addPayee()函数是在合约初始化时被调用,用来增加受益人地址和其分红份额。这个函数会检查地址和份额是否合法,同时更新 payees 数组、shares 映射和总份额 totalShares。

release()函数是分红合约的核心函数,用来分发分红。任何人都可以触发这个函数,但 ETH 会转给受益人地址 account。在调用之前会先调用 releasable()函数计算受益人现在应分的 ETH。

releasable()函数会根据受益人地址_account, 分红合约总收入_totalReceived 和该地址已领取的钱_alreadyReleased,计算该受益人现在应分的 ETH。如果计算结果大于 0,说明该受益人有分红可领取,返回 true。否则返回 false。

pendingPayment()函数则是用来计算一个受益人地址应领取的 ETH。它根据受益人地址_account, 分红合约总收入_totalReceived 和该地址已领取的钱_alreadyReleased,计算该受益人现在应分的 ETH。

总的来说,分红派息型智能合约可以方便地实现对持币用户或 LP 用户的分红,并大大提高分红的公平性和便利性。在实现时需要注意安全性和代码逻辑的正确性,以保证合约的稳定性和安全性。

在区块链领域,分红合约是一种常见的合约类型,它可以为持有者或流动性提供者分配一定的收益。通过智能合约编写,可以提高分红的公平性和透明度。分红合约中涉及的状态变量、事件和函数都非常重要,对于合约的运行和管理至关重要。

通过使用 Remix 演示,可以更好地理解和掌握分红合约的实现过程,包括合约部署、添加受益人、领取分红等操作。同时,掌握以太坊合约的开发逻辑,可以为开发其他公链的合约提供参考和借鉴。在实际开发中,合理设计和实现分红合约可以为项目带来更多的用户和价值。

分红合约的实现可以提高分红的公平性和便利性,为持币用户或LP用户提供了更好的分红体验。在开发币安智能链、火币智能链等平台的合约时,我们可以参考以太坊上的分红合约实现,从而更好地满足用户需求。

定制开发:DexDao

© 版权声明

相关文章

暂无评论

暂无评论...