#bcos #fisco #tls #sdk #tassl

sys fisco-bcos-service

Rust SDK for FISCO BCOS

5 releases (3 breaking)

0.4.1 Mar 9, 2022
0.4.0 Mar 9, 2022
0.3.0 Dec 17, 2021
0.2.0 Nov 24, 2021
0.1.0 Oct 22, 2021

#272 in #tls

25 downloads per month
Used in fisco-bcos-cli

Apache-2.0

205KB
4K SLoC

fisco-bcos-service

Rust SDK For FISCO BCOS 2.7.0+

安装

[dependencies]
fisco-bcos-service = ">=0.4, <1"

此 crate 使用了 TASSL 来处理 TLS 连接,在 LinuxMacos 下无需做任何额外操作,其他环境下则需要指定以下环境变量:

  • TASSL_LIB_PATH:lib 库加载路径。
  • TASSL_INCLUDE_PATH:头文件检索路径。
  • TASSL_LIB_KIND:lib 库类型,可用值为:staticdylib

LinuxMacos 下,如果你已经编译好了 TASSL,也可以通过指定以上环境变量来缩短编译时间。

使用

一、配置

配置文件为包含以下信息的 json 文件:

{
    "service_type": "rpc",
    "node": {
        "host": "127.0.0.1",
        "port": 8545
    },
    "account": "./accounts/alice.pem",
    "contract":  {
        "solc": "./bin/solc-0.4.25",
        "source": "./contracts",
        "output": "./contracts/.output"
    },
    "authentication": {
        "ca_cert": "./authentication/gm/gmca.crt",
        "sign_cert": "./authentication/gm/gmsdk.crt",
        "sign_key": "./authentication/gm/gmsdk.key",
        "enc_key": "./authentication/gm/gmensdk.key",
        "enc_cert": "./authentication/gm/gmensdk.crt"
    },
    "sm_crypto": false,
    "group_id": 1,
    "chain_id": 1,
    "timeout_seconds": 10
}

每一项的解释如下:

  • service_type:服务类型,可用值为:rpcchannel

  • node:服务节点信息,包含以下属性:

    • host:服务节点主机地址。
    • port:服务节点端口号。
  • account:用户证书文件路径(仅支持 pem 格式)。

  • contract:合约相关配置,包含以下属性:

    • solc:Solidity 编译器所在路径。
    • source:Solidity 合约源文件所在路径。
    • output:Solidity 合约编译后的 abibin 文件输出目录(该目录需自行创建)。
  • authentication:节点验证配置信息,包含以下属性:

    • ca_cert:CA 证书文件路径。
    • sign_cert:签名证书文件路径。
    • sign_key:签名密钥文件路径。
    • enc_key:enc 密钥文件路径(非国密模式下无需设置)。
    • enc_cert:enc 证书文件路径(非国密模式下无需设置)。
  • sm_crypto:交易签名是否使用国密

  • group_id:组 ID。

  • chain_id:链 ID。

  • timeout_seconds: 网络请求过期时间(单位为秒)。

注:配置项中 accountcontractauthentication 中的路径如果使用相对路径,它的参考路径为该配置文件所在路径。

二、Web3Service

Web3Service 是对 FISCO BCOS JSON-RPC 的封装。

2.1 实例化

use fisco_bcos_service::create_web3_service;

let config_file_path = "./configs/config.json";
let web3_service = create_web3_service(config_file_path).unwrap();

