bitshares研究系列【bitshares-ui代码分析之api】

bitshares研究系列【bitshares-ui代码分析之基本结构】已经对bitshares-ui的目录结构等做了基本分析,先从网络接口开始看吧,在node_modules下有两个目录:bitsharesjs和bitsharesjs-ws,主要功能提供一个访问比特股API节点的工具,通讯方式采用WebSocket方式,代码用JS编写。

WebSocket API

在看代码之前,先熟悉一下比特股的WebSocket API,文档在此:http://docs.bitshares.org/api/websocket.html

调用格式

格式是JSON结构,如下:

{
 "id":1,
 "method":"call",
 "params":[
           0,
           "get_accounts",
           [["1.2.0"]]
          ]
}

id:消息顺序号,用于应答消息时检查是哪条请求消息的返回
params格式:

[API-identifier, Method-to-Call, Call-Parameters]
[API类型标识,方法名称,参数列表]

为了简单测试,先装个wscat

npm install -g wscat

在app/api/apiConfig.js中找一个线上地址,我找的是中国杭州节点

    {url: "wss://bitshares.dacplay.org/ws", location: "Hangzhou, China"},

在运行witness_node节点上,初始有两个API有效:API 0提供对数据库的只读访问,而API 1用来登录并访问其他受限制的API,执行命令测试一下:

> Chaim:bitshares-ui Chaim$ wscat -c wss://bitshares.dacplay.org/ws
connected (press CTRL+C to quit)
> {"id":1, "method":"call", "params":[0,"get_accounts",[["1.2.0"]]]}
< {"id":1,"jsonrpc":"2.0","result":[{"id":"1.2.0","membership_expiration_date":"1969-12-31T23:59:59","registrar":"1.2.0","referrer":"1.2.0","lifetime_referrer":"1.2.0","network_fee_percentage":2000,"lifetime_referrer_fee_percentage":8000,"referrer_rewards_percentage":0,"name":"committee-account","owner":{"weight_threshold":1,"account_auths":[],"key_auths":[],"address_auths":[]},"active":{"weight_threshold":131043,"account_auths":[["1.2.121",32903],["1.2.159",19751],["1.2.282",22172],["1.2.12376",28643],["1.2.21106",19292],["1.2.25010",28240],["1.2.97845",20056],["1.2.125824",22940],["1.2.130258",20520],["1.2.158781",21455],["1.2.711128",26113]],"key_auths":[],"address_auths":[]},"options":{"memo_key":"BTS1111111111111111111111111111111114T1Anm","voting_account":"1.2.5","num_witness":0,"num_committee":0,"votes":[],"extensions":[]},"statistics":"2.6.0","whitelisting_accounts":[],"blacklisting_accounts":[],"whitelisted_accounts":[],"blacklisted_accounts":[],"owner_special_authority":[0,{}],"active_special_authority":[0,{}],"top_n_control_flags":0}]}

强行修改get_accounts为get_account,来看一下错误信息:

Chaim:bitshares-ui Chaim$ wscat -c wss://bitshares.dacplay.org/ws
connected (press CTRL+C to quit)
> {"id":1, "method":"call", "params":[0,"get_account",[["1.2.0"]]]}
< {"id":1,"jsonrpc":"2.0","error":{"code":1,"message":"Assert Exception: itr != _by_name.end(): no method with name 'get_acco

请求API访问

调用流程如下:

  1. 登录完整节点
  2. 请求访问API集
  3. 获得API标识
  4. 调用API标识指定的API集中的API

现在有几个API集可以调用:

  1. Database API
  2. Account History API
  3. Network Broadcast API
  4. Network Nodes API

调用流程不细列了,可以看官方文档,三步操作如下:

Chaim:bitshares-ui Chaim$ wscat -c wss://bitshares.dacplay.org/ws
connected (press CTRL+C to quit)
> {"id":2,"method":"call","params":[1,"login",["",""]]}
< {"id":2,"jsonrpc":"2.0","result":true}
> {"id":2,"method":"call","params":[1,"database",[]]}
< {"id":2,"jsonrpc":"2.0","result":2}
> {"id":3, "method":"call", "params":[2,"get_accounts",[["1.2.0"]]]}
< {"id":3,"jsonrpc":"2.0","result":[{"id":"1.2.0","membership_expiration_date":"1969-12-31T23:59:59","registrar":"1.2.0","ref

看起来这个id也不用连续,当然如果用来判断就必须每个不同了

数据库通知

有几个通知,这个在ui显示是也是很重要的,直接列下原文说明:

  • set_subscribe_callback( int identifier, bool clear_filter ):

To simplify development a global subscription callback can be registered.

Every notification initiated by the full node will carry a particular id as defined by the user with the identifier parameter.

  • set_pending_transaction_callback(int identifier):

Notifications for incoming unconfirmed transactions.

  • set_block_applied_callback(blockid):

Gives a notification whenever the block blockid is applied to the blockchain.

  • subscribe_to_market(int identifier, asset_id a, asset_id b)):

Subscribes to market changes in market a:b and sends notifications with id identifier.

  • get_full_accounts(array account_ids, bool subscribe):

Returns the full account object for the accounts in array account_ids and subscribes to changed to that account if subscribe is set to True.

执行一个全局通知看一下结果:

Chaim:bitshares-ui Chaim$ wscat -c wss://bitshares.dacplay.org/ws
connected (press CTRL+C to quit)
> {"method": "call", "params": [1, "login", ["", ""]], "id": 2}
< {"id":2,"jsonrpc":"2.0","result":true}
> {"method": "call", "params": [1, "database", []], "id": 3}
< {"id":3,"jsonrpc":"2.0","result":2}
> {"method": "call", "params": [1, "history", []], "id": 4}
< {"id":4,"jsonrpc":"2.0","result":3}
> {"method": "call", "params": [2, "set_subscribe_callback", [5, false]], "id": 6}
< {"id":6,"jsonrpc":"2.0","result":null}
> {"method": "call", "params": [2, "get_objects", [["2.1.0"]]], "id": 7}
< {"id":7,"jsonrpc":"2.0","result":[{"id":"2.1.0","head_block_number":25995299,"head_block_id":"018ca823af6eb356b33c07aa424ce06f42c70e98","time":"2018-04-10T12:46:42","current_witness":"1.6.105","next_maintenance_time":"2018-04-10T13:00:00","last_budget_time":"2018-04-10T12:00:00","witness_budget":27000000,"accounts_registered_this_interval":51,"recently_missed_count":0,"current_aslot":26142244,"recent_slots_filled":"340282366920938463463374607431768211455","dynamic_flags":0,"last_irreversible_block_num":25995280}]}
< {"method":"notice","params":[5,[[{"id":"2.1.0","head_block_number":25995300,"head_block_id":"018ca824af5b469d8fd78dfd790b1d248e78f986","time":"2018-04-10T12:46:45","current_witness":"1.6.69","next_maintenance_time":"2018-04-10T13:00:00","last_budget_time":"2018-04-10T12:00:00","witness_budget":26900000,"accounts_registered_this_interval":51,"recently_missed_count":0,"current_aslot":26142245,"recent_slots_filled":"340282366920938463463374607431768211455","dynamic_flags":0,"last_irreversible_block_num":25995281}]]]}

method为notice的就是通知数据了,每3秒收到一个块数据。

边写边抄就这么多内容,明天继续分析bitshares-ui代码...

a.b.c 是什么?

The first number specifies the space. Space 1 is for protocol objects, 2 is for implementation objects. Protocol space objects can appear on the wire, for example in the binary form of transactions. Implementation space objects cannot appear on the wire and solely exist for implementation purposes, such as optimization or internal bookkeeping.

不太好翻译出来,看原文吧!

所有账户ID都是这种形式1.2.x。如果您是第9735个账户,您的账户ID将为1.2.9735。帐户0是特殊的(这是“委员会帐户”,由委员会成员控制,并且有其他帐户不具备的一些能力和限制)。

所有资产ID都是这种形式1.3.x。如果您是要注册的第29个资产,则您的资产ID将为1.3.29。资产0是特殊的(它是BTS,它被认为是“核心资产”)。

第一个和第二个数字共同确定了你正在谈论的事物类型(1.2对于账户,1.3资产)。第三个数字表示特定的事物。

1.b.x 的b在types.hpp中有定义,如下:

   enum object_type
   {
      null_object_type,
      base_object_type,
      account_object_type,
      asset_object_type,
      force_settlement_object_type,
      committee_member_object_type,
      witness_object_type,
      limit_order_object_type,
      call_order_object_type,
      custom_object_type,
      proposal_object_type,
      operation_history_object_type,
      withdraw_permission_object_type,
      vesting_balance_object_type,
      worker_object_type,
      balance_object_type,
      OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
   };

2.b.x 的b在types.hpp中有定义,如下:

   enum impl_object_type
   {
      impl_global_property_object_type,
      impl_dynamic_global_property_object_type,
      impl_reserved0_object_type,      // formerly index_meta_object_type, TODO: delete me
      impl_asset_dynamic_data_type,
      impl_asset_bitasset_data_type,
      impl_account_balance_object_type,
      impl_account_statistics_object_type,
      impl_transaction_object_type,
      impl_block_summary_object_type,
      impl_account_transaction_history_object_type,
      impl_blinded_balance_object_type,
      impl_chain_property_object_type,
      impl_witness_schedule_object_type,
      impl_budget_record_object_type,
      impl_special_authority_object_type,
      impl_buyback_object_type,
      impl_fba_accumulator_object_type,
      impl_collateral_bid_object_type
   };   

更多说明见:http://docs.bitshares.org/development/blockchain/objects.html

参考

https://bitshares.org/doxygen/index.html


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

H2
H3
H4
3 columns
2 columns
1 column
4 Comments