Detailed explanation of Flow transaction process and transaction structure

# Flow transaction process and transaction structure detailed explanation

## write in front

We all know that smart contracts written using [Cadence]( in the Flow network also need to be queried or invoked through Cadence scripts. Once the developer grasps the [resource]( model and programming philosophy, it is easy to use Cadence to write very flexible script, contract query does not support pagination? No flexible permission control? Integrated query of multiple contract interfaces? Want to implement batch execution of a single transaction? These are not problems, by customizing flexible Cadence scripts, only the imagination of the programmer is limited.

The same abstract account design and natively supported multi-signature transactions also help us to meet various demand scenarios safely and flexibly.

In order to facilitate everyone’s understanding, let’s start with the transaction structure of Flow.

### Flow Cadence Transaction Script Structure

Transactions are the basic structure of transactions with Cadence smart contracts. All calls to contracts or requests that cause changes to the contract state are transactions, and require different roles to sign and authorize and send them to the Flow network.
Let’s first look at an example of a Cadence transaction script:

“`plain text
transaction(amount: UFix64) {
var props: UFix64
prepare(signer1: AuthAccount, signer2: AuthAccount) {
// …
self.props = amount
pre {
// …
execute {
// …
post {
// …


We can see that `transaction` contains parameters, variables and code blocks for different runtime stages, and `prepare` also contains parameters, but here the parameters are all `AuthAccount` [type](https://docs.onflow .org/cadence/language/accounts/#authaccount), representing different authorized users (we will explain in detail later), here use the prepare code block to initialize the parameters and resources required for the exchange.

Use pre and post to check and check the code before and after the transaction is executed. Note that although the Cadence script of the transaction has different execution stages, it is still atomic, that is, once any of these code blocks have an execution error , the entire transaction is rolled back.

### Transaction process

The flow of a Cadence transaction is as follows:

– Assembly data

– Script

– Parameters

– proposer account information

– Authorizer address collection (array form)

– Transaction fee payer address

– Initialization parameters

– gas limit

– Authorized person’s signature authorization

– Get keyIndex and seqNumber

– encode transaction body (payload) data and sign

– Assemble signature array

– Final signature of the fee payer

– send transaction

So how Cadence’s transaction script is assembled and sent to the Flow blockchain, we can learn from the sample code of [ fcl.js](

“`plain text
export const sendTrx = async (CODE, args, limit = 9999) => {
const txId = await fcl. send([
fcl.transaction(CODE), // Cadence transaction script
fcl.args(args), // transaction parameter list
fcl.proposer(fcl.authz), // Transaction initiator signature authorization method
fcl.payer(fcl.authz), // Transaction fee payer signature authorization method
fcl.authorizations([fcl.authz]), // here is the signature of prepare’s authorized account (will be converted to AuthAccount parameter)
fcl.limit(limit) // gas limit
return txId


The points to note in the above code snippet are:

– proposer is the initiator of the transaction (only for off-chain verification)

– payer is the payer of the transaction fee and requires a final signature

– authorizations is an array, can support multiple signatures, and will be passed as a parameter to the `prepare` block parameter in the Cadence script

– args is also a list type and will become the parameters of the transaction code block

– fcl.authz is the signature function, which can support remote signature (custodial) and local signature (non-custodial), will encode the entire transaction body and sign the hash value of the transaction body, and assemble it on the payloadSigs array to complete multi-signature Authorization for an account

After the process is clear, let’s understand the transaction more intuitively through the transaction body data

### Transaction details

Here is an official anatomy of a trading body


We can also look at raw transactions in combination with data:

“`plain text
script: ‘Cadence script …’, // Cadence transaction script
refBlock: ‘d719c892c80b45de3d19c459dc7eeba8ab809b5f3b007a51c69f697b7eb42361’, // referenced block ID
arguments: [ { type: ‘String’, value: ‘Test’ } ], // Arguments for the Cadence transaction
proposalKey: { address: ‘0xe242ccfb4b8ea3e2’, keyId: 0, sequenceNum: 480 }, // transaction initiator information
payer: ‘0xc6de0d94160377cd’, // transaction fee payer information
authorizers: [ ‘0xe242ccfb4b8ea3e2’, ‘0xc6de0d94160377cd’, ‘0xb05b2abb42335e88’ ],
gasLimit: 1000,
payloadSignatures: [
address: ‘0xe242ccfb4b8ea3e2’,
keyIndex: 0,
signature: ‘9aa7ca757c0c995d1cc11b71c6c5d3b83be92708905c8ba4528fadc602438acd027b479e1546f9ed96a3c9f8df424eccd318333c7f55378ce4994b164972c450’
envelopeSignatures: [
“address”: “0x01”,
“keyId”: 1,
“sig”: “0xabc123”


The data in this Json format is the transaction body after our signature:

– script – the Cadence script mentioned earlier

– refBlock – the block id when the transaction was constructed

– arguments – Cadence’s transaction parameters (parameters of the transaction method body) will be verified according to the order and type of the parameters

– proposalKey – transaction initiator’s information

– address – address

– keyId – the public key corresponds to the Index in the account, which involves Flow’s abstract account model design details [here](

– sequenceNum – the transaction sequence number of the key

– authorizers —— The address of the authorizer, which matches the prepare parameter in Cadence. The order is not required to be consistent, but the signature of any party cannot be missing.

– gasLimit – the maximum gas consumption value of the transaction

– payloadSignatures – a list of signature information for the above authorization, a collection of signatures used to determine whether it complies with multi-signature permissions

– address – authorizer address

– keyIndex – authorizer key index

– signature – authorized private key signature

– envelopeSignatures – the fee payer, and finally sign the package transaction (the normal process is that the user himself will become the proposal and payer)

But it is also possible to let others pay the transaction fee in the form of raw transaction delivery with the help of some escrow services or tools

### Transaction fee payment

According to the above diagram and process, the advantage of Flow’s design here is that payer is the safest process to encapsulate and sign transactions as the last process, and the verification function of the chain is used to solve the problem of trust.

As an authorized transaction user, only the person who pays the fee needs to pay, and the person who pays the fee can avoid stealing the authorizer’s assets by tampering with the script authorized by the authorizer through transaction data. Similarly, the person who pays the transaction fee also needs to verify the transaction. Correctness, and at the same time, it does not need to spend a lot of effort to verify the reliability of the transaction source, whether there is a man-in-the-middle attack, etc., only the transaction approval and the final original transaction package signature. Both authentication and security are guaranteed by the Flow network.

From a business point of view, users who authorize transactions and those who pay for transactions can completely distrust each other under this mechanism, and can also fulfill the demand for fee payment. The security of the entire process is guaranteed by Flow’s abstract account model and a reasonable transaction signature mechanism.

The specific signature and payment process is actually reflected in the transaction process. The user signs the transaction body of the payload and sends the transaction data to the payment service. The payment service verifies the user’s signature and transaction content. The signature is equivalent to authorizing the operation of commission payment, and sending the final transaction to the Flow blockchain to complete the commission payment operation.

The well-known Blocto service completes a function similar to passing signatures on the escrow server in this form, helping users to subsidize handling fees.


We can see in the block explorer that the payer is a third-party address in this transaction, and the transaction initiation and authorization are completed by the user.

## Summarize

Flexible scripts and rationally designed transaction structures can help developers meet the needs of various scenarios.

In the next article, I will share with actual usage and scenarios how Flowns completes the permission separation of super administrator accounts through flexible Cadence scripts and multi-signature, so that Flow Cadence can do not modify the existing contract permission structure but also The transaction use case of multi-party signature authorization can be implemented safely and conveniently.

This article is reprinted from:
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment

Your email address will not be published.