AElf区块链分红合约(Profit Contract)接口和实现思路

Stella981
• 阅读 779

初衷

简单说,我们需要一个智能合约来管理所有的分红项目(profit item)。

分红项目是一个代币分配中心:每个分红项目的创建者(creator)可以为该分红项目注册(register)分红的接收地址(receiver address)或其他可以接收分红的分红项目,并为每个接收方设定权重(weight)。之后,每次分红项目的创建者释放(release)分红时,就会为其下注册的接收方地址(可以是一个单独的账户地址,也可以是一个分红项目的虚拟地址(virtual address))按指定的权重分配代币——把待分配的代币一律转化为ELF,或者直接采取Transfer的方式打到相应的地址上,或者等待接收地址的所有人自行获取分红(profit)。每次释放分红后,该分红项目的账期(account period)加一。

我们从中提取出几个概念:

  • 分红项目(profit item)。通过分红合约创建出来的区块链代币分配中心。
  • 分红项目创建者(creator)。有权限为创造出来的分红项目注册分红接收地址。
  • 分红的接收地址(receiver address)。一个平平无奇的AElf区块链上的用来接收分红代币的账户地址。要注意的是,该部分分红需要接收人自行获取,不会在释放分红的时候自动打到这个账户上(见“获取分红(profit)”)。
  • 分红项目的虚拟地址(virtual address)。每个分红项目,都会通过其唯一标识(profit id)映射出来一个只有该分红项目的创建人可以操作的虚拟地址,这个地址仅用来释放分红,没有对应的公私钥对(碰撞出来这个地址的概率可以忽略不计)。
  • 子分红项目(sub profit item)。这是一个相对的概念,每个分红项目都可能成为子分红项目。子分红项目可以被其他分红项目分配权重,这样其他分红项目在释放分红时,会为子分红项目的虚拟地址打上一笔代币。
  • 获取分红(profit)。作为一个能够接收某个分红的普通用户,需要自行发送交易来获取自己应得的分红,这是为了避免被注册的接收地址过多,释放分红的交易执行超时。
  • 权重(weight)。我们选择使用权重来管理每一个分红接收地址能够获取的分红的比例,即(该接收地址被分配的权重/总权重),这样会更加灵活。在必要的时候,我们会限制某一类分红项目的总权重,并把一部分权重分配给固定的(子)分红项目,以达到强行分红的目的——只要这一类分红项目释放了分红,固定的子分红项目就可以至少接收到一定比例的分红。如DApp开发者部署的合约可以选择将一定比例的分红贡献给国库(Treasury)。
  • 释放(release)分红。将该分红项目虚拟地址上的余额全部通过Bancor合约转化为ELF,并Transfer给分红接收地址的过程。
  • 账期(account period)。账期的时长由每个分红项目自行控制,释放分红后账期自增1。
  • 国库(Treasury)。这可能是AElf区块链中最大的分红项目,它可以作为区块生产奖励、合约交易费分红、合约利润分红的子项目,也作为一般的分红项目将它虚拟地址中的余额分配给上一届产生了区块的CDC、参加了AElf竞选的验证节点VDC、参与了AElf竞选的选民等。

接口

创建分红项目:

rpc CreateProfitItem (CreateProfitItemInput) returns (aelf.Hash) {
}

...

message CreateProfitItemInput {
    sint64 profit_receiving_due_period_count = 1;
    bool is_release_all_balance_everytime_by_default = 2;
}

message ProfitItem {
    aelf.Address virtual_address = 1;
    sint64 total_weight = 2;
    map<string, sint64> total_amounts = 3;// token_symbol -> total_amount
    sint64 current_period = 4;
    repeated SubProfitItem sub_profit_items = 7;
    aelf.Address creator = 8;
    sint64 profit_receiving_due_period_count = 9;
    bool is_release_all_balance_everytime_by_default = 10;
    bool is_treasury_profit_item = 11;
}

message SubProfitItem {
    aelf.Hash profit_id = 1;
    sint64 weight = 2;
}

在创建某分红项目时,可以指定receiver address获取分红的超时时间,过期会删除相应的分红信息以减少State DB的存储开销。

除此之外,在分红项目创建者释放分红的时候,可以指定本次账期释放多少分红,如果该创建者本意是每次释放分红时就将分红项目虚拟地址账面上的所有余额进行释放,可以将is_release_all_balance_everytime_by_default设置为true,释放分红时将释放额度传为0(或者不传)即可。

注册子分红项目:

rpc RegisterSubProfitItem (RegisterSubProfitItemInput) returns (google.protobuf.Empty) {
}

...

message RegisterSubProfitItemInput {
    aelf.Hash profit_id = 1;
    aelf.Hash sub_profit_id = 2;
    sint64 sub_item_weight = 3;
}

用来添加子分红项目并分配相应的权重。

权重管理:

rpc AddWeight (AddWeightInput) returns (google.protobuf.Empty) {
}
rpc SubWeight (SubWeightInput) returns (google.protobuf.Empty) {
}
rpc AddWeights (AddWeightsInput) returns (google.protobuf.Empty) {
}
rpc SubWeights (SubWeightsInput) returns (google.protobuf.Empty) {
}

