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

初衷

简单说,我们需要一个智能合约来管理所有的分红项目(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竞选的选民等。

接口

创建分红项目:

1rpc CreateProfitItem (CreateProfitItemInput) returns (aelf.Hash) { 2} 3 4... 5 6message CreateProfitItemInput { 7 sint64 profit_receiving_due_period_count = 1; 8 bool is_release_all_balance_everytime_by_default = 2; 9} 10 11message ProfitItem { 12 aelf.Address virtual_address = 1; 13 sint64 total_weight = 2; 14 map<string, sint64> total_amounts = 3;// token_symbol -> total_amount 15 sint64 current_period = 4; 16 repeated SubProfitItem sub_profit_items = 7; 17 aelf.Address creator = 8; 18 sint64 profit_receiving_due_period_count = 9; 19 bool is_release_all_balance_everytime_by_default = 10; 20 bool is_treasury_profit_item = 11; 21} 22 23message SubProfitItem { 24 aelf.Hash profit_id = 1; 25 sint64 weight = 2; 26}

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

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

注册子分红项目:

1rpc RegisterSubProfitItem (RegisterSubProfitItemInput) returns (google.protobuf.Empty) { 2} 3 4... 5 6message RegisterSubProfitItemInput { 7 aelf.Hash profit_id = 1; 8 aelf.Hash sub_profit_id = 2; 9 sint64 sub_item_weight = 3; 10}

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

权重管理:

1rpc AddWeight (AddWeightInput) returns (google.protobuf.Empty) { 2} 3rpc SubWeight (SubWeightInput) returns (google.protobuf.Empty) { 4} 5rpc AddWeights (AddWeightsInput) returns (google.protobuf.Empty) { 6} 7rpc SubWeights (SubWeightsInput) returns (google.protobuf.Empty) { 8} 9 10... 11 12message AddWeightInput { 13 aelf.Address receiver = 1; 14 aelf.Hash profit_id = 2; 15 sint64 weight = 3; 16 sint64 end_period = 4; 17} 18 19message SubWeightInput { 20 aelf.Address receiver = 1; 21 aelf.Hash profit_id = 2; 22} 23 24message AddWeightsInput { 25 aelf.Hash profit_id = 1; 26 repeated WeightMap weights = 2; 27 sint64 end_period = 4; 28} 29 30message WeightMap { 31 aelf.Address receiver = 1; 32 sint64 weight = 2; 33} 34 35message SubWeightsInput { 36 repeated aelf.Address receivers = 1; 37 aelf.Hash profit_id = 2; 38}

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

添加分红:

1rpc AddProfits (AddProfitsInput) returns (google.protobuf.Empty) { 2} 3 4... 5 6message AddProfitsInput { 7 aelf.Hash profit_id = 1; 8 sint64 amount = 2; 9 sint64 period = 3; 10 string token_symbol = 4; 11}

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

释放分红:

1rpc ReleaseProfit (ReleaseProfitInput) returns (google.protobuf.Empty) { 2} 3 4... 5 6message ReleaseProfitInput { 7 aelf.Hash profit_id = 1; 8 sint64 period = 2; 9 sint64 amount = 3; 10 sint64 total_weight = 4; 11}

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

获取分红:

1rpc Profit (ProfitInput) returns (google.protobuf.Empty) { 2} 3 4... 5 6message ProfitInput { 7 aelf.Hash profit_id = 1; 8}

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

点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

NEO从源码分析看UTXO交易

_0x00前言_社区大佬:“交易是操作区块链的唯一方式。”_0x01交易类型_在NEO中,几乎除了共识之外的所有的对区块链的操作都是一种“交易”,甚至在“交易”面前,合约都只是一个小弟。交易类型的定义在Core中的TransactionType中:源码位置:neo/Core/TransactionType

Bytom Dapp 开发笔记(三):Dapp Demo前端源码分析

本章内容会针对比原官方提供的dappdemo,分析里面的前端源码,分析清楚整个demo的流程,然后针对里面开发过程遇到的坑,添加一下个人的见解还有解决的方案。储蓄分红合约简述为了方便理解,这里简单说说储蓄分红合约的内容,具体可以查看储蓄分红合约详细说明(https://www.oschina.net/action/GoToLink?ur