bitshares转账流程
第1章 【绪言】
1.1 编写目的
本文档主要讲述使用bitshares的用户进行转账操作的处理流程,转账操作是bitshares里面比较简单的一个操作。通过对转账操作的理解,可以大致理解bitshares下面数据的处理逻辑。
1.2 术语定义
transaction:字面意思是交易,在bitshares里面,transaction意义既包含通用意义上的交易:比如充值、提现、转账、发布限价单,还包含其它一些意义,如:创建账户,升级账户,创建见证人节点,等一系列操作。
signed_transaction:当见证人对transaction进行签名之后,这个transaction具有一定的效力,可以认为是被确认过的,所以是signed_transaction。
processed_transaction:被执行过的transaction,当一个transaction被签名后,才可以被执行,执行转账及订单撮合等操作,只有被执行过的processed_transaction,才可以被放入区块中。
signed_block:区块结构,一个区块包含一个或多个processed_transaction。
第2章 【转账流程分析】
2.1 工作原理
用户使用bitshares的命令行或ui界面客户端,而见证人节点为这些客户端提供websocket服务。在客户端发布转账请求后,所连接的见证人节点将生成一条transaction,将转账所有信息封装进这条transaction中,然后执行签名操作,签名过的transaction将被广播给网络上其它的见证人结点,然后,此见证人节点会执行一下这个transaction,将执行结束后的transaction放入待打包的列表中。当轮到当前见证人节点打包区块时,会从列表中取出所有的transaction,打包到区块里面。
2.2 代码分析
当用户进行一笔转账操作如下图所示:
此时该用户使用的由bitshares-ui编译的用户界面客户端,发布转账请求后,所连接的见证人节点会接收到请求命令(本质上是一段json),在websocket_api.cpp 82行on_message函数中,由见证人节点所创建的websocket服务端,接收到消息,进行解析及rpc调用,这之间的调用流程暂时不详细说明,最终会调用到wallet.cpp 1991行的transfer函数,由此函数进行转账(transfer)的处理。
如图所示 account_object from_account和account_object to_account这两行代码就是从数据库中查询转账操作的源用户和目标用户,然后新创建一个transfer_operation结构体,transfer_operation在transfer.hpp中定义
如图所示,transfer_operation中包含了transfer操作的两个用户:转账操作的来源账户和目标账户,转账资产数量,手续费数量,备注这些信息。
然后调用sign_transaction函数,对此条transaction进行签名操作,在sign_transaction最后,调用broadcast_transaction(api.cpp 163行)函数,将这个transaction广播给其它见证人结点。
在api.cpp中,首先调用_app.chain_database()->push_transaction(trx),进行数据库操作,将transaction存入数据库中,具体流程如下:
db_block.cpp 229行
调用_apply_transaction函数,apply_transaction函数的功能是执行这条transaction,生成一个processed_transaction。然后将这个processed_transaction存入_pending_tx这个缓存vector中。
在apply_transaction中,再进一步调用apply_operation函数,在apply_operation中,根据operation的类型,从_operation_evaluators找到对应的operation执行器,_operation_evaluators的初始化在db_init.cpp 130行的initialize_evaluators函数中,可以看到,在此处添加了一系列evaluator对象,evaluator类是对operation进行具体操作的类,每一种opertion对有与之对应的evaluator,如transfer_operation对应的是transfer_evaluator。
在transfer_evaluator中,我们重点关注do_apply函数
可以看到,此处进行了数据库操作,执行adjust_balance函数,看代码可以看出,adjust_balance就是对源用户的相应资产进行减法操作,对目标用户的相应资产进行加法操作。
adjust_balance在db_balance.cpp 53行
所图所示,先得到account_balance_index索引,再在索引上根据account_id找到对应的用户账户,如果没有找到对应的account_balance_object,就创建一个,如果找到,就调用account_balance_object的adjust_balance函数。
在account_object.cpp中
void account_balance_object::adjust_balance(const asset& delta)
{
assert(delta.asset_id == asset_type);
balance += delta.amount;
}
如图所示,对该对象的balance进行修改操作。
上面所有的代码都属于层级调用,bitshares大多数处理都属于单线程操作,虽然层级调用层次较多,看起来复杂,但这些所有的操作都在最外层的apply_transaction。当操作完成后,将processed_transaction缓存进_pending_tx里面。
在witness.cpp中,此处执行见证人节点的轮询操作,周期行的检查是否轮到自己出块了, 判断自己是否能出块的逻辑在 maybe_produce_block() 方法中,当轮到当前见证人结点打包区块时,调用database的generate_block(db_block.cpp)函数。
如图所示,在for循环中,从_pending_tx中取出transaction,将其放入要打包的区块即pening_block中,完成生成一个区块操作。
第3章 【总结】
本篇简单介绍了转账操作时关键代码:在底层网部层接收到消息,在wallet中生成相应的transaction,对transaction进行签名,处理transaction中的operation,修改数据库中对应的账户余额,最后将transaction打包进区块中,完成此次转账操作。
Leave bitshares转账流程 to:
Read more #bitshares posts
Best Posts From lpbottle
We have not curated any of lpbottle's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.