...

message AddWeightInput {
    aelf.Address receiver = 1;
    aelf.Hash profit_id = 2;
    sint64 weight = 3;
    sint64 end_period = 4;
}

message SubWeightInput {
    aelf.Address receiver = 1;
    aelf.Hash profit_id = 2;
}

message AddWeightsInput {
    aelf.Hash profit_id = 1;
    repeated WeightMap weights = 2;
    sint64 end_period = 4;
}

message WeightMap {
    aelf.Address receiver = 1;
    sint64 weight = 2;
}

message SubWeightsInput {
    repeated aelf.Address receivers = 1;
    aelf.Hash profit_id = 2;
}

为了避免过多交易,应该提供批量管理权重的接口。

添加分红:

rpc AddProfits (AddProfitsInput) returns (google.protobuf.Empty) {
}

...

message AddProfitsInput {
    aelf.Hash profit_id = 1;
    sint64 amount = 2;
    sint64 period = 3;
    string token_symbol = 4;
}

用于给指定分红项目增加一定数量可用来分红的代币,什么币种都可以。当period为0(为空)时,这一笔代币会添加到分红项目的虚拟地址上(可以称之为总账)。当指定了大于0的period时,这一笔代币会添加到指定账期的账期虚拟地址上。

释放分红:

rpc ReleaseProfit (ReleaseProfitInput) returns (google.protobuf.Empty) {
}

...

message ReleaseProfitInput {
    aelf.Hash profit_id = 1;
    sint64 period = 2;
    sint64 amount = 3;
    sint64 total_weight = 4;
}

period即本次释放分红的账期,不可以跳着释放,但是有必要自己传入该释放的账期供合约检查,以防止分红项目创建人手滑发送两个同样的交易,导致分红释放两次。当amount设置为0且该分红项目创建时指定is_release_all_balance_everytime_by_default为true,则本次会释放分红项目虚拟地址上的所有余额。这里的total_weight是为分红需要延期释放的分红项目准备的,因为延期释放的分红项目的可用总权重无法使用释放时的该分红项目的总权重,只能自己将总权重设置为过去某个时间点的总权重。比如今天是6号,要给5号时注册在分红接收列表中的地址释放分红,就应该把5号时的总权重传入参数ReleaseProfitInput中。

获取分红:

rpc Profit (ProfitInput) returns (google.protobuf.Empty) {
}

...

message ProfitInput {
    aelf.Hash profit_id = 1;
}

提供分红项目的唯一标识,收取自己所有能获取的分红。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
NEO从源码分析看UTXO交易
_0x00前言_社区大佬:“交易是操作区块链的唯一方式。”_0x01交易类型_在NEO中,几乎除了共识之外的所有的对区块链的操作都是一种“交易”,甚至在“交易”面前,合约都只是一个小弟。交易类型的定义在Core中的TransactionType中:源码位置:neo/Core/TransactionType
Stella981 Stella981
3年前
Bytom Dapp 开发笔记(三):Dapp Demo前端源码分析
本章内容会针对比原官方提供的dappdemo,分析里面的前端源码,分析清楚整个demo的流程,然后针对里面开发过程遇到的坑,添加一下个人的见解还有解决的方案。储蓄分红合约简述为了方便理解,这里简单说说储蓄分红合约的内容,具体可以查看储蓄分红合约详细说明(https://www.oschina.net/action/GoToLink?ur
Stella981 Stella981
3年前
Bytom 储蓄分红 DAPP 开发指南
储蓄分红DAPP储蓄分红合约简介储蓄分红合约指的是项目方发起了一个锁仓计划(即储蓄合约和取现合约),用户可以在准备期自由选择锁仓金额参与该计划,等到锁仓到期之后还可以自动获取锁仓的利润。用户可以在准备期内(dueBlockHeight)参与储蓄,按照合约规定可以1:1获取同等数量的储蓄票据资产,同时用户
在家办公,年薪20w起步,后端、前端、测试招聘
网站后端(影视类、视频网站):岗位待遇描述:1、薪资1200018000(人民币),14薪;2、工作时间:弹性工作时间,每天9小时,单休;3、在家上班,不限制地点4、年终分红:工作月数5000项目提成岗位职责:1、负责PC端及移动端产品的后端代码开发工作,撰写相关技术文档;2、根据系统中具体难点问题,有针对性的进行技术攻关;3、能根据需求设计整体技术架构方
在家办公,年薪20w起步,后端、前端、测试招聘
网站后端(影视类、视频网站):岗位待遇描述:1、薪资1200018000(人民币),14薪;2、工作时间:弹性工作时间,每天9小时,单休;3、在家上班,不限制地点4、年终分红:工作月数5000项目提成岗位职责:1、负责PC端及移动端产品的后端代码开发工作,撰写相关技术文档;2、根据系统中具体难点问题,有针对性的进行技术攻关;3、能根据需求设计整体技术架构方案,可扩展性强;4、按照项目计划,按时提交高质量代码,完成开发任务;5、规范文档的编写、维护,以及其他与项目相关工作;任职要求:1计算机或相关专业