Update docs.rs links to use specified versions rather than the latest (#106)

This commit is contained in:
acheron 2024-12-30 22:06:55 +01:00 committed by GitHub
parent b43e2aeebf
commit 64a4e1ef46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 27 additions and 24 deletions

View File

@ -37,7 +37,7 @@ fn find_pda(seeds, program_id) {
```
It is technically possible that no bump is found within 256 tries but this probability is negligible.
If you're interested in the exact calculation of a PDA, check out the [`solana_program` source code](https://docs.rs/solana-program/latest/solana_program/pubkey/struct.Pubkey.html#method.find_program_address).
If you're interested in the exact calculation of a PDA, check out the [`solana_program` source code](https://docs.rs/solana-program/1.17.0/solana_program/pubkey/struct.Pubkey.html#method.find_program_address).
The first bump that results in a PDA is commonly called the "canonical bump". Other bumps may also result in a PDA but it's recommended to only use the canonical bump to avoid confusion.

View File

@ -1,6 +1,6 @@
# Errors
> [`AnchorError` Rust Reference](https://docs.rs/anchor-lang/latest/anchor_lang/error/struct.AnchorError.html)
> [`AnchorError` Rust Reference](https://docs.rs/anchor-lang/0.29.0/anchor_lang/error/struct.AnchorError.html)
> [`AnchorError` Typescript Reference](https://coral-xyz.github.io/anchor/ts/classes/AnchorError.html)
@ -13,11 +13,11 @@ custom errors which the user (you!) can return.
- Custom Errors
- Non-anchor errors.
[AnchorErrors](https://docs.rs/anchor-lang/latest/anchor_lang/error/struct.AnchorError.html) provide a range of information like the error name and number or the location in the code where the error was thrown, or the account that violated a constraint (e.g. a `mut` constraint). Once thrown inside the program, [you can access the error information](https://coral-xyz.github.io/anchor/ts/classes/AnchorError.html) in the anchor clients like the typescript client. The typescript client also enriches the error with additional information about which program the error was thrown in and the CPI calls (which are explained [here](./CPIs.md) in the book) that led to the program from which the error was thrown from. [The milestone chapter](./milestone_project_tic-tac-toe.md) explores how all of this works together in practice. For now, let's look at how different errors can be returned from inside a program.
[AnchorErrors](https://docs.rs/anchor-lang/0.29.0/anchor_lang/error/struct.AnchorError.html) provide a range of information like the error name and number or the location in the code where the error was thrown, or the account that violated a constraint (e.g. a `mut` constraint). Once thrown inside the program, [you can access the error information](https://coral-xyz.github.io/anchor/ts/classes/AnchorError.html) in the anchor clients like the typescript client. The typescript client also enriches the error with additional information about which program the error was thrown in and the CPI calls (which are explained [here](./CPIs.md) in the book) that led to the program from which the error was thrown from. [The milestone chapter](./milestone_project_tic-tac-toe.md) explores how all of this works together in practice. For now, let's look at how different errors can be returned from inside a program.
## Anchor Internal Errors
> [Anchor Internal Error Code Reference](https://docs.rs/anchor-lang/latest/anchor_lang/error/enum.ErrorCode.html)
> [Anchor Internal Error Code Reference](https://docs.rs/anchor-lang/0.29.0/anchor_lang/error/enum.ErrorCode.html)
Anchor has many different internal error codes. These are not meant to be used by users, but it's useful to study the reference to learn about the mappings between codes and their causes. They are, for example, thrown when a constraint has been violated, e.g. when an account is marked with `mut` but its `is_writable` property is `false`.
@ -25,9 +25,9 @@ Anchor has many different internal error codes. These are not meant to be used b
You can add errors that are unique to your program by using the `error_code` attribute.
Simply add it to an enum with a name of your choice. You can then use the variants of the enum as errors in your program. Additionally, you can add a message attribute to the individual variants. Clients will then display this error message if the error occurs. Custom Error code numbers start at the [custom error offset](https://docs.rs/anchor-lang/latest/anchor_lang/error/constant.ERROR_CODE_OFFSET.html).
Simply add it to an enum with a name of your choice. You can then use the variants of the enum as errors in your program. Additionally, you can add a message attribute to the individual variants. Clients will then display this error message if the error occurs. Custom Error code numbers start at the [custom error offset](https://docs.rs/anchor-lang/0.29.0/anchor_lang/error/constant.ERROR_CODE_OFFSET.html).
To actually throw an error use the [`err!`](https://docs.rs/anchor-lang/latest/anchor_lang/macro.err.html) or the [`error!`](https://docs.rs/anchor-lang/latest/anchor_lang/prelude/macro.error.html) macro. These add file and line information to the error that is then logged by anchor.
To actually throw an error use the [`err!`](https://docs.rs/anchor-lang/0.29.0/anchor_lang/macro.err.html) or the [`error!`](https://docs.rs/anchor-lang/0.29.0/anchor_lang/prelude/macro.error.html) macro. These add file and line information to the error that is then logged by anchor.
```rust,ignore
#[program]
@ -52,7 +52,7 @@ pub enum MyError {
### require!
You can use the [`require`](https://docs.rs/anchor-lang/latest/anchor_lang/macro.require.html) macro to simplify writing errors. The code above can be simplified to this (Note that the `>=` flips to `<`):
You can use the [`require`](https://docs.rs/anchor-lang/0.29.0/anchor_lang/macro.require.html) macro to simplify writing errors. The code above can be simplified to this (Note that the `>=` flips to `<`):
```rust,ignore
#[program]
@ -73,6 +73,6 @@ pub enum MyError {
}
```
There are a couple of `require` macros to choose from ([search for require in the docs](https://docs.rs/anchor-lang/latest/anchor_lang/?search=require)). When comparing public keys, it's important to use the `keys` variants of the require statements like `require_keys_eq` instead of `require_eq` because comparing public keys with `require_eq` is very expensive.
There are a couple of `require` macros to choose from ([search for require in the docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/?search=require)). When comparing public keys, it's important to use the `keys` variants of the require statements like `require_keys_eq` instead of `require_eq` because comparing public keys with `require_eq` is very expensive.
> (Ultimately, all programs return the same Error: The [`ProgramError`](https://docs.rs/solana-program/latest/solana_program/program_error/enum.ProgramError.html). This Error has a field for a custom error number. This is where Anchor puts its internal and custom error codes. However, this is just a single number and a single number is only so useful. So in addition, in the case of AnchorErrors, Anchor logs the returned AnchorError and the Anchor clients parse these logs to provide as much information as possible. This is not always possible. For example, there is currently no easy way to get the logs of a `processed` transaction with preflight checks turned off. In addition, non-anchor or old anchor programs might not log AnchorErrors. In these cases, Anchor will fall back to checking whether the returned error number by the transaction matches an error number defined in the `IDL` or an Anchor internal error code. If so, Anchor will at least enrich the error with the error message. Also, if there are logs available, Anchor will always try to parse the program error stack and return that so you know which program the error was returned from.
> (Ultimately, all programs return the same Error: The [`ProgramError`](https://docs.rs/solana-program/1.17.0/solana_program/program_error/enum.ProgramError.html). This Error has a field for a custom error number. This is where Anchor puts its internal and custom error codes. However, this is just a single number and a single number is only so useful. So in addition, in the case of AnchorErrors, Anchor logs the returned AnchorError and the Anchor clients parse these logs to provide as much information as possible. This is not always possible. For example, there is currently no easy way to get the logs of a `processed` transaction with preflight checks turned off. In addition, non-anchor or old anchor programs might not log AnchorErrors. In these cases, Anchor will fall back to checking whether the returned error number by the transaction matches an error number defined in the `IDL` or an Anchor internal error code. If so, Anchor will at least enrich the error with the error message. Also, if there are logs available, Anchor will always try to parse the program error stack and return that so you know which program the error was returned from.

View File

@ -4,13 +4,13 @@ The Accounts struct is where you define which accounts your instruction expects
## Types
> [Account Types Reference](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/index.html)
> [Account Types Reference](https://docs.rs/anchor-lang/0.29.0/anchor_lang/accounts/index.html)
Each type has a specific use case in mind. Detailed explanations for the types can be found in the [reference](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/index.html). We will briefly explain the most important type here, the `Account` type.
Each type has a specific use case in mind. Detailed explanations for the types can be found in the [reference](https://docs.rs/anchor-lang/0.29.0/anchor_lang/accounts/index.html). We will briefly explain the most important type here, the `Account` type.
### The Account Type
> [Account Reference](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/account/struct.Account.html)
> [Account Reference](https://docs.rs/anchor-lang/0.29.0/anchor_lang/accounts/account/struct.Account.html)
The `Account` type is used when an instruction is interested in the deserialized data of the account. Consider the following example where we set some data in an account:
@ -91,11 +91,11 @@ To run this example, add `anchor-spl = "<version>"` to the dependencies section
In this example, we set the `data` field of an account if the caller has admin rights. We decide whether the caller is an admin by checking whether they own admin tokens for the account they want to change. We do most of this via constraints which we will look at in the next section.
The important thing to take away is that we use the `TokenAccount` type (that wraps around the token program's `Account` struct and adds the required functions) to make anchor ensure that the incoming account is owned by the token program and to make anchor deserialize it. This means we can use the `TokenAccount` properties inside our constraints (e.g. `token_account.mint`) as well as in the instruction function.
Check out the [reference for the Account type](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/account/struct.Account.html) to learn how to implement your own wrapper types for non-anchor programs.
Check out the [reference for the Account type](https://docs.rs/anchor-lang/0.29.0/anchor_lang/accounts/account/struct.Account.html) to learn how to implement your own wrapper types for non-anchor programs.
## Constraints
> [Constraints reference](https://docs.rs/anchor-lang/latest/anchor_lang/derive.Accounts.html)
> [Constraints reference](https://docs.rs/anchor-lang/0.29.0/anchor_lang/derive.Accounts.html)
Account types can do a lot of work for you but they're not dynamic enough to handle all the security checks a secure program requires.
@ -133,7 +133,7 @@ You can find information about all constraints in the reference. We will cover s
## Safety checks
Two of the Anchor account types, [AccountInfo](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/account_info/index.html) and [UncheckedAccount](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/unchecked_account/index.html) do not implement any checks on the account being passed. Anchor implements safety checks that encourage additional documentation describing why additional checks are not necessary.
Two of the Anchor account types, [AccountInfo](https://docs.rs/anchor-lang/0.29.0/anchor_lang/accounts/account_info/index.html) and [UncheckedAccount](https://docs.rs/anchor-lang/0.29.0/anchor_lang/accounts/unchecked_account/index.html) do not implement any checks on the account being passed. Anchor implements safety checks that encourage additional documentation describing why additional checks are not necessary.
Attempting to build a program containing the following excerpt with `anchor build`:

View File

@ -1,4 +1,5 @@
# The Program Module
The program module is where you define your business logic. You do so by writing functions which can be called by clients or other programs. You've already seen one example of such a function, the `set_data` function from the previous section.
```rust,ignore
@ -16,7 +17,7 @@ mod hello_anchor {
## Context
> [Context Reference](https://docs.rs/anchor-lang/latest/anchor_lang/context/index.html)
> [Context Reference](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/index.html)
Each endpoint function takes a `Context` type as its first argument. Through this context argument it can access the accounts (`ctx.accounts`), the program id (`ctx.program_id`) of the executing program, and the remaining accounts (`ctx.remaining_accounts`). `remaining_accounts` is a vector that contains all accounts that were passed into the instruction but are not declared in the `Accounts` struct. This is useful when you want your function to handle a variable amount of accounts, e.g. when initializing a game with a variable number of players.
@ -75,4 +76,4 @@ pub struct MyAccount {
}
...
```
```

View File

@ -1,5 +1,5 @@
# Code References
- [Accounts Reference](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/index.html)
- [Constraints Reference](https://docs.rs/anchor-lang/latest/anchor_lang/derive.Accounts.html)
- [Error Codes](https://docs.rs/anchor-lang/latest/anchor_lang/error/enum.ErrorCode.html)
- [Accounts Reference](https://docs.rs/anchor-lang/0.29.0/anchor_lang/accounts/index.html)
- [Constraints Reference](https://docs.rs/anchor-lang/0.29.0/anchor_lang/derive.Accounts.html)
- [Error Codes](https://docs.rs/anchor-lang/0.29.0/anchor_lang/error/enum.ErrorCode.html)

View File

@ -2,6 +2,6 @@
Anchor's official documentation is split up into multiple parts, namely the guide, which is what you are reading right now and the references.
There are three references. One for the [core library](https://docs.rs/anchor-lang/latest/anchor_lang/) and one for each official client library ([typescript](https://coral-xyz.github.io/anchor/ts/index.html) and [rust](https://docs.rs/anchor-client/latest/anchor_client/)). These references are close to the code and detailed. If you know what you are looking for and want to understand how it works more deeply, you'll find explanations there.
There are three references. One for the [core library](https://docs.rs/anchor-lang/0.29.0/anchor_lang/) and one for each official client library ([typescript](https://coral-xyz.github.io/anchor/ts/index.html) and [rust](https://docs.rs/anchor-client/0.29.0/anchor_client/)). These references are close to the code and detailed. If you know what you are looking for and want to understand how it works more deeply, you'll find explanations there.
However, if you're new to anchor, you need to know what anchor has to offer before you can even try to understand it more deeply. That's what this guide is for. Its purpose is to introduce you to anchor, to help you become familiar with it. It teaches you what features are available in Anchor so you can explore them yourself in detail using the references.

View File

@ -22,6 +22,7 @@ Since all state lives in the heap, even programs themselves live there. Accounts
## Transactions and Accounts
You can make a program read and write data by sending transactions. Programs provide endpoints that can be called via transactions (In reality it's a bit more complex than that but frameworks like Anchor abstract away this complexity). A function signature usually takes the following arguments:
- the accounts that the program may read from and write to during this transaction.
- additional data specific to the function
@ -29,7 +30,7 @@ The first point means that even if in theory the program may read and write to a
> This design is partly responsible for Solanas high throughput. The runtime can look at all the incoming transactions of a program (and even across programs) and can check whether the memory regions in the first argument of the transactions overlap. If they dont, the runtime can run these transactions in parallel because they dont conflict with each other. Even better, if the runtime sees that two transactions access overlapping memory regions but only read and dont write, it can also parallelize those transactions because they do not conflict with each other.
How exactly can a transaction specify a memory region/account? To answer that, we need to look deeper into what properties an account has ([docs here](https://docs.rs/solana-program/latest/solana_program/account_info/struct.AccountInfo.html). This is the data structure for an account in a transaction. The `is_signer` and `is_writable` fields are set per transaction (e.g. `is_signed` is set if the corresponding private key of the account's `key` field signed the transaction) and are not part of the metadata that is saved in the heap). In front of the user data that the account can store (in the `data` field) , there is some metadata connected to each account. First, it has a key property which is a ed25519 public key and serves as the address of the account. This is how the transaction can specify which accounts the program may access in the transaction.
How exactly can a transaction specify a memory region/account? To answer that, we need to look deeper into what properties an account has ([docs here](https://docs.rs/solana-program/1.17.0/solana_program/account_info/struct.AccountInfo.html). This is the data structure for an account in a transaction. The `is_signer` and `is_writable` fields are set per transaction (e.g. `is_signed` is set if the corresponding private key of the account's `key` field signed the transaction) and are not part of the metadata that is saved in the heap). In front of the user data that the account can store (in the `data` field) , there is some metadata connected to each account. First, it has a key property which is a ed25519 public key and serves as the address of the account. This is how the transaction can specify which accounts the program may access in the transaction.
<div style="text-align: center">
@ -37,7 +38,7 @@ How exactly can a transaction specify a memory region/account? To answer that, w
</div>
An account also has a lamports field (a lamport is SOLs smallest unit). Since all state lives in the heap, normal SOL accounts are on the heap too. They're accounts with a `data` field of length 0 (they still have metadata though!) and some amount of lamports. The System Program owns all regular SOL accounts.
An account also has a lamports field (a lamport is SOLs smallest unit). Since all state lives in the heap, normal SOL accounts are on the heap too. They're accounts with a `data` field of length 0 (they still have metadata though!) and some amount of lamports. The System Program owns all regular SOL accounts.
## Rent
@ -76,7 +77,7 @@ Next to transferring lamports, the system program is used to create accounts for
## Program Composition
There are two ways for developers to make programs interact with each other. To explain these, we'll use a common flow on Solana: Create & Initialize.
There are two ways for developers to make programs interact with each other. To explain these, we'll use a common flow on Solana: Create & Initialize.
Consider a counter program with two endpoints. One to initialize the counter and one to increment it. To create a new counter, we call the system program's `create_account` to create the account in memory and then the counter's `initialize` function.
@ -89,6 +90,7 @@ a single transaction can also include multiple calls to different programs.
![create & initialize using multiple instructions in a transaction](../images/create_initialize_multiple_ix.svg)
If we went with this approach, our counter data structure would look like this:
```rust
pub struct Counter {
pub count: u64,