分红币的实现原理

2021-07-22 10:40:54 +08:00
 czz5242199

最近市场上出现了很多分红币,比如最近流行的( BabyDoge, MiniDoge 之类的),大概模式都是交易手续费的 x% 按照持有比例分给所有持币人,今天我们来解析一下背后的代码实现方式。

第一想法肯定是计算出分红的手续费之后,按照比例给所有人加上,solidity 代码如下:

// 分红总金额
uint profit;

// 当前总持币量
uint totalAmounts;

for (uint i = 0; i < users.length; i++) {
// 给每个用户分红
    amounts[i] += amounts[i] / totalAmounts \* profit;
}

但这样做会有一个很大的问题:随着持币人数过多,每一笔转账消耗的计算资源会急速增长,甚至超出交易的单笔上限。

目前分红类代币采用了一个很聪明的做法,使用了类似于金融中的通缩概念:“如果货币总量减少,每个人手上的货币不就变得更值钱的,相当于变相完成了分红“

接下来我们来看源代码是怎么实现的

// 存储用户的虚拟数量
mapping(address => uint256) private _rOwned;
// 真正的发行量(比如发行了 1w 枚币,精度为 0,_tTotal = 10000 )
uint _tTotal;

uint256 private constant MAX = ~uint256(0);
// 最大的一个可以整除 _tTotal 的数,这个数字类似于“虚拟的货币总量”
uint _rTotal = (MAX - (MAX % _tTotal));
假设在合约部署时需要把 1w 枚币发给 owner,代码如下

constructor() {
    _tTotal = 10000;

    // 初始化 rTotal
    uint256 private constant MAX = ~uint256(0);
    uint _rTotal = (MAX - (MAX % _tTotal));

    // 把所有的币发给 owner
    _rOwned[owner] = _rTotal;
}

那么此时怎么计算用户余额呢?我们来看 balanceOf 函数

function balanceOf(address account) public view override returns (uint256) {
    uint256 currentRate = _rTotal / _tTotal;
    return _rOwned[account] / currentRate;
}

看起来就是先用 虚拟货币总量 / 真实货币总量 得到一个比例,然后除以这个比例即可拿到真实的余额。

我们再看一下 最重要的 transfer 函数是怎么实现的,我们假设分币比例是 3%

function transfer(address from, address to, uint amount) public {
    uint currentRate = _rTotal / _tTotal;
    uint rAmount = amount _ currentRate;
    // 3%的分红
    uint rProfit = amount _ currentRate _ 3 / 100;
    // 转让人扣除 100%
    _rOwned[from] = _rOwned[from] - rAmount;
    // 接收人收到 97%
    _rOwned[to] = _rOwned[to] + rAmount _ 97 / 100;

    // 剩下 3%扣除总的虚拟货币,这时候所有人的 banlanceOf 函数计算都会按照比例增长
    _rTotal = _rTotal - rProfit;
}

不得不说整套体系设计得挺厉害的,虽然存在一定的计算误差,但大大提高了计算效率。

联系作者

微信:czz5242199

telegram: @zhuozhongcao

1075 次点击
所在节点    问与答
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/790999

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX