Introduction to eosio.system smart contract (3) Election, voting, system settings

This article introduces the election, voting, and system settings in the eosio.system smart contract in detail. It is suitable for junior developers of EOS smart contracts to understand how to conduct elections, votes, and system settings.

01

overview

The "eosio.system" smart contract is the system command contract of eos. This contract implements almost all system commands of eos, including functions such as account creation, resource pledge, super node voting, domain name auction, etc. It defines the structure and operations required for the core functions of the blockchain.

The following will introduce how eosio.system implements election, voting and system settings.

02

Environmental preparation

(1) A running and accessible blockchain

China Mobile Chain (based on EOS) test environment setup:

https://mp.weixin.qq.com/s/NBNFk9Xk9FCukMVgl0tfHA

(2) Make sure the local wallet is opened and unlocked

How to create a wallet:

https://developers.eos.io/manuals/eos/latest/cleos/how-to-guides/how-to-create-a-wallet

(3) The construction and deployment of eosio.contracts has been completed

How to build eosio.contracts:

https://developers.eos.io/manuals/eosio.contracts/latest/build-and-deploy

(4) The creation, issuance and transfer of tokens have been completed

How to create, issue and transfer tokens:

https://developers.eos.io/manuals/eosio.contracts/latest/guides/how-to-create-issue-and-transfer-a-token

03

election

(1) Node registration and cancellation

The super node election of eos is carried out around the account. Only when the account is registered as a super node candidate account, other accounts can vote for it.

To register as a supernode candidate account, you need to provide a public key, which is used to verify signatures when producing blocks after being elected as a supernode.

Command infrastructure:

cleos system regproducer [OPTIONS] account producer_key [url] [location]

Register node example:

cleos system regproducer alice EOS6u3S5RbCxVrCE2sW7yBQLZ7fftaupqB85BLDeuV9j4eTBGCKX1

Cancel node:

cleos system unregprod alice EOS6u3S5RbCxVrCE2sW7yBQLZ7fftaupqB85BLDeuV9j4eTBGCKX1

After canceling the node, other accounts can no longer vote for it, but the votes cast before will be retained, and the next time the node is created, it will still appear.

04

vote

(1) Voting process

1. Register node

Run the following command to register the node (see above for details):

cleos system regproducer alice EOS6u3S5RbCxVrCE2sW7yBQLZ7fftaupqB85BLDeuV9j4eTBGCKX1

2. Mortgage and Cancellation of Mortgage

mortgage:

Mortgage to yourself:

cleos system delegatebw ost ost "5 SYS" "5 SYS" 

Mortgage successful return value

executed transaction: 403f264c483947d3a5b2cd3508632d2993789467674ff458fac1b413d2f2b4ea  144 bytes  318 us
#         eosio <= eosio::delegatebw            {"from":"ost","receiver":"ost","stake_net_quantity":"51.0000 SYS","stake_cpu_quantity":"49.0000 SYS"...
#   eosio.token <= eosio.token::transfer        {"from":"ost","to":"eosio.stake","quantity":"100.0000 SYS","memo":"stake bandwidth"}
#           ost <= eosio.token::transfer        {"from":"ost","to":"eosio.stake","quantity":"100.0000 SYS","memo":"stake bandwidth"}
#   eosio.stake <= eosio.token::transfer        {"from":"ost","to":"eosio.stake","quantity":"100.0000 SYS","memo":"stake bandwidth"}
warning: transaction executed locally, but may not be confirmed by the network yet         ]

Transfer to ost 1000.0000 SYS token before mortgage, check the account after mortgage:

cleos get table eosio.token ost accounts
{
  "rows": [{
      "balance": "900.0000 SYS"
    }
  ],
  "more": false,
  "next_key": "",
  "next_key_bytes": ""
}

View mortgage information:

cleos get table eosio ost delband
{
  "rows": [{
      "from": "ost",
      "to": "ost",
      "net_weight": "153.0000 SYS",
      "cpu_weight": "147.0000 SYS"
    }
  ],
  "more": false,
  "next_key": "",
  "next_key_bytes": ""
}

