天天看點

EOS合約開發第十一章-合約執行上下文

目前請求執行的上下文環境主要包含以下幾類:

1. action資料

read_action_data擷取了action調用的完整資料

get_action擷取action的方法名稱

action_data_size擷取action調用完整資料的大小

2. 上下文free data

get_context_free_data擷取action執行請求時指定的free data

3. transaction相關

transaction_size

4. 節點相關

get_active_producers擷取激活的産快節點

5. 權限驗證相關

require_auth驗證賬戶是否在請求的簽名中

require_recipient

二、讀取合約執行上下文資訊

1. 入口參數

receiver:接受該請求的合約賬戶

code:合約名稱

action:合約方法

extern "C" {

   /// The apply method implements the dispatch of events to this contract
   void apply( uint64_t receiver, uint64_t code, uint64_t action ) {
      print(" receiver: ", name{receiver});
      print(" code: ", name{code});
      print(" action: ", name{action});
   }
} // extern "C"
           

2. 合約調用參數

/**
    *  Copy up to @ref len bytes of current action data to the specified location
    *  @brief Copy current action data to the specified location
    *  @param msg - a pointer where up to @ref len bytes of the current action data will be copied
    *  @param len - len of the current action data to be copied, 0 to report required size
    *  @return the number of bytes copied to msg, or number of bytes that can be copied if len==0 passed
    */
   uint32_t read_action_data( void* msg, uint32_t len );

   /**
    * Get the length of the current action's data field
    * This method is useful for dynamically sized actions
    * @brief Get the length of current action's data field
    * @return the length of the current action's data field
    */
   uint32_t action_data_size();
           

例如:

#pragma pack(push,1)
   struct dummy_action {
     char a;
     uint64_t b;
     uint32_t c;
   };
#pragma pack(pop)

......

req_size = action_data_size();
read_action_data(buffer, 100);
dummy_action* dummy = reinterpret_cast<dummy_action*>(buffer);
           

通過以下方式可以直接擷取參數:

struct dummy_action {
 char a;
 uint64_t b;
 uint32_t c;
};

.....

dummy_action dummy = unpack_action_data<dummy_action>();
           

3. 讀取目前的活躍産快節點

*  Example:
    *  @code
    *  account_name producers[21];
    *  uint32_t bytes_populated = get_active_producers(producers, sizeof(account_name)*21);
    *  @endcode
    */

   uint32_t get_active_producers( account_name* producers, uint32_t datalen );
           

例如:

account_name producers[21];
     uint32_t byte_prods = get_active_producers(producers, sizeof(account_name) * 21);
     uint32_t num_prods = byte_prods / sizeof(account_name);

     for(int i = 0;i < num_prods;i ++) {
       print(" producer: ", name{producers[i]});
     }
           

4. 擷取時間

/**
    *  Returns the time in microseconds from 1970 of the current block
    *  @brief Get time of the current block (i.e. the block including this action)
    *  @return time in microseconds from 1970 of the current block
    */
   uint64_t  current_time();

   /**
    *  Returns the time in seconds from 1970 of the block including this action
    *  @brief Get time (rounded down to the nearest second) of the current block (i.e. the block including this action)
    *  @return time in seconds from 1970 of the current block
    */
   uint32_t  now();  
   
   /**
    *  Returns the time in microseconds from 1970 of the publication_time
    *  @brief Get the publication time
    *  @return the time in microseconds from 1970 of the publication_time
    */
   uint64_t  publication_time();
           

例如:

//@abi action gettime
   void gettime() {
     uint64_t t_now = now();
     uint64_t t_time = current_time();
     uint64_t t_pub_time = publication_time();

     print(" now : ", t_now);
     print(" current time: ", t_time);
     print(" publication time: ", t_pub_time);
   }
           

5. 檢查授權

/**
    *  Verifies that @ref name exists in the set of provided auths on a action. Throws if not found
    *  @brief Verify specified account exists in the set of provided auths
    *  @param name - name of the account to be verified
    */
   void require_auth( account_name name );
   bool has_auth( account_name name );

   /**
    *  Verifies that @ref name exists in the set of provided auths on a action. Throws if not found
    *  @brief Verify specified account exists in the set of provided auths
    *  @param name - name of the account to be verified
    *  @param permission - permission level to be verified
    */
   void require_auth2( account_name name, permission_name permission );
           

繼續閱讀