요약
각 명령어 실행 후 런타임 검사: 소유자만 램포트를 차감하거나 데이터를 수정할 수 있으며, 데이터는 명령어당 최대 10 KiB까지 증가할 수 있고, 소유자 변경은 제로 초기화된 데이터를 요구하며, 실행 가능 플래그는 되돌릴 수 없습니다.
Solana 런타임은
BorrowedInstructionAccount
메서드를 통해 각 명령어 실행 후 이러한 규칙을 강제합니다. 각 규칙은 수정 시점에
검사되며, 검사가 실패하면 트랜잭션이 롤백됩니다.
램포트 규칙
| 규칙 | 강제 사항 | 오류 |
|---|---|---|
| 소유자만 램포트를 차감할 수 있음 | set_lamports(): lamports < current일 때 is_owned_by_current_program()를 확인 | ExternalAccountLamportSpend |
| 읽기 전용 계정은 램포트를 변경할 수 없음 | set_lamports(): is_writable()를 확인 | ReadonlyLamportChange |
| 모든 프로그램은 쓰기 가능한 계정에 램포트를 입금할 수 있음 | set_lamports(): 소유권 검사는 새 잔액이 현재 잔액보다 적을 때만 적용되며, 쓰기 가능 검사는 여전히 적용됨 | ReadonlyLamportChange |
| 명령어 전체에서 램포트의 균형이 맞아야 함 | 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 상태 전환
계정은 세 가지
RentState
값 중 하나로 존재합니다: Uninitialized (0 lamports), RentPaying
(0보다 크지만 rent 면제 최소값 미만), 그리고 RentExempt (최소값 이상).
허용되지 않는 전환은 *rsTransactionError::InsufficientFundsForRent*를
생성합니다.
런타임은
transition_allowed()를
통해 이러한 규칙을 적용합니다:
- 모든 계정은
Uninitialized(닫기) 또는 *rsRentExempt*로 전환할 수 있습니다. - 어떤 계정도
Uninitialized또는 *rsRentExempt*에서 *rsRentPaying*로 진입할 수 없습니다. 모든 새 계정은 rent 면제 상태여야 합니다.
계정 대여 규칙
명령어 실행 중에 런타임은 계정에 대한 단일 작성자 대여 의미론을 적용합니다.
프로그램은 계정에 대해 하나의 가변 참조 또는 여러 불변 참조를 얻을 수 있지만, 둘
다 동시에 얻을 수는 없습니다. 프로그램이 이미 가변 대여된 계정을 대여하려고
시도하거나 (또는 이미 불변 대여된 계정을 가변 대여하려고 시도하면), 명령어는
try_borrow()
및
try_borrow_mut()를
통해 *rsAccountBorrowFailed*로 실패합니다. 명령어가 완료될 때 대여가 여전히
남아 있으면, 런타임은
TransactionContext::pop()에서
*rsAccountBorrowOutstanding*를 반환합니다.
Is this page helpful?