简单说,咱们须要一个智能合约来管理全部的分成项目(profit item)。区块链
分成项目是一个代币分配中心:每一个分成项目的建立者(creator)能够为该分成项目注册(register)分成的接收地址(receiver address)或其余能够接收分成的分成项目,并为每一个接收方设定权重(weight)。以后,每次分成项目的建立者释放(release)分成时,就会为其下注册的接收方地址(能够是一个单独的帐户地址,也能够是一个分成项目的虚拟地址(virtual address))按指定的权重分配代币——把待分配的代币一概转化为ELF,或者直接采起Transfer的方式打到相应的地址上,或者等待接收地址的全部人自行获取分成(profit)。每次释放分成后,该分成项目的帐期(account period)加一。google
咱们从中提取出几个概念:code
分成项目(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竞选的选民等。token
建立分成项目:接口
rpc CreateProfitItem (CreateProfitItemInput) returns (aelf.Hash) {
}开发
...rpc
message CreateProfitItemInput {部署
sint64 profit_receiving_due_period_count = 1; bool is_release_all_balance_everytime_by_default = 2;
}string
message ProfitItem {it
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;
}提供分成项目的惟一标识,收取本身全部能获取的分成。