EOS EOS 多索引表使用指南

pendingauth · 2018年10月31日 · 148 次阅读

本文转载自汇智网官博,原译文链接:http://blog.hubwiz.com/2018/08/17/EOS-multi-index-tables-Usage-Guide/

下面是多索引表的使用指南。

为了深入和清晰的了解多索引表,最终的.cpp文件部分将被进一步详细讨论和讨论。注意,完整的.cpp文件可以在页面的底部找到。

词汇表

  • code :是指已公布智能合约的account_name
  • scope:account_name所涉及数据范围。
  • table_name: 存储在内存中的表的名称。

代码分解

要存储的结构

要在多索引表中存储的数据是limit_order结构。primary_key()get_expiration()get_price()函数用于返回表。返回的表将根据调用的函数排序。

struct limit_order {  
  uint64_t     id;  
  uint128_t    price;  
  uint64_t     expiration;  
  account_name owner;  

  auto primary_key() const { return id; }  
  uint64_t get_expiration() const { return expiration; }  
  uint128_t get_price() const { return price; }  

  EOSLIB_SERIALIZE( limit_order, ( id )( price )( expiration )( owner ) )  
};  

建一个多索引表

auto payer = ilm.get_account();  
...  

payer是保存帐户的变量,它将账单元素添加到多索引表中,并修改已经在多索引表中的元素。

...  
eosio::multi_index< N( orders ), limit_order,   
...  

N(orders)是多索引表的名称,limit_order是要存储在表中的数据。

...    
indexed_by< N( byexp ), const_mem_fun< limit_order, uint64_t,   
&limit_order::get_expiration> >,  
...  

indexed_by< N( byexp ), const_mem_fun< limit_order, uint64_t, &limit_order::get_expiration> >定义了多索引表的索引方式。N(byexp)是这个索引的名称。const_mem_fun表示正在查询的数据类型、limit_order的变量的类型是uint64_t,将使用get_expiration函数获取变量。

...  
  indexed_by< N( byprice ), const_mem_fun< limit_order, uint128_t, &limit_order::get_price> >  
...  

indexed_by< N( byprice ), const_mem_fun< limit_order, uint128_t, &limit_order::get_price> >定义了多索引表的索引方式。N(byprice)是这个索引的名称。const_mem_fun表示正在查询的数据类型、limit_order的变量的类型是uint128_t,将使用get_price函数获取变量。