Mortgage to others:

cleos system delegatebw ost imtube "5.0000 SYS" "5.0000 SYS"

View mortgage information:

cleos get table eosio ost delband{
{
  "rows": [{
      "from": "ost",
      "to": "imtube",
      "net_weight": "5.0000 SYS",
      "cpu_weight": "5.0000 SYS"
    },{
      "from": "ost",
      "to": "ost",
      "net_weight": "153.0000 SYS",
      "cpu_weight": "147.0000 SYS"
    }
  ],
  "more": false,
  "next_key": "",
  "next_key_bytes": ""
}

Query the balance of ost: 890.0000 SYS

Foreclosure:

The unstaking command infrastructure is as follows:

cleos system undelegatebw [OPTIONS] from receiver unstake_net_quantity unstake_cpu_quantity

At this time, check the balance of ost again, and the display is still 890.0000 SYS, and there is no return of canceling the mortgage. The reason is that there is a 3-day delay in canceling the mortgage. You can check it after 3 days to get a normal feedback.

cleos get table eosio.token ost accounts
{
  "rows": [{
      "balance": "890.0000 SYS"
    }
  ],
  "more": false,
  "next_key": "",
  "next_key_bytes": ""
}

3. Voting and unvoting

Before voting:

Create a node:

cleos system regproducer ost EOS6u3S5RbCxVrCE2sW7yBQLZ7fftaupqB85BLDeuV9j4eTBGCKX1

cleos system regproducer imtube EOS6u3S5RbCxVrCE2sW7yBQLZ7fftaupqB85BLDeuV9j4eTBGCKX1

mortgage:

ost→ost 5.0000 SYS,ost→imtube 5.0000 SYS

cleos get table eosio ost delband
{
  "rows": [{
      "balance": "880.0000 SYS"
    }
  ],
  "more": false,
  "next_key": "",
  "next_key_bytes": ""
}
root@5dca586566d1:~# cleos get table eosio ost delband
{
  "rows": [{
      "from": "ost",
      "to": "imtube",
      "net_weight": "5.0000 SYS",
      "cpu_weight": "5.0000 SYS"
    },{
      "from": "ost",
      "to": "ost",
      "net_weight": "158.0000 SYS",
      "cpu_weight": "152.0000 SYS"
    }
  ],
  "more": false,
  "next_key": "",
  "next_key_bytes": ""
}

imtube→imtube

cleos system delegatebw imtube imtube "2 SYS" "2 SYS"

View imtube mortgage information:

cleos get table eosio imtube delband
{
  "rows": [{
      "from": "imtube",
      "to": "imtube",
      "net_weight": "2.0000 SYS",
      "cpu_weight": "2.0000 SYS"
    }
  ],
  "more": false,
  "next_key": "",
  "next_key_bytes": ""
}

imtube→bob

cleos system delegatebw imtube bob "3 SYS" "3 SYS"

Nodes vote for other nodes

cleos system voteproducer prods imtube ost

Successful vote return value:

executed transaction: e21875311a7445bb9714b83fde2442a09839c246868e80cd5eef58212f83c8d5  120 bytes  300 us
#         eosio <= eosio::voteproducer          {"voter":"imtube","proxy":"","producers":["ost"]}
warning: transaction executed locally, but may not be confirmed by the network yet    ]       
Get voter information:
cleos get table eosio eosio voters
{
  "rows": [{
      "owner": "eosio",
      "proxy": "",
      "producers": [],
      "staked": 800840,
      "last_vote_weight": "0.00000000000000000",
      "proxied_vote_weight": "0.00000000000000000",
      "is_proxy": 0,
      "flags1": 0,
      "reserved2": 0,
      "reserved3": "0 "
    },{
      "owner": "imtube",
      "proxy": "",
      "producers": [
        "ost"
      ],
      "staked": 100000,
      "last_vote_weight": "1080641469324.71191406250000000",
      "proxied_vote_weight": "0.00000000000000000",
      "is_proxy": 0,
      "flags1": 0,
      "reserved2": 0,
      "reserved3": "0 "
    },{
      "owner": "jiscfgtizds5",
      "proxy": "",
      "producers": [],
      "staked": 2000000,
      "last_vote_weight": "0.00000000000000000",
      "proxied_vote_weight": "0.00000000000000000",
      "is_proxy": 0,
      "flags1": 0,
      "reserved2": 0,
      "reserved3": "0 "
    },{
      "owner": "ost",
      "proxy": "",
      "producers": [],
      "staked": 3200000,
      "last_vote_weight": "0.00000000000000000",
      "proxied_vote_weight": "0.00000000000000000",
      "is_proxy": 0,
      "flags1": 0,
      "reserved2": 0,
      "reserved3": "0 "
    },{
      "owner": "pagbbj4afmu5",
      "proxy": "",
      "producers": [],
      "staked": 2000000,
      "last_vote_weight": "0.00000000000000000",
      "proxied_vote_weight": "0.00000000000000000",
      "is_proxy": 0,
      "flags1": 0,
      "reserved2": 0,
      "reserved3": "0 "
    }
  ],
  "more": false,
  "next_key": "",
  "next_key_bytes": ""
}

