EOS系统合约链账户介绍

一、目的

本文档围绕EOS系统合约的九种基本链账户在源码中的使用情况进行介绍,适用于想要了解系统合约链账户的初学者和开发者,帮助其快速了解和上手EOS系统合约链账户创建与使用。

二、链账户介绍

EOS账户是存储在区块链中的可读标识符。由权限配置决定,该账户是个人授权还是多人授权拥有。EOS账户有12个字符的限制(允许字符a~z、1~5),该字符由64位整数的base-32编码衍生而来。

EOS短账户是通过账户之间竞拍购买得到的账户,如:com、a等,短账户非常稀少。由竞拍获得的短账户创建的二级账户也是短账户,类似于网站域名,比如:com账户可以创建a.com、1.com等子账户。短账户可以参与账户竞拍获得,但是拍卖成交价一般在数千到数万EOS不等。也可以向短账户拥有者购买二级账户,如:向e账户购买e.e账户。

三、系统链账户介绍

1、系统账户介绍

在基于EOSIO的区块链的起源当中,只有一个账户存在,也就是eosio账户。它是主要的系统账户,还有一些其他的系统账户,都由它创建。以下是几个重要的系统账户:

帐户 特权 合约 描述
eosio eosio.system 合约 基于 EOSIO 的区块链上的主系统帐户。
eosio.msig eosio.msig 合约 如果所有需要的各方在到期时间之前签署提案,则允许签署多重签名交易提案以供以后执行。
eosio.wrap eosio.wrap 合约 通过使它们更具可读性和更易于审核来简化块生产者超级用户的操作。
eosio.token eosio.token 合约 定义允许用户在基于 EOSIO 的区块链上创建、发行和管理令牌的结构和操作。
eosio.names 持有命名空间拍卖资金的帐户。
eosio.bpay 支付区块生产者生产区块的账户。它根据区块生产者在过去 24 小时内创建的区块数量分配 0.25% 的通货膨胀。
eosio.ram 根据用户购买或出售 RAM 的行为跟踪 SYS 余额的帐户。
eosio.ramfee 跟踪从用户 RAM 交易行为中收取的费用的账户:每笔交易价值的 0.5% 进入该账户。
eosio.saving 持有 4% 网络通胀的账户。
eosio.stake 跟踪已为 NET 或 CPU 带宽抵押的所有 SYS 代币的帐户。
eosio.vpay 根据赢得的选票相应地支付区块生产者的账户。它根据区块生产者在过去 24 小时内赢得的票数分配 0.75% 的通货膨胀率。
eosio.rex 跟踪 REX 相关操作执行产生的费用和余额的帐户。
2、链账户在源码中的使用
(1)eosio.msig

在EOS中,eosio.msig是一个特殊的链账户,用于管理多签名 (multisig)操作,部署提案合约。

多签名(Multisig):多签名是一种安全机制,其中需要多个账户的授权才能执行某些敏感操作或交易。对于eosio.msig账户来说,多个账户可以被配置为需要授权才能执行事务。

eosio.msig账户功能:eosio.msig账户是EOS.0软件平台中的一个特殊账户,负责管理和执行多签名操作。

多签名交易执行过程:

  • 创建提案:使用eosio.msig账户创建一个提案(proposal),其中包括待执行的交易和所需的签名授权列表。

  • 授权签名:参与多签名的账户根据规定的授权列表对提案进行签名。一旦所有所的签名被授权,提案就可以准备执行。

  • 执行提案:eosio.msig账户可以执行已收集足够授权签名的提案,从而触发交易的执行。

(2)eosio.names

eosio.names:持有命名空间拍卖资金的帐户。投标名称操作,允许帐户 bidder 为名称 newname 出价。参数如下:

  • bidder:获得退款的帐户;

  • newname:投标的名称;

  • bid:为投标支付的系统代币数量;

账户在源码eosio.system.hpp中的别名定义:

` static constexpr eosio::name names_account{"eosio.names"_n};`

在源码eosio.system/src/namebidding.cpp中的使用:

