Focus mode
Now you’re rocking. Let’s take this to 11.
In this lesson we’ll go over how use #[account(...)]
attribute with the following constraints:
seeds
and bump
- to initialize and validate PDAsrealloc
- to reallocate space on an accountclose
- to close an accountRecall that PDAs are derived using a list of optional seeds, a bump seed, and a programId
. Anchor provides a convenient way to validate a PDA with the seeds
and bump
constraints.
During account validation, Anchor will derive a PDA using the seeds specified in the seeds
constraint and verify that the account passed into the instruction matches the PDA found using the specified seeds
.
When the bump constraint is included without specifying a specific bump, Anchor will default to using the canonical bump (the first bump that results in a valid PDA).
In this example, the seeds and bump constraints are used to validate that the address of the pda_account is the expected PDA.
The seeds
used derive the PDA include:
The seeds
used derive the PDA include:
example_seed
- a hardcoded string valueuser.key()
- the public key of the account passed in as the user
instruction_data
- the instruction data passed into the instruction.#[instruction(...)]
attribute.#[instruction(...)]
attribute, the instruction data must be in the order that was passed into the instruction.An error would result if the inputs were listed in a different order:
You can combine the init
constraint with the seeds
and bump
constraints to initialize an account using a PDA.
The init
constraint must be used in combination with:
payer
- account specified to pay for the initializationspace
- space allocated to new accountsystem_program
- the init
constraint requires system_program
to exist in the account validation structBy default init sets the owner of the created account to the currently executing program.
init
with seeds
and bump
to initialize an account using a PDA, the owner must be the executing program.bump
value does not need to be specified since init
uses find_program_address
to derive the PDA.space
for an account initialized and owned by the executing Anchor program, remember that the first 8 bytes are reserved for a unique account discriminator that Anchor calculates and uses to identify the program account types.More often than creating new accounts, you'll be updating existing ones. Anchor has the awesome realloc
constraint that provides a simply way to reallocate space for existing accounts.
The realloc
constraint must be used in combination with:
mut
- the account must be set as mutablerealloc::payer
- the account to subtract or add lamports to depending on whether the reallocation is decreasing or increasing account spacerealloc::zero
- boolean to specify if new memory should be zero initializedsystem_program
- the realloc
constraint requires system_program
to exist in the account validation structFor example, reallocate space for an account that stores a data
field of type String
.
String
types, an addition 4 bytes of space is used to store the length of the String
in addition to the space allocated for the String
itself.realloc::payer
into the program account in order to maintain rent exemption.realloc::payer
.realloc::zero
constraint is required in order to determine whether the new memory should be zero initialized after reallocation.What happens when you're done with an account and don't want it to exist? You can close it!
This lets you free up space and you get the SOL paid for rent back!
This is done using the close
constraint:
close
constraint marks the account as closed at the end of the instruction’s execution by setting its discriminator to the CLOSED_ACCOUNT_DISCRIMINATOR
and sends its lamports to a specified account.data_account
and sending the lamports allocated for rent to the receiver
account.data_account
has_one
constraint can be used to check that an account passed into the instruction matched one stored on data
field of an accountdata
field of the account you are using the has_one
constraint to check againsthas_one = receiver
:data
of the account to check against be have a receiver
field#[derive(Accounts)]
struct must also be called receiver
close
constraint is just an example and the has_one
constraint can be used more generallyPrograms to Accelerate Your Progress in a Software Career
Join our 4-8 month intensive Patika+ bootcamps, start with the fundamentals and gain comprehensive knowledge to kickstart your software career!
You need to enroll in the course to be able to comment!