Treasury合约
Treasury合约是一个智能合约,与Treasury分红方案不是一回事。
Treasury是aelf主网中的分红方案,其子分红方案和受益者的构成可以参考aelf系统概述 和aelf经济与治理白皮书。
提及Treasury的时候,可以通过上下文判断指的是合约还是分红方案。
初始化经济系统 - InitialTreasuryContract & InitialMiningRewardProfitItem
在InitialTreasuryContract中构建的分红方案的层级结构,各个分红方案的名字以注释为准,State的相应字段最好不要改了,改State的名字会导致旧的key访问不到,除非专门写个方法做一下key的迁移。
这就是为什么State.VotesWeightRewardHash实际上存储的是Welcome Reward的哈希值,State.ReElectionRewardHash实际上存储的是Flexible Rewarod的哈希值。
要注意的是,在InitialMiningRewardProfitItem初始化分红方案的时候,把Backup Subsidy和Citizen Welfare两个分红方案的Manager转移给了Election合约,因为实质上这两个分红方案的维护就是在Election合约中完成的。
ACS10实现
acs10是一个针对分红池的标准接口,主要方法有:
Donate:为分红池添加分红。
Release:释放分红。
SetSymbolList:设置可分红的代币列表。
GetSymbolList:获取可分红的代币列表。
GetUndistributedDividends:获取未释放的分红。
GetDividends:获取现在分红池里的分红。
Donate
Treasury分红池只接收ELF,因此,被捐赠到Treasury的Token有一个要求:必须能在TokenConverter合约中进行交易(通过TokenConverter合约的IsSymbolAbleToSell方法进行判断)。
Treasury合约会将收到的非ELF代币通过TokenConverter合约转换成ELF。到了needToConvert这块,详情见DonateAll。随后:
Treasury合约把Sender贡献的代币通过MultiToken合约的Transfer方法打到自己的地址上(如果Sender就是Treasury自己,就跳过)。
对Profit合约进行Approve。
调用Profit合约的
ContributeProfits方法,把分红打入Treasury分红合约。
最终在State.DonatedDividends中维护一下Treasury分红方案在每个区块收到分红的数量。
Release
作为释放分红的实现,它的主要任务是调用Profit合约的DistributeProfits方法。
不仅要释放Treasury分红方案,还要释放经济与治理白皮书中描述的Treasury的几个次级分红方案。
这些分红释放的时机是每次完成换届的那一个区块上,会在完成上述方法的调用后,顺便维护一下各个子分红方案的权重。顺序是这样的:
释放Treasury分红方案;
维护Basic Miner Reward、Welcome Reward、Flexible Reward分红方案的权重信息;
根据当前候选人和BP的信息,释放Miner Reward、Basic Miner Reward、Welcome Reward、Flexible Reward分红方案;(另外两个分红方案,Backup Subsidy和Citizen Welfare是在Election合约中完成释放的,调
TakeSnapshot方法,实际上调用时机也是换届时)维护候选人和BP的信息。
SetSymbolList
作为一个分红池,并不一定所有的代币都会参与每一届的分红。这个方法用来设置Treasury分红方案支持分红的代币。
为分红池添加所有代币 - DonateAll
这个方法用于捐赠Sender名下某类Token的所有余额。
功能很简单,不过这里需要提一下这个方法的初衷。在Donate接口的描述中提到过,Treasury分红方案只接受ELF作为代币(暂时)。
而系统中又有一些自动捐赠其他资源币的场景(详见侧链经济模型),因此需要完成这样一个需求:自动地把能够通过TokenConverter合约兑换为ELF代币的其他代币,兑换为ELF,再捐赠进Treasury分红方案中。
因此,在Donate执行过程中,会判断收到的代币是不是ELF。如果不是的话:
调用MultiTokenh合约,对TokenConverter合约Approve收到的代币和数量;
调用TokenConverter合约的Sell方法,把收到的代币兑换为ELF;
通过Inline的方式调用DonateAll方法,把兑换完的ELF全部捐赠进Treasury分红方案。
更新区块奖励 - UpdateMiningReward
初始化为0.125ELF。在AEDPoS合约中,每逢换届,会判断一下是不是需要减半了(现在设定为4年减半)。
如果需要减半,就会调用Treasury的UpdateMiningReward方法实施减半操作。从减半的这一届开始,Treasury方案每周释放的分红数量就会立刻少一半。
替换BP公钥 - RecordMinerReplacement
实际上,替换BP公钥的步骤是:
BP的Admin调用Election合约的
ReplaceCandidatePubkey方法;Election合约的
ReplaceCandidatePubkey方法调用AEDPoS合约的RecordCandidateReplacement方法,完成出块信息中Pubkey的替换;共识合约的
RecordCandidateReplacement方法调用Treasury合约的RecordCandidateReplacement方法,如果Pubkey此前没有被标记为作恶,修改一下State.LatestMinedTerm,如果被标记为作恶,存进State.ReplaceCandidateMap,释放分红获取新的BP列表的时候需要用到这个信息。
Last updated