eos程式碼閱讀筆記05- 事務transaction
阿新 • • 發佈:2019-01-22
資料庫的事務定義:事務(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(){}