action.hpp 4.1 KB
Newer Older
1 2 3 4
/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
5
#pragma once
6 7 8
#include <eosiolib/action.h>
#include <eosiolib/datastream.hpp>
#include <eosiolib/serialize.hpp>
9

P
Pravin 已提交
10
namespace eosio {
11 12

   /**
13 14 15
    * @defgroup actioncppapi Action C++ API
    * @ingroup actionapi
    * @brief Type-safe C++ wrapers for Action C API
16
    *
17
    * @note There are some methods from the @ref actioncapi that can be used directly from C++
18
    *
19
    * @{
20 21 22
    */

   /**
23
    *
24 25
    *  This method attempts to reinterpret the action body as type T. This will only work
    *  if the action has no dynamic fields and the struct packing on type T is properly defined.
26
    *
27
    *  @brief Interpret the action body as type T
28 29
    *  
    *  Example:
30
    *  @code
31
    *  struct dummy_action {
32 33 34
    *    char a; //1
    *    unsigned long long b; //8
    *    int  c; //4
35
    *  };
36
    *  dummy_action msg = current_action<dummy_action>();
37
    *  @endcode
38 39
    */
   template<typename T>
40
   T current_action() {
41
      T value;
42
      auto read = read_action( &value, sizeof(value) );
43
      eosio_assert( read >= sizeof(value), "action shorter than expected" );
44 45 46
      return value;
   }

47 48 49 50
   template<typename T>
   T unpack_action() {
      char buffer[action_size()];
      read_action( buffer, sizeof(buffer) );
51
      return unpack<T>( buffer, sizeof(buffer) );
52 53
   }

54
   using ::require_auth;
55
   using ::require_recipient;
56 57

   /**
58
    *  All of the listed accounts will be added to the set of accounts to be notified
59
    *
60
    *  This helper method enables you to add multiple accounts to accounts to be notified list with a single
61 62
    *  call rather than having to call the similar C API multiple times.
    *
63
    *  @note action.code is also considered as part of the set of notified accounts
64 65
    *
    *  @brief Verify specified accounts exist in the set of notified accounts
66 67
    *
    *  Example:
68
    *  @code
69
    *  require_recipient(N(Account1), N(Account2), N(Account3)); // throws exception if any of them not in set.
70
    *  @endcode
71
    */
72
   template<typename... accounts>
73 74 75
   void require_recipient( account_name name, accounts... remaining_accounts ){
      require_recipient( name );
      require_recipient( remaining_accounts... );
76 77
   }

D
Daniel Larimer 已提交
78
   struct permission_level {
79 80 81
      permission_level( account_name a, permission_name p ):actor(a),permission(p){}
      permission_level(){}

D
Daniel Larimer 已提交
82 83
      account_name    actor;
      permission_name permission;
84

85
      EOSLIB_SERIALIZE( permission_level, (actor)(permission) )
D
Daniel Larimer 已提交
86
   };
87

D
Daniel Larimer 已提交
88 89 90 91
   /**
    * This is the packed representation of an action along with
    * meta-data about the authorization levels.
    */
D
Daniel Larimer 已提交
92
   struct action {
93
      account_name               account;
D
Daniel Larimer 已提交
94 95
      action_name                name;
      vector<permission_level>   authorization;
96 97 98
      bytes                      data;

      action() = default;
D
Daniel Larimer 已提交
99

D
Daniel Larimer 已提交
100 101
      /**
       *  @tparam Action - a type derived from action_meta<Scope,Name>
102
       *  @param value - will be serialized via pack into data
D
Daniel Larimer 已提交
103 104
       */
      template<typename Action>
105 106
      action( vector<permission_level>&& auth, const Action& value ) {
         account       = Action::get_account();
D
Daniel Larimer 已提交
107
         name          = Action::get_name();
D
Daniel Larimer 已提交
108
         authorization = move(auth);
109
         data          = pack(value);
D
Daniel Larimer 已提交
110
      }
111 112


113 114
      /**
       *  @tparam Action - a type derived from action_meta<Scope,Name>
115
       *  @param value - will be serialized via pack into data
116 117 118
       */
      template<typename Action>
      action( const permission_level& auth, const Action& value )
119
      :authorization(1,auth) {
120 121
         account       = Action::get_account();
         name          = Action::get_name();
122
         data          = pack(value);
123 124
      }

125
      EOSLIB_SERIALIZE( action, (account)(name)(authorization)(data) )
126 127

      void send() const {
128
         auto serialize = pack(*this);
129 130
         ::send_inline(serialize.data(), serialize.size());
      }
D
Daniel Larimer 已提交
131 132
   };

D
Daniel Larimer 已提交
133
   template<uint64_t Account, uint64_t Name>
D
Daniel Larimer 已提交
134
   struct action_meta {
D
Daniel Larimer 已提交
135 136
      static uint64_t get_account() { return Account; }
      static uint64_t get_name()  { return Name; }
D
Daniel Larimer 已提交
137 138
   };

D
Daniel Larimer 已提交
139

140
 ///@} actioncpp api
141

D
Daniel Larimer 已提交
142 143
} // namespace eosio

144

145
#define ACTION( CODE, NAME ) struct NAME : ::eosio::action_meta<CODE, ::eosio::string_to_name(#NAME) >