Transactions

The consensus layer uses a common transaction format for all transactions. As with other Oasis Core components, it tries to be independent of any concrete consensus backend.

The transaction API definitions and helper methods for creating and verifying transactions lives in go/consensus/api/transaction. For more information you can also check out the consensus backend API documentation.

Format

Each (unsigned) transaction is represented by the following encoded structure:

type Transaction struct {
Nonce uint64 `json:"nonce"`
Fee *Fee `json:"fee,omitempty"`
Method string `json:"method"`
Body interface{} `json:"body,omitempty"`
}

Fields:

  • nonce is the current caller's nonce to prevent replays.

  • fee is an optional fee that the caller commits to paying to execute the

    transaction.

  • method is the called method name. Method names are composed of two parts,

    the component name and the method name, joined by a separator (.). For

    example, staking.Transfer is the method name of the staking service's

    Transfer method.

  • body is the method-specific body.

The actual transaction that is submitted to the consensus layer must be signed which means that it is wrapped into a signed envelope.

Domain separation context (+ chain domain separation):

oasis-core/consensus: tx

Fees

As the consensus operations require resources to process, the consensus layer charges fees to perform operations.

Gas

Gas is an unsigned 64-bit integer denominated in gas units.

Different operations cost different amounts of gas as defined by the consensus parameters of the consensus component that implements the operation.

Transactions that require fees to process will include a fee field to declare how much the caller is willing to pay for fees. Specifying an amount (in base units) and gas (in gas units) implicitly defines a gas price (price of one gas unit) as amount / gas. Consensus validators may refuse to process operations with a gas price that is too low.

The gas field defines the maximum amount of gas that can be used by an operation for which the fee has been included. In case an operation uses more gas, processing will be aborted and no state changes will take place.

Signing a transaction which includes a fee structure implicitly grants permission to withdraw the given amount of base units from the signer's account. In case there is not enough balance in the account, the operation will fail.

type Fee struct {
Amount quantity.Quantity `json:"amount"`
Gas Gas `json:"gas"`
}

Fees are not refunded.

Fields:

  • amount is the total fee amount (in base units) to be paid.

  • gas is the maximum gas that an operation can use.

Gas Estimation

As transactions need to provide the maximum amount of gas that can be consumed during their execution, the caller may need to be able to estimate the amount of gas needed. In order to do that the consensus backend API includes a method called EstimateGas for estimating gas.

The implementation of gas estimation is backend-specific but usually involves some kind of simulation of transaction execution to derive the maximum amount consumed by execution.

Submission

Transactions can be submitted to the consensus layer by calling SubmitTx and providing a signed transaction.

The consensus backend API provides a submission manager for cases where the signer is available and automatic gas estimation and nonce lookup is desired. It is available via the SignAndSubmitTx function.