orders( N( limitorders ), N( limitorders )  

orders即是多索引表。

auto payer = ilm.get_account();  

print("Creating multi index table 'orders'.\n");  
eosio::multi_index< N( orders ), limit_order,   
  indexed_by< N( byexp ),   const_mem_fun< limit_order, uint64_t, &limit_order::get_expiration> >,  
  indexed_by< N( byprice ), const_mem_fun< limit_order, uint128_t, &limit_order::get_price> >  
    > orders( N( limitorders ), N( limitorders ) );  

添加多索引表

下面,将两个limit_order添加到orders表中。请注意,payer是正在修改orders表的“账单”帐户。

orders.emplace( payer, [&]( auto& o ) {  
  o.id = 1;  
  o.expiration = 300;  
  o.owner = N(dan);  
});  

auto order2 = orders.emplace( payer, [&]( auto& o ) {  
  o.id = 2;  
  o.expiration = 200;  
  o.owner = N(thomas);  
});  

按照主键排序

默认的orders表按照主键排序。

print("Items sorted by primary key:\n");  
for( const auto& item : orders ) {  
  print(" ID=", item.id, ", expiration=", item.expiration, ", owner=", name{item.owner}, "\n");  
}  

按第二索引expiration排序

orders表通过expiration进行排序并分配给expidx

auto expidx = orders.get_index<N(byexp)>();  

print("Items sorted by expiration:\n");  
for( const auto& item : expidx ) {  
  print(" ID=", item.id, ", expiration=", item.expiration, ", owner=", name{item.owner}, "\n");  
}  

按第二索引price排序

orders表通过price进行排序并分配给oridx

auto pridx = orders.get_index<N(byprice)>();  

print("Items sorted by price:\n");  
for( const auto& item : pridx ) {  
  print(" ID=", item.id, ", expiration=", item.expiration, ", owner=", name{item.owner}, "\n");  
}  

修改一个输入值

下面,“ID=2”的条目被修改。请注意,payer是正在修改orders表的“账单”帐户。

print("Modifying expiration of order with ID=2 to 400.\n");  
orders.modify( order2, payer, [&]( auto& o ) {  
  o.expiration = 400;  
});  

得到一个最小值

auto lower = expidx.lower_bound(100);  

print("First order with an expiration of at least 100 has ID=", lower->id, " and expiration=", lower->get_expiration(), "\n");  

完整的.cpp文件

#include <eosiolib/eosio.hpp>  
   #include <eosiolib/dispatcher.hpp>  
   #include <eosiolib/multi_index.hpp>  

   using namespace eosio;  

   namespace limit_order_table {  

       struct limit_order {  
           uint64_t     id;  
           uint128_t    price;  
           uint64_t     expiration;  
           account_name owner;  

           auto primary_key() const { return id; }  
           uint64_t get_expiration() const { return expiration; }  
           uint128_t get_price() const { return price; }  

           EOSLIB_SERIALIZE( limit_order, ( id )( price )( expiration )( owner ) )  
       };  

       class limit_order_table {  
           public:  

           ACTION( N( limitorders ), issue_limit_order ) {  
               EOSLIB_SERIALIZE( issue_limit_order )  
           };  

           static void on( const issue_limit_order& ilm ) {  
               auto payer = ilm.get_account();  

               print("Creating multi index table 'orders'.\n");  
               eosio::multi_index< N( orders ), limit_order,   
                   indexed_by< N( byexp ),   const_mem_fun< limit_order, uint64_t, &limit_order::get_expiration> >,  
                   indexed_by< N( byprice ), const_mem_fun< limit_order, uint128_t, &limit_order::get_price> >  
                   > orders( N( limitorders ), N( limitorders ) );  

               orders.emplace( payer, [&]( auto& o ) {  
                   o.id = 1;  
                   o.expiration = 300;  
                   o.owner = N(dan);  
               });  

               auto order2 = orders.emplace( payer, [&]( auto& o ) {  
                   o.id = 2;  
                   o.expiration = 200;  
                   o.owner = N(thomas);  
               });  

               print("Items sorted by primary key:\n");  
               for( const auto& item : orders ) {  
                   print(" ID=", item.id, ", expiration=", item.expiration, ", owner=", name{item.owner}, "\n");  
               }  

               auto expidx = orders.get_index<N(byexp)>();  

               print("Items sorted by expiration:\n");  
               for( const auto& item : expidx ) {  
                   print(" ID=", item.id, ", expiration=", item.expiration, ", owner=", name{item.owner}, "\n");  
               }  

               auto pridx = orders.get_index<N(byprice)>();  

               print("Items sorted by price:\n");  
               for( const auto& item : pridx ) {  
                   print(" ID=", item.id, ", expiration=", item.expiration, ", owner=", name{item.owner}, "\n");  
               }  

               print("Modifying expiration of order with ID=2 to 400.\n");  
               orders.modify( order2, payer, [&]( auto& o ) {  
                   o.expiration = 400;  
               });  

               auto lower = expidx.lower_bound(100);  

               print("First order with an expiration of at least 100 has ID=", lower->id, " and expiration=", lower->get_expiration(), "\n");  
      };  

   } /// limit_order_table  

   namespace limit_order_table {  
      extern "C" {  
         /// The apply method implements the dispatch of events to this contract  
         void apply( uint64_t code, uint64_t action ) {  
            require_auth( code );  
            eosio_assert( eosio::dispatch< limit_order_table, limit_order_table::issue_limit_order >( code, action ), "Could not dispatch" );  
         }  
      }  
   }  

删除表

表不能直接删除,但是,在删除所有行之后,表将自动删除。

这里是原文

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册