|
@@ -31,27 +31,16 @@ Some new syntax elements are introduced here.
|
|
First, let's start with the initialize instruction. Notice the `data` argument passed into the program. This argument and any other valid
|
|
First, let's start with the initialize instruction. Notice the `data` argument passed into the program. This argument and any other valid
|
|
Rust types can be passed to the instruction to define inputs to the program.
|
|
Rust types can be passed to the instruction to define inputs to the program.
|
|
|
|
|
|
-::: tip
|
|
|
|
-If you'd like to pass in your own type as an input to an instruction handler, then it must be
|
|
|
|
-defined in the same `src/lib.rs` file as the `#[program]` module, so that the IDL parser can
|
|
|
|
-pick it up.
|
|
|
|
-:::
|
|
|
|
-
|
|
|
|
Additionally,
|
|
Additionally,
|
|
notice how we take a mutable reference to `my_account` and assign the `data` to it. This leads us to
|
|
notice how we take a mutable reference to `my_account` and assign the `data` to it. This leads us to
|
|
-the `Initialize` struct, deriving `Accounts`. There are three things to notice about `Initialize`.
|
|
|
|
|
|
+the `Initialize` struct, deriving `Accounts`. There are two things to notice about `Initialize`.
|
|
|
|
|
|
1. The `my_account` field is of type `ProgramAccount<'info, MyAccount>`, telling the program it *must*
|
|
1. The `my_account` field is of type `ProgramAccount<'info, MyAccount>`, telling the program it *must*
|
|
be **owned** by the currently executing program, and the deserialized data structure is `MyAccount`.
|
|
be **owned** by the currently executing program, and the deserialized data structure is `MyAccount`.
|
|
-2. The `my_account` field is marked with the `#[account(init)]` attribute. This should be used
|
|
|
|
-in one situation: when a given `ProgramAccount` is newly created and is being used by the program
|
|
|
|
-for the first time (and thus its data field is all zero). If `#[account(init)]` is not used
|
|
|
|
-when account data is zero initialized, the transaction will be rejected.
|
|
|
|
-3. The `Rent` **sysvar** is required for the rent exemption check, which the framework enforces
|
|
|
|
-by default for any account marked with `#[account(init)]`. To be more explicit about the check,
|
|
|
|
-one can specify `#[account(init, rent_exempt = enforce)]`. To skip this check, (and thus
|
|
|
|
-allowing you to omit the `Rent` acccount), you can specify
|
|
|
|
-`#[account(init, rent_exempt = skip)]` on the account being initialized (here, `my_account`).
|
|
|
|
|
|
+2. The `my_account` field is marked with the `init` attribute. This will create a new
|
|
|
|
+account owned by the current program, zero initialized. When using `init`, one must also provider
|
|
|
|
+`payer`, which will fund the account creation, `space`, which defines how large the account should be,
|
|
|
|
+and the `system_program`, which is required by the runtime for creating the account.
|
|
|
|
|
|
::: details
|
|
::: details
|
|
All accounts created with Anchor are laid out as follows: `8-byte-discriminator || borsh
|
|
All accounts created with Anchor are laid out as follows: `8-byte-discriminator || borsh
|
|
@@ -81,15 +70,16 @@ for persisting changes.
|
|
|
|
|
|
## Creating and Initializing Accounts
|
|
## Creating and Initializing Accounts
|
|
|
|
|
|
-For a moment, assume an account of type `MyAccount` was created on Solana, in which case,
|
|
|
|
-we can invoke the above `initialize` instruction as follows.
|
|
|
|
|
|
+We can interact with the program as follows.
|
|
|
|
|
|
-<<< @/../examples/tutorial/basic-1/tests/basic-1.js#code-separated
|
|
|
|
|
|
+<<< @/../examples/tutorial/basic-1/tests/basic-1.js#code-simplified
|
|
|
|
|
|
The last element passed into the method is common amongst all dynamically generated
|
|
The last element passed into the method is common amongst all dynamically generated
|
|
methods on the `rpc` namespace, containing several options for a transaction. Here,
|
|
methods on the `rpc` namespace, containing several options for a transaction. Here,
|
|
we specify the `accounts` field, an object of all the addresses the transaction
|
|
we specify the `accounts` field, an object of all the addresses the transaction
|
|
-needs to touch.
|
|
|
|
|
|
+needs to touch, and the `signers` array of all `Signer` objects needed to sign the
|
|
|
|
+transaction. Because `myAccount` is being created, the Solana runtime requries it
|
|
|
|
+to sign the transaction.
|
|
|
|
|
|
::: details
|
|
::: details
|
|
If you've developed on Solana before, you might notice two things 1) the ordering of the accounts doesn't
|
|
If you've developed on Solana before, you might notice two things 1) the ordering of the accounts doesn't
|
|
@@ -98,22 +88,6 @@ options are not specified on the account anywhere. In both cases, the framework
|
|
of these details for you, by reading the IDL.
|
|
of these details for you, by reading the IDL.
|
|
:::
|
|
:::
|
|
|
|
|
|
-However it's common--and sometimes necessary for security purposes--to batch
|
|
|
|
-instructions together. We can extend the example above to both create an account
|
|
|
|
-and initialize it in one atomic transaction.
|
|
|
|
-
|
|
|
|
-<<< @/../examples/tutorial/basic-1/tests/basic-1.js#code
|
|
|
|
-
|
|
|
|
-Here, notice the **two** fields introduced: `signers` and `instructions`. `signers`
|
|
|
|
-is an array of all `Account` objects to sign the transaction and `instructions` is an
|
|
|
|
-array of all instructions to run **before** the explicitly specified program instruction,
|
|
|
|
-which in this case is `initialize`. Because we are creating `myAccount`, it needs to
|
|
|
|
-sign the transaction, as required by the Solana runtime.
|
|
|
|
-
|
|
|
|
-We can simplify this further.
|
|
|
|
-
|
|
|
|
-<<< @/../examples/tutorial/basic-1/tests/basic-1.js#code-simplified
|
|
|
|
-
|
|
|
|
As before, we can run the example tests.
|
|
As before, we can run the example tests.
|
|
|
|
|
|
```
|
|
```
|