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