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

chore(docs): Update tx concepts page #10947

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion barretenberg/sol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The verifier will follow an overall architecture below, consisting of 3 contract

![Verifier architecture](./figures/verifier.png)

The verification key is currently generated via [Barretenberg](https://github.com/AztecProtocol/barretenberg/blob/master/cpp/src/aztec/plonk_honk_shared/verification_key/sol_gen.hpp), Aztec's backend for generating proofs.
The verification key is currently generated via [Barretenberg](https://github.com/AztecProtocol/barretenberg/blob/master/cpp/src/barretenberg/plonk/proof_system/verification_key/sol_gen.hpp), Aztec's backend for generating proofs.

## Current implementations

Expand Down
67 changes: 65 additions & 2 deletions docs/docs/aztec/concepts/transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ _The sequencer has passed the transaction information – proofs of correct exec

5. **The transaction settles to L1** – the verifier contract on Ethereum can now validate the rollup proof and record a new state root. The state root is submitted to the rollup smart contract. Once the state root is verified in an Ethereum transaction, the private transfer has settled and the transaction is considered final.

### Going deeper
### Detailed Diagram

Transactions on Aztec start with a call from Aztec.js, which creates a request containing transaction details. This request moves to the Private Execution Environment (PXE) which simulates and processes it. Then the PXE interacts with the Aztec Node which uses the sequencer to ensure that all the transaction details are enqueued properly. The sequencer then submits the block to the rollup contract, and the transaction is successfully mined.

Expand All @@ -51,7 +51,70 @@ See [this diagram](https://raw.githubusercontent.com/AztecProtocol/aztec-package

See the page on [contract communication](../smart_contracts/functions/public_private_calls.md) for more context on transaction execution.

### Enabling Transaction Semantics: The Aztec Kernel
### Transaction Requests

Transaction requests are how transactions are constructed and sent to the network.

In Aztec.js:

#include_code constructor yarn-project/circuits.js/src/structs/tx_request.ts javascript

Where:

- `origin` is the account contract where the transaction is initiated from.
- `functionData` contains the function selector and indicates whether the function is private or public.
- `argsHash` is the hash of the arguments of all of the calls to be executed. The complete set of arguments is passed to the PXE as part of the [TxExecutionRequest](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/circuit-types/src/tx_execution_request.ts) and checked against this hash.
- `txContext` contains the chain id, version, and gas settings.

The `functionData` includes an `AppPayload`, which includes information about the application functions and arguments, and a `FeePayload`, which includes info about how to pay for the transaction.

An account contract validates that the transaction request has been authorized via its specified authorization mechanism, via the `is_valid_impl` function (e.g. [an ECDSA signature](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr#L56-L57), generated [in JS](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/accounts/src/ecdsa/ecdsa_k/account_contract.ts#L30)).

Transaction requests are simulated in the PXE in order to generate the necessary inputs for generating proofs. Once transactions are proven, a [transaction object](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/circuit-types/src/tx/tx.ts#L26) is created and can be sent to the network to be included in a block.

#### Contract Interaction Methods

Most transaction requests are created as interactions with specific contracts. The exception is transactions that deploy contracts. Here are the main methods for interacting with contracts related to transactions.

1. [`create`](#create)
2. [`simulate`](#simulate)
3. [`prove`](#prove)
4. [`send`](#send)

And fee utilities:

- [`estimateGas`](#estimategas)
- [`getFeeOptions`](#getfeeoptions)

##### `create`

#include_code create yarn-project/aztec.js/src/contract/contract_function_interaction.ts javascript

##### `simulate`

#include_code simulate yarn-project/aztec.js/src/contract/contract_function_interaction.ts javascript

##### `prove`

#include_code prove yarn-project/aztec.js/src/contract/base_contract_interaction.ts javascript

##### `send`

#include_code send yarn-project/aztec.js/src/contract/base_contract_interaction.ts javascript

##### `estimateGas`

#include_code estimateGas yarn-project/aztec.js/src/contract/base_contract_interaction.ts javascript

##### `getFeeOptions`

#include_code getFeeOptions yarn-project/aztec.js/src/contract/base_contract_interaction.ts javascript

### Batch Transactions

Batched transactions are a way to send multiple transactions in a single call. They are created by the [`BatchCall` class in Aztec.js](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec.js/src/contract/batch_call.ts). This allows a batch of function calls from a single wallet to be sent as a single transaction through a wallet.

### Enabling Transaction Semantics

There are two kernel circuits in Aztec, the private kernel and the public kernel. Each circuit validates the correct execution of a particular function call.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,19 @@ export abstract class BaseContractInteraction {
return await this.wallet.proveTx(txRequest, txSimulationResult.privateExecutionResult);
}

// docs:start:prove
/**
* Proves a transaction execution request and returns a tx object ready to be sent.
* @param options - optional arguments to be used in the creation of the transaction
* @returns The resulting transaction
*/
public async prove(options: SendMethodOptions = {}): Promise<ProvenTx> {
// docs:end:prove
const txProvingResult = await this.proveInternal(options);
return new ProvenTx(this.wallet, txProvingResult.toTx());
}

// docs:start:send
/**
* Sends a transaction to the contract function with the specified options.
* This function throws an error if called on an unconstrained function.
Expand All @@ -74,13 +77,15 @@ export abstract class BaseContractInteraction {
* @returns A SentTx instance for tracking the transaction status and information.
*/
public send(options: SendMethodOptions = {}): SentTx {
// docs:end:send
const promise = (async () => {
const txProvingResult = await this.proveInternal(options);
return this.wallet.sendTx(txProvingResult.toTx());
})();
return new SentTx(this.wallet, promise);
}

// docs:start:estimateGas
/**
* Estimates gas for a given tx request and returns gas limits for it.
* @param opts - Options.
Expand All @@ -90,6 +95,7 @@ export abstract class BaseContractInteraction {
public async estimateGas(
opts?: Omit<SendMethodOptions, 'estimateGas' | 'skipPublicSimulation'>,
): Promise<Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>> {
// docs:end:estimateGas
const txRequest = await this.create({ ...opts, fee: { ...opts?.fee, estimateGas: false } });
const simulationResult = await this.wallet.simulateTx(
txRequest,
Expand All @@ -116,6 +122,7 @@ export abstract class BaseContractInteraction {
return { gasSettings, paymentMethod };
}

// docs:start:getFeeOptions
/**
* Return fee options based on the user opts, estimating tx gas if needed.
* @param request - Request to execute for this interaction.
Expand All @@ -125,6 +132,7 @@ export abstract class BaseContractInteraction {
protected async getFeeOptions(
request: Omit<ExecutionRequestInit, 'fee'> & { /** User-provided fee options */ fee?: UserFeeOptions },
): Promise<FeeOptions> {
// docs:end:getFeeOptions
const defaultFeeOptions = await this.getDefaultFeeOptions(request.fee);
const paymentMethod = defaultFeeOptions.paymentMethod;
const maxFeesPerGas = defaultFeeOptions.gasSettings.maxFeesPerGas;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
}
}

// docs:start:create
/**
* Create a transaction execution request that represents this call, encoded and authenticated by the
* user's wallet, ready to be simulated.
* @param opts - An optional object containing additional configuration for the transaction.
* @returns A Promise that resolves to a transaction instance.
*/
public async create(opts: SendMethodOptions = {}): Promise<TxExecutionRequest> {
// docs:end:create
if (this.functionDao.functionType === FunctionType.UNCONSTRAINED) {
throw new Error("Can't call `create` on an unconstrained function.");
}
Expand All @@ -68,12 +70,14 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
return await this.wallet.createTxExecutionRequest({ calls, fee, nonce, cancellable });
}

// docs:start:request
/**
* Returns an execution request that represents this operation. Useful as a building
* block for constructing batch requests.
* @returns An execution request wrapped in promise.
*/
public request(): FunctionCall {
// docs:end:request
const args = encodeArguments(this.functionDao, this.args);
return {
name: this.functionDao.name,
Expand All @@ -86,6 +90,7 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
};
}

// docs:start:simulate
/**
* Simulate a transaction and get its return values
* Differs from prove in a few important ways:
Expand All @@ -96,6 +101,7 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
* @returns The result of the transaction as returned by the contract function.
*/
public async simulate(options: SimulateMethodOptions = {}): Promise<any> {
// docs:end:simulate
if (this.functionDao.functionType == FunctionType.UNCONSTRAINED) {
return this.wallet.simulateUnconstrained(this.functionDao.name, this.args, this.contractAddress, options?.from);
}
Expand Down
4 changes: 3 additions & 1 deletion yarn-project/circuits.js/src/structs/tx_request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { TxContext } from './tx_context.js';
*/
export class TxRequest {
constructor(
// docs:start:constructor
/** Sender. */
public origin: AztecAddress,
/** Function data representing the function to call. */
Expand All @@ -21,7 +22,8 @@ export class TxRequest {
public argsHash: Fr,
/** Transaction context. */
public txContext: TxContext,
) {}
) // docs:end:constructor
{}

static getFields(fields: FieldsOf<TxRequest>) {
return [fields.origin, fields.functionData, fields.argsHash, fields.txContext] as const;
Expand Down
Loading