View imtube mortgage information:

cleos get table eosio imtube delband
{
  "rows": [{
      "from": "imtube",
      "to": "bob",
      "net_weight": "3.0000 SYS",
      "cpu_weight": "3.0000 SYS"
    },{
      "from": "imtube",
      "to": "imtube",
      "net_weight": "2.0000 SYS",
      "cpu_weight": "2.0000 SYS"
    }
  ],
  "more": false,
  "next_key": "",
  "next_key_bytes": ""
}

Nodes vote for themselves

cleos system voteproducer prods imtube imtube

Successful vote return value:

executed transaction: 65cc7f09e0b5d0bc3e263f3b770b520838c44583be1da2f6c151d57275a0b951  120 bytes  306 us
#         eosio <= eosio::voteproducer          {"voter":"imtube","proxy":"","producers":["imtube"]}
warning: transaction executed locally, but may not be confirmed by the network yet   ] 

Account to vote for the node:

bob Mortgage:

cleos system delegatebw bob bob "11 SYS" "11 SYS"

bob votes for ost:

cleos system voteproducer prods bob ost

Voting quantity calculation formula: votingNum=(stake_net_quantity+stake_cpu_quantity)*10000;

vote for multiple nodes

set alice as a node

cleos system regproducer alice EOS6u3S5RbCxVrCE2sW7yBQLZ7fftaupqB85BLDeuV9j4eTBGCKX1

cleos system voteproducer prods is a command to directly vote for supernodes. You can specify a voting account, and you can vote for multiple supernode candidate accounts at one time. The account names need to be sorted alphabetically from small to large, with a maximum of 30 accounts.

cleos system voteproducer prods [OPTIONS] voter producers...

4. Fail to vote

The following conditions will result in a vote failure:

  • uncreated node;

  • Nodes that were created and then canceled;

  • If you vote for more than 30 nodes at a time, only the top 30 can succeed;

  • Multiple nodes vote, not in order;

5. Node rewards

cleos system voteproducer prods [OPTIONS] voter producers...

If you need to issue node rewards, you must ensure that per_block_payments is greater than 0;

Otherwise it will lead to an error

Error 3050003: eosio_assert_message assertion failure
Error Details:
assertion failure with message: cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)
pending console output:
  • Block rewards are only distributed to 21 super nodes, which involves the concept of a block reward pool. Since each node will issue some EOS when receiving it, all unclaimed block rewards will be placed in the block reward pool to wait Node pick up. Each time a single node claims (claim), the calculation formula for the number of block rewards that can be claimed is as follows: the amount that a single node can claim = the number of EOS in the block reward pool * the number of blocks that the BP has not claimed rewards / all unclaimed blocks Number of blocks to receive rewards

  • Vote percentage rewards are issued to super nodes and backup nodes, similar to block rewards, all unclaimed vote percentage rewards will be placed in the vote reward pool and wait for nodes to claim them. Each time a single node claims (claim), the calculation formula for the number of vote rate rewards that can be claimed is as follows: the number that a single node can claim = the number of EOS in the vote rate reward pool * the vote weight of the BP / the total vote weight of all BP

  • Claim (claim) Conditions Nodes need to meet three conditions to claim rewards: super nodes and backup nodes can claim it; the interval between two claims of the same node should not be less than 24 hours; backup nodes have no block rewards, only vote rate rewards and need to be in More than 100 EOS, otherwise it is not considered a backup node and cannot receive rewards.

