Source code for agora.solana.system.program
from enum import IntEnum
from typing import NamedTuple
from agora.keys import PublicKey
from agora.solana.instruction import Instruction, AccountMeta
from agora.solana.transaction import Message
PROGRAM_KEY = PublicKey(bytes(32))
# RentSysVar points to the system variable "Rent"
#
# Source: https://github.com/solana-labs/solana/blob/f02a78d8fff2dd7297dc6ce6eb5a68a3002f5359/sdk/src/sysvar/rent.rs#L11
RENT_SYS_VAR = PublicKey.from_base58('SysvarRent111111111111111111111111111111111')
[docs]class Command(IntEnum):
CREATE_ACCOUNT = 0
ASSIGN = 1
TRANSFER = 2
CREATE_ACCOUNT_WITH_SEED = 3
ADVANCE_NONCE_ACCOUNT = 4
WITHDRAW_NONCE_ACCOUNT = 5
INITIALIZE_NONCE_ACCOUNT = 6
AUTHORIZE_NONCE_ACCOUNT = 7
ALLOCATE = 8
ALLOCATE_WITH_SEED = 9
ASSIGN_WITH_SEED = 10
TRANSFER_WITH_SEED = 11
# Reference: https://github.com/solana-labs/solana/blob/f02a78d8fff2dd7297dc6ce6eb5a68a3002f5359/sdk/src/system_instruction.rs#L58-L72 #noqa: E501
[docs]def create_account(
subsidizer: PublicKey, address: PublicKey, owner: PublicKey, lamports: int, size: int
) -> Instruction:
"""
Account references
0. [WRITE, SIGNER] Funding account
1. [WRITE, SIGNER] New account
CreateAccount {
// Number of lamports to transfer to the new account
lamports: u64,
// Number of bytes of memory to allocate
space: u64,
// Address of program that will own the new account
owner: Pubkey,
}
"""
data = bytearray()
data.extend(Command.CREATE_ACCOUNT.to_bytes(4, 'little'))
data.extend(lamports.to_bytes(8, 'little'))
data.extend(size.to_bytes(8, 'little'))
data.extend(owner.raw)
return Instruction(
PROGRAM_KEY,
data,
[
AccountMeta.new(subsidizer, True),
AccountMeta.new(address, True),
],
)
[docs]class DecompiledCreateAccount(NamedTuple):
funder: PublicKey
address: PublicKey
owner: PublicKey
lamports: int
size: int
[docs]def decompile_create_account(m: Message, index: int) -> DecompiledCreateAccount:
if index >= len(m.instructions):
raise ValueError(f"instruction doesn't exist at {index}")
i = m.instructions[index]
if m.accounts[i.program_index] != PROGRAM_KEY:
raise ValueError('incorrect program')
if len(i.accounts) != 2:
raise ValueError(f'invalid number of accounts: {len(i.accounts)}')
if len(i.data) != 52:
raise ValueError(f'invalid instruction data size: {len(i.data)}')
if int.from_bytes(i.data[0:4], 'little') != Command.CREATE_ACCOUNT:
raise ValueError(f'incorrect command')
return DecompiledCreateAccount(
m.accounts[i.accounts[0]],
m.accounts[i.accounts[1]],
PublicKey(i.data[4 + 2 * 8:]),
int.from_bytes(i.data[4:12], 'little'),
int.from_bytes(i.data[12:20], 'little'),
)