9. Extrinsics
9.1. Introduction
An extrinsic is a SCALE encoded array consisting of a version number, signature, and varying data types indicating the resulting Runtime function to be called, including the parameters required for that function to be executed.
9.2. Preliminaries
Definition 152. Extrinsic
An extrinsic , , is a tuple consisting of the extrinsic version, (Definition 153), and the body of the extrinsic, .
The value of varies for each version. The current version 4 is described in Section 9.3.1..
Definition 153. Extrinsic Version
is a 8-bit bitfield and defines the extrinsic version. The required format of an extrinsic body, , is dictated by the Runtime. Older or unsupported versions are rejected.
The most significant bit of indicates whether the transaction is signed () or unsigned (). The remaining 7-bits represent the version number. As an example, for extrinsic format version 4, a signed extrinsic represents as 132
while an unsigned extrinsic represents it as 4
.
9.3. Extrinsics Body
9.3.1. Version 4
Version 4 of the Polkadot extrinsic format is defined as follows:
where
is the multi-address of the sender defined in Definition 154.
: the signature of the sender (Definition 155).
: the extra data for the extrinsic (Definition 156).
: the indicator of the Polkadot module (Definition 157).
: the indicator of the function of the Polkadot module (Definition 158).
Definition 154. Extrinsic Address
Account Id, , is the 32-byte address of the sender of the extrinsic as described in the external SS58 address format.
Definition 155. Extrinsic Signature
The signature, , is a varying data type indicating the used signature type, followed by the signature created by the extrinsic author. The following types are supported:
Signature types vary in size, but each individual type is always fixed-size and therefore does not contain a length prefix. Ed25519
and Sr25519
signatures are 512-bit while Ecdsa
is 520-bit, where the last 8 bits are the recovery ID.
The signature is created by signing payload .
where
: the module indicator (Definition 157).
: the function indicator of the module (Definition 158).
: the extra data (Definition 156).
: a UINT32 containing the specification version (
spec_version
) of the Runtime (Section C.4.1.), which can be updated and is therefore subject to change.: a UINT32 containing the transaction version (
transaction_version
) of the Runtime (Section C.4.1.), which can be updated and is therefore subject to change.: a 32-byte array containing the genesis hash.
: a 32-byte array containing the hash of the block which starts the mortality period, as described in Definition 159.
Definition 156. Extra Data
Extra data, , is a tuple containing additional metadata about the extrinsic and the system it is meant to be executed in.
where
: contains the SCALE encoded mortality of the extrinsic (Definition 159).
: a compact integer containing the nonce of the sender. The nonce must be incremented by one for each extrinsic created, otherwise, the Polkadot network will reject the extrinsic.
: a compact integer containing the transactor pay including tip.
Definition 157. Module Indicator
is an indicator for the Runtime to which Polkadot module, , the extrinsic should be forwarded to.
is a varying data type pointing to every module exposed to the network.
Definition 158. Function Indicator
is a tuple which contains an indicator, , for the Runtime to which function within the Polkadot module, , the extrinsic should be forwarded to. This indicator is followed by the concatenated and SCALE encoded parameters of the corresponding function, .
The value of varies for each Polkadot module since every module offers different functions. As an example, the Balances
module has the following functions:
9.3.2. Mortality
Definition 159. Extrinsic Mortality
Extrinsic mortality is a mechanism which ensures that an extrinsic is only valid within a certain period of the ongoing Polkadot lifetime. Extrinsics can also be immortal, as clarified in Section 9.3.2.2..
The mortality mechanism works with two related values:
: the period of validity in terms of block numbers from the block hash specified as in the payload (Definition 155). The requirement is and must be the power of two, such as
32
,64
,128
, etc.: the phase in the period that this extrinsic’s lifetime begins. This value is calculated with a formula, and validators can use this value in order to determine which block hash is included in the payload. The requirement is .
In order to tie a transaction’s lifetime to a certain block () after it was issued, without wasting precious space for block hashes, block numbers are divided into regular periods and the lifetime is instead expressed as a "phase" () from these regular boundaries:
and are then included in the extrinsic, as clarified in Definition 156, in the SCALE encoded form of (Section 9.3.2.2.). Polkadot validators can use to figure out the block hash included in the payload, which will therefore result in a valid signature if the extrinsic is within the specified period or an invalid signature if the extrinsic "died".
9.3.2.1. Example
The extrinsic author choses at block 10'000
, resulting with . The extrinsic is then valid for blocks ranging from 10'000
to 10'256
.
9.3.2.2. Encoding
refers to the SCALE encoded form of type and . is the size of two bytes if the extrinsic is considered mortal, or simply one bytes with a value equal to zero if the extrinsic is considered immortal.
The SCALE encoded representation of mortality deviates from most other types, as it’s specialized to be the smallest possible value, as described in Encode Mortality and Decode Mortality.
If the extrinsic is immortal, specify a single byte with a value equal to zero.
Algorithm 25. Encode Mortality
\begin{algorithm} \caption{Encode Mortality} \begin{algorithmic} \Require{$M_{per}, M_{pha}$} \Return $0 \enspace \textbf{if} \enspace \textit{extrinsic is immortal}$ \State \textbf{init} $factor = $\call{Limit}{$M_{per} \gg 12, 1, \phi$} \State \textbf{init} $left = $\call{Limit}{\call{TZ}{$M_{per}$}$ - 1, 1, 15$} \State \textbf{init} $right = \frac{M_{pha}}{factor} \ll 4$ \Return $left|right$ \end{algorithmic} \end{algorithm}
Algorithm 26. Decode Mortality
\begin{algorithm} \caption{Decode Mortality} \begin{algorithmic} \Require{$T_{mor}$} \Return $\textit{Immortal} \enspace \textbf{if} \enspace T^{b0}_{mor} = 0$ \State \textbf{init} $enc = T^{b0}_{mor} + (T^{b1}_{mor} \ll 8)$ \State \textbf{init} $M_{per} = 2 \ll (enc\ mod\ (1 \ll 4))$ \State \textbf{init} $factor =$ \call{Limit}{$M_{per} \gg 12, 1, \phi$} \State \textbf{init} $M_{pha} = (enc \gg 4) * factor$ \Return $(M_{per}, M_{pha})$ \end{algorithmic} \end{algorithm}
where
: the first byte of .
: the second byte of .
Limit(, , ): Ensures that is between and . If or is defined as , then there is no requirement for the specified minimum/maximum.
TZ(): returns the number of trailing zeros in the binary representation of . For example, the binary representation of
40
is0010 1000
, which has three trailing zeros.: performs a binary right shift operation.
: performs a binary left shift operation.
: performs a bitwise OR operation.