Skip to main content

Transaction structure

StarkNet, in its Alpha version, supports two types of transactions: a Deploy transaction and an Invoke Function transaction. We describe the available fields for both of these transaction types and how the transaction hash is calculated in both cases.

Deploy transaction

caution

The deploy transaction will be deprecated in future StarkNet versions. To deploy new constract instances, you can use the deploy syscall. For more information, see contract classes.

A deploy transaction is a transaction type used to deploy contracts to StarkNet.

A deploy transaction has the following fields:

NameTypeDescription
contract_address_saltFieldElementA random number used to distinguish between different instances of the contract
contract_definitionContractClassThe object that defines the contract's functionality
constructor_calldataList<FieldElement>The arguments passed to the constructor during deployment
caller_addressFieldElementWho invoked the deployment. Set to 0 (in future: the deploying account contract)
versionFieldElementThe transaction's version 1

Calculating the hash of a deploy transaction

In order to calculate the transaction hash, we first need to obtain the deployed contract address.

The Deploy transaction’s hash is calculated as follows:

deploy_tx_hash=h("deploy",version,contract_address,sn_keccak(“constructor”),h(constructor_calldata),0,chain_id)\begin{aligned} \text{deploy\_tx\_hash} = h( & \text{"deploy"}, \text{version}, \text{contract\_address}, sn\_keccak(\text{“constructor”}),\\ & h(\text{constructor\_calldata}), 0, \text{chain\_id}) \end{aligned}

Where:

  • The placeholder zero is used to align the hash computation for the different types of transactions (here, it holds the place of the max_fee field which exsists in both invoke and declare transactions)
  • “deploy” and “constructor” constant’s prefixes, encoded in bytes (ASCII), with big-endian.
  • hh is the Pedersen hash and sn_keccaksn\_keccak is StarkNet Keccak
  • chain_id is a constant value that specifies the network to which this transaction is sent. See Chain-Id.
  • contract_address is calculated as described here.

Invoke Transaction

The invoke function transaction is the main transaction type used to invoke contract functions in StarkNet.

An invoke function transaction has the following fields:

NameTypeDescription
contract_addressFieldElementThe address of the contract invoked by this transaction
entry_point_selectorFieldElementThe encoding of the selector for the function invoked (the entry point in the contract)
calldataList<FieldElement>The arguments passed to the invoked function
signatureList<FieldElement>Additional information given by the caller, representing the signature of the transaction
max_feeFieldElementThe maximum fee that the sender is willing to pay for the transaction
versionFieldElementThe transaction's version 1
transaction version

The StarkNet OS contains a hard-coded version (currently set to 0), and can only accept transactions with this version. A transaction with a different version can not be included in a proof. By advancing the version with breaking changes in the StarkNet OS, we can prevent old transactions from being executed in this unintended version, thus protecting the user. Note that setting a different version can be useful for testing purposes, since even if the transaction is properly signed, it can never be included in the production StarkNet (testnet or mainnet).

Calculating the hash of an invoke transaction

The invoke function transaction hash is calculated as a hash over the given transaction elements, specifically:

invoke_tx_hash=h("invoke",version,contract_address,entry_point_selector,h(calldata),max_fee,chain_id)\begin{aligned} \text{invoke\_tx\_hash} = h( & \text{"invoke"}, \text{version}, \text{contract\_address}, \text{entry\_point\_selector}, \\ & h(\text{calldata}), \text{max\_fee}, \text{chain\_id}) \end{aligned}

Where:

  • “invoke” is a constant prefix, encoded in bytes (ASCII), with big-endian.
  • chain_id is a constant value that specifies the network to which this transaction is sent. See Chain-Id.
  • hh is the Pedersen hash

Declare transaction

The declare transaction is used to introduce new classes into the state of StarkNet, enabling other contracts to deploy instances of those classes or using them in a library call. For more information, see contract classes.

A declare transaction has the following fields:

NameTypeDescription
contract_classContractClassThe class object
sender_addressFieldElementThe address of the account initiating the transaction
max_feeList<FieldElement>The maximum fee that the sender is willing to pay for the transaction
signatureList<FieldElement>Additional information given by the caller, representing the signature of the transaction
nonceFieldElementThe transaction nonce
versionFieldElementThe transaction's version 1

Calculating the hash of a declare transaction

The declare transaction hash is calculated as a hash over the given transaction elements, specifically:

invoke_tx_hash=h("declare",version,sender_address,0,0,max_fee,chain_id,class_hash)\begin{aligned} \text{invoke\_tx\_hash} = h( & \text{"declare"}, \text{version}, \text{sender\_address}, \\& 0, 0, \text{max\_fee}, \text{chain\_id}, \text{class\_hash}) \end{aligned}

Where:

  • The placeholders zeros are used to align the hash computation for the different types of transactions (here, they stand for the empty call data and entry point selector)
  • chain_id is a constant value that specifies the network to which this transaction is sent. See Chain-Id.
  • hh is the Pedersen hash

Signature

While StarkNet does not have a specific signature scheme built into the protocol, the Cairo language, in which smart contracts are written, does have an efficient implementation for ECDSA signature with respect to a STARK-friendly curve.

The generator used in the ECDSA algorithm is G=(gx,gy)G=\left(g_x, g_y\right) where:

gx=874739451078007766457464989774322083649278607533249481151382481072868806602g_x=874739451078007766457464989774322083649278607533249481151382481072868806602 gy=152666792071518830868575557812948353041420400780739481342941381225525861407g_y=152666792071518830868575557812948353041420400780739481342941381225525861407

Chain-Id

StarkNet currently supports two chain IDs. Chain IDs are given as numbers, representing an encoding of specific constants as bytes (ASCII) using big-endian, as illustrated by the following Python snippet:

chain_id = int.from_bytes(value, byteorder=“big”, signed=False)

Two constants are currently used:

  • SN_MAIN for StarkNet’s main network.
  • SN_GOERLI for StarkNet's testnet.

  1. The StarkNet OS defines the supported transaction versions (e.g. if a new field is added to the transaction, then the version is increased). A transaction whose version is not supported by the StarkNet OS can not be included in a block.