数据库的事务定义:事务(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(){}