通过对源码的分析,可以知道accounts是accounts.json数据的集合,包含字段name、pub以及ppvt,分别代表账户名称、公钥和私钥的属性。然而,allocateFunds函数要做的事情是为accounts集合的每一个对象增加一个字段‘funds’,这个字段的值是通过帕累托分配模型计算出来的,可以使众多的普通账户的fund值呈现80-20规则。而目前funds的值并未真正是账户所拥有的token,而是相当于一个计划!后面会有使用到的地方,这里系个扣b1。
感兴趣的同学可以通过来研究它具体的思想以及实现方法。
创建股权账户下面使用system newaccount创建账户,并抵押资产。
root@iZ2ze5wsiqz8cj0lqgf73tZ:~/239# cleos system newaccount eosio --transfer accountnum11 "EOS8aCaHAARJvWqD7XsbqK25c4ahDKT4TwmqjvSCFbD3bof8L16Fb" --stake-net "100000.0000 SYS" --stake-cpu "100000.0000 SYS" --buy-ram="0.1 SYS" 1601937ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea30551082d4334f4d1132e8030000000000000453595300000000"} arg: {"code":"eosio","action":"buyram","args":{"payer":"eosio","receiver":"accountnum11","quant":"0.1000 SYS"}} 1601938ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea30551082d4334f4d113200ca9a3b00000000045359530000000000ca9a3b00000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"accountnum11","stake_net_quantity":"100000.0000 SYS","stake_cpu_quantity":"100000.0000 SYS","transfer":true}} executed transaction: 24a805a6a582a35ddd594ae25b7cf4a506244201d3fbcb4cfb4d079bf582764d 344 bytes 6072 us # eosio <= eosio::newaccount {"creator":"eosio","name":"accountnum11","owner":{"threshold":1,"keys":[{"key":"EOS8aCaHAARJvWqD7Xsb... # eosio <= eosio::buyram {"payer":"eosio","receiver":"accountnum11","quant":"0.1000 SYS"} # eosio.token <= eosio.token::transfer {"from":"eosio","to":"eosio.ram","quantity":"0.0995 SYS","memo":"buy ram"} # eosio <= eosio.token::transfer {"from":"eosio","to":"eosio.ram","quantity":"0.0995 SYS","memo":"buy ram"} # eosio.ram <= eosio.token::transfer {"from":"eosio","to":"eosio.ram","quantity":"0.0995 SYS","memo":"buy ram"} # eosio.token <= eosio.token::transfer {"from":"eosio","to":"eosio.ramfee","quantity":"0.0005 SYS","memo":"ram fee"} # eosio <= eosio.token::transfer {"from":"eosio","to":"eosio.ramfee","quantity":"0.0005 SYS","memo":"ram fee"} # eosio.ramfee <= eosio.token::transfer {"from":"eosio","to":"eosio.ramfee","quantity":"0.0005 SYS","memo":"ram fee"} # eosio <= eosio::delegatebw {"from":"eosio","receiver":"accountnum11","stake_net_quantity":"100000.0000 SYS","stake_cpu_quantity... # eosio.token <= eosio.token::transfer {"from":"eosio","to":"eosio.stake","quantity":"200000.0000 SYS","memo":"stake bandwidth"} # eosio <= eosio.token::transfer {"from":"eosio","to":"eosio.stake","quantity":"200000.0000 SYS","memo":"stake bandwidth"} # eosio.stake <= eosio.token::transfer {"from":"eosio","to":"eosio.stake","quantity":"200000.0000 SYS","memo":"stake bandwidth"} warning: transaction executed locally, but may not be confirmed by the network yet注意这里--stake-net, --stake-cpu, --buy-ram的值都是手动随意填的,并不是自动算出来的。
关于这个问题,我们就可以解扣了,扣b1提到的填充组装到accounts集合的字段‘funds’,就是用来计算这些参数的值的,具体计算方式,可以通过脚本源码来看:
def createStakedAccounts(b, e): ramFunds = round(args.ram_funds * 10000) # 通过参数ram_funds设置用于购买内存的资金 configuredMinStake = round(args.min_stake * 10000) # 通过参数min_stake设置最小抵押值 maxUnstaked = round(args.max_unstaked * 10000) # 最大非抵押值 for i in range(b, e): a = accounts[i] funds = a['funds'] # 获取‘funds’值 print('#' * 80) print('# %d/%d %s %s' % (i, e, a['name'], intToCurrency(funds))) print('#' * 80) if funds < ramFunds: print('skipping %s: not enough funds to cover ram' % a['name']) continue minStake = min(funds - ramFunds, configuredMinStake) # 最小抵押值 unstaked = min(funds - ramFunds - minStake, maxUnstaked) # 非抵押值 stake = funds - ramFunds - unstaked # 剩余可分配抵押值总数 stakeNet = round(stake / 2) # net和cpu均分,各抵押一半。 stakeCpu = stake - stakeNet print('%s: total funds=%s, ram=%s, net=%s, cpu=%s, unstaked=%s' % (a['name'], intToCurrency(a['funds']), intToCurrency(ramFunds), intToCurrency(stakeNet), intToCurrency(stakeCpu), intToCurrency(unstaked))) assert(funds == ramFunds + stakeNet + stakeCpu + unstaked) retry(args.cleos + 'system newaccount --transfer eosio %s %s --stake-net "%s" --stake-cpu "%s" --buy-ram "%s" ' % (a['name'], a['pub'], intToCurrency(stakeNet), intToCurrency(stakeCpu), intToCurrency(ramFunds))) if unstaked: # 用完资源以后,再还回账户。 retry(args.cleos + 'transfer eosio %s "%s"' % (a['name'], intToCurrency(unstaked)))