2.2 接口

  • 接口列表:

    • get_client_version
    • get_block_number
    • get_pbft_view
    • get_sealer_list
    • get_observer_list
    • get_consensus_status
    • get_sync_status
    • get_peers
    • get_group_peers
    • get_node_id_list
    • get_group_list
    • get_block_by_hash
    • get_block_by_number
    • get_block_header_by_hash
    • get_block_header_by_number
    • get_block_hash_by_number
    • get_transaction_by_hash
    • get_transaction_by_block_hash_and_index
    • get_transaction_by_block_number_and_index
    • get_transaction_receipt
    • get_pending_transactions
    • get_pending_tx_size
    • get_code
    • get_total_transaction_count
    • get_system_config_by_key
    • call
    • send_raw_transaction
    • send_raw_transaction_and_get_proof
    • deploy
    • compile
    • get_transaction_by_hash_with_proof
    • get_transaction_receipt_by_hash_with_proof
    • generate_group
    • start_group
    • stop_group
    • remove_group
    • recover_group
    • query_group_status
    • get_node_info
    • get_batch_receipts_by_block_number_and_range
    • get_batch_receipts_by_block_hash_and_range
  • 接口将 FISCO BCOS JSON-RPC 返回的 error 属性转换成了 fisco_bcos_service::web3::service::ServiceError::FiscoBcosError 异常并返回,包含以下属性:

    • code:错误类型,详情参见:错误码描述
    • message:错误信息。
  • call 的返回值结构与相关 JSON-RPC 方法不一致外,其余接口的返回值结构参见 FISCO BCOS JSON-RPC 中相关方法返回值中的 result 属性。

  • 调用 callsend_raw_transactionsend_raw_transaction_and_get_proofdeploy 之前,请确保相关合约的 abibin 文件已存放在配置属性 contract.output 中的指定目录下,你可点击以下链接 download_solc.sh 下载编译器后自行编译,也可调用 compile 接口编译。

  • deploy 的返回值结构如下所示:

    {
      "status": "0x0",
      "transactionHash": "0x31ad4fd454fbe72557cbcb55bde067cfcd80fa43e9d97bdf2c13d2007f066370",
      "contractAddress": "0x62195d0f77f66c445c4878b845f55d266875705d"
    }
    
  • 接口中的 Token 实为 ethabi::token::Token,具体使用参见 ethabi token,在使用过程中无需安装 ethabi 依赖,只需引用 fisco_bcos_service::ethabi::token::Token 即可。

三、SystemConfigService

SystemConfigService 是对预编译合约 SystemConfigPrecompiled 的封装。

3.1 实例化

use fisco_bcos_service::{
    create_web3_service,
    precompiled::system_config_service::SystemConfigService,
};

let config_file_path = "./configs/config.json";
let web3_service = create_web3_service(config_file_path).unwrap();
let system_config_service = SystemConfigService::new(&web3_service);

3.2 接口

  • 接口列表:

    • set_value_by_key
  • 以上接口的返回值如果大于等于 0,返回此值,否则返回 fisco_bcos_service::precompiled::precompiled_service::PrecompiledServiceError 异常,包含以下属性:

    • code:错误类型。
    • message:错误信息。

四、TableCRUDService

TableCRUDService 是对预编译合约 TableFactoryCRUDPrecompiled 的封装。

4.1 实例化

use fisco_bcos_service::{
    create_web3_service,
    precompiled::table_crud_service::TableCRUDService,
};

let config_file_path = "./configs/config.json";
let web3_service = create_web3_service(config_file_path).unwrap();
let table_crud_service = TableCRUDService::new(&web3_service);

4.2 接口

  • 接口列表:

    • create_table
    • insert
    • remove
    • select
    • update
    • desc
  • 接口 create_tableinsertremoveupdate 的返回值如果大于等于 0,返回此值,否则返回 fisco_bcos_service::precompiled::precompiled_service::PrecompiledServiceError 异常,包含以下属性:

    • code:错误类型。
    • message:错误信息。
  • 接口 select 会将返回值由 string 转换成 Vec<serde_json::Value> 格式。

  • 接口 desc 返回 (String, Vec<String>) 类型,其中第一个值为主键字段,第二个值为普通字段列表。

五、SQLService

通过 SQLService ,我们可以以 SQL 语句的方式来操作 TableCRUDService 相关接口。

5.1 实例化

use fisco_bcos_service::{
    create_web3_service,
    sql_service::SQLService,
};

let config_file_path = "./configs/config.json";
let web3_service = create_web3_service(config_file_path).unwrap();
let sql_service = SQLService::new(&web3_service);

5.2 接口

  • 接口列表:

    • execute
  • CREATE TABLE 语句中,将忽略指定的字段类型,并且通过指定 PRIMARY KEY(有且仅有一个)来设置表单的 key 字段。

  • INSERT 语句中,必须设置 key 字段的值。

  • SELECT 语句中,不支持联表查询。

  • SELECTUPDATEDELETE 语句中,where 语句中必须指定 key 字段的值,多个语句之间仅支持 AND 操作(比如 name = "Tom" and age = "18"),单个条件仅支持 =!=><>=<= 操作,条件的值必须为字面值。

六、ConsensusService

ConsensusService 是对预编译合约 ConsensusPrecompiled 的封装。

6.1 实例化

use fisco_bcos_service::{
    create_web3_service,
    precompiled::consensus_service::ConsensusService,
};

let config_file_path = "./configs/config.json";
let web3_service = create_web3_service(config_file_path).unwrap();
let consensus_service = ConsensusService::new(&web3_service);

6.2 接口

  • 接口列表:

    • add_sealer
    • add_observer
    • remove
  • 以上接口的返回值如果大于等于 0,返回此值,否则返回 fisco_bcos_service::precompiled::precompiled_service::PrecompiledServiceError 异常,包含以下属性:

    • code:错误类型。
    • message:错误信息。

七、CNSService

CNSService 是对预编译合约 CNSPrecompiled 的封装。

7.1 实例化

use fisco_bcos_service::{
    create_web3_service,
    cns_service::CNSService,
};

let config_file_path = "./configs/config.json";
let web3_service = create_web3_service(config_file_path).unwrap();
let cns_service = CNSService::new(&web3_service);

7.2 接口

  • 接口列表:

    • insert
    • select_by_name
    • select_by_name_and_version
    • get_contract_address
  • 接口 insert 的返回值如果大于等于 0,返回此值,否则返回 fisco_bcos_service::precompiled::precompiled_service::PrecompiledServiceError 异常,包含以下属性:

    • code:错误类型。
    • message:错误信息。
  • 接口 select_by_nameselect_by_name_and_version 会将返回值由 string 转换成 serde_json::Value 格式。

  • 接口 get_contract_address 会将返回值由 address 转换成 String 格式。

八、PermissionService

PermissionService 是对预编译合约 PermissionPrecompiled 的封装。

8.1 实例化

use fisco_bcos_service::{
    create_web3_service,
    permission_service::PermissionService,
};

let config_file_path = "./configs/config.json";
let web3_service = create_web3_service(config_file_path).unwrap();
let permission_service = PermissionService::new(&web3_service);

8.2 接口

  • 接口列表:

    • insert
    • remove
    • query_by_name
    • grant_write
    • revoke_write
    • query_permission
  • 接口 insertremovegrant_writerevoke_write 的返回值如果大于等于 0,返回此值,否则返回 fisco_bcos_service::precompiled::precompiled_service::PrecompiledServiceError 异常,包含以下属性:

    • code:错误类型。
    • message:错误信息。
  • 接口 query_by_namequery_permission 会将返回值由 string 转换成 serde_json::Value 格式。

九、ContractLifeCycleService

ContractLifeCycleService 是对预编译合约 ContractLifeCyclePrecompiled 的封装。

9.1 实例化

use fisco_bcos_service::{
    create_web3_service,
    contract_life_cycle_service::ContractLifeCycleService,
};

let config_file_path = "./configs/config.json";
let web3_service = create_web3_service(config_file_path).unwrap();
let contract_life_cycle_service = ContractLifeCycleService::new(&web3_service);

9.2 接口

  • 接口列表:

    • freeze
    • unfreeze
    • grant_manager
    • get_status
    • list_manager
  • 接口 freezeunfreezegrant_manager 的返回值如果大于等于 0,返回此值,否则返回 fisco_bcos_service::precompiled::precompiled_service::PrecompiledServiceError 异常,包含以下属性:

    • code:错误类型。
    • message:错误信息。
  • 接口 get_status 的返回值为 (i32, String),其中如果 i32 的值小于 0,将返回 fisco_bcos_service::precompiled::precompiled_service::PrecompiledServiceError 异常。

  • 接口 list_manager 的返回值为 (i32, Vec<String>),其中如果 i32 的值小于 0,将返回 fisco_bcos_service::precompiled::precompiled_service::PrecompiledServiceError 异常。

十、ChainGovernanceService

ChainGovernanceService 是对预编译合约 ChainGovernancePrecompiled 的封装。

10.1 实例化

use fisco_bcos_service::{
    create_web3_service,
    chain_governance_service::ChainGovernanceService,
};

let config_file_path = "./configs/config.json";
let web3_service = create_web3_service(config_file_path).unwrap();
let chain_governance_service = ChainGovernanceService::new(&web3_service);

10.2 接口

  • 接口列表:

    • grant_committee_member
    • revoke_committee_member
    • list_committee_members
    • query_committee_member_weight
    • update_committee_member_weight
    • query_votes_of_member
    • query_votes_of_threshold
    • update_threshold
    • query_threshold
    • grant_operator
    • revoke_operator
    • list_operators
    • freeze_account
    • unfreeze_account
    • get_account_status
  • 接口 grant_committee_memberrevoke_committee_memberupdate_committee_member_weightupdate_thresholdquery_thresholdgrant_operatorrevoke_operatorfreeze_accountunfreeze_account 的返回值如果大于等于 0,返回此值,否则返回 fisco_bcos_service::precompiled::precompiled_service::PrecompiledServiceError 异常,包含以下属性:

    • code:错误类型。
    • message:错误信息。
  • 接口 query_committee_member_weight 的返回值为 (bool, i32),其中如果 i32 的值小于 0,将返回 fisco_bcos_service::precompiled::precompiled_service::PrecompiledServiceError 异常。

  • 接口 list_committee_membersquery_votes_of_memberquery_votes_of_thresholdlist_operators 会将返回值由 string 转换成 serde_json::Value 格式。

