【精解】EOS标准货币体系与源码实现分析 (6)

上面我们将问题抛了出来,下面我们对代码进行debug,来分析这100个BTC在发放给用户的时候是如何转变的?我们打个断点,开始运行程序,走到convert函数中,由于我们的USD等于base的符号,所以执行到了convert_to_exchange函数。

asset connector::convert_to_exchange(exchange_state &ex, const asset &input) { real_type R(ex.supply);// 1e+11 real_type S(balance.amount + input.amount); //100000100,等于state资产得新发行100个USD real_type F(weight);//0.489999999999999991118,USD所占比重,state初始化时已经设置好 real_type T(input.amount);//100 real_type ONE(1.0);//1 auto E = R * (ONE - std::pow(ONE + T / S, F));// 根据这个算法得到对应的state资产的增发量的值。pow是cmath库的一个函数,有两个参数,返回结果为第一个参数为底,第二个参数为幂值的结果。 // (1e+11)*(1-(1+100/100000100)^+0.489999999999999991118),这得借助计算器了,算出结果为:-48999.9385,约等于程序执行结果-48999.938505084501827。 token_type issued = -E; //48999.9385,增发100个USD,实际上要增发state这么多。 ex.supply += issued;// 更新总发行量,加入以上计算的值。 balance.amount += input.amount;//state的USD connector(可理解为基于某稳值数字资产下的token)的余额可以增加100个USD了。 return asset{issued, exchange_symbol};// 最后是以EXC资产增发48999.9385个的形式返回。 }

EXC是state的“原值”符号,USD和BTC是基于EXC抵押资产发行的数字token。

继续调试,回到convert函数中。我们获得了要对应增发EXC的数量,那么要具体执行影响到state数字资产,是通过:

result.output[balance_key{user, final_output.symbol}] += final_output.amount;// 将增发EXC的数量添加至state的output集合中。

output存放形式:

集合中一个元素位置,下标为0开始存储。

每个元素是一个pair类型。不懂C++ 中pair类型的可以参考《C++ 语法》。可以理解为一个元组,包含一对值first和second。

first是一个自定义结构体balance_key,包含一个账户名称成员和一个符号成员。这里对应的是"dan","EXC"。

second是一个增发量48999.9385。

结果就是EXC总账户通过dan增发了48999.9385,然后接下来继续,

result.output[balance_key{user, input.symbol}] -= input.amount;

这是给dan账户进行减持,同样的,我们列出output的存放形式:

下标1

pair类型,first,second

first是"dan","USD"

second是一个销毁量100个。

结果就是dan个人账户欠了100个USD,dan在调用convert的时候,要求最小输出资产是BTC类型的,而现在针对输入资产类型USD以及EXC相应的操作已经做完。下面要做的是EXC和BTC的convert。

if (min_output.symbol != final_output.symbol) {// 当计算的最终输出资产的符号与传入的最小输出资产不一致时,要调用本身convert来转换。 return convert(result, user, final_output, min_output, out); }

携带新的参数EXC和BTC再次进入convert函数时,state数字资产已经发生了变化,它的总发行量变为100000048999.93851,base的USD的余额变为100000100,quote的BTC的余额不变,仍旧为1亿。我们新带过来的参数是:

48999.938505084501个EXC作为输入资产

最小输出资产仍旧为第一次调用convert的0个BTC

由于我们这一次处理的输入资产类型就是state的默认符号EXC,所以会走另外一个处理分支,根据最小输出资产类型会执行convert_from_exchange函数:

initial_output = result.quote.convert_from_exchange(result, initial_output);

convert_from_exchange函数源码:

asset connector::convert_from_exchange(exchange_state &ex, const asset &input) { real_type R(ex.supply - input.amount);// 先找回原值:1e+11 real_type S(balance.amount);// BTC余额不变,仍为1亿个1e+8 real_type F(weight);// 权重为0.51 real_type E(input.amount);// EXC的输入数量48999.93851 real_type ONE(1.0); real_type T = S * (std::pow(ONE + E / R, ONE / F) - ONE);// 1e+8*((1+48999.93851/1e+11)^(1/0.51)-1),通过科学计算器了,算出结果为:96.07833342,约等于程序执行结果96.0783334103356735645。 // 这是通过抵押资产EXC的增发量来反推对应的BTC的增发量。 auto out = T; ex.supply -= input.amount;// 将EXC增发的部分减掉,其实是维持了原有增发量1e+11不变。 balance.amount -= token_type(out);// BTC的总量减少了96.07833342(这部分发给dan了),变为99999903.921666592。 return asset{token_type(out), balance.symbol};//最终以BTC减掉(发放出去)96.07833342的形式返回。 }

它的函数体与上面的convert_to_exchange函数很相似,但细一看会发现里面的某些数值运算发生了变化。然后,我们继续回到二重convert函数中,BTC发给dan的部分(实际上从dan的角度上来讲,可以是BTC增发)具体执行为:

result.output[balance_key{user, final_output.symbol}] += final_output.amount;// 将发给dan的96.07833342加到dan的账户里。

结果就是dan账户中多了96.07833342个BTC。然后对作为输入资产的EXC进行处理:

result.output[balance_key{user, input.symbol}] -= input.amount;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxppy.html