EOS多索引表开发

作者: 编程狂魔 | 来源:发表于2018-08-20 14:13 被阅读15次

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

    为了深入和清晰的了解多索引表,最终的.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" );
          }
       }
    }
    

    删除表

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

    ======================================================================

    分享一个交互式的在线编程实战,EOS智能合约与DApp开发入门

    EOS教程

    本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。

    • web3j教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
    • 以太坊教程,主要介绍智能合约与dapp应用开发,适合入门。
    • 以太坊开发,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
    • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
    • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和事件等内容。
    • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和事件等。

    汇智网原创翻译,转载请标明出处。这里是原文

    相关文章

      网友评论

        本文标题:EOS多索引表开发

        本文链接:https://www.haomeiwen.com/subject/oafliftx.html