【AELF開發者社區】AElf區塊鏈分成合約(Profit Contract)接口和實現思路

初衷

簡單說,咱們須要一個智能合約來管理全部的分成項目(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;

}提供分成項目的惟一標識,收取本身全部能獲取的分成。

相關文章
相關標籤/搜索