Skip to content

Commit

Permalink
Delineating functions in one H2 section.
Browse files Browse the repository at this point in the history
  • Loading branch information
stoobie committed Mar 6, 2024
1 parent 8cd664b commit 1c758ff
Showing 1 changed file with 119 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -1,40 +1,55 @@
[id="validate_and_execute"]
= Account functions
[id="account_interface_functions"]
= Account interface functions
:toc:

The functions in the table xref:#starknet_account_interface_functions[] are part of account contracts. Where required, you must include these functions within your contract. The logic of these functions can be mostly arbitrary, with a few limitations. For information on these limitations, see xref:#invalid_transactions[].
== Overview

The functions in the table xref:#starknet_account_interface_functions[] are part of account contracts. Where required, you must include these functions within your contract. The logic of these functions can be mostly arbitrary, with a few limitations. For information on these limitations, see xref:#invalid_transactions[].

[#starknet_account_interface_functions]
.Starknet account interface functions
[cols="1,3"]
|===
| Function name | Description of minimal functionality

| `+__validate__+` | _Required_.

Initiates the validation stage in the sequencer. Validates the sender's address. The sequencer calls this function upon receiving an `INVOKE` transaction.

In most implementations, `+__validate__+` ensures that only the account owner can initiate transactions.

If the signature is verified, the method yields a `+'VALID'+` `+felt252+` value. If not, it returns 0.

| `+__execute__+` | _Required_.

Initiates the execution stage in the sequencer. The sequencer calls this function upon receiving an `INVOKE` transaction, after the `+__validate__+` function successfully completes.
| Function name | When required

In most implementations, `+__execute__+` initiates a sequence of calls from the account.
| `+__validate_declare__+` | _Required for a contract to be able to send a_`DECLARE` _transaction._
| `+__validate__+` | Alway required
| `+__execute__+` | Alway required
| `+__validate_declare__+` | Required for a contract to be able to send a `DECLARE` transaction.
| `+__validate_deploy__+` | Required when deploying an account with a `DEPLOY_ACCOUNT` _transaction_.
|===

The sequencer calls this function upon receiving a `DECLARE` transaction. Validates the sender's address.

If the contract declares other contracts and handles the corresponding gas fees, this function authenticates the contract declaration.
| `+__validate_deploy__+`
| _Required when deploying an account with a_ `DEPLOY_ACCOUNT` _transaction_.

The sequencer calls this function upon receiving a `DEPLOY_ACCOUNT` transaction. Validates the deployment of the class referred to by the `class_hash` parameter in the transaction.

You can use this function to set up an account contract without linking it to the address that deploys it or depending on another account contract for gas fees.
|===
// [#starknet_account_interface_functions]
// .Starknet account interface functions
// [cols="1,3"]
// |===
// | Function name | Description of minimal functionality
//
// | `+__validate__+` | _Required_.
//
// Initiates the validation stage in the sequencer. Validates the sender's address. The sequencer calls this function upon receiving any transaction.
//
// In most implementations, `+__validate__+` ensures that only the account owner can initiate transactions.
//
// If the signature is verified, the method yields a `+'VALID'+` `+felt252+` value. If not, it returns 0.
//
// | `+__execute__+` | _Required_.
//
// Initiates the execution stage in the sequencer. The sequencer calls this function upon receiving an `INVOKE` transaction, after the `+__validate__+` function successfully completes.
//
// In most implementations, `+__execute__+` initiates a sequence of calls from the account.
// | `+__validate_declare__+` | _Required for a contract to be able to send a_`DECLARE` _transaction._
//
// The sequencer calls this function upon receiving a `DECLARE` transaction.
//
// If the contract declares other contracts and handles the corresponding gas fees, this function authenticates the contract declaration.
// | `+__validate_deploy__+`
// | _Required when deploying an account with a_ `DEPLOY_ACCOUNT` _transaction_.
//
// The sequencer calls this function upon receiving a `DEPLOY_ACCOUNT` transaction. Validates the deployment of the class referred to by the `class_hash` parameter in the transaction.
//
// You can use this function to set up an account contract without linking it to the address that deploys it or depending on another account contract for gas fees.
// |===

When the sequencer receives a transaction request, it calls the corresponding validation function with the fields of the transaction request. For an `INVOKE` transaction, after successfully completing validation, the sequencer calls the `+__execute__+` function with the fields of the transaction request.

Expand All @@ -43,17 +58,6 @@ When the sequencer receives a transaction request, it calls the corresponding va

Separating the validation and execution stages guarantees payment to sequencers for work completed and protects them from Denial of Service (DoS) attacks.

[id="the_validate_function"]
=== The `+__validate__+` function

#Does this apply to all validation functions?#

The `+__validate__+` function typically ensures that any transaction submitted was indeed initiated by the account owner and therefore does not take up unjustified resources during the execution process.

Without this mechanism, a forged transaction can result in the sequencer stealing the user's funds. So the `+__validate__+` function ensures that the sequencer can only include transactions that were approved by the account owner.

The arbitrary logic allowed in the `+__validate__+` function gives the account's designer the ability to determine what it means for a transaction to be valid, enabling different signature schemes and other xref:architecture_and_concepts:Accounts/introduction.adoc#examples[exotic accounts].

[id="invalid_transactions"]
== Invalid transactions

Expand Down Expand Up @@ -105,25 +109,88 @@ The validation limitations prevent the following attacks:
. However, shortly after the transactions are sent, the attacker sends one transaction that somehow invalidates all the previous ones and makes sure it's included in the block, by offering higher fees for this one transaction, before the sequencer can publish the block.
* Consider many validation functions checking that the value of a storage slot is `1`, and the attacker's transaction later sets it to `0`. To handle this issue, we add some further limitations. By restricting validation functions from calling external contracts, Starknet prevents this attack.

[id="reverted_transactions"]
== Reverted transactions

A transaction has the status *REVERTED* when the `+__execute__+` function fails. A reverted transaction is included in a block, and the sequencer is eligible to charge a fee for the work done up to the point of failure, similar to Ethereum.

== Function descriptions

[id="the_execute_function"]
== The `+__execute__+` function
=== `+__execute__+`

.Description

Initiates the execution stage in the sequencer. The sequencer calls this function upon receiving an `INVOKE` transaction, after the `+__validate__+` function successfully completes.

In most implementations, `+__execute__+` initiates a sequence of calls from the account.

The purpose of the `+__execute__+` function is to abstract away the remaining actions performed by a transaction.

In Ethereum, a transaction is necessarily a call to a specific function in a smart contract. With the `+__execute__+` abstraction, the account designer controls the flow of the transaction. For example, multicalls can be natively supported in your account, saving the need to send multiple transactions (in practice, this is even harder to manage without multicalls due to nonces).
In Ethereum, a transaction is necessarily a call to a specific function in a smart contract. With the `+__execute__+` abstraction, the account designer controls the flow of the transaction. For example, you can natively support multicalls in your account, saving the need to send multiple transactions. In practice, however, #this# is even harder to manage without multicalls due to nonces. #What does _this_ refer to?#

[id="reverted_transactions"]
== Reverted transactions
.Returns

A transaction has the status *REVERTED* when the `+__execute__+` function fails. A reverted transaction is included in a block, and the sequencer is eligible to charge a fee for the work done up to the point of failure, similar to Ethereum.
The list of each call's serialized return value.


'''

[id="the_validate_function"]
=== `+__validate__+`

.Description

_Always required_

Initiates the validation stage in the sequencer. Validates the sender's address. The sequencer calls this function upon receiving any transaction.

In most implementations, `+__validate__+` ensures that only the account owner can initiate transactions.


The `+__validate__+` function typically ensures that any transaction submitted was indeed initiated by the account owner and therefore does not take up unjustified resources during the execution process.


Without this mechanism, a forged transaction could result in the sequencer stealing the user's funds. So the `+__validate__+` function ensures that the sequencer can only include transactions that were approved by the account owner.

The arbitrary logic allowed in the `+__validate__+` function gives the account's designer the ability to determine what it means for a transaction to be valid, enabling different signature schemes and other xref:architecture_and_concepts:Accounts/introduction.adoc#examples[exotic accounts].

.Returns

If the signature is verified, the function should return the string `VALID` as `felt252` value. If not, it should return any other value, such as `0`.


======
This section is not appropriate, because the function can have arbitrary logic.
'''

== `+__validate_deploy__+`
[id="the_validate_declare_function"]
=== `+__validate_declare__+`

Validates a `DEPLOY_ACCOUNT` transaction.
.Description

_Required for a contract to be able to send a_`DECLARE` _transaction._

The sequencer calls this function upon receiving a `DECLARE` transaction.

If the contract declares other contracts and handles the corresponding gas fees, this function authenticates the contract declaration.

.Returns

If the signature is verified, the function should return the string `VALID` as `felt252` value. If not, it should return any other value, such as `0`.



'''

[id="the_validate_deploy_function"]
=== `+__validate_deploy__+`

.Description

_Required when deploying an account with a_ `DEPLOY_ACCOUNT` _transaction_.

The sequencer calls this function upon receiving a `DEPLOY_ACCOUNT` transaction. Validates the deployment of the class referred to by the `class_hash` parameter in the transaction.

You can use this function to set up an account contract without linking it to the address that deploys it or depending on another account contract for gas fees. When determining the contract's address, use the deployer address `0x0`.

[discrete]
=== Parameters
Expand All @@ -138,6 +205,10 @@ Validates a `DEPLOY_ACCOUNT` transaction.
In determining the contract address, the deployer address `0x0` is used.
====

.Returns

If the signature is verified, the function should return the string `VALID` as a `felt252` value. If not, it should return any other value, such as `0`.

[discrete]
=== Example
Consider an account with the following constructor signature:
Expand All @@ -161,5 +232,4 @@ fn constructor(ref self: ContractState, public_key: felt252)
[NOTE]
====
You can access the transaction hash and value for `max_fee` with the `get_tx_info` system call.
====
======
====

0 comments on commit 1c758ff

Please sign in to comment.