(2) Proxy voting process

1. Register node

cleos system regproducer ost EOS6u3S5RbCxVrCE2sW7yBQLZ7fftaupqB85BLDeuV9j4eTBGCKX1

2. Establish and cancel proxy

Create proxy:

cleos system regproxy imtube

Proxy successful return value:

executed transaction: 06616d46400deef7191c869cb3d96f1d35b4fec1f98adb41b32b4754e00afa77  104 bytes  243 us
#         eosio <= eosio::regproxy              {"proxy":"imtube","isproxy":1}
warning: transaction executed locally, but may not be confirmed by the network yet   ]
 
 

Cancel proxy:

cleos system unregproxy imtube

Successfully cancel the proxy return value:​​​​​​​​

executed transaction: 07a59f11b4f076dd57bc9356c65d9621bdbd40a4d5a48077cc7e48f650925c9a  104 bytes  268 us
#         eosio <= eosio::regproxy              {"proxy":"imtube","isproxy":0}
warning: transaction executed locally, but may not be confirmed by the network yet   ]

3. Proxy voting

Create proxy:

cleos system regproxy alice

mortgage:

cleos system delegatebw imtube imtube "11.0000 SYS" "11.0000SYS"

Agent:

cleos system voteproducer proxy imtube alice

Delegate successful return value:​​​​​​​​

executed transaction: 667ffb20e7ec556d1760495f3f6ecfe1c315405d9ac31c2133f1523854dd8672  112 bytes  285 us
#         eosio <= eosio::voteproducer          {"voter":"imtube","proxy":"alice","producers":[]}
warning: transaction executed locally, but may not be confirmed by the network yet   ]      ]

Proxy voting:

cleos system voteproducer prods alice ost
  • Voting by proxy, that is, voting for the proxy first, and then the proxy votes for the producer.

  • The role of the proxy is to make choices and votes for others, and it does not require collateral itself.

  • When voting, you must first mortgage. There are two options for voting, and you can only choose one, and the two cannot exist at the same time.

  • If you choose to vote by yourself, you can directly operate; if you choose to vote by proxy, you will mortgage the vote to the proxy, and the proxy will choose the node to vote.

  • An account that has already been used as a proxy cannot be set up to vote by proxy.

05

system settings

(1) setlimits set account resource limit

source code:

void system_contract::setalimits( const name& account, int64_t ram, int64_t net, int64_t cpu ) {
      require_auth( get_self() );

      user_resources_table userres( get_self(), account.value );
      auto ritr = userres.find( account.value );
      check( ritr == userres.end(), "only supports unlimited accounts" );

      auto vitr = _voters.find( account.value );
      if( vitr != _voters.end() ) {
         bool ram_managed = has_field( vitr->flags1, voter_info::flags1_fields::ram_managed );
         bool net_managed = has_field( vitr->flags1, voter_info::flags1_fields::net_managed );
         bool cpu_managed = has_field( vitr->flags1, voter_info::flags1_fields::cpu_managed );
         check( !(ram_managed || net_managed || cpu_managed), "cannot use setalimits on an account with managed resources" );
      }

      set_resource_limits( account, ram, net, cpu );
   }

Detailed parameter explanation :

account: 要设置其资源限制的帐户的名称

ram_bytes: 账户内存总购买量(以绝对字节为单位)

net_weight: 账户带宽总抵押权重;账户带宽总抵押权重/全网总抵押权重=账户实际可使用率;对账户总抵押权重的修改也会反应到全网总抵押权重上。

cpu_weight: 账户CPU总抵押权重;与net_weight同理。

cpu_weight: the total mortgage weight of the account CPU; the same as net_weight.

The setlimits() method calls the set_resource_limits function to set the maximum usage of a user's ram, net, and cpu resources. This function is mainly used to buy and sell memory in the eosio.system system contract. It is only allowed to be called by the contract account itself, and can only be used for existing Accounts in the user resource table set resource limits.

Resources Introduction:

EOS resources can be divided into two categories:

  • One type is resources that can be lent to others: CPU, NET, are called transferable resources;

  • The other type is resources that can only be used by oneself and cannot be lent to others: RAM, also known as non-transferable resources.

Note: CPU and NET can be recovered after use, but RAM is different. RAM is a fixed resource and needs to be purchased again when it is used up.

Why use setlimits() to set account resource limits?

1. The resources in the EOS network are always limited, and transaction processing is resource-sensitive. Therefore, in order to avoid resource abuse and ensure the normal operation of the network, it is necessary to restrict and manage resource usage rights.

2. Some basic data restrictions need to be implemented in the use of resources, such as the maximum CPU limit of a single transaction is 150ms, the maximum bandwidth limit of a single block is 1M, etc., through hard-coded source code constants, or set interface calls, or passing parameters in each transaction to make sure;

(2) setacctram sets the memory limit

source code:

void setacctram( const name& account, const std::optional<int64_t>& ram_bytes );

Detailed parameter explanation :

account:账户

ram_bytes:内存限制

Due to the limited RAM resources, it is necessary to set the RAM resource limit in the specific implementation: a single account limit, a single transaction limit and a single block limit. Here, the setacctram() method sets a single account limit, which only allows the contract account itself transfer.

Why set a RAM limit?

RAM is very valuable to developers, because developing DApps requires RAM space. In addition, there is no concept of address in EOS. If users want to use EOS, they must create an account on EOS. Creating an EOS account requires memory consumption, that is, RAM. RAM is used for some special operations on the EOS chain, such as: generating new accounts, bidding for EOS account name auctions, etc. Database records consume RAM, and RAM is a precious resource. So you need to set the size of ram used by the account.

(3) The memory size provided by setram setting

source code:

void system_contract::setram( uint64_t max_ram_size ) {
      require_auth( get_self() );

      check( _gstate.max_ram_size < max_ram_size, "ram may only be increased" ); /// decreasing ram might result market maker issues
      check( max_ram_size < 1024ll*1024*1024*1024*1024, "ram size is unrealistic" );
      check( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" );

      auto delta = int64_t(max_ram_size) - int64_t(_gstate.max_ram_size);
      auto itr = _rammarket.find(ramcore_symbol.raw());

      /**
       *  Increase the amount of ram for sale based upon the change in max ram size.
       */
      _rammarket.modify( itr, same_payer, [&]( auto& m ) {
         m.base.balance.amount += delta;
      });

      _gstate.max_ram_size = max_ram_size;
   }

Detailed parameter explanation:

max_ram_size: 内存大小

The initial default of max_ram_size is 64G, and the setram() method implements a one-time expansion of RAM, which is only allowed to be called by the contract account itself.

Application scenario:

A chain developed based on EOS provides a free account registration interface. After the call is executed, the account mortgages CPU, NET and purchases RAM for free. Due to the lack of strict and effective anti-swiping treatment on the interface, the account registration has seriously exceeded expectations, resulting in a serious waste of system resources in the chain, and some system tokens for airdrops occupy too much.

Solution:

  • Expand the RAM capacity at one time through the setram() method

  • Through the setramrate() method, it is set to continuously add new blocks for each block.

(4) setramrate sets the memory growth rate of each block

source code:

void system_contract::setramrate( uint16_t bytes_per_block ) {
      require_auth( get_self() );

      update_ram_supply();
      _gstate2.new_ram_per_block = bytes_per_block;
   }

Detailed parameter explanation:

bytes_per_block: 每个块的内存大小

The setramrate() method implements the setting of the memory growth rate of each block, and this method is only allowed to be called by the contract account itself.

Notice:

  • Sets the increase rate of ram in bytes/block, up to uint16.

  • The maximum rate is 3TB per year, if update_ram_supply is not covered by the latest block.

  • Before switching the rate, new ram will be allocated at the old rate until the current block.

(5) setpriv set privilege switch

Source code :

void system_contract::setpriv( const name& account, uint8_t ispriv ) {
      require_auth( get_self() );
      set_privileged( account, ispriv );
   }

Detailed parameter explanation :

account: 账户

is_priv: 是否开启特权( 0不开,>0开启 )

The setpriv() method is only allowed to be called by the contract account itself, realizing the setting of the privilege switch. After the call is successful, the account becomes a privileged account, which can skip the standard authorization check to execute the transaction.

(6) setparams set system parameters

1. Detailed explanation of setparams() method

source code:

void system_contract::setparams( const eosio::blockchain_parameters& params ) {
      require_auth( get_self() );
      (eosio::blockchain_parameters&)(_gstate) = params;
      check( 3 <= _gstate.max_authority_depth, "max_authority_depth should be at least 3" );
      set_blockchain_parameters( params );
   }

Detailed parameter explanation:

params: 参数

setparams() is a public function that sets the chain parameter eosio::blockchain_parameter, which is only allowed to be called by the contract account itself.

Application scenario:

  • The CPU resource allocation algorithm is dynamic. The CPU utilization of the entire network is divided into busy hours and idle hours. When the utilization rate exceeds a certain threshold, it is busy. This threshold will be modified using the setparams() method, modifying the parameter to target_block_cpu_usage_pct. Currently, the value of the eos mainnet is 3000, which means the CPU utilization is 30%.

The setparams() method modifies the chain configuration. The configurable parameters are as follows:​​​​​​​​

{ "params":
  {
    "max_block_net_usage": 1048577,
    "target_block_net_usage_pct": 1000,
    "max_transaction_net_usage": 524288,
    "base_per_transaction_net_usage": 12,
    "net_usage_leeway": 500,
    "context_free_discount_net_usage_num": 20,
    "context_free_discount_net_usage_den": 100,
    "max_block_cpu_usage": 200000,
    "target_block_cpu_usage_pct": 1000,
    "max_transaction_cpu_usage": 150000,
    "min_transaction_cpu_usage": 100,
    "max_transaction_lifetime": 3600,
    "deferred_trx_expiration_window": 600,
    "max_transaction_delay": 3888000,
    "max_inline_action_size": 4096,
    "max_inline_action_depth": 4,
    "max_authority_depth": 6
  }
}

2. Blockchain_parameters default configuration and parameter details

data structure:

/* 区块链全局状态 */
struct eosio_global_state : public blockchain_parameters
{
  uint64_t max_ram_size = 64 * 1024 * 1024 * 1024; // 64GB
  uint64_t total_ram_bytes_reserved;
  int64_t total_ram_stake;
  block_timestamp last_porducer_schedule_update;
  uint64_t last_pervote_bucket_fill;
  int64_t pervote_bucket;
  int64_t perblock_bucket;
  uint32_t total_unpaid_blocks;
  int64_t total_activated_stake_time;
  uint64_t thresh_activated_stake_time;
  uint16_t last_producer_schedule_size;
  double total_producer_vote_weight;
  block_timestamp last_name_close;
}

// 区块链参数
struct blockchain_parameters
{
  uint64_t max_block_net_usage;
  uint32_t target_block_net_usage_pct;
  uint32_t max_transaction_net_usage;
  uint32_t base_per_transaction_net_usage;
  uint32_t net_usage_leeway;
  uint32_t context_free_discount_net_usage_num;
  uint32_t context_free_discount_net_usage_den;
  uint32_t max_block_cpu_usage;
  uint32_t target_block_cpu_usage_pct;
  uint32_t max_transaction_cpu_usage;
  uint32_t min_transaction_cpu_usage;
  uint64_t context_free_discount_cpu_usage_num;
  uint64_t context_free_discount_cpu_usage_den;
  uint32_t max_transaction_lifetime;
  uint32_t deferred_trx_expiration_window;
  uint32_t max_transaction_delay;
  uint32_t max_inline_action_size;
  uint16_t max_inline_action_depth;
  uint16_t max_authority_depth;
};

Detailed explanation of core parameters:

name note
max_ram_size Maximum memory, the default size is 64GB
total_ram_bytes_reserved Available memory size, the default configuration is 0
total_ram_stake The total memory mortgage size, the default configuration is 0
last_producer_schedule_update last block generation time
last_pervote_bucket_fill Last put into bucket time
pervote_bucket
perblock_bucket
total_unpaid_blocks Total outstanding blocks
total_activated_stake total active blocks
thresh_activated_stake_time
last_producer_schedule_size The size of the last producer scheduling task
total_producer_vote_weight Producer voting assets
last_name_close

(7) setinflation sets the inflation rate

source code:

void system_contract::setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) {
      require_auth(get_self());
      check(annual_rate >= 0, "annual_rate can't be negative");
      if ( inflation_pay_factor < pay_factor_precision ) {
         check( false, "inflation_pay_factor must not be less than " + std::to_string(pay_factor_precision) );
      }
      if ( votepay_factor < pay_factor_precision ) {
         check( false, "votepay_factor must not be less than " + std::to_string(pay_factor_precision) );
      }
      _gstate4.continuous_rate      = get_continuous_rate(annual_rate);
      _gstate4.inflation_pay_factor = inflation_pay_factor;
      _gstate4.votepay_factor       = votepay_factor;
      _global4.set( _gstate4, get_self() );
   }

Detailed parameter explanation:

annual_rate: 年率(核心代币供应的年通货膨胀率)

inflation_pay_factor: 通胀系数(用于奖励区块生产者的通货膨胀分数的倒数)

votepay_factor: 投票系数(区块生产者奖励的分数与所产生的区块成比例的倒数)

Related data structures :

static constexpr int64_t  default_inflation_pay_factor  = 50000;
static constexpr int64_t  default_votepay_factor = 40000;

The setinflation() method implements setting the inflation rate by changing the annual inflation rate of the core token supply and specifying how newly issued tokens are allocated according to the following structure:

  • For example, for 5% annual inflation rate =>annual_rate=default_inflation_pay_factor*5%=500, for 1.5% annual inflation rate=>annual_rate=default_inflation_pay_factor*1.5%=150

  • After setting the inflation coefficient, a part of tokens will be issued, 20% of which will be used to reward producers (rewards will be distributed according to the proportion of the specified producers), and the remaining 80% will be stored in eosio.saving (used for WPS work Proposal rewards).

  • The remaining rewards after setting the voting coefficient will be distributed proportionally according to the votes received. For example, 25% of the amount will be rewarded according to the number of blocks produced by the producer; 75% of the amount will be rewarded according to the number of votes received by the producer.

Why set an annual inflation rate?

The realization of block rewards and token issuance is set through the annual inflation coefficient.

Block rewards and token issuance:

In each new block, the block producer will generate the first transaction, which is onblock, which is used to mark the number of unpaid blocks (unpaid block) and update the account bidding information. The claimrewards interface for issuing rewards is triggered by external calls. EOSIO does not only issue additional EOS once a year, and issue all EOS for the whole year at one time, but adopts a continuous additional issuance method, that is, when any node claims (claim), it will trigger the system’s additional issuance action, which means that the additional issuance is based on the flow time Occurs irregularly in length.

The formula for calculating the number of additional tokens:

The number of additional tokens issued = annual inflation coefficient (0.04879=4.879%) × current total token issuance × time since the last additional issuance of tokens / number of microseconds in a year

-END-

Guess you like

Origin blog.csdn.net/BSN_yanxishe/article/details/131533505