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競選的選民等。
?
接口
創建分紅項目:
?
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_amountsint64 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; }提供分紅項目的唯一標識,收取自己所有能獲取的分紅。
?
轉載于:https://my.oschina.net/aelf/blog/3074885
總結
以上是生活随笔為你收集整理的AElf区块链分红合约(Profit Contract)接口和实现思路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: adm浏览器识别为linux,QQ浏览器
- 下一篇: 2.模块Ⅰ