概要
各命令実行後のランタイムチェック: 所有者のみがlamportsを引き落としたりデータを変更でき、データは命令ごとに最大10 KiB成長可能、所有者変更にはゼロ初期化されたデータが必要、実行可能フラグは不可逆です。
Solanaランタイムは、BorrowedInstructionAccountメソッドを介して、各命令実行後にこれらのルールを強制します。各ルールは変更時点でチェックされ、いずれかのチェックが失敗するとトランザクションはロールバックされます。
Lamportsルール
| ルール | 強制 | エラー |
|---|---|---|
| 所有者のみがlamportsを引き落とし可能 | set_lamports(): lamports < currentの場合にis_owned_by_current_program()をチェック | ExternalAccountLamportSpend |
| 読み取り専用アカウントはlamportsを変更不可 | set_lamports(): is_writable()をチェック | ReadonlyLamportChange |
| 任意のプログラムが書き込み可能アカウントにlamportsを入金可能 | set_lamports(): 所有権チェックは新しい残高が現在の残高より少ない場合のみ適用され、書き込み可能チェックは引き続き適用されます | ReadonlyLamportChange |
| Lamportsは命令全体でバランスする必要がある | TransactionContext::pop(): get_lamports_delta() == 0を検証 | UnbalancedInstruction |
データルール
| ルール | 強制 | エラー |
|---|---|---|
| 所有者のみがデータを変更可能 | can_data_be_changed(): is_owned_by_current_program()をチェック | ExternalAccountDataModified |
| 読み取り専用アカウントはデータを変更不可 | can_data_be_changed(): is_writable()をチェック | ReadonlyDataModified |
| 所有者のみがデータをリサイズ可能 | can_data_be_resized(): new_len != old_lenの場合にis_owned_by_current_program()をチェック | AccountDataSizeChanged |
| 最大データサイズ: 10 MiB | TransactionAccounts::can_data_be_resized(): new_len <= MAX_ACCOUNT_DATA_LENをチェック | InvalidRealloc |
| 命令ごとの最大成長量: 10 KiB | deserialize_parameters_aligned()でのデシリアライゼーション: post_len - pre_len <= MAX_PERMITTED_DATA_INCREASEをチェック | InvalidRealloc |
| トランザクションごとの最大成長量: 20 MiB | TransactionAccounts::can_data_be_resized(): 累積resize_delta <= MAX_ACCOUNT_DATA_GROWTH_PER_TRANSACTIONをチェック | MaxAccountsDataAllocationsExceeded |
オーナールール
| ルール | 実施 | エラー |
|---|---|---|
| 現在のオーナーのみがオーナーを再割り当てできる | set_owner(): is_owned_by_current_program()をチェック | ModifiedProgramId |
| アカウントは書き込み可能である必要がある | set_owner(): is_writable()をチェック | ModifiedProgramId |
| データはゼロ初期化されている必要がある | set_owner(): is_zeroed(data)をチェック | ModifiedProgramId |
実行可能フラグルール
| ルール | 実施 | エラー |
|---|---|---|
| アカウントはrent免除である必要がある | set_executable(): rent.is_exempt(lamports, data_len)をチェック | ExecutableAccountNotRentExempt |
| オーナーのみがフラグを設定できる | set_executable(): is_owned_by_current_program()をチェック | ExecutableModified |
| アカウントは書き込み可能である必要がある | set_executable(): is_writable()をチェック | ExecutableModified |
Rent状態遷移
アカウントは3つの
RentState
値のいずれかに存在します:Uninitialized(0
lamports)、RentPaying(0より大きいがrent免除最小値未満)、およびRentExempt(最小値以上)。許可されていない遷移は*rsTransactionError::InsufficientFundsForRent*を生成します。
ランタイムは
transition_allowed()
を介してこれらのルールを実施します:
- すべてのアカウントは
Uninitialized(クローズ)または*rsRentExempt*に遷移できます。 - *rs
UninitializedまたはrsRentExemptからrsRentPaying*に入ることはできません。すべての新しいアカウントはrent免除である必要があります。
アカウント借用ルール
命令実行中、ランタイムはアカウントに対してシングルライター借用セマンティクスを実施します。プログラムは、アカウントに対して1つの可変参照または複数の不変参照のいずれかを取得できますが、両方を同時に取得することはできません。プログラムがすでに可変借用されているアカウントを借用しようとした場合(またはすでに不変借用されているアカウントを可変借用しようとした場合)、命令は
try_borrow()
および
try_borrow_mut()
を介して*rsAccountBorrowFailedで失敗します。借用がまだ未解決のまま命令が完了した場合、ランタイムは
TransactionContext::pop()
でrsAccountBorrowOutstanding*を返します。
Is this page helpful?