Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates with more info #1118

Open
wants to merge 11 commits into
base: phklive-docs-update-transaction
Choose a base branch
from
70 changes: 43 additions & 27 deletions docs/architecture/transaction.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,72 @@
# Transaction

`Transaction`s are a mechanism by which the state of the chain is updated. That is, all changes in account and note states result from executing `Transaction`s. In Miden, `Transaction`s can originate either from the users or from the network itself.
A `Transaction` in Miden is the state change of a single account. This is different to most other blockchains, where a transaction typically involves the sender and the receiver, e.g., Alice sends 5 ETH to Bob. In Miden, sending 5 ETH from Alice to Bob takes two transactions, one in which Alice creates a note containing 5 ETH and one in which Bob consumes that note and receives the ETH. This concept concept enables Miden to treat transactions (single state transitions) asynchronously and therefore allows accounts to prove their own state transitions independently from each other - no global lock is needed and transactions can happen in parallel.
Dominik1999 marked this conversation as resolved.
Show resolved Hide resolved

Miden aims for the following characteristics in `Transaction`s:
Miden's transaction model aims for:

- **Parallel transaction execution**: Because a transaction is always performed against a single account, Miden obtains asynchronicity.
- **Private transaction execution**: Local execution of transactions enables preservation of sensitive data.
- **Parallel transaction execution**: Accounts can changes their state independent from each other and in parallel.
- **Private transaction execution**: Client-side transaction proofs allow the network to verify transactions with zero knowledge.

## What is the purpose of a transaction?
## Transaction definition

In Miden, a `Transaction` represents the state transition of a single account. A `Transaction` takes a single [account](accounts.md) and zero or more [notes](notes.md), and none or one script (piece of code executed after all notes have been executed) as input, and outputs the same account with a potentially updated state, together with some potential newly created notes.
In Miden, a `Transaction` represents the state transition of a single account. A `Transaction` takes a single [account](accounts.md) and zero or more [notes](notes.md), and outputs the same account in a new state, together with zero or more [notes]. `Transaction`s are well-defined processes and they are implemented as programs for the Miden VM. That means there is a zero-knowledge proof for every transaction.
Dominik1999 marked this conversation as resolved.
Show resolved Hide resolved

![Transaction diagram](../img/architecture/transaction/transaction-diagram.png)

## Transaction core components
## Transaction types

WIP
There will be two types of transactions in Miden: **local transactions** and in the future **network transactions**.
Dominik1999 marked this conversation as resolved.
Show resolved Hide resolved

## Transaction types
In **local transactions**, clients apply the account's state transition locally and send a transaction proof to the network. The network only verifies the proof and changes the global parts of the state.
Dominik1999 marked this conversation as resolved.
Show resolved Hide resolved

Local transactions are useful, because

1. They are cheaper (i.e., lower fees) as zk-proofs are already generated by the clients. This means privacy is the cheaper option on Miden.
2. They allow fairly complex computations because the proof size doesn't grow linearly with the complexity of the computation. That means there is no gas limit for client-side proofs.
3. They enable privacy as neither the account state nor account code are needed to verify the zk-proof. Public inputs are only commitments and block information that are stored on-chain anyway.

There are two types of transactions in Miden: **local transactions** and **network transactions**.
In the near future, there will be **network transactions** as well. In network transactions, the Miden operator or the network executes the transaction and generates the proof. Miden needs network transactions for smart contracts with public shared state. This type of transaction is more in line with a traditional understanding of how blockchains work.

Network transactions are useful, because

1. Smart contracts should be executed autonomously. Local transactions require a client to execute and sometimes a smart contract should execute when a certain condition is met or simply when it is called by someone. Network transactions ensure liveness of smart contracts.
2. For public shared state of smart contracts. Network transactions allow orchestrated state changes of public smart contracts without race conditions. See <here> for an in-depth explanation of public share state on Miden.
Dominik1999 marked this conversation as resolved.
Show resolved Hide resolved
3. Clients may not have sufficient resources to generate zk-proofs.

![Local vs network transactions](../img/architecture/transaction/local-vs-network-transaction.png)

### Local transactions
In general, the ability to facilitate both, local and network transactions, is what differentiates Miden. Local transaction execution can happen in parallel and for most transactions there is no need for public state changes. This increases the network's throughput tremendously. Network transactions on the other hand is what constitutes a normal blockchain with autonomous smart contracts and public shared state.

This is where clients executing the transactions also generate the proofs of their correct execution. So, no additional work needs to be performed by the network.

Local transactions are useful for several reasons:
## Transaction process

1. They are cheaper (i.e., lower fees) as zk-proofs are already generated by the clients.
2. They allow fairly complex computations because the proof size doesn't grow linearly with the complexity of the computation.
3. They enable privacy as neither the account state nor account code are needed to verify the zk-proof.
Every `Transaction` describes the process of an account changing its state. This process is a well-defined program resulting in a zero-knowledge proof of correct execution.

### Network transactions
![Transaction execution process](../img/architecture/transaction/transaction-execution-process.png)

