结果集会根据是否按照json格式输出而做出相应处理,如果不是json格式,要进行事务打包packed,这个之前也分析过。本接口实现函数内容较多,鉴于接口本身使用并不频繁,这里不展开研究。
17. abi数据明文json转二进制 abi_json_to_bin入参结构:
struct abi_json_to_bin_params { name code; // 合约owner账户 name action; // action名字 fc::variant args; // action参数,json明文格式 };返回值就是二进制串集合。实现函数:
read_only::abi_json_to_bin_result read_only::abi_json_to_bin( const read_only::abi_json_to_bin_params& params )const try { abi_json_to_bin_result result; const auto code_account = db.db().find<account_object,by_name>( params.code ); // 找到合约owner账户 EOS_ASSERT(code_account != nullptr, contract_query_exception, "Contract can't be found ${contract}", ("contract", params.code)); abi_def abi; if( abi_serializer::to_abi(code_account->abi, abi) ) {// 反序列化解析abi abi_serializer abis( abi, abi_serializer_max_time ); auto action_type = abis.get_action_type(params.action); // 获得action类型,在abi的action中寻找目标action EOS_ASSERT(!action_type.empty(), action_validate_exception, "Unknown action ${action} in contract ${contract}", ("action", params.action)("contract", params.code)); try { result.binargs = abis.variant_to_binary( action_type, params.args, abi_serializer_max_time, shorten_abi_errors ); //将入参args由json转为二进制 } EOS_RETHROW_EXCEPTIONS(chain::invalid_action_args_exception, "'${args}' is invalid args for action '${action}' code '${code}'. expected '${proto}'", ("args", params.args)("action", params.action)("code", params.code)("proto", action_abi_to_variant(abi, action_type))) } else { EOS_ASSERT(false, abi_not_found_exception, "No ABI found for ${contract}", ("contract", params.code)); } return result; } FC_RETHROW_EXCEPTIONS( warn, "code: ${code}, action: ${action}, args: ${args}", ("code", params.code)( "action", params.action )( "args", params.args ))实际上的转换工作是由variant_to_binary函数执行的。
18. abi数据二进制转明文json abi_bin_to_json功能正好与上一个接口相反。入参结构中唯一不同的字段是json格式的args改为了二进制类型的binargs,实际上这个二进制是字符的集合vector<char>。返回值是json格式。函数实现与上面类似,不再展示。实际的转换工作是由binary_to_variant函数执行的。总结这两个接口实现函数可以发现,binary对应的就是二进制数据格式,而variant变体对应的是json格式。
19. 获取必须密钥 get_required_keys传入使用密钥的transaction(json格式),以及当前支持的密钥集合。
read_only::get_required_keys_result read_only::get_required_keys( const get_required_keys_params& params )const { transaction pretty_input; auto resolver = make_resolver(this, abi_serializer_max_time); try { abi_serializer::from_variant(params.transaction, pretty_input, resolver, abi_serializer_max_time);//根据明文json事务,通过abi序列化器将数据输出到pretty_input,转为transaction对象。 } EOS_RETHROW_EXCEPTIONS(chain::transaction_type_exception, "Invalid transaction") // 通过认证管理器获得必须密钥 auto required_keys_set = db.get_authorization_manager().get_required_keys( pretty_input, params.available_keys, fc::seconds( pretty_input.delay_sec )); get_required_keys_result result; result.required_keys = required_keys_set; return result; }所以核心处理函数为认证管理器authorization_manager的get_required_keys函数:
flat_set<public_key_type> authorization_manager::get_required_keys( const transaction& trx, const flat_set<public_key_type>& candidate_keys, fc::microseconds provided_delay )const { auto checker = make_auth_checker( [&](const permission_level& p){ return get_permission(p).auth; },// 获取权限内容 _control.get_global_properties().configuration.max_authority_depth, // 当前全局属性的最大权限深度 candidate_keys, {}, provided_delay, _noop_checktime ); // 获取认证检查器 for (const auto& act : trx.actions ) { // 遍历事务的action for (const auto& declared_auth : act.authorization) { EOS_ASSERT( checker.satisfied(declared_auth), unsatisfied_authorization, "transaction declares authority '${auth}', but does not have signatures for it.", ("auth", declared_auth) );// 如果在密钥集合中发现没有能满足任意action需要的权限的,即报错提醒。 } } return checker.used_keys(); } 20. 获取事务id get_transaction_id入参对象会转为transaction结构,返回对象是transaction_id_type,过程就很简单了,因为本身transaction_id_type就是transaction的成员,因此将入参转型后直接返回对象的调用即可。
21. 异步读写操作:推送区块 push_block