[aelf developer community] interface and implementation idea of profit contract of aelf blockchain

Time:2019-12-22

original intention

In short, we need a smart contract to manage all the profit items.

The dividend item is a token distribution center: the creator of each dividend item can register the receiver address of the dividend item or other dividend items that can receive dividends, and set the weight for each receiver. After that, each time the creator of the dividend project releases the dividend, it will allocate tokens according to the specified weight for the registered receiver address (either a separate account address or a virtual address of the dividend project) – convert all the tokens to be allocated into elf, or directly use the transfer method to type the corresponding tokens The owner of the address, or waiting for the address to be received, gets his own profit. After each dividend is released, the account period of the dividend item is increased by one.

We extract several concepts from it:

Profit item. A blockchain token distribution center created through a dividend contract.
Creator of dividend project. Have the right to register the dividend receiving address for the created dividend project.
The receiver address of the dividend. The address of the account used to receive the dividend token on a mediocre aelf blockchain. It should be noted that this part of the dividend needs to be obtained by the recipient, and will not be automatically printed on this account when the dividend is released (see “obtain dividend”).
Virtual address of the dividend item. Each dividend item will be mapped with its unique ID to a virtual address that can only be operated by the creator of the dividend item. This address is only used to release dividends, and there is no corresponding public-private key pair (the probability of collision of this address can be ignored).
Sub dividend item. This is a relative concept, each dividend project may become a sub dividend project. Sub dividend items can be assigned weight by other dividend items, so that when other dividend items release dividends, they will put a token on the virtual address of sub dividend items.
Get a profit. As an ordinary user who can receive a dividend, he / she needs to send a transaction by himself / herself to get the dividend he / she deserves. This is to avoid too many registered receiving addresses and overtime execution of the transaction to release the dividend.
Weight. We choose to use weight to manage the proportion of dividends that can be obtained by each dividend receiving address, i.e. (the weight / total weight allocated to the receiving address), which will be more flexible. When necessary, we will limit the total weight of a certain type of dividend project and allocate a part of the weight to the fixed (sub) dividend project to achieve the purpose of forced dividend – as long as this type of dividend project releases the dividend, the fixed sub dividend project can receive at least a certain proportion of the dividend. For example, contracts deployed by DAPP developers can choose to contribute a certain proportion of dividends to the Treasury.
Release dividends. The process of converting the balance on the virtual address of the dividend project into elf through Bancor contract and transferring it to the dividend receiving address.
Account period. The duration of the accounting period is controlled by each dividend project. After the dividend is released, the accounting period will increase by 1.
Treasury. This may be the largest dividend project in the aelf blockchain. It can be used as a sub project of block production reward, contract transaction fee dividend and contract profit dividend. It can also be used as a general dividend project to distribute the balance in its virtual address to the CDC that generated the block in the last session, the verification node VDC that participated in the aelf campaign, the voters that participated in the aelf campaign, etc.

Interface

Create dividend items:

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;
}

When creating a dividend item, you can specify the timeout period for the receiver address to get the dividend. When it expires, the corresponding dividend information will be deleted to reduce the storage cost of state dB.

In addition, when the creator of the dividend project releases the dividend, you can specify how much dividend is released in the current accounting period. If the Creator intended to release all the balances on the book of the virtual address of the dividend project every time he releases the dividend, you can set is “release” all balance “everytime” by “default to true, and when releasing the dividend, transfer the release limit to 0 (or not) Yes.

Registered sub dividend items:

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;
}

Used to add sub dividend items and assign corresponding weights.

Weight management:

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;
}

In order to avoid too many transactions, the interface of batch management weight should be provided.

Add Dividend:

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

...

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

It is used to add a certain number of tokens for dividend to the specified dividend items. Any currency can be used. When period is 0 (empty), this token is added to the virtual address of the dividend item (which can be called the general ledger). When a period greater than 0 is specified, this token will be added to the virtual address of the specified period.

Release Dividend:

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 is the account period of this dividend release. You can’t jump to release it. However, it’s necessary to pass in the account period of this release for contract inspection, so as to prevent the creation of dividend items from manually sending two same transactions, resulting in the dividend release twice. When amount is set to 0 and is “release” all balance “everytime” by “default” is specified when the dividend item is created, all balances on the virtual address of the dividend item will be released this time. The total weight here is prepared for the dividend items that need to be released later. Because the available total weight of the dividend items that need to be released later cannot use the total weight of the dividend items when they are released, you can only set the total weight to the total weight of a certain time point in the past. For example, today is the 6th. To release dividends to the address registered in the dividend receiving list on the 5th, you should transfer the total weight of the 5th to the releaseprofitinput parameter.

Get dividends:

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

...

message ProfitInput {
    aelf.Hash profit_id = 1;
}

Provide the unique identification of the dividend items and collect all the dividends you can get.

Recommended Today

PHP realizes UnionPay business H5 payment

UnionPay business H5 payment interface document: document address 1: H5 payment interface address: 1: Alipay payment Test address: http://58.247.0.18:29015/v1/netpay/trade/h5-pay Official address: https://api-mop.chinaums.com/ 2: UnionPay payment Test address: http://58.247.0.18:29015/v1/netpay/uac/order Official address: https://api-mop.chinaums.com/ 2: Basic parameters required by the interface The interface uses get parameters. After the interface parameters are directly put into the interface address, the […]