asset.hpp是合约中关于资产方面的数据结构的定义。该文件包含asset结构体以及extended_asset结构体。下面首先分析asset结构体的源码部分。
struct asset { int64_t amount; // 资产数量 symbol_type symbol; // 资产符号名称,详见以下symbol_type源码分析。 static constexpr int64_t max_amount = (1LL << 62) - 1; // 资产数量最大值,取决于int64_t类型的取值范围。 // 通过给定的符号名称以及资产数量构建一个新的资产对象。 explicit asset(int64_t a = 0, symbol_type s = CORE_SYMBOL) : amount(a), symbol{s} { eosio_assert(is_amount_within_range(), "magnitude of asset amount must be less than 2^62"); eosio_assert(symbol.is_valid(), "invalid symbol name"); } // 检查资产数量是否在范围以内,是否超过了最大限额。 bool is_amount_within_range() const { return -max_amount <= amount && amount <= max_amount; } // 检查资产对象是否有效,有效资产的数量应该小于等于最大限额同时它的符号名称也是有效的。 bool is_valid() const { return is_amount_within_range() && symbol.is_valid(); } // 设置资产的数量 void set_amount(int64_t a) { amount = a; eosio_assert(is_amount_within_range(), "magnitude of asset amount must be less than 2^62"); } /** * 以下为资产对象的运算符重载,包含 * 取负,-=,+=,+,-,*=,*(数乘以资产,资产乘以数),/(资产除以数,资产除以资产),/=,==,!=,<,<=,>,>= * 源码部分省略。 */ // 打印资产 void print() const { int64_t p = (int64_t)symbol.precision(); int64_t p10 = 1; while (p > 0) { p10 *= 10; --p; } p = (int64_t)symbol.precision(); char fraction[p + 1]; fraction[p] = '\0'; auto change = amount % p10; for (int64_t i = p - 1; i >= 0; --i) { fraction[i] = (change % 10) + '0'; change /= 10; } printi(amount / p10); prints("."); prints_l(fraction, uint32_t(p)); prints(" "); symbol.print(false); } EOSLIB_SERIALIZE(asset, (amount)(symbol)) }; symbol_type直接通过源码注释分析,如下:
/** * @brief 存储关于符号相关的信息的结构体 */ struct symbol_type { symbol_name value; // uint64_t类型的符号名称 symbol_type() {} symbol_type(symbol_name s) : value(s) {} // 符号的类型 bool is_valid() const { return is_valid_symbol(value); } // 符号是否有效 uint64_t precision() const { return value & 0xff; } // 符号类型中包含对资产精度的要求,即小数点后包含几位数。 uint64_t name() const { return value >> 8; } // 返回代表符号名称的uint64_t的值 uint32_t name_length() const { return symbol_name_length(value); } // 返回符号名称的长度 operator symbol_name() const { return value; } //重载符号对象的()运算符,返回符号名称的uint64_t值 void print(bool show_precision = true) const { // 打印符号信息,包含uint64_t转字符的算法。 if (show_precision) { ::eosio::print(precision()); // 打印符号的精度 prints(","); } //uint64_t转字符 auto sym = value; sym >>= 8; for (int i = 0; i < 7; ++i) { char c = (char)(sym & 0xff); if (!c) return; prints_l(&c, 1); sym >>= 8; } } EOSLIB_SERIALIZE(symbol_type, (value)) }; extended_assetextended_asset,顾名思义是asset资产的延展类型,主要是在asset的基础上增加了资产拥有者的相关字段。内容不多仍旧通过源码分析一下:
struct extended_asset : public asset { account_name contract; // 资产拥有者 // 获得资产的扩展符号 extended_symbol get_extended_symbol() const { return extended_symbol(symbol, contract); } // 默认构造器,构造一个扩展资产对象 extended_asset() = default; // 通过给定的数量和扩展符号构造一个扩展资产对象。 extended_asset(int64_t v, extended_symbol s) : asset(v, s), contract(s.contract) {} // 通过给定的资产以及拥有者账户名构造一个扩展资产。 extended_asset(asset a, account_name c) : asset(a), contract(c) {} // 打印相关信息 void print() const { asset::print(); prints("@"); printn(contract); } /** * 运算符重载,包括符号取反,-,+ * 主要是对资产拥有者的操作,其他的操作于asset一致。 */ EOSLIB_SERIALIZE(extended_asset, (amount)(symbol)(contract)) }; 五、eosio.system.hpp下面查看system合约的主要头文件eosio.system.hpp,该文件包含了合约的属性,定义了大量结构体用于支撑system合约的业务功能,下面重点浏览system合约的成员属性。
成员 | 权属 | 解释
--- | --- | ---
_voters | 私有属性 | voters_table实例,投票状态表,表名为voters,结构为voter_info结构体。
_producers | 私有属性 | producers_table实例,生产者信息状态表,表名为produceers,包含一个自定义索引prototalvote,结构为producer_info结构体。
global | 私有属性 | global_state_singleton实例,全局状态单例状态表,表名为global,结构为eosio
global_state结构体,继承自eosio::block
-chain_parameters与genesis.json内容高度匹配。
_gstate | 私有属性 | eosio_global_state结构体实例,就是上面这个状态表的数据结构实例。
_rammarket | 私有属性 | rammarket实例,内存市场状态表,定义在exchange_state.hpp头文件中。表名为rammarket,结构为使用了bancor算法的exchange_state结构体。