您正在查看: EOS-新手教程 分类下的文章

EOS 合约 table primary key支持的类型

https://github.com/EOSIO/eos/blob/5082391c60b0fa5e68157c385cd402bf25aea934/plugins/chain_plugin/chain_plugin.cpp#L1158

read_only::get_table_rows_result read_only::get_table_rows( const read_only::get_table_rows_params& p )const {
   const abi_def abi = eosio::chain_apis::get_abi( db, p.code );
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
   bool primary = false;
   auto table_with_index = get_table_index_name( p, primary );
   if( primary ) {
      EOS_ASSERT( p.table == table_with_index, chain::contract_table_query_exception, "Invalid table name ${t}", ( "t", p.table ));
      auto table_type = get_table_type( abi, p.table );
      if( table_type == KEYi64 || p.key_type == "i64" || p.key_type == "name" ) {
         return get_table_rows_ex<key_value_index>(p,abi);
      }
      EOS_ASSERT( false, chain::contract_table_query_exception,  "Invalid table type ${type}", ("type",table_type)("abi",abi));
   } else {
      EOS_ASSERT( !p.key_type.empty(), chain::contract_table_query_exception, "key type required for non-primary index" );

      if (p.key_type == chain_apis::i64 || p.key_type == "name") {
         return get_table_rows_by_seckey<index64_index, uint64_t>(p, abi, [](uint64_t v)->uint64_t {
            return v;
         });
      }
      else if (p.key_type == chain_apis::i128) {
         return get_table_rows_by_seckey<index128_index, uint128_t>(p, abi, [](uint128_t v)->uint128_t {
            return v;
         });
      }
      else if (p.key_type == chain_apis::i256) {
         if ( p.encode_type == chain_apis::hex) {
            using  conv = keytype_converter<chain_apis::sha256,chain_apis::hex>;
            return get_table_rows_by_seckey<conv::index_type, conv::input_type>(p, abi, conv::function());
         }
         using  conv = keytype_converter<chain_apis::i256>;
         return get_table_rows_by_seckey<conv::index_type, conv::input_type>(p, abi, conv::function());
      }

结论

primary key 只支持uint64_tcapi_name
如果想支持其他类型只能用
二级索引支持了 index_position + key_type

官方解释

它们是多索引表,因为它们支持在数据上使用多个索引,主索引类型必须是uint64_t并且必须是唯一的,但其他次要索引可以具有重复项。最多可以有16个附加索引,字段类型可以是uint64_t,uint128_t,eosio::checksum256,double或long double

参考

https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables#section-introduction
https://developers.eos.io/eosio-nodeos/reference#get_table_rows
https://eosio.stackexchange.com/questions/3091/is-it-possible-to-use-a-type-other-than-uint64-t-for-a-table-primary-key/3097#3097

ScatterWebExtension popup window

https://github.com/GetScatter/ScatterWebExtension/blob/9d0f0946f8f53fe56c9a52afbeb55cc72c41f8e4/src/copied/prompt.html

https://github.com/GetScatter/ScatterWebExtension/blob/9d0f0946f8f53fe56c9a52afbeb55cc72c41f8e4/src/services/NotificationService.js#L38

const getPopup = async () => {
            try {
                const url = apis.runtime.getURL('/prompt.html');

                // Notifications get bound differently depending on browser
                // as Firefox does not support opening windows from background.
                if(typeof browser !== 'undefined') {
                    const created = await apis.windows.create({
                        url,
                        height,
                        width,
                        type:'popup'
                    });

                    window.notification = notification;
                    return created;
                }
                else {
                    const win = window.open(url, 'ScatterPrompt', `width=${width},height=${height},resizable=0,top=${middleY},left=${middleX},titlebar=0`);
                    win.data = notification;
                    openWindow = win;
                    return win;
                }
            } catch (e) {
                console.log('notification error', e);
                return null;
            }
        }

EOS合约内查询代币余额

#include <eosiolib/eosio.token.hpp>   // right path to eosio.token.hpp file
void getBalance(account_name owner){
    eosio::token t(N(eosio.token));
    const auto sym_name = eosio::symbol_type(S(4,EOS)).name();
    const auto my_balance = t.get_balance(N(owner), sym_name );
    eosio::print("My balance is ", my_balance);
}

https://eosio.stackexchange.com/questions/375/how-can-i-get-my-contract-currency-balance-with-c-code?rq=1

action data pack/unpack

// pack action data
   string unpacked_action_data_account_string;
   string unpacked_action_data_name_string;
   string unpacked_action_data_string;
   auto pack_action_data = convert->add_subcommand("pack_action_data", localized("From json action data to packed form"));
   pack_action_data->add_option("account", unpacked_action_data_account_string, localized("The name of the account that hosts the contract"))->required();
   pack_action_data->add_option("name", unpacked_action_data_name_string, localized("The name of the function that's called by this action"))->required();
   pack_action_data->add_option("unpacked_action_data", unpacked_action_data_string, localized("The action data expressed as json"))->required();
   pack_action_data->set_callback([&] {
      fc::variant unpacked_action_data_json;
      try {
         unpacked_action_data_json = json_from_file_or_string(unpacked_action_data_string);
      } EOS_RETHROW_EXCEPTIONS(transaction_type_exception, "Fail to parse unpacked action data JSON")
      bytes packed_action_data_string = variant_to_bin(unpacked_action_data_account_string, unpacked_action_data_name_string, unpacked_action_data_json);
      std::cout << fc::to_hex(packed_action_data_string.data(), packed_action_data_string.size()) << std::endl;
   });

   // unpack action data
   string packed_action_data_account_string;
   string packed_action_data_name_string;
   string packed_action_data_string;
   auto unpack_action_data = convert->add_subcommand("unpack_action_data", localized("From packed to json action data form"));
   unpack_action_data->add_option("account", packed_action_data_account_string, localized("The name of the account that hosts the contract"))->required();
   unpack_action_data->add_option("name", packed_action_data_name_string, localized("The name of the function that's called by this action"))->required();
   unpack_action_data->add_option("packed_action_data", packed_action_data_string, localized("The action data expressed as packed hex string"))->required();
   unpack_action_data->set_callback([&] {
      EOS_ASSERT( packed_action_data_string.size() >= 2, transaction_type_exception, "No packed_action_data found" );
      vector<char> packed_action_data_blob(packed_action_data_string.size()/2);
      fc::from_hex(packed_action_data_string, packed_action_data_blob.data(), packed_action_data_blob.size());
      fc::variant unpacked_action_data_json = bin_to_variant(packed_action_data_account_string, packed_action_data_name_string, packed_action_data_blob);
      std::cout << fc::json::to_pretty_string(unpacked_action_data_json) << std::endl;
   });

https://github.com/EOSIO/eos/blob/686f0deb5dac097cc292f735ccb47c238e763de0/programs/cleos/main.cpp#L2401

https://github.com/EOSIO/eos/blob/686f0deb5dac097cc292f735ccb47c238e763de0/programs/cleos/main.cpp#L2418

EOS 插入数据的RAM消耗

context.add_ram_usage(
    l.account,
    (int64_t)(config::billable_size_v<permission_link_object>)
);

https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/eosio_contract.cpp#L340