Transaction Subquery
Description
Transaction subqueries provide data about a transaction that was submitted on-chain. Etherscan provides a lot of useful information when looking at this data.
Limits
The number of transaction subqueries allowed in a single client circuit depends on the size of the transaction and receipt subqueries in the circuit.
-
Transaction subqueries are not supported for transactions with input data length greater than
330000
bytes or for transactions with RLP encoded access list length greater than131072
bytes. -
If your circuit has any of:
- transaction subquery for a transaction with input data length greater than
32768
bytes - transaction subquery for a transaction with RLP encoded access list length greater than
16384
bytes - receipt subquery for a transaction with more than
80
logs,
then the maximum number of transaction subqueries allowed in the circuit is
4
. - transaction subquery for a transaction with input data length greater than
-
Otherwise if your circuit has any of:
- transaction subquery for a transaction with input data length greater than
8192
bytes - transaction subquery for a transaction with RLP encoded access list length greater than
4096
bytes - receipt subquery for a transaction which contains a log with more than
1024
bytes in the data field,
then the maximum number of transaction subqueries allowed in the circuit is
16
. - transaction subquery for a transaction with input data length greater than
-
Otherwise the maximum number of transaction subqueries allowed is
128
.
For more details about limits on receipt subqueries, see Receipt Subquery.
Usage
To access data from a particular transaction, you must first find the blockNumber
the transaction is contained in, and the transaction index txIdx
of the transaction in that block. Then you need to construct a Tx
object using the getTx
function:
const getTx: (
blockNumber: number | CircuitValue,
txIdx: number | CircuitValue
) => Readonly<Tx>;
The returned Tx
is an interface with the functions below.
Note that all functions in the interface are async.
Example Usage
Here is an example of how to use the Tx
interface:
const tx: Tx = getTx(blockNumber, txIdx);
const value: CircuitValue256 = tx.value();
Tx
Interface
nonce: () => Promise<CircuitValue256>;
Returns the transaction nonce.
chainId: () => Promise<CircuitValue256>;
Returns the chain ID of the chain the transaction was on. Will error if called on a Legacy transaction.
maxPriorityFeePerGas: () => Promise<CircuitValue256>;
Returns the maximum priority fee per gas of the transaction. Only callable on a Type 2 transaction.
maxFeePerGas: () => Promise<CircuitValue256>;
Returns the max fee per gas of the transaction. Only callable on a Type 2 transaction.
gasLimit: () => Promise<CircuitValue256>;
Returns the gas limit of the transaction.
to: () => Promise<CircuitValue256>;
Returns the recipient address of the transaction. Will return 0
if the transaction is a contract creation.
value: () => Promise<CircuitValue256>;
Returns the value in wei sent with the transaction.
data: () => Promise<CircuitValue256>;
Returns the first 32 bytes of the transaction input data. Right pads with zeros if the input data is less than 32 bytes.
gasPrice: () => Promise<CircuitValue256>;
Returns the gas price of the transaction. Will error if called on a Type 2 transaction.
v: () => Promise<CircuitValue256>;
Returns v
of the transaction signature if the transaction is a Legacy transaction (see EIP-155). Otherwise returns the signatureYParity
.
r: () => Promise<CircuitValue256>;
Returns r
of the transaction signature, also known as signatureR
.
s: () => Promise<CircuitValue256>;
Returns s
of the transaction signature, also known as signatureS
.
blockNumber: () => Promise<CircuitValue256>;
Returns the block number of the block the transaction was included in.
txIdx: () => Promise<CircuitValue256>;
Returns the transaction index of the transaction in the block.
type: () => Promise<CircuitValue256>;
Returns the transaction type. This is one of 0, 1, 2
.
functionSelector: () => Promise<CircuitValue256>;
Returns the function selector (the first 4
bytes of calldata) of the transaction or one of two special values:
- If the transaction is a pure EOA transfer, it will return
NO_CALLDATA_SELECTOR = 61
. - If the transaction is a contract deployment, it will return
CONTRACT_DEPLOY_SELECTOR = 60
.
calldata: (calldataIdx: ConstantValue | CircuitValue) =>
Promise<CircuitValue256>;
This function is only callable on a non-contract deploy transaction that has non-empty calldata.
The function requires an additional input calldataIdx
and will returns the 32 bytes chunk in range [4 + 32 * calldataIdx, 4 + 32 * (calldataIdx + 1))
of the calldata of the transaction.
The shift by 4
bytes is for the function selector. This function will throw an error if 4 + 32 * calldataIdx
is greater than or equal to the length of the calldata.
The 32 bytes chunk is right padded with zeros when necessary.
contractData: (contractDataIdx: ConstantValue | CircuitValue) =>
Promise<CircuitValue256>;
The function requires an additional input contractDataIdx
and will returns the 32 bytes chunk in range [32 * contractDataIdx, 32 * (contractDataIdx + 1))
of the input data of the transaction.
This function will throw an error if 32 * contractDataIdx
is greater than or equal to the length of the input data.
The 32 bytes chunk is right padded with zeros when necessary.