@@ -88,7 +88,6 @@ impl AccountCheck for SystemAccount {
8888
8989正如我们在之前的示例中看到的,` SystemAccount ` 和 ` SignerAccount ` 检查非常简单,不需要任何额外的验证,因此我们将在 ` helper.rs ` 中添加以下内容:
9090
91-
9291``` rust
9392pub trait AccountCheck {
9493 fn check (account : & AccountInfo ) -> Result <(), ProgramError >;
@@ -118,14 +117,12 @@ impl AccountCheck for SystemAccount {
118117}
119118```
120119
121-
122120这里我们只是检查账户是否是签名者,或者是否由系统程序拥有。请注意,这两个结构体都提供了相同的检查方法,为我们提供了前面提到的通用接口。
123121
124122<ArticleSection name = " 铸币账户和代币账户" id = " mint-and-token-accounts" level = " h2" />
125123
126124现在事情变得更有趣了。我们从常规的 ` AccountCheck ` trait 开始,但我们还添加了其他特定的 traits,以提供类似于 Anchor 宏的额外辅助功能,例如 ` init ` 和 ` init_if_needed ` 。
127125
128-
129126``` rust
130127pub struct MintAccount ;
131128
@@ -144,10 +141,8 @@ impl AccountCheck for MintAccount {
144141}
145142```
146143
147-
148144对于 ` init ` 和 ` init_if_needed ` 的功能,我们创建了另一个名为 ` MintInit ` 的 trait,专门用于此目的,因为它需要独特的字段。然后我们使用 ` CreateAccount ` 和 ` InitializeMint2 ` CPI 来初始化 ` Mint ` 账户:
149145
150-
151146``` rust
152147pub trait MintInit {
153148 fn init (account : & AccountInfo , payer : & AccountInfo , decimals : u8 , mint_authority : & [u8 ; 32 ], freeze_authority : Option <& [u8 ; 32 ]>) -> ProgramResult ;
@@ -185,10 +180,8 @@ impl MintInit for MintAccount {
185180}
186181```
187182
188-
189183然后我们对 ` TokenAccount ` 执行完全相同的操作:
190184
191-
192185``` rust
193186pub struct TokenAccount ;
194187
@@ -242,7 +235,6 @@ impl AccountInit for TokenAccount {
242235}
243236```
244237
245-
246238### Token2022
247239
248240您可能已经注意到,对于传统的 SPL Token Program,我们仅对 ` Mint ` 和 ` TokenAccount ` 进行了长度检查。这种方法之所以有效,是因为当您只有两种固定大小的账户类型时,可以仅通过它们的长度来区分它们。
@@ -255,7 +247,6 @@ impl AccountInit for TokenAccount {
255247
256248这导致了修改后的验证检查:
257249
258-
259250``` rust
260251// TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
261252pub const TOKEN_2022_PROGRAM_ID : [u8 ; 32 ] = [
@@ -372,12 +363,10 @@ impl AccountInit for TokenAccount2022Account {
372363}
373364```
374365
375-
376366### Token 接口
377367
378368为了让 Token2022 和传统的 Token Programs 更容易一起使用,而无需在它们之间进行区分,我们创建了一个遵循相同基本原则的辅助工具:
379369
380-
381370``` rust
382371pub struct MintInterface ;
383372
@@ -440,12 +429,10 @@ impl AccountCheck for TokenAccountInterface {
440429}
441430```
442431
443-
444432### 关联 Token 账户
445433
446434我们可以为 Associated Token Program 创建一些检查。这些检查与普通的 Token Program 检查非常相似,但它们包括一个额外的派生检查,以确保账户被正确派生。
447435
448-
449436``` rust
450437pub struct AssociatedTokenAccount ;
451438
@@ -493,7 +480,6 @@ impl AssociatedTokenAccountInit for AssociatedTokenAccount {
493480}
494481```
495482
496-
497483<ArticleSection name = " Program Accounts" id = " program-accounts" level = " h2" />
498484
499485最后,我们为 program account 实现了检查和辅助功能,包括 ` init ` 和 ` close ` 功能。
@@ -502,7 +488,6 @@ impl AssociatedTokenAccountInit for AssociatedTokenAccount {
502488
503489重新初始化攻击是指攻击者试图通过重新初始化已关闭的账户并注入恶意数据来重新利用该账户。通过将第一个字节设置为 255 并将账户缩小到几乎为零的大小,我们可以确保该账户在未来不会被误认为任何有效的账户类型。这是 Solana 程序中常见的安全模式。
504490
505-
506491 ``` rust
507492 pub struct ProgramAccount ;
508493
@@ -574,7 +559,6 @@ impl AssociatedTokenAccountInit for AssociatedTokenAccount {
574559 }
575560 ```
576561
577-
578562### 优化账户数据访问
579563
580564虽然我们可以实现一个通用的 ` Trait ` 来从 ` ProgramAccount ` 中读取数据,但创建特定的 ` readers ` 和 ` setters ` 来仅访问所需字段,而不是反序列化整个账户,会更高效。这种方法可以减少计算开销和 gas 成本。
0 commit comments