Introduction to the Transaction Manifest
The transaction model used with Radix Engine v2 is dramatically different from the transaction model used currently on the Radix Olympia mainnet. This new transaction manifest model will not become the model used for transactions on the Radix mainnet until the Babylon release.
A transaction manifest is the Radix way of building transactions. It makes it possible to compose multiple actions to be executed atomically by describing a sequence of component calls and movements of resources between components. In short, full atomic composability becomes possible directly in transactions.
Transaction manifests can also describe the use of badges for authorization to components, payment of transaction fees, and checks on resources amounts to provide guaranteed results for the user.
Transaction manifests are human-readable so that developers or client software (such as a new Radix Wallet currently in development) can understand what they are signing. When it’s time to submit, the transaction manifest is translated into a binary representation and cryptographically signed to create a final transaction that may be efficiently sent to the network and processed by the Radix Engine.
Transaction manifests orchestrate the movement of resources between components. This includes accounts, which are also components (that only their owner may withdraw from). This is done through a sequence of instructions using a special instruction set created specifically for this purpose (transaction manifests do not use Scrypto). Radix Engine processes these instructions in order, and if any step fails for any reason, the entire transaction fails and none of the steps are committed to the ledger on the Radix network. This is what is meant by the transaction being "atomic".
Execution of a given transaction can be thought of as happening at its own "layer", above any components that are called during the transaction. This layer has some special features that make transaction manifests quite powerful.
The most common instruction in a transaction manifest is a component call. Each call to a component can include data and buckets of resources, and each component may then return resources.
The transaction layer itself must include a way of managing resources between component calls. For this, we introduce the worktop. Each transaction has a worktop that is a place that resources may be held during the transaction execution. Resources returned from component calls are automatically put onto the worktop. From there, the manifest may specify that resources on the worktop be put into buckets so that those buckets may be passed as arguments to other component calls.
The manifest may also use ASSERT commands to check the contents of the worktop, causing the entire transaction to fail if not enough of the checked resource is present. This is useful to guarantee results of a transaction, even if you may be unsure of what a component may return.
Of course we know that all resources must be in a vault by the end of any transaction, so the transaction manifest creator must ensure that no resources are left hanging around the worktop or in buckets by the end of the manifest’s steps.
Another feature of the transaction layer is the authorization zone. This is somewhat similar to the worktop, but is used specifically for authorization. Rather than holding resources, the authorization zone holds Proofs. A Proof is a special object that proves the possession of a given resource or resources. When a component is called by the transaction manifest, the Proofs in that transaction’s authorization zone are automatically passed to that component method’s authorization rules to be checked to determine if that method may be called or not.
These Proofs will include those that are automatically added to the authorization zone from "virtual badges" that are produced by signatures to the transaction. This, for example, is how you are able to call the
withdraw method on your account component.
For more about Proofs and authorization, please see Access Control.
To run a transaction on the Radix network, you have to pay a fee depending on the number of instructions you are calling and the permanent storage used. You do this by locking XRD from a vault that will then be used to pay for the fee calculated at the end of a transaction. To lock a fee, you must call a method that essentially calls
.lock_fee(amount) on a vault containing XRD. There is a method that do this on the Account component:
CALL_METHOD Address("[account_component_address]") "lock_fee" Decimal("[amount]");
For testing purposes, on the local simulator, you can also call the
lock_fee on the System component (address
component_sim1qftacppvmr9ezmekxqpq58en0nk954x0a7jv2zz0hc7q8utaxr) so the fee payment comes from the system rather than your account.
You can read more about fees here.
Ready to learn how to write and generate your transaction manifests? Head over to [this] page.