diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 614c74edd9..1317d2a35e 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -22,6 +22,7 @@ * [Blockstore](validator/blockstore.md) * [Gossip Service](validator/gossip.md) * [The Runtime](validator/runtime.md) +* [Anatomy of a Transaction](transaction.md) * [Running a Validator](running-validator/README.md) * [Validator Requirements](running-validator/validator-reqs.md) * [Choosing a Testnet](running-validator/validator-testnet.md) @@ -38,8 +39,6 @@ * [Offline Signing](offline-signing/README.md) * [Durable Transaction Nonces](offline-signing/durable-nonce.md) * [API Reference](api-reference/README.md) - * [Transaction](api-reference/transaction-api.md) - * [Instruction](api-reference/instruction-api.md) * [JSON RPC API](api-reference/jsonrpc-api.md) * [JavaScript API](api-reference/javascript-api.md) * [solana CLI](api-reference/cli.md) diff --git a/book/src/api-reference/instruction-api.md b/book/src/api-reference/instruction-api.md deleted file mode 100644 index e460c9a9f0..0000000000 --- a/book/src/api-reference/instruction-api.md +++ /dev/null @@ -1,38 +0,0 @@ -# Instruction - -For the purposes of building a [Transaction](../transaction.md), a more verbose instruction format is used: - -* **Instruction:** - * **program\_id:** The pubkey of the on-chain program that executes the - - instruction - - * **accounts:** An ordered list of accounts that should be passed to - - the program processing the instruction, including metadata detailing - - if an account is a signer of the transaction and if it is a credit - - only account. - - * **data:** A byte array that is passed to the program executing the - - instruction - -A more compact form is actually included in a `Transaction`: - -* **CompiledInstruction:** - * **program\_id\_index:** The index of the `program_id` in the - - `account_keys` list - - * **accounts:** An ordered list of indices into `account_keys` - - specifying the accounds that should be passed to the program - - processing the instruction. - - * **data:** A byte array that is passed to the program executing the - - instruction - diff --git a/book/src/api-reference/transaction-api.md b/book/src/api-reference/transaction-api.md deleted file mode 100644 index 0b40a15e1a..0000000000 --- a/book/src/api-reference/transaction-api.md +++ /dev/null @@ -1,62 +0,0 @@ -# Transaction - -## Components of a `Transaction` - -* **Transaction:** - * **message:** Defines the transaction - * **header:** Details the account types of and signatures required by - - the transaction - - * **num\_required\_signatures:** The total number of signatures - - required to make the transaction valid. - - * **num\_credit\_only\_signed\_accounts:** The last - - `num_readonly_signed_accounts` signatures refer to signing - - credit only accounts. Credit only accounts can be used concurrently - - by multiple parallel transactions, but their balance may only be - - increased, and their account data is read-only. - - * **num\_credit\_only\_unsigned\_accounts:** The last - - `num_readonly_unsigned_accounts` public keys in `account_keys` refer - - to non-signing credit only accounts - - * **account\_keys:** List of public keys used by the transaction, including - - by the instructions and for signatures. The first - - `num_required_signatures` public keys must sign the transaction. - - * **recent\_blockhash:** The ID of a recent ledger entry. Validators will - - reject transactions with a `recent_blockhash` that is too old. - - * **instructions:** A list of [instructions](instruction-api.md) that are - - run sequentially and committed in one atomic transaction if all - - succeed. - * **signatures:** A list of signatures applied to the transaction. The - - list is always of length `num_required_signatures`, and the signature - - at index `i` corresponds to the public key at index `i` in `account_keys`. - - The list is initialized with empty signatures \(i.e. zeros\), and - - populated as signatures are added. - -## Transaction Signing - -A `Transaction` is signed by using an ed25519 keypair to sign the serialization of the `message`. The resulting signature is placed at the index of `signatures` matching the index of the keypair's public key in `account_keys`. - -## Transaction Serialization - -`Transaction`s \(and their `message`s\) are serialized and deserialized using the [bincode](https://crates.io/crates/bincode) crate with a non-standard vector serialization that uses only one byte for the length if it can be encoded in 7 bits, 2 bytes if it fits in 14 bits, or 3 bytes if it requires 15 or 16 bits. The vector serialization is defined by Solana's [short-vec](https://github.com/solana-labs/solana/blob/master/sdk/src/short_vec.rs). diff --git a/book/src/transaction.md b/book/src/transaction.md new file mode 100644 index 0000000000..fa3e6c6c1f --- /dev/null +++ b/book/src/transaction.md @@ -0,0 +1,79 @@ +# Anatomy of a Transaction + +This chapter documents the binary format of a transaction. + +## Transaction Format + +A transaction contains a [compact-array](#Compact-Array-Format) of signatures, +followed by a [message](#Message-Format). Each item in the signatures array is +a [digital signature](#Signature-Format) of the given message. The Solana +runtime verifies that the number of signatures matches the number in the first +8 bits of the [message header](#Message-Header-Format). It also verifies that +each signature was signed by the private key corresponding to the public key at +the same index in the message's account addresses array. + +### Signature Format + +Each digital signature is in the ed25519 binary format and consumes 64 bytes. + + +## Message Format + +A message contains a [header](#Message-Header-Format), followed by a +compact-array of [account addresses](#Account-Address-Format), followed by a +recent [blockhash](#Blockhash-Format), followed by a compact-array of +[instructions](#Instruction-Format). + +### Message Header Format + +The message header contains three unsigned 8-bit values. The first value is the +number of required signatures in the containing transaction. The second value +is the number of those corresponding account addresses that are read-only. The +third value in the message header is the number of read-only account addresses +not requiring signatures. + +### Account Addresses Format + +The addresses that require signatures appear at the beginning of the account +address array, with addresses requesting write access first and read-only +accounts following. The addresses that do not require signatures follow the +addresses that do, again with read-write accounts first and read-only accounts +following. + + +### Blockhash Format + +A blockhash contains a 32-byte SHA-256 hash. It is used to indicate when a +client last observed the ledger. Validators will reject transactions when the +blockhash is too old. + + +## Instruction Format + +An instruction contains a program ID index, followed by a compact-array of +account address indexes, followed by a compact-array of opaque 8-bit data. The +program ID index is used to identify an on-chain program that can interpret the +opaque data. The program ID index is an unsigned 8-bit index to an account +address in the message's array of account addresses. The account address +indexes are each an unsigned 8-bit index into that same array. + + +## Compact-Array Format + +A compact-array is serialized as the array length, followed by each array item. +The array length is a special multi-byte encoding called compact-u16. + +### Compact-u16 Format + +A compact-u16 is a multi-byte encoding of 16 bits. The first byte contains the +lower 7 bits of the value in its lower 7 bits. If the value is above 0x7f, the +high bit is set and the next 7 bits of the value are placed into the lower 7 +bits of a second byte. If the value is above 0x3fff, the high bit is set and +the remaining 2 bits of the value are placed into the lower 2 bits of a third +byte. + +## Account Address Format + +An account address is 32-bytes of arbitrary data. When the address requires a +digital signature, the runtime interprets it as the public key of an ed25519 +keypair.