Özet
Her talimat sonrası çalışma zamanı kontrolleri: yalnızca sahip lamports düşebilir veya veriyi değiştirebilir, veri talimat başına maksimum 10 KiB büyüyebilir, sahip değişiklikleri sıfırlanmış veri gerektirir ve çalıştırılabilir bayrak geri alınamaz.
Solana çalışma zamanı bu kuralları her talimat yürütüldükten sonra
BorrowedInstructionAccount
metotları aracılığıyla uygular. Her kural değişiklik noktasında kontrol edilir
ve herhangi bir kontrol başarısız olursa işlem geri alınır.
Lamports kuralları
| Kural | Uygulama | Hata |
|---|---|---|
| Yalnızca sahip lamports düşebilir | set_lamports(): lamports < current olduğunda is_owned_by_current_program() kontrolü yapar | ExternalAccountLamportSpend |
| Salt okunur hesapların lamports değeri değiştirilemez | set_lamports(): is_writable() kontrolü yapar | ReadonlyLamportChange |
| Herhangi bir program yazılabilir hesaba lamports ekleyebilir | set_lamports(): sahiplik kontrolü yalnızca yeni bakiye mevcut bakiyeden az olduğunda uygulanır; yazılabilirlik kontrolü hala geçerlidir | ReadonlyLamportChange |
| Lamports bir talimat boyunca dengede olmalıdır | TransactionContext::pop(): get_lamports_delta() == 0 doğrulaması yapar | UnbalancedInstruction |
Veri kuralları
| Kural | Uygulama | Hata |
|---|---|---|
| Yalnızca sahip veriyi değiştirebilir | can_data_be_changed(): is_owned_by_current_program() kontrolü yapar | ExternalAccountDataModified |
| Salt okunur hesapların verisi değiştirilemez | can_data_be_changed(): is_writable() kontrolü yapar | ReadonlyDataModified |
| Yalnızca sahip veri boyutunu değiştirebilir | can_data_be_resized(): new_len != old_len olduğunda is_owned_by_current_program() kontrolü yapar | AccountDataSizeChanged |
| Maksimum veri boyutu: 10 MiB | TransactionAccounts::can_data_be_resized(): new_len <= MAX_ACCOUNT_DATA_LEN kontrolü yapar | InvalidRealloc |
| Talimat başına maksimum büyüme: 10 KiB | deserialize_parameters_aligned() içinde deserializasyon: post_len - pre_len <= MAX_PERMITTED_DATA_INCREASE kontrolü yapar | InvalidRealloc |
| İşlem başına maksimum büyüme: 20 MiB | TransactionAccounts::can_data_be_resized(): kümülatif resize_delta <= MAX_ACCOUNT_DATA_GROWTH_PER_TRANSACTION kontrolü yapar | MaxAccountsDataAllocationsExceeded |
Sahip kuralları
| Kural | Uygulama | Hata |
|---|---|---|
| Yalnızca mevcut sahip, sahipliği yeniden atayabilir | set_owner(): is_owned_by_current_program() kontrolü yapar | ModifiedProgramId |
| Hesap yazılabilir olmalıdır | set_owner(): is_writable() kontrolü yapar | ModifiedProgramId |
| Veri sıfır ile başlatılmış olmalıdır | set_owner(): is_zeroed(data) kontrolü yapar | ModifiedProgramId |
Çalıştırılabilir bayrak kuralları
| Kural | Uygulama | Hata |
|---|---|---|
| Hesap rent-exempt olmalıdır | set_executable(): rent.is_exempt(lamports, data_len) kontrolü yapar | ExecutableAccountNotRentExempt |
| Yalnızca sahip bayrağı ayarlayabilir | set_executable(): is_owned_by_current_program() kontrolü yapar | ExecutableModified |
| Hesap yazılabilir olmalıdır | set_executable(): is_writable() kontrolü yapar | ExecutableModified |
Rent durum geçişleri
Hesaplar üç
RentState
değerinden birinde bulunur: Uninitialized (0 lamport), RentPaying
(0'ın üzerinde ancak rent-exempt minimumun altında) ve RentExempt
(minimumda veya üzerinde). İzin verilmeyen geçişler
TransactionError::InsufficientFundsForRent üretir.
Çalışma zamanı bu kuralları
transition_allowed()
aracılığıyla uygular:
- Herhangi bir hesap
Uninitialized(kapatma) veyaRentExemptdurumuna geçebilir. - Hiçbir hesap
UninitializedveyaRentExemptdurumundanRentPayingdurumuna giremez. Tüm yeni hesaplar rent-exempt olmalıdır.
Hesap ödünç alma kuralları
Talimat yürütme sırasında, çalışma zamanı hesaplar üzerinde tek-yazıcı ödünç
alma semantiklerini uygular. Bir program bir hesaba ya bir değiştirilebilir
referans ya da birden fazla değiştirilemez referans alabilir, ancak ikisini aynı
anda alamaz. Bir program zaten değiştirilebilir şekilde ödünç alınmış bir hesabı
ödünç almaya çalışırsa (veya zaten değiştirilemez şekilde ödünç alınmış bir
hesabı değiştirilebilir şekilde ödünç almaya çalışırsa), talimat
try_borrow()
ve
try_borrow_mut()
aracılığıyla AccountBorrowFailed ile başarısız olur. Bir talimat
tamamlandığında hala bekleyen bir ödünç alma varsa, çalışma zamanı
TransactionContext::pop()
içinde AccountBorrowOutstanding döndürür.
Is this page helpful?