0
# System Programs
1
2
Built-in Solana programs including the System program for account creation and transfers, the Compute Budget program for transaction optimization, and Address Lookup Table operations. These programs provide essential blockchain functionality and performance management.
3
4
## Capabilities
5
6
### System Program Operations
7
8
Core blockchain operations for account management, transfers, and state changes provided by the System program.
9
10
```python { .api }
11
# System Program ID
12
ID: Final[Pubkey] = Pubkey.from_string("11111111111111111111111111111112")
13
```
14
15
#### Account Creation and Management
16
17
```python { .api }
18
def create_account(params: CreateAccountParams) -> Instruction:
19
"""
20
Create a new account with specified size and owner.
21
22
Parameters:
23
- params: CreateAccountParams, account creation parameters
24
25
Returns:
26
Instruction for creating account
27
"""
28
29
class CreateAccountParams:
30
"""Parameters for create_account instruction."""
31
from_pubkey: Pubkey # Funding account (must sign)
32
to_pubkey: Pubkey # New account address
33
lamports: int # Initial balance in lamports
34
space: int # Data size in bytes
35
owner: Pubkey # Program that will own the account
36
37
def decode_create_account(instruction: Instruction) -> CreateAccountParams:
38
"""
39
Decode create account instruction.
40
41
Parameters:
42
- instruction: Instruction, create account instruction
43
44
Returns:
45
CreateAccountParams with decoded parameters
46
"""
47
48
def create_account_with_seed(params: CreateAccountWithSeedParams) -> Instruction:
49
"""
50
Create account with deterministic address based on seed.
51
52
Parameters:
53
- params: CreateAccountWithSeedParams, creation parameters
54
55
Returns:
56
Instruction for creating account with seed
57
"""
58
59
class CreateAccountWithSeedParams:
60
"""Parameters for create_account_with_seed instruction."""
61
from_pubkey: Pubkey # Funding account
62
to_pubkey: Pubkey # Derived account address
63
base: Pubkey # Base pubkey for derivation
64
seed: str # Seed string for derivation
65
lamports: int # Initial balance
66
space: int # Data size
67
owner: Pubkey # Program owner
68
```
69
70
#### Account Assignment and Allocation
71
72
```python { .api }
73
def assign(params: AssignParams) -> Instruction:
74
"""
75
Assign account to a new owner program.
76
77
Parameters:
78
- params: AssignParams, assignment parameters
79
80
Returns:
81
Instruction for assigning account
82
"""
83
84
class AssignParams:
85
"""Parameters for assign instruction."""
86
account_pubkey: Pubkey # Account to assign
87
owner: Pubkey # New owner program
88
89
def assign_with_seed(params: AssignWithSeedParams) -> Instruction:
90
"""
91
Assign account created with seed to new owner.
92
93
Parameters:
94
- params: AssignWithSeedParams, assignment parameters
95
96
Returns:
97
Instruction for assigning account with seed
98
"""
99
100
class AssignWithSeedParams:
101
"""Parameters for assign_with_seed instruction."""
102
account_pubkey: Pubkey # Account to assign
103
base: Pubkey # Base pubkey used in derivation
104
seed: str # Seed string used in derivation
105
owner: Pubkey # New owner program
106
107
def allocate(params: AllocateParams) -> Instruction:
108
"""
109
Allocate space in an account for data storage.
110
111
Parameters:
112
- params: AllocateParams, allocation parameters
113
114
Returns:
115
Instruction for allocating space
116
"""
117
118
class AllocateParams:
119
"""Parameters for allocate instruction."""
120
account_pubkey: Pubkey # Account to allocate space in
121
space: int # Number of bytes to allocate
122
123
def allocate_with_seed(params: AllocateWithSeedParams) -> Instruction:
124
"""
125
Allocate space in account created with seed.
126
127
Parameters:
128
- params: AllocateWithSeedParams, allocation parameters
129
130
Returns:
131
Instruction for allocating space with seed
132
"""
133
134
class AllocateWithSeedParams:
135
"""Parameters for allocate_with_seed instruction."""
136
account_pubkey: Pubkey # Account to allocate
137
base: Pubkey # Base pubkey for derivation
138
seed: str # Seed string for derivation
139
space: int # Space to allocate
140
```
141
142
#### Lamport Transfers
143
144
```python { .api }
145
def transfer(params: TransferParams) -> Instruction:
146
"""
147
Transfer lamports between accounts.
148
149
Parameters:
150
- params: TransferParams, transfer parameters
151
152
Returns:
153
Instruction for transferring lamports
154
"""
155
156
class TransferParams:
157
"""Parameters for transfer instruction."""
158
from_pubkey: Pubkey # Source account (must sign)
159
to_pubkey: Pubkey # Destination account
160
lamports: int # Amount to transfer
161
162
def transfer_with_seed(params: TransferWithSeedParams) -> Instruction:
163
"""
164
Transfer lamports from account created with seed.
165
166
Parameters:
167
- params: TransferWithSeedParams, transfer parameters
168
169
Returns:
170
Instruction for transferring with seed
171
"""
172
173
class TransferWithSeedParams:
174
"""Parameters for transfer_with_seed instruction."""
175
from_pubkey: Pubkey # Source account
176
from_base: Pubkey # Base pubkey for source derivation
177
from_seed: str # Seed string for source
178
from_owner: Pubkey # Owner of source account
179
to_pubkey: Pubkey # Destination account
180
lamports: int # Amount to transfer
181
182
def transfer_many(transfers: List[TransferParams]) -> List[Instruction]:
183
"""
184
Create multiple transfer instructions efficiently.
185
186
Parameters:
187
- transfers: List[TransferParams], list of transfers to create
188
189
Returns:
190
List[Instruction], transfer instructions
191
"""
192
```
193
194
#### Nonce Account Operations
195
196
```python { .api }
197
def initialize_nonce_account(params: InitializeNonceAccountParams) -> Instruction:
198
"""
199
Initialize account as nonce account for durable transactions.
200
201
Parameters:
202
- params: InitializeNonceAccountParams, initialization parameters
203
204
Returns:
205
Instruction for initializing nonce account
206
"""
207
208
class InitializeNonceAccountParams:
209
"""Parameters for initialize_nonce_account instruction."""
210
nonce_pubkey: Pubkey # Nonce account address
211
authorized_pubkey: Pubkey # Authority for nonce operations
212
213
def advance_nonce_account(params: AdvanceNonceAccountParams) -> Instruction:
214
"""
215
Advance nonce value to invalidate previous transactions.
216
217
Parameters:
218
- params: AdvanceNonceAccountParams, advance parameters
219
220
Returns:
221
Instruction for advancing nonce
222
"""
223
224
class AdvanceNonceAccountParams:
225
"""Parameters for advance_nonce_account instruction."""
226
nonce_pubkey: Pubkey # Nonce account
227
authorized_pubkey: Pubkey # Authority (must sign)
228
229
def withdraw_nonce_account(params: WithdrawNonceAccountParams) -> Instruction:
230
"""
231
Withdraw lamports from nonce account.
232
233
Parameters:
234
- params: WithdrawNonceAccountParams, withdrawal parameters
235
236
Returns:
237
Instruction for withdrawing from nonce account
238
"""
239
240
class WithdrawNonceAccountParams:
241
"""Parameters for withdraw_nonce_account instruction."""
242
nonce_pubkey: Pubkey # Nonce account
243
authorized_pubkey: Pubkey # Authority (must sign)
244
to_pubkey: Pubkey # Recipient account
245
lamports: int # Amount to withdraw
246
247
def authorize_nonce_account(params: AuthorizeNonceAccountParams) -> Instruction:
248
"""
249
Change nonce account authority.
250
251
Parameters:
252
- params: AuthorizeNonceAccountParams, authorization parameters
253
254
Returns:
255
Instruction for changing nonce authority
256
"""
257
258
class AuthorizeNonceAccountParams:
259
"""Parameters for authorize_nonce_account instruction."""
260
nonce_pubkey: Pubkey # Nonce account
261
authorized_pubkey: Pubkey # Current authority (must sign)
262
new_authorized_pubkey: Pubkey # New authority
263
264
def create_nonce_account(
265
from_pubkey: Pubkey,
266
nonce_pubkey: Pubkey,
267
authorized_pubkey: Pubkey,
268
lamports: int
269
) -> List[Instruction]:
270
"""
271
Create and initialize nonce account in single call.
272
273
Parameters:
274
- from_pubkey: Pubkey, funding account
275
- nonce_pubkey: Pubkey, new nonce account
276
- authorized_pubkey: Pubkey, nonce authority
277
- lamports: int, initial balance
278
279
Returns:
280
List[Instruction], create and initialize instructions
281
"""
282
283
def create_nonce_account_with_seed(
284
from_pubkey: Pubkey,
285
nonce_pubkey: Pubkey,
286
base: Pubkey,
287
seed: str,
288
authorized_pubkey: Pubkey,
289
lamports: int
290
) -> List[Instruction]:
291
"""
292
Create and initialize nonce account with seed derivation.
293
294
Returns:
295
List[Instruction], create and initialize instructions
296
"""
297
```
298
299
### Address Lookup Table Operations
300
301
Efficient address compression through lookup table management.
302
303
```python { .api }
304
def create_lookup_table(params: CreateLookupTableParams) -> Instruction:
305
"""
306
Create new address lookup table.
307
308
Parameters:
309
- params: CreateLookupTableParams, creation parameters
310
311
Returns:
312
Instruction for creating lookup table
313
"""
314
315
class CreateLookupTableParams:
316
"""Parameters for create_lookup_table instruction."""
317
lookup_table: Pubkey # Lookup table account address
318
authority: Pubkey # Table authority
319
payer: Pubkey # Fee payer (must sign)
320
recent_slot: int # Recent slot for derivation
321
322
def create_lookup_table_signed(params: CreateLookupTableSignedParams) -> Instruction:
323
"""
324
Create lookup table with explicit signing.
325
326
Parameters:
327
- params: CreateLookupTableSignedParams, creation parameters
328
329
Returns:
330
Instruction for creating signed lookup table
331
"""
332
333
def extend_lookup_table(params: ExtendLookupTableParams) -> Instruction:
334
"""
335
Add addresses to existing lookup table.
336
337
Parameters:
338
- params: ExtendLookupTableParams, extension parameters
339
340
Returns:
341
Instruction for extending lookup table
342
"""
343
344
class ExtendLookupTableParams:
345
"""Parameters for extend_lookup_table instruction."""
346
lookup_table: Pubkey # Lookup table account
347
authority: Pubkey # Table authority (must sign)
348
payer: Optional[Pubkey] # Fee payer for expansion
349
new_addresses: List[Pubkey] # Addresses to add
350
351
def deactivate_lookup_table(params: DeactivateLookupTableParams) -> Instruction:
352
"""
353
Deactivate lookup table (prepare for closure).
354
355
Parameters:
356
- params: DeactivateLookupTableParams, deactivation parameters
357
358
Returns:
359
Instruction for deactivating lookup table
360
"""
361
362
class DeactivateLookupTableParams:
363
"""Parameters for deactivate_lookup_table instruction."""
364
lookup_table: Pubkey # Lookup table account
365
authority: Pubkey # Table authority (must sign)
366
367
def freeze_lookup_table(params: FreezeLookupTableParams) -> Instruction:
368
"""
369
Freeze lookup table (prevent further modifications).
370
371
Parameters:
372
- params: FreezeLookupTableParams, freeze parameters
373
374
Returns:
375
Instruction for freezing lookup table
376
"""
377
378
class FreezeLookupTableParams:
379
"""Parameters for freeze_lookup_table instruction."""
380
lookup_table: Pubkey # Lookup table account
381
authority: Pubkey # Table authority (must sign)
382
383
def close_lookup_table(params: CloseLookupTableParams) -> Instruction:
384
"""
385
Close deactivated lookup table and reclaim rent.
386
387
Parameters:
388
- params: CloseLookupTableParams, closure parameters
389
390
Returns:
391
Instruction for closing lookup table
392
"""
393
394
class CloseLookupTableParams:
395
"""Parameters for close_lookup_table instruction."""
396
lookup_table: Pubkey # Lookup table account
397
authority: Pubkey # Table authority (must sign)
398
recipient: Pubkey # Recipient of reclaimed rent
399
```
400
401
### Compute Budget Program
402
403
Transaction performance optimization through compute unit management.
404
405
```python { .api }
406
# Compute Budget Program ID
407
ID: Final[Pubkey] = Pubkey.from_string("ComputeBudget111111111111111111111111111111")
408
```
409
410
```python { .api }
411
def set_compute_unit_limit(units: int) -> Instruction:
412
"""
413
Set maximum compute units for transaction.
414
415
Parameters:
416
- units: int, compute unit limit (max 1,400,000)
417
418
Returns:
419
Instruction for setting compute limit
420
"""
421
422
def set_compute_unit_price(micro_lamports: int) -> Instruction:
423
"""
424
Set compute unit price for transaction prioritization.
425
426
Parameters:
427
- micro_lamports: int, price per compute unit in micro-lamports
428
429
Returns:
430
Instruction for setting compute price
431
"""
432
433
def request_heap_frame(bytes: int) -> Instruction:
434
"""
435
Request additional heap memory for transaction.
436
437
Parameters:
438
- bytes: int, additional heap bytes requested
439
440
Returns:
441
Instruction for requesting heap frame
442
"""
443
444
class ComputeBudget:
445
"""
446
Compute budget configuration for transaction optimization.
447
"""
448
def __init__(self, max_units: int, heap_size: int, additional_fee: int):
449
"""
450
Create compute budget configuration.
451
452
Parameters:
453
- max_units: int, maximum compute units allowed
454
- heap_size: int, heap memory allocation
455
- additional_fee: int, prioritization fee in micro-lamports
456
"""
457
458
@property
459
def max_units(self) -> int:
460
"""Maximum compute units."""
461
462
@property
463
def heap_size(self) -> int:
464
"""Heap memory size."""
465
466
@property
467
def additional_fee(self) -> int:
468
"""Additional fee for prioritization."""
469
```
470
471
## Usage Examples
472
473
### Basic Account Operations
474
475
```python
476
from solders.system_program import (
477
create_account, transfer, CreateAccountParams, TransferParams, ID
478
)
479
from solders.keypair import Keypair
480
from solders.transaction import Transaction
481
482
# Generate keypairs
483
payer = Keypair()
484
new_account = Keypair()
485
recipient = Keypair()
486
487
# Create account instruction
488
create_params = CreateAccountParams(
489
from_pubkey=payer.pubkey(),
490
to_pubkey=new_account.pubkey(),
491
lamports=2039280, # Rent-exempt minimum for token account
492
space=165, # Token account size
493
owner=ID # System program owns initially
494
)
495
create_ix = create_account(create_params)
496
497
# Transfer instruction
498
transfer_params = TransferParams(
499
from_pubkey=payer.pubkey(),
500
to_pubkey=recipient.pubkey(),
501
lamports=1000000 # 0.001 SOL
502
)
503
transfer_ix = transfer(transfer_params)
504
505
# Combine in transaction
506
transaction = Transaction.new_with_payer([create_ix, transfer_ix], payer.pubkey())
507
```
508
509
### Nonce Account Management
510
511
```python
512
from solders.system_program import (
513
create_nonce_account, advance_nonce_account, AdvanceNonceAccountParams
514
)
515
516
# Create nonce account for durable transactions
517
nonce_keypair = Keypair()
518
authority = Keypair()
519
520
# Create and initialize nonce account
521
nonce_instructions = create_nonce_account(
522
from_pubkey=payer.pubkey(),
523
nonce_pubkey=nonce_keypair.pubkey(),
524
authorized_pubkey=authority.pubkey(),
525
lamports=2000000 # Rent-exempt amount
526
)
527
528
nonce_tx = Transaction.new_with_payer(nonce_instructions, payer.pubkey())
529
nonce_tx.sign([payer, nonce_keypair], recent_blockhash)
530
531
# Later: advance nonce for new transaction
532
advance_params = AdvanceNonceAccountParams(
533
nonce_pubkey=nonce_keypair.pubkey(),
534
authorized_pubkey=authority.pubkey()
535
)
536
advance_ix = advance_nonce_account(advance_params)
537
```
538
539
### Address Lookup Table Operations
540
541
```python
542
from solders.system_program import (
543
create_lookup_table, extend_lookup_table,
544
CreateLookupTableParams, ExtendLookupTableParams
545
)
546
from solders.address_lookup_table_account import derive_lookup_table_address
547
548
# Create lookup table
549
recent_slot = 100000000 # Current slot number
550
authority = Keypair()
551
552
# Derive lookup table address
553
lookup_table_address, bump = derive_lookup_table_address(
554
authority.pubkey(), recent_slot
555
)
556
557
# Create lookup table
558
create_table_params = CreateLookupTableParams(
559
lookup_table=lookup_table_address,
560
authority=authority.pubkey(),
561
payer=payer.pubkey(),
562
recent_slot=recent_slot
563
)
564
create_table_ix = create_lookup_table(create_table_params)
565
566
# Add addresses to table
567
frequently_used_addresses = [
568
Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"), # Token program
569
Pubkey.from_string("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"), # Associated token
570
# ... more frequently used addresses
571
]
572
573
extend_params = ExtendLookupTableParams(
574
lookup_table=lookup_table_address,
575
authority=authority.pubkey(),
576
payer=payer.pubkey(),
577
new_addresses=frequently_used_addresses
578
)
579
extend_ix = extend_lookup_table(extend_params)
580
```
581
582
### Compute Budget Optimization
583
584
```python
585
from solders.compute_budget import set_compute_unit_limit, set_compute_unit_price
586
587
# Set compute budget for transaction optimization
588
compute_limit_ix = set_compute_unit_limit(200000) # Reduce from default 1.4M
589
compute_price_ix = set_compute_unit_price(1000) # 1000 micro-lamports per CU
590
591
# Add to transaction (compute budget instructions go first)
592
optimized_tx = Transaction.new_with_payer([
593
compute_limit_ix,
594
compute_price_ix,
595
transfer_ix # Your main instruction
596
], payer.pubkey())
597
```
598
599
### Account Creation with Seed
600
601
```python
602
from solders.system_program import create_account_with_seed, CreateAccountWithSeedParams
603
from solders.pubkey import Pubkey
604
605
# Create account with deterministic address
606
base_pubkey = payer.pubkey()
607
seed = "my_deterministic_seed"
608
609
# Calculate derived address
610
derived_address = Pubkey.create_with_seed(base_pubkey, seed, ID)
611
612
# Create account with seed
613
create_seed_params = CreateAccountWithSeedParams(
614
from_pubkey=payer.pubkey(),
615
to_pubkey=derived_address,
616
base=base_pubkey,
617
seed=seed,
618
lamports=1000000,
619
space=100,
620
owner=ID
621
)
622
create_seed_ix = create_account_with_seed(create_seed_params)
623
```
624
625
### Multi-Transfer Operations
626
627
```python
628
# Transfer to multiple recipients efficiently
629
recipients = [recipient1.pubkey(), recipient2.pubkey(), recipient3.pubkey()]
630
amounts = [500000, 750000, 1000000] # Different amounts
631
632
transfer_params_list = [
633
TransferParams(
634
from_pubkey=payer.pubkey(),
635
to_pubkey=recipient,
636
lamports=amount
637
)
638
for recipient, amount in zip(recipients, amounts)
639
]
640
641
# Create all transfer instructions
642
transfer_instructions = transfer_many(transfer_params_list)
643
644
# Add to transaction
645
multi_transfer_tx = Transaction.new_with_payer(transfer_instructions, payer.pubkey())
646
```
647
648
## Instruction Decoding
649
650
### Decoding System Instructions
651
652
```python
653
from solders.system_program import (
654
decode_create_account, decode_transfer, decode_assign
655
)
656
657
# Decode instructions from transaction
658
for instruction in transaction.message.instructions:
659
if instruction.program_id == system_program.ID:
660
try:
661
# Try different decoders based on instruction data
662
create_params = decode_create_account(instruction)
663
print(f"Create account: {create_params.space} bytes for {create_params.to_pubkey}")
664
except:
665
try:
666
transfer_params = decode_transfer(instruction)
667
print(f"Transfer: {transfer_params.lamports} lamports to {transfer_params.to_pubkey}")
668
except:
669
print("Unknown system instruction")
670
```
671
672
## Constants and Limits
673
674
### System Program Limits
675
676
```python { .api }
677
# Maximum account data size
678
MAX_PERMITTED_DATA_LENGTH: Final[int] = 10 * 1024 * 1024 # 10 MB
679
680
# Minimum lamports for account creation
681
LAMPORTS_PER_SIGNATURE: Final[int] = 5000
682
683
# Maximum seed length for derived addresses
684
MAX_SEED_LENGTH: Final[int] = 32
685
```
686
687
### Compute Budget Limits
688
689
```python { .api }
690
# Default compute unit limit
691
DEFAULT_COMPUTE_UNITS: Final[int] = 200000
692
693
# Maximum compute unit limit
694
MAX_COMPUTE_UNITS: Final[int] = 1400000
695
696
# Maximum compute unit price (micro-lamports)
697
MAX_COMPUTE_UNIT_PRICE: Final[int] = 1000000
698
```
699
700
## Error Handling
701
702
System program operations can fail for various reasons:
703
704
```python
705
from solders.errors import InstructionError
706
707
try:
708
# Account creation with insufficient funds
709
create_ix = create_account(CreateAccountParams(
710
from_pubkey=payer.pubkey(),
711
to_pubkey=new_account.pubkey(),
712
lamports=10000000000, # More than payer has
713
space=165,
714
owner=ID
715
))
716
except InstructionError as e:
717
print(f"Account creation failed: {e}")
718
719
try:
720
# Transfer more than available
721
transfer_ix = transfer(TransferParams(
722
from_pubkey=payer.pubkey(),
723
to_pubkey=recipient.pubkey(),
724
lamports=999999999999 # Excessive amount
725
))
726
except InstructionError as e:
727
print(f"Transfer failed: {e}")
728
```