This is where the operator executes the transaction and generates the proofs.
In order to execute a transaction locally, the executor needs to know the full data of the account and notes that serve as inputs to the transaction. That means, one can only consume private notes in a transaction, if the full private note data is present. The same goes for foreign account data, whether it is private or public. If data from a foreign account is read during a transaction, the data must be present before the local transaction execution. Together with the account and note data, information about the current state of the blockchain needs to be fetched from the Miden operator. This entails the current `BlockHeader` and the `ChainMMR` which authenticates input notes during transaction execution.
phklive marked this conversation as resolved.
Show resolved Hide resolved

Network transactions are useful for two reasons:
> **Info**
phklive marked this conversation as resolved.
Show resolved Hide resolved
> - `InputNotes` must not be recorded on-chain in order for the transaction to succeed. In Miden there is the concept of ephemeral notes that can be consumed in a transaction before registered on-chain. <link to notes chapter ephemeral notes>
> - There is no nullifier-check during a transaction. Nullifiers are checked by the Miden operator during transaction verification. So at the transaction level, there is "double spending." If a note was already spent, i.e. there exists a nullifier for that note, the whole transaction will fail when submitted to the network.
phklive marked this conversation as resolved.
Show resolved Hide resolved

1. Clients may not have sufficient resources to generate zk-proofs.
2. Executing many transactions against the same public account by different clients is challenging, as the account state changes after every transaction. Due to this, the Miden node/operator acts as a "synchronizer" to execute transactions sequentially by feeding the output of the previous transaction into the input of the next.
Transaction execution starts with a prologue where on-chain commitments are checked against the provided data. Then, all notes are being executed sequentially against the account. The executor can define the sequence of the `InputNotes` and notes must be consumed fully. That means all assets must be consumed into the account and the note script must be executed fully given the provided [note inputs](notes.md/inputs) and transaction arguments. Let's unfold what that means:

## Transaction lifecycle
When a note is being consumed in a transaction, the note script is being executed against the executing account. That way, the note script can call exposed functions of the account interface. For example, a basic wallet account exposes `receive_asset`. When a note calls this function in its script, the assets that are contained in the note are being transferred to the account. In most cases, the note creator doesn't want a note and its assets to be consumable by all the accounts. That is why, the note creator can impose an additional checks. Since the executing account needs to execute the full note script in order to consume the note, it can not circumvent the checks set by the note creator. For example, the P2ID note script checks that the ID of the executing account matches the AccountID provided by the [note inputs](notes.md/inputs). But also the executor can inject arguments to the note script execution called `TransactionArguments`. For example, a basic SWAP note is defined as "Anyone can consume this note and take the X assets A on it if during execution another note is created to send Y of asset B back to the sender". Now, the executor might not want to "buy" X of asset A, but only X-m - a smaller portion. If the note creator is fine with also selling less of A for the same price, this can be encoded in the note script. The executor will then provide the amount willing to buy via the `TransactionArguments` and the note script forces the executor to create two new notes - one back to the sender containing Y-((m*Y)/X) of asset B (assuming that X/Y = m/n) and another one, a copy of the initial node containing X-m of asset A for other accounts to consume. Note creators can define any arbitrary logic into their note scripts which is executed during transaction execution. However, note scripts can only call functions of the account that are exposed via the account code. Most internal account functions, manipulating the vault or storage, are shielded from note scripts.
phklive marked this conversation as resolved.
Show resolved Hide resolved

In Miden, every `Transaction` is executed within the Miden VM. Throughout its lifetime, a `Transaction` progresses through various phases:
After all notes are being consumed, the transaction script is next in line. The transaction script is an optional piece of code defined by the executor. Normally, it is used to sign the transaction, but it can also be used to interact with an account without using notes. For example, the owner of a faucet can `mint` new tokens using only a transaction script.

1. **Compilation:** All `Transaction` inputs (account, notes, script) are compiled into an executable Miden program.
2. **Execution:** The `Transaction` program is executed within the Miden VM, which produces outputs (updated account, notes).
3. **Proving:** The executed `Transaction` is proven by the Miden prover.
After all note scripts and the optional transaction script are being processed, the account is being updated in the transaction's epilogue. If the transaction also creates new notes, they are now being created and assets are moved from the account to the corresponding `OutputNotes`. Now, the transaction execution is complete resulting in an account with a new state and the corresponding `OutputNotes`.
Dominik1999 marked this conversation as resolved.
Show resolved Hide resolved

![Transaction execution process](../img/architecture/transaction/transaction-program.png)

If the kernel doesn't throw an error and the transaction can be completed, a proof is being generated of the correct transaction execution. This proof together with the corresponding data needed for verification and updates on the global state can then be submitted and processed by the network.
Dominik1999 marked this conversation as resolved.
Show resolved Hide resolved

![Transaction execution process](../img/architecture/transaction/transaction-execution-process.png)

> **Info**
> - One of the main reasons for separating out the execution and proving steps is to allow _stateless provers_; i.e., the executed transaction has all the data it needs to re-execute and prove a transaction without database access. This supports easier proof-generation distribution.

More notable transaction features:

- It is possible to set transaction expiration heights and in doing so, to define a block height until a transaction should be included into a block. If the transaction is expired, the resulting account state change is not valid and the transaction can not be verified anymore.
- Note and transaction scripts can read the state of foreign accounts during execution. This is called foreign procedure invocation. For example the price of an asset for the SWAP script might depend on a certain value stored in the oracle account.
phklive marked this conversation as resolved.
Show resolved Hide resolved
Binary file modified docs/img/architecture/transaction/transaction-diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading