账户空间
Rust 类型计算账户数据大小(字节)要求的参考指南
本参考指南告诉你应该为账户分配多少空间。
这仅适用于不使用 zero-copy 的账户。zero-copy 使用 repr(C) 并带有指针转换,因此 C 布局适用。
除了账户数据的空间外,你还需要在 space 约束中为 Anchor 的内部标识符(discriminator)添加 8(见示例)。
类型图表
| 类型 | 空间(字节) | 详情/示例 |
|---|---|---|
| bool | 1 | 只需要 1 位,但仍然使用 1 字节 |
| u8/i8 | 1 | |
| u16/i16 | 2 | |
| u32/i32 | 4 | |
| u64/i64 | 8 | |
| u128/i128 | 16 | |
| [T;数量] | space(T) * 数量 | 例如 space([u16;32]) = 2 * 32 = 64 |
| Pubkey | 32 | |
| Vec<T> | 4 + (space(T) * 数量) | 账户大小是固定的,因此账户应该从一开始就分配足够的空间 |
| String | 4 + 字符串的字节长度 | 账户大小是固定的,因此账户应该从一开始就分配足够的空间 |
| Option<T> | 1 + (space(T)) | |
| Enum | 1 + 最大变体的大小 | 例如 Enum { A, B { val: u8 }, C { val: u16 } } -> 1 + space(u16) = 3 |
| f32 | 4 | NaN 会导致序列化失败 |
| f64 | 8 | NaN 会导致序列化失败 |
示例
InitSpace 宏
有时计算账户的初始空间可能比较困难。此宏将为结构体添加一个 INIT_SPACE 常量。结构体不需要包含 #[account] 宏来生成该常量。以下是一个示例:
需要了解的几个重要事项:
- 定义
space时不要忘记标识符 max_len长度表示结构的长度,不是总长度。(例如:Vec<u32> 的max_len将是max_len* 4)