1. 程式人生 > >eos程式碼閱讀筆記05- 事務transaction

eos程式碼閱讀筆記05- 事務transaction

      資料庫的事務定義:事務(Transaction)是併發控制的單位,是使用者定義的一個操作序列。這些操作要麼都做,要麼都不做,是一個不可分割的工作單位。

      eos的transaction很像資料庫的事務。用事務完成交易,賬號/許可權的建立。

事務中的物件繼承關係

transaction_header (頭)-> transaction -> signed_transaction(簽名) -> deferred_transaction(推遲)

事務頭物件 /eos/libraries/chain/include/eosio/chain/transaction.hpp

 /**
    *  The transaction header contains the fixed-sized data
    *  associated with each transaction. It is separated from
    *  the transaction body to facilitate partial parsing of
    *  transactions without requiring dynamic memory allocation.
    *事務頭包含與每個事務相關聯的固定大小的資料。它與事務體分離,以便於事務的部分解析,而不需要動態記憶體分配。
    *  All transactions have an expiration time after which they
    *  may no longer be included in the blockchain. Once a block
    *  with a block_header::timestamp greater than expiration is
    *  deemed irreversible, then a user can safely trust the transaction
    *  will never be included.
    *所有事務都有一個到期時間,在此之後它們可能不再被包含在BROG鏈中。一旦一個帶有BuffixHead的塊::大於到期的時間戳被認為是不可逆的,那麼使用者可以安全地信任該事務將永遠不被包括在內。

    *  Each region is an independent blockchain, it is included as routing
    *  information for inter-blockchain communication. A contract in this
    *  region might generate or authorize a transaction intended for a foreign
    *  region.每個區域是一個獨立的塊鏈,它被作為路由資訊用於鏈間鏈通訊。該地區的合同可能產生或授權旨在為外國地區進行的交易。
    */
   struct transaction_header {
      time_point_sec         expiration;   ///< the time at which a transaction expires 交易到期的時間
      uint16_t               ref_block_num       = 0U; ///< specifies a block num in the last 2^16 blocks.指定到上一個塊
      uint32_t               ref_block_prefix    = 0UL; ///< specifies the lower 32 bits of the blockid at get_ref_blocknum 指定塊的較低的32位。
      fc::unsigned_int       max_net_usage_words = 0UL; /// upper limit on total network bandwidth (in 8 byte words) billed for this transaction 8位元組的總網路頻寬上線
      uint8_t                max_cpu_usage_ms    = 0; /// upper limit on the total CPU time billed for this transaction 此交易的總CPU時間上限
      fc::unsigned_int       delay_sec           = 0UL; /// number of seconds to delay this transaction for during which it may be canceled.延遲該事務的秒數,在此期間可以取消該事務。

事務物件

  /**
    *  A transaction consits of a set of messages which must all be applied or
    *  all are rejected. These messages have access to data within the given
    *  read and write scopes.事務必須包含一組訊息,這些訊息必須全部應用或全部被拒絕。這些訊息可以訪問給定的讀寫範圍內的資料。
    */
   struct transaction : public transaction_header {
      vector<action>         context_free_actions;上下文-自由動作
      vector<action>         actions;操作,一個事務可以有多個操作
      extensions_type        transaction_extensions;擴充套件型事務

      transaction_id_type        id()const;
      digest_type                sig_digest( const chain_id_type& chain_id, const vector<bytes>& cfd = vector<bytes>() )const;
      flat_set<public_key_type>  get_signature_keys( const vector<signature_type>& signatures,
                                                     const chain_id_type& chain_id,
                                                     const vector<bytes>& cfd = vector<bytes>(),
                                                     bool allow_duplicate_keys = false )const;

      uint32_t total_actions()const { return context_free_actions.size() + actions.size(); }
      account_name first_authorizor()const {
         for( const auto& a : actions ) {
            for( const auto& u : a.authorization )
               return u.actor;
         }
         return account_name();
      }

   };

簽名


 struct signed_transaction : public transaction
   {
      signed_transaction() = default;
//      signed_transaction( const signed_transaction& ) = default;
//      signed_transaction( signed_transaction&& ) = default;
      signed_transaction( transaction&& trx, const vector<signature_type>& signatures, const vector<bytes>& context_free_data)
      : transaction(std::move(trx))
      , signatures(signatures)
      , context_free_data(context_free_data)
      {
      }

      vector<signature_type>    signatures;
      vector<bytes>             context_free_data; ///< for each context-free action, there is an entry here

      const signature_type&     sign(const private_key_type& key, const chain_id_type& chain_id);
      signature_type            sign(const private_key_type& key, const chain_id_type& chain_id)const;
      flat_set<public_key_type> get_signature_keys( const chain_id_type& chain_id, bool allow_duplicate_keys = false )const;
   };

延遲執行

/**
    *  When a transaction is generated it can be scheduled to occur
    *  in the future. It may also fail to execute for some reason in
    *  which case the sender needs to be notified. When the sender
    *  sends a transaction they will assign it an ID which will be
    *  passed back to the sender if the transaction fails for some
    *  reason.
當生成事務時,它可以被安排在將來發生。它也可能由於某種原因而無法執行,在這種情況下,需要通知傳送方。
當傳送方傳送一個事務時,如果某個原因由於事務失敗,他們會將ID分配給傳送方。
    */
   struct deferred_transaction : public signed_transaction
   {
      uint128_t      sender_id; /// ID assigned by sender of generated, accessible via WASM api when executing normal or error
                                   當執行正常或錯誤時,由傳送者通過WASM API生成、可訪問的ID
      account_name   sender; /// receives error handler callback 接收錯誤處理回撥
      account_name   payer;
      time_point_sec execute_after; /// delayed execution 延遲執行

操作,事務中的操作

/**
    *  An action is performed by an actor, aka an account. It may
    *  be created explicitly and authorized by signatures or might be
    *  generated implicitly by executing application code.
    *一個動作是由一個演員來完成的,也就是一個賬戶。它可以顯式建立並由簽名授權,或者可以通過執行應用程式程式碼隱式地生成。
    *  This follows the design pattern of React Flux where actions are
    *  named and then dispatched to one or more action handlers (aka stores).
    *  In the context of eosio, every action is dispatched to the handler defined
    *  by account 'scope' and function 'name', but the default handler may also
    *  forward the action to any number of additional handlers. Any application
    *  can write a handler for "scope::name" that will get executed if and only if
    *  this action is forwarded to that application.
    *這遵循反應磁通的設計模式,其中動作被命名,然後被排程到一個或多個動作處理器(AKA儲存)。
在EOSIO的上下文中,每個動作都被分配到由帳戶“範圍”和函式“名稱”定義的處理程式中,但預設處理程式也可以將操作轉發到任意數量的附加處理程式。
任何應用程式都可以編寫一個“範圍::名稱”的處理程式,當且僅當此操作被轉發到該應用程式時,它將被執行。
    *  Each action may require the permission of specific actors. Actors can define
    *  any number of permission levels. The actors and their respective permission
    *  levels are declared on the action and validated independently of the executing
    *  application code. An application code will check to see if the required authorization
    *  were properly declared when it executes.
每一個動作都需要特定演員的許可。參與者可以定義任意數量的許可權級別。
演員及其各自許可在操作中宣告級別,並獨立於執行的應用程式程式碼進行驗證。
應用程式程式碼將檢查在執行時是否正確聲明瞭所需的授權。
 */
   struct action {
      account_name               account;
      action_name                name;
      vector<permission_level>   authorization;
      bytes                      data;

      action(){}