十一、EventService

通过 EventService,可对合约时间进行监听。

11.1 实例化

use fisco_bcos_service::create_event_service;

let config_file_path = "./configs/config.json";
let event_service = create_event_service(config_file_path).unwrap();

11.2 接口

  • 接口列表:

    • register_block_notify_listener
    • remove_block_notify_listener
    • run_block_notify_loop
    • stop_block_notify_loop
    • register_event_log_listener
    • remove_event_log_listener
    • run_event_log_loop
    • stop_event_log_loop
  • 接口 run_block_notify_looprun_event_log_loop 最后两个参数的意义如下:

    • sleep_seconds:链上数据读取失败后,进入下一轮监听前要等待的时间(单位为秒)。
    • max_retry_times:链上数据读取失败后,最大重试次数,如果失败次数大于指定的值,将主动终止 loop。当值为 -1 时,表示无限循环。
  • 接口 run_block_notify_loop 会一直运行下去,想要终止需调用 stop_block_notify_loop 接口,因此一般需要开启新的线程来运行 run_block_notify_loop,比如下面的例子:

    use std::sync::Arc;
    use std::thread;
    use std::time::Duration;
    use fisco_bcos_service::create_event_service;
    
    let event_service = create_event_service("./configs/config.json").unwrap();
    event_service.register_block_notify_listener(1, |v| println!("{:?}", v));
    
    let event_service_arc = Arc::new(event_service);
    let block_notify_loop_service = event_service_arc.clone();
    let block_notify_loop_handle = thread::spawn(move || {
        block_notify_loop_service.run_block_notify_loop(1, 1, -1);
    });
    thread::sleep(Duration::from_millis((10 * 1000) as u64));
    event_service_arc.clone().stop_block_notify_loop(1);
    block_notify_loop_handle.join().unwrap();
    
  • 调用 stop_block_notify_loop 后,run_block_notify_loop 并不会立即终止,而是等到当前一轮监听返回后才终止。

  • 接口 run_event_log_loop 会一直运行下去,想要终止需调用 stop_event_log_loop 接口,因此一般需要开启新的线程来运行 run_event_log_loop,比如下面的例子:

    use std::sync::Arc;
    use std::thread;
    use std::time::Duration;
    use fisco_bcos_service::create_event_service;
    use fisco_bcos_service::event::event_log_param::EventLogParam;
    use fisco_bcos_service::event::parse_event_log;
    use fisco_bcos_service::event::topic::{from_event_signature, from_integer};
    
    let event_log_param = EventLogParam::new();
    event_log_param.add_address("0xf2df2e7c2a2dc9bd23523f4272e1de1d08d1e9a9");
    event_log_param.add_topic(&from_event_signature("event2(string,int256)", false));
    event_log_param.add_topic(&from_integer(0));
    
    let event_service = create_event_service("./configs/config.json").unwrap();
    event_service.register_event_log_listener(&event_log_param, |v| {
       match v {
           Ok(value) => {
               let logs = parse_event_log(
                   value, "event2",
                   r#"{"anonymous":false,"inputs":[{"indexed":false,"name":"s","type":"string"},{"indexed":true,"name":"n","type":"int256"}],"name":"event2","type":"event"}"#,
                   false,
               ).unwrap();
               println!("{:?}", logs);
           },
           _ => {}
       }
    });
    
    let event_service_arc = Arc::new(event_service);
    let event_log_param_arc = Arc::new(event_log_param);
    let event_log_loop_service = event_service_arc.clone();
    let event_log_loop_param = event_log_param_arc.clone();
    let event_log_loop_handle = thread::spawn(move || {
        event_log_loop_service.run_event_log_loop(&event_log_loop_param, 1, -1);
    });
    thread::sleep(Duration::from_millis((10 * 1000) as u64));
    event_service_arc.clone().stop_event_log_loop(&event_log_param_arc.clone());
    event_log_loop_handle.join().unwrap();
    
  • 调用 stop_event_log_loop 后,run_event_log_loop 并不会立即终止,而是等到当前一轮监听返回后才终止。

十二、注意事项

  • 所有接口除特殊说明外均为异步调用(使用了 Rust 的 async 特性)。

License

Apache-2.0

Dependencies

~19–30MB
~413K SLoC