bitshares基本概念详解【喂价】

in #bitshares6 years ago (edited)

timg.png

什么是喂价

通俗说法:喂价就是一种资产与另一种资产的价格比率。

专业说法:可信的见证人将外盘交易汇率输入到区块链上,使得软件算法可以将这些信息并入到市场规则里,这些外盘汇率信息叫做“喂价”。

还是通俗说法比较靠谱,专业说法又要解释什么是外盘、内盘、见证人等。

喂价数据必须包括两种资产,和带资产精度的资产数量,如下:

      "settlement_price": {
        "base": {
          "amount": 14569,
          "asset_id": "1.3.113"
        },
        "quote": {
          "amount": 85656,
          "asset_id": "1.3.0"
        }
      }

谁来喂价

谁来喂价这个由资产属性来指定,可以是以下几种:

  1. 资产指定见证人喂价
  2. 资产指定理事会成员喂价
  3. 资产指定喂价人

以上1、2在资产数据的flags指定由有效见证人喂价、或者有效理事会成员喂价,定义如下:

   enum asset_issuer_permission_flags
   {
      charge_market_fee    = 0x01, /**< an issuer-specified percentage of all market trades in this asset is paid to the issuer */
      white_list           = 0x02, /**< accounts must be whitelisted in order to hold this asset */
      override_authority   = 0x04, /**< issuer may transfer asset back to himself */
      transfer_restricted  = 0x08, /**< require the issuer to be one party to every transfer */
      disable_force_settle = 0x10, /**< disable force settling */
      global_settle        = 0x20, /**< allow the bitasset issuer to force a global settling -- this may be set in permissions, but not flags */
      disable_confidential = 0x40, /**< allow the asset to be used with confidential transactions */
      witness_fed_asset    = 0x80, /**< allow the asset to be fed by witnesses */
      committee_fed_asset  = 0x100 /**< allow the asset to be fed by the committee */
   };

如“CNY”的flags = 129 = 0x81 = witness_fed_asset | charge_market_fee

资产指定喂价人可以通过cli_wallet的如下命令指定:

signed_transaction update_asset_feed_producers(string symbol, flat_set<string> new_feed_producers, bool broadcast)

怎么喂价

cli_wallet

喂价命令格式:

publish_asset_feed nathan USD {"settlement_price": {"base": {"amount": 25,"asset_id": "1.3.1"},"quote": {"amount": 63647,"asset_id": "1.3.0"}},"maintenance_collateral_ratio": 1750,"maximum_short_squeeze_ratio":1100,"core_exchange_rate": {"base": {"amount": 25,"asset_id": "1.3.1"},"quote": {"amount": 66829,"asset_id": "1.3.0"}}} true

喂价信息包括资产对数量、最小抵押比率、强制平仓比率、核心兑换率。

抵押比率等可参考bitshares研究系列【喂价和资产抵押率】

wallet.cpp

发送 asset_publish_feed_operation 到节点

   struct asset_publish_feed_operation : public base_operation
   {
      struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };

      asset                  fee; ///< paid for by publisher
      account_id_type        publisher;
      asset_id_type          asset_id; ///< asset for which the feed is published
      price_feed             feed;
      extensions_type        extensions;

      account_id_type fee_payer()const { return publisher; }
      void            validate()const;
   };

数据里有喂价发布人、资产id、喂价信息

喂价有效时间

资产options字段中会指定喂价有效时间、最小喂价人个数等信息:

    "options": {
      "feed_lifetime_sec": 86400,
      "minimum_feeds": 7,
      "force_settlement_delay_sec": 86400,
      "force_settlement_offset_percent": 500,
      "maximum_force_settlement_volume": 50,
      "short_backing_asset": "1.3.0",
      "extensions": []
    }

feed_lifetime_sec指定了喂价有效时间,超过这个时间此喂价人的喂价数据就会失效。

minimum_feeds指定了有效喂价人的个数。

当前喂价

资产喂价有多人指定,那么谁的喂价是有效的呢?

系统采用所有喂价的中间值,因此如果某些见证人没有相当大程度上的勾结串通,想试图操纵喂价是非常困难的。喂价和其他受托人行为都是公开可审计的,而且受托人在任何时候都可以被BTS持有者投票撤掉。投票可参见bitshares基本概念详解【见证人】

asset_object.cpp

void graphene::chain::asset_bitasset_data_object::update_median_feeds(time_point_sec current_time)
{
   current_feed_publication_time = current_time;
   vector<std::reference_wrapper<const price_feed>> current_feeds;
   for( const pair<account_id_type, pair<time_point_sec,price_feed>>& f : feeds )
   {
      if( (current_time - f.second.first).to_seconds() < options.feed_lifetime_sec &&
          f.second.first != time_point_sec() )
      {
         current_feeds.emplace_back(f.second.second);
         current_feed_publication_time = std::min(current_feed_publication_time, f.second.first);
      }
   }

   // If there are no valid feeds, or the number available is less than the minimum to calculate a median...
   if( current_feeds.size() < options.minimum_feeds )
   {
      //... don't calculate a median, and set a null feed
      current_feed_publication_time = current_time;
      current_feed = price_feed();
      return;
   }
   if( current_feeds.size() == 1 )
   {
      current_feed = std::move(current_feeds.front());
      return;
   }

   // *** Begin Median Calculations ***
   price_feed median_feed;
   const auto median_itr = current_feeds.begin() + current_feeds.size() / 2;
#define CALCULATE_MEDIAN_VALUE(r, data, field_name) \
   std::nth_element( current_feeds.begin(), median_itr, current_feeds.end(), \
                     [](const price_feed& a, const price_feed& b) { \
      return a.field_name < b.field_name; \
   }); \
   median_feed.field_name = median_itr->get().field_name;

   BOOST_PP_SEQ_FOR_EACH( CALCULATE_MEDIAN_VALUE, ~, GRAPHENE_PRICE_FEED_FIELDS )
#undef CALCULATE_MEDIAN_VALUE
   // *** End Median Calculations ***

   current_feed = median_feed;
}

此函数会判断喂价人个数,如果有效喂价人个数不够,当前喂价为null,实际上这种情况可能会导致程序一些接口出错。

nth_element函数仅排序第n个元素(从0开始索引),即将位置n(从0开始)的元素放在第n大的位置,处理完之后,默认排在它前面的元素都不比它大,排在它后面的元素都不比它小。

BOOST_PP_SEQ_FOR_EACH宏,用于将一个序列中参数依次按照指定宏进行展开。

再看看GRAPHENE_PRICE_FEED_FIELDS宏定义:

#define GRAPHENE_PRICE_FEED_FIELDS (settlement_price)(maintenance_collateral_ratio)(maximum_short_squeeze_ratio) \
   (maintenance_collateral_cash_ratio)(maximum_short_squeeze_cash_ratio)\
   (core_exchange_rate)

使用BOOST_PP_SEQ_FOR_EACH会展开为6个CALCULATE_MEDIAN_VALUE语句。

如果喂价人为8个,也就是current_feeds.size() = 8,用update_median_feeds函数会算出这8人喂价中排在第4位的settlement_price、maintenance_collateral_ratio、maximum_short_squeeze_ratio、maintenance_collateral_cash_ratio、maximum_short_squeeze_cash_ratio、core_exchange_rate。

注意这里计算的是每项数据的中间值


感谢您阅读 @chaimyu 的帖子,期待您能留言交流!

Sort:  

你这一系列BTS的文章总结的真好,学习了

谢谢,没时间写

好专业。
崇拜你

互相学习吧

u 喜欢你的分析帖

继续让你喜欢😘

你好请接受cn区点赞机器人 @cnbuddy 对你作为cn区一员的感谢。如果不想再收到我的留言,请回复“取消”。

你超~強!石墨烯專家!期待你對EOS的剖析。

学习中...eos是应该看看,你币很厉害啊

同期待分析 EOS !

略懂而已,沒深入研究。介紹數位貨幣的文章是轉發的,我只是加上一點評論。現在EOS要延遲上線了……

以后跟楼主学习了,新人请多指教!!

Coin Marketplace

STEEM 0.30
TRX 0.12
JST 0.034
BTC 63960.62
ETH 3142.95
USDT 1.00
SBD 3.95