void system_contract::bidname( const name& bidder, const name& newname, const asset& bid ) {
      ......//other code
        
      require_auth( bidder );check( (bool)newname
      check( newname.suffix() == newname, "you can only bid on top-level suffix" );
​
      check( (bool)newname, "the empty name is not a valid account name to bid on" );
      check( (newname.value & 0xFull) == 0, "13 character names are not valid account names to bid on" );
      check( (newname.value & 0x1F0ull) == 0, "accounts with 12 character names and no dots can be created without bidding required" );
      check( !is_account( newname ), "account already exists" );
      check( bid.symbol == core_symbol(), "asset must be system token" );
      check( bid.amount > 0, "insufficient bid" );
    
      //代币从bidder转移到names_account
      token::transfer_action transfer_act{ token_account, { {bidder, active_permission} } };
      transfer_act.send( bidder, names_account, bid, std::string("bid name ")+ newname.to_string() );
}

出价退款操作,允许帐户 bidder 取回到目前为止对 newname 名称出价的金额。参数如下:

  • bidder:获得退款的帐户;

  • newname:投标的名称;现在可以退款;

在源码eosio.system/src/namebidding.cpp中的使用:

void system_contract::bidrefund( const name& bidder, const name& newname ) {
      bid_refund_table refunds_table(get_self(), newname.value);
      auto it = refunds_table.find( bidder.value );
      check( it != refunds_table.end(), "refund not found" );
​
      //代币从names_account转移到bidder
      token::transfer_action transfer_act{ token_account, { {names_account, active_permission}, {bidder, active_permission} } };
      transfer_act.send( names_account, bidder, asset(it->amount), std::string("refund bid on name")+(name{newname}).to_string() );
      refunds_table.erase( it );
   }
​
(3)eosio.saving、eosio.bpay和eosio.vpay使用

eosio.saving:持有4%网络通胀的账户。

eosio.bpay:支付块生产者生产块的账户,根据区块生产者过去24小时内创建的区块数量分配0.25%的通胀。

eosio.vpay:用赢得的选票向区块生产者支付相应费用的账户。根据区块生产者在过去24小时内赢得的票数分配0.75%的通货膨胀率。

账户在源码eosio.system.hpp中的别名定义:

static constexpr eosio::name saving_account{"eosio.saving"_n};
static constexpr eosio::name bpay_account{"eosio.bpay"_n};
static constexpr eosio::name vpay_account{"eosio.vpay"_n};

在源码eosio.system/src/producer_pay.cpp中的使用:

        if( new_tokens > 0 ) {
            {
               token::issue_action issue_act{ token_account, { {get_self(), active_permission} } };
               issue_act.send( get_self(), asset(new_tokens, core_symbol()), "issue tokens for producer pay and savings" );
            }
            {
               token::transfer_action transfer_act{ token_account, { {get_self(), active_permission} } };
               if( to_savings > 0 ) {
                  transfer_act.send( get_self(), saving_account, asset(to_savings, core_symbol()), "unallocated inflation" );
               }
               if( to_per_block_pay > 0 ) {
                  transfer_act.send( get_self(), bpay_account, asset(to_per_block_pay, core_symbol()), "fund per-block bucket" );
               }
               if( to_per_vote_pay > 0 ) {
                  transfer_act.send( get_self(), vpay_account, asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" );
               }
            }
         }
(4)eosio.ram和eosio.ramfee使用

eosio.ram:根据用户购买或出售ram的行为跟踪SYS余额的账户。

eosio.ramfee:跟踪从用户ram交易行为收取的费用的账户,每笔交易价值的0.5%进入该账户。

账户在源码eosio.system.hpp中的别名定义:

static constexpr eosio::name ram_account{"eosio.ram"_n};
static constexpr eosio::name ramfee_account{"eosio.ramfee"_n};

当购买ram时,付款人不可逆地将数量转移到系统合约,只有接收者可以通过sellram操作收回代币。接收方支付与此操作相关联的所有数据库记录的存储费用。RAM是一种稀缺资源,其供应量由全局属性max_RAM_size定义。RAM使用bancor算法定价,使得每个字节的价格具有100:1的恒定储备比。

在源码eosio.system/src/delegate_bandwidth.cpp中的使用:

     // 如果quant.amount>1,则quant_after_fee.amount应>0。如果quant.amaunt==1,则quant_after_fee.amount==0,并且下一次内联传输将失败,导致buyram操作失败。
      {
         token::transfer_action transfer_act{ token_account, { {payer, active_permission}, {ram_account, active_permission} } };
         transfer_act.send( payer, ram_account, quant_after_fee, "buy ram" );
      }
      if ( fee.amount > 0 ) {
         token::transfer_action transfer_act{ token_account, { {payer, active_permission} } };
         transfer_act.send( payer, ramfee_account, fee, "ram fee" );
         channel_to_rex( ramfee_account, fee );
      }
(5)eosio.stake使用

eosio.stake:跟踪所有为NET或CPU宽带质押的SYS代币的账户。

账户在源码eosio.system.hpp中的别名定义:

static constexpr eosio::name stake_account{"eosio.stake"_n};

在源码eosio.system/src/delegate_bandwidth.cpp中的使用:

auto transfer_amount = net_balance + cpu_balance;//NET或CPU
         if ( 0 < transfer_amount.amount ) {
            token::transfer_action transfer_act{ token_account, { {source_stake_from, active_permission} } };
            transfer_act.send( source_stake_from, stake_account, asset(transfer_amount), "stake bandwidth" );
         }
(6)eosio.rex使用

eosio.rex:跟踪费用和余额的账户是由REX相关操作执行产生的。

账户在源码eosio.system.hpp中的别名定义:

static constexpr eosio::name rex_account{"eosio.rex"_n};

在源码eosio.system\src\rex.cpp中的使用:

const asset payment = from_net + from_cpu;
      // inline transfer from stake_account to rex_account 从stake_account到rex_account的内联转账
      {
         token::transfer_action transfer_act{ token_account, { stake_account, active_permission } };
         transfer_act.send( stake_account, rex_account, payment, "buy REX with staked tokens" ); //使用赌注代币购买REX
      }
      const asset rex_received = add_to_rex_pool( payment );
      add_to_rex_balance( owner, payment, rex_received );
      runrex(2);
      update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ), true );
      // dummy action added so that amount of REX tokens purchased shows up in action trace 添加了虚拟操作,以便购买的REX代币数量显示在操作跟踪中
      rex_results::buyresult_action buyrex_act( rex_account, std::vector<eosio::permission_level>{ } );
      buyrex_act.send( rex_received );

猜你喜欢

转载自blog.csdn.net/BSN_yanxishe/article/details/133384627