eos代码架构
EOS由programs、plugins、librarires、和contracts四部分组成,可以看出石墨烯的架构和EOS的架构是很相近的,EOS增加了对智能合约的支持。实际上EOS并没有直接用石墨烯的源代码,而是重写了90%的代码,不过基本架构是一样的。
石墨烯技术(Graphene blockchain library)是一种区块链底层技术架构,由Cryptonomex公司开发, 采用C++语言编写。而BM就是Cryptonomex的创始人。他创建的Bitshares、Steem和EOS都是基于石墨烯架构的项目,基于此架构开发的区块链项目还包括YOYOW,公信宝,DECENT等。
我们说的EOS的DPoS共识、高度模块化等特点其实都是石墨烯架构包含的内容,凡是基于石墨烯技术的项目都具有通用的特性,比如较快的转账速度、较高的交易吞吐量以及稳定、功能强大等。不同的项目基于石墨烯架构则会总不同的修改和开发,例如EOS基于DPoS共识增加了BFT容错算法,手续费改成了免费等《详谈什么是石墨烯技术?》
《BM的**经历》
文章目录
- programs(应用层)
- plugins(插件层)
- 插件的继承关系
- 1. chain_plugin
- 2. net_plugin
- 3. http_plugin
- 4. producer_plugin
- 5. wallet_plugin
- 6. account_history_plugin
- 7. bnet_plugin
- history_plugin
- http_client_plugin
- mongo_db_plugin
- txn_test_gen_plugin
- chain_api_plugin
- history_api_plugin
- net_api_plugin
- producer_api_plugin
- wallet_api_plugin
- libraries(库函数层)
- constracts(智能合约层)
programs(应用层)
cloes:客户端命令行交互模块,用于解析用户命令,根据具体命令请求调用相应的接口,例如查看区块信息、操作钱包等等。
nodeos:服务器端,也就是区块生产节点,用于接受客户端的远端请求,并打包区块,主要包含四个插件,chain_plugin、http_plugin、net_plugin、producer_plugin。
keosd:钱包管理模块,主要包括三个插件,wallet_plugin、wallet_api_plugin、http_plugin。
plugins(插件层)
插件体系
EOS插件由三层类来实现。
最顶层是抽象类abstract_plugin,定义了插件的基本接口。
中间层是插件模板类plugin,主要用来解决插件之间依赖调用。
最底层是具体插件类,专注单个插件的业务功能实现。
EOS采用石墨烯引擎为基础构建区块链,并且实现了一套灵活的模块化插件机制,在抽象插件类和具体功能类之间引入一层模板类,来将插件间依赖调用从具体类中解耦出来,有利于插件功能内聚以及新插件扩展。
《插件源码解析》
插件的继承关系
系统的插件系统位于 eos/plugins 目录下,插件系统包含三个层次:
最顶层抽象类
这是一个位于 libraries/appbase/include/appbase/plugin.hpp 文件中的抽象类 abstract_plugin。这个抽象类提供了插件的基本接口,包括:
-
initialize初始化插件。
-
startup运行插件。
-
shutdown关闭插件。
-
set_program_options
设置插件可以接收的选项。 -
get_state
返回插件的状态。插件当前有 4 种状态,分别是:已注册、已初始化、运行中、已停止。其中已注册表示插件对象已经被实例化,但没有做任何事情;已初始化表示插件的参数已经被初始化,可以随时运行;运行中插件已经在运行状态;已停止表示插件已经停止运行。 -
name
表示插件的名称,通过运行时类识别技术 RITT,结合 boost::core::demangle 来获取,获取到的名称包括了命名空间,比如:eosio::chain_api_plugin。
中间层模板插件
这是一个位于 libraries/appbase/include/appbase/application.hpp 文件中的模板类,它实现了抽象插件中定义的方法,并且定义了一个虚函数来定义了插件的依赖的。
plugin
构造函数。在方法中,通过 C++ 的 RTTI 运行时类型识别技术,获得具体的实例化插件的名称,并保存在 _name 属性中。这个名称包含了命名空间在内,比如:eosio::chain_api_plugin。
get_state
返回当前的状态对象 _state。
name
返回当前实例化类的名称,见构造函数解释。
register_dependencies
通过 static_cast 方法,把当前插件转化为具体的实例化插件,然后调用插件的 plugin_requires 模板方法,加载插件依赖的其他插件。
initialize
如果当前插件不是已注册状态,那么不做任务处理。对于处在已注册状态的插件,执行下面的处理:
首先,设置插件状态为已初始化;
其次,调用插件的 plugin_requires 模板方法,加载插件依赖的其他插件,并且通过 Lambda 表达式执行其它插件的 initialize 方法;
然后,调用插件的 plugin_initialize 方法,进行初始化;
最后,调用应用程序的 plugin_initialized 方法,把插件加入已初始化集合 initialized_plugins。
通过以上几个步骤,插件及其依赖都得到了初始化。
startup
如果当前插件不是已初始化状态,那么不做任务处理。对于处在已初始化状态的插件,执行下面的处理:
首先,设置插件状态为已启动;
其次,调用插件的 plugin_requires 模板方法,加载插件依赖的其他插件,并且通过 Lambda 表达式执行其它插件的 startup 方法;
然后,调用插件的 plugin_startup 方法,进行启动;
最后,调用应用程序的 plugin_started 方法,把插件加入已运行集合 running_plugins。
通过以上几个步骤,插件及其依赖都是运行中的。
shutdown
如果当前插件不是已初始化状态,那么不做任务处理。对于处在已初始化状态的插件,执行下面的处理:
首先,设置插件状态为已停止;
其次,调用插件的 plugin_shutdown 方法,进行停止。
注意:插件的初始与启动方法分别是在 main 函数中通过调用应用对象的 application::iinitialize_impl 与 application::startup 中被调用的。
最下层具体功能的插件
承担各种具体功能的插件,这些插件都位于 eos/plugins,它们都定义了下面一些方法:
plugin_requires
模板方法,加载插件的依赖,通过表达式依赖插件的对应方法。
set_program_options
从抽象类类继承的虚函数
plugin_initialize
实例化插件
plugin_startup
启动插件
plugin_shutdown
关闭插件
在 EOS 提供的插件中 chain_plugin、net_plugin、http_plugin、producer_plugin 这4个插件不需要用户手动注册,节点会自动注册。
支持动态加载相关组件,实现了应用层的业务逻辑和区块链底层实现的解耦,同时为应用开发者提供友好的API接口。
系统提供的插件及其功能如下所述:
1. chain_plugin
这个插件承载了 nodeos 节点程序与区块链交互的基本功能,包括:
- 读取本地不可逆区块链基本信息;
- 设置本地链检查点;
- 设置本地链参数;
- 设置可逆区块数据库参数;
- 设置账户黑/白名单;
- 设置智能合约黑/白名单;
- 重载区块链初始状态文件;
- 删除、重写、替换本地区块链数据(包括开始、停止等动作);
2. net_plugin
这个插件定义了 P2P 网络插件,这个插件承载了 EOS 系统的 P2P 网络中 TCP/IP 层相关功能,包括 4 个基本功能:
- 建立节点之间握手并互联;
- 监听/发送/接收新交易请求;
- 监听/发送/接收新区块请求;
- 验证接收数据合法性;
3. http_plugin
这个插件定义了网络 http 插件,这个插件承载了 EOS 系统的 P2 P网络中 http 层相关功能,包括 3 个基本功能:
- 监听/发送/接收新交易请求;
- 监听/发送/接收新区块请求;
- 验证接收数据合法性;
4. producer_plugin
定义了区块生产节点的功能插件,其中功能包括:
- 生产/打包新区块数据;
- 对新区块签名;
- 对接收的区块进行验证,包括区块头合法性、签名合法性和交易合法性;
5. wallet_plugin
这个插件定义了钱包插件,这个插件承载了 nodeos 节点程序与钱包交互的相关功能,包括3个基本功能:
- 创建/读取钱包文件;
- 设置解锁超时时间;
- **导入钱包;
6. account_history_plugin
这个插件定义了历史记录查询插件,该插件承载了节点程序对本地链发起查询的相关功能,包括3个基本功能:
- 指定区块查询;
- 指定账户状态查询;
- 指定交易查询;
7. bnet_plugin
这个插件定义了 EOS 的 P2P 网络中不同节点之间同步各自本地链数据的算法,简单来讲,包括如下特征:
- 查找本地链上的最后一个区块ID;
- 如果本地产生新区块,则将该区块发送给其他节点;
- 如果本地不产生新区块,则将接受到的未确认交易发送给其他节点;
faucet_testnet_plugin
这个插件定义了在测试网上快速建立测试帐号的插件,该插件为测试提供便利。
history_plugin
这个插件定义了查询指定账户中指定公钥的所有历史交易记录。
http_client_plugin
这个插件定义了eos网络http层响应请求,并做相应的安全验证的客户端插件。
mongo_db_plugin
这个插件定义了保存并管理本地不可逆转区块链数据的MongoDB数据库基本配置插件。
txn_test_gen_plugin
这个插件定定义了一个每秒自动产生指定数量的交易信息的插件,该插件主要用作对eos网络的吞吐量(TPS)测试。
chain_api_plugin
这个插件定义了一些用户可以调用的、区块链相关的 API。主要有:
/v1/chain/abi_bin_to_json
/v1/chain/abi_json_to_bin
/v1/chain/get_abi
/v1/chain/get_account
/v1/chain/get_block
/v1/chain/get_block_header_state
/v1/chain/get_code
/v1/chain/get_code_hash
/v1/chain/get_currency_balance
/v1/chain/get_currency_stats
/v1/chain/get_info
/v1/chain/get_producer_schedule
/v1/chain/get_producers
/v1/chain/get_raw_abi
/v1/chain/get_raw_code_and_abi
/v1/chain/get_required_keys
/v1/chain/get_scheduled_transactions
/v1/chain/get_table_by_scope
/v1/chain/get_table_rows
/v1/chain/get_transaction_id
/v1/chain/push_block
/v1/chain/push_transaction
/v1/chain/push_transactions
db_size_api_plugin
这个插件定义了一些用户可以调用的关于存储相关的 API。主要有:
/v1/db_size/get
history_api_plugin
这个插件定义了一些用户可以调用的、历史数据相关的 API。主要有:
/v1/history/get_actions
get_transaction
get_key_accounts
get_controlled_accounts
net_api_plugin
这个插件定义了一些用户可以调用的、网络数据相关的 API。主要有:
/v1/net/connect
/v1/net/disconnect
/v1/net/status
/v1/net/connections
producer_api_plugin
这个插件定义了一些用户可以调用的、生产区块相关的 API。主要有:
/v1/producer/pause
/v1/producer/resume
/v1/producer/paused
/v1/producer/get_runtime_options
/v1/producer/update_runtime_options
/v1/producer/add_greylist_accounts
/v1/producer/remove_greylist_accounts
/v1/producer/get_greylist
/v1/producer/get_whitelist_blacklist
/v1/producer/set_whitelist_blacklist
/v1/producer/get_integrity_hash
/v1/producer/create_snapshot
wallet_api_plugin
这个插件定义了一些用户可以调用的、钱包相关的 API。主要有:
/v1/wallet/set_timeout
/v1/wallet/sign_transaction
/v1/wallet/sign_digest
/v1/wallet/create
/v1/wallet/open
/v1/wallet/lock_all
/v1/wallet/lock
/v1/wallet/unlock
/v1/wallet/import_key
/v1/wallet/remove_key
/v1/wallet/create_key
/v1/wallet/list_wallets
/v1/wallet/list_keys
/v1/wallet/get_public_keys
链接:https://www.jianshu.com/p/11c210b6f8f1
libraries(库函数层)
为应用层和插件层提供基础能力,实现了区块链的底层关键技术,例如,交易处理,生产区块,加密功能,文件IO操作,网络通信能力等等;
appbase
chain
fc
-crypto
-io
-log
-network
-rpc
utilities
constracts(智能合约层)
主要包含一些智能合约的示例代码。
set_program_options:用来设置插件的参数
plugin_initialize:实现了插件具体的初始化过程
plugin_startup:运行插件