Các chương trình

Trên Solana, một hợp đồng thông minh được gọi là chương trình. Một chương trình là một tài khoản phi trạng thái chứa mã thực thi. Mã này được tổ chức thành các hàm gọi là các chỉ thị. Người dùng tương tác với một chương trình bằng cách gửi một giao dịch chứa một hoặc nhiều chỉ thị. Một giao dịch có thể bao gồm chỉ thị từ nhiều chương trình.

Khi một chương trình được triển khai, Solana sử dụng LLVM để biên dịch nó thành định dạng thực thi và liên kết (ELF). Tệp ELF chứa mã nhị phân của chương trình ở Định dạng Bytecode Solana (sBPF) và được lưu trên chuỗi trong một tài khoản thực thi.

sBPF là phiên bản tùy chỉnh của Solana cho mã bytecode eBPF.

Viết chương trình

Phần lớn các chương trình được viết bằng Rust, với hai phương pháp phát triển phổ biến:

  • Anchor: Anchor là một framework được thiết kế để phát triển Solana nhanh chóng và dễ dàng. Nó sử dụng Rust macros để giảm mã soạn sẵn—làm cho nó trở nên tuyệt vời cho người mới bắt đầu.
  • Native Rust: Viết chương trình bằng Rust mà không sử dụng bất kỳ framework nào. Phương pháp này cung cấp nhiều linh hoạt hơn nhưng đi kèm với độ phức tạp cao hơn.

Cập nhật chương trình

Để sửa đổi một chương trình hiện có, một tài khoản phải được chỉ định là quyền nâng cấp. (Thường là cùng một tài khoản đã ban đầu triển khai chương trình.) Nếu quyền nâng cấp bị rút lại và đặt thành null, chương trình không thể được cập nhật nữa.

Xác minh chương trình

Solana hỗ trợ bản dựng có thể xác minh, cho phép người dùng kiểm tra xem mã trên chuỗi của một chương trình có khớp với mã nguồn công khai của nó hay không. Framework Anchor cung cấp hỗ trợ tích hợp để tạo một bản dựng có thể xác minh.

Để kiểm tra xem một chương trình hiện có đã được xác minh hay chưa, tìm kiếm ID chương trình của nó trên Solana Explorer. Ngoài ra, bạn có thể sử dụng Solana Verifiable Build CLI của Ellipsis Labs, để độc lập xác minh các chương trình trên chuỗi.

Các chương trình tích hợp sẵn

System Program

System Program là tài khoản duy nhất có thể tạo ra các tài khoản mới. Theo mặc định, tất cả các tài khoản mới đều thuộc sở hữu của System Program, mặc dù nhiều tài khoản được gán cho chủ sở hữu mới khi tạo. System Program thực hiện các chức năng chính sau đây:

Chức năngMô tả
Tạo tài khoản mớiChỉ System Program mới có thể tạo tài khoản mới.
Phân bổ không gianThiết lập dung lượng byte cho trường dữ liệu của mỗi tài khoản.
Gán quyền sở hữu chương trìnhSau khi System Program tạo một tài khoản, nó có thể gán lại chủ sở hữu chương trình được chỉ định cho một program account khác. Đó là cách các chương trình tùy chỉnh nắm quyền sở hữu các tài khoản mới được tạo bởi System Program.
Chuyển SOLChuyển lamports (SOL) từ các tài khoản hệ thống sang các tài khoản khác.

Địa chỉ của System Program là 11111111111111111111111111111111.

Chương trình tải

Mỗi chương trình đều thuộc sở hữu của một chương trình khác—trình tải của nó. Các trình tải được sử dụng để triển khai, triển khai lại, nâng cấp hoặc đóng các chương trình. Chúng cũng được sử dụng để hoàn thiện một chương trình và chuyển giao quyền quản lý chương trình.

Các chương trình tải đôi khi được gọi là 'BPF Loaders'.

Hiện tại có năm chương trình tải, như được hiển thị trong bảng dưới đây.

Trình tảiID chương trìnhGhi chúLiên kết hướng dẫn
nativeNativeLoader1111111111111111111111111111111Sở hữu bốn trình tải còn lại
v1BPFLoader1111111111111111111111111111111111Các hướng dẫn quản lý bị vô hiệu hóa, nhưng các chương trình vẫn thực thi
v2BPFLoader2111111111111111111111111111111111Các hướng dẫn quản lý bị vô hiệu hóa, nhưng các chương trình vẫn thực thiHướng dẫn
v3BPFLoaderUpgradeab1e11111111111111111111111Các chương trình có thể được cập nhật sau khi triển khai. Tệp thực thi chương trình được lưu trữ trong một tài khoản dữ liệu chương trình riêng biệtHướng dẫn
v4LoaderV411111111111111111111111111111111111Đang phát triển (chưa phát hành)Hướng dẫn

Các chương trình được triển khai với loader-v3 hoặc loader-v4 có thể được sửa đổi sau khi triển khai, tùy thuộc vào quyền nâng cấp của nó.

Khi một chương trình mới được triển khai, phiên bản loader mới nhất sẽ được sử dụng theo mặc định.

Các chương trình được biên dịch sẵn

Ngoài các chương trình loader, Solana cung cấp các chương trình được biên dịch sẵn sau đây.

Xác minh chữ ký ed25519

Chương trình ed25519 được sử dụng để xác minh một hoặc nhiều chữ ký ed25519.

Chương trìnhID Chương trìnhMô tảHướng dẫn
Chương trình Ed25519Ed25519SigVerify111111111111111111111111111Xác minh chữ ký ed25519. Nếu bất kỳ chữ ký nào thất bại, một lỗi sẽ được trả về.Hướng dẫn

Chương trình ed25519 xử lý một lệnh. u8 đầu tiên của lệnh chứa số lượng chữ ký cần kiểm tra, theo sau là một byte đệm. Sau đó, cấu trúc sau đây được tuần tự hóa, một cho mỗi chữ ký cần kiểm tra.

Ed25519SignatureOffsets
struct Ed25519SignatureOffsets {
signature_offset: u16, // offset to ed25519 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to public key of 32 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u16, // index of instruction data to get message data
}
Signature verification pseudocode
process_instruction() {
for i in 0..count {
// i'th index values referenced:
instructions = &transaction.message().instructions
instruction_index = ed25519_signature_instruction_index != u16::MAX ? ed25519_signature_instruction_index : current_instruction;
signature = instructions[instruction_index].data[ed25519_signature_offset..ed25519_signature_offset + 64]
instruction_index = ed25519_pubkey_instruction_index != u16::MAX ? ed25519_pubkey_instruction_index : current_instruction;
pubkey = instructions[instruction_index].data[ed25519_pubkey_offset..ed25519_pubkey_offset + 32]
instruction_index = ed25519_message_instruction_index != u16::MAX ? ed25519_message_instruction_index : current_instruction;
message = instructions[instruction_index].data[ed25519_message_data_offset..ed25519_message_data_offset + ed25519_message_data_size]
if pubkey.verify(signature, message) != Success {
return Error
}
}
return Success
}

Xác minh khôi phục secp256k1

Chương trình secp256k1 được sử dụng để xác minh các hoạt động khôi phục khóa công khai secp256k1.

Chương trìnhID Chương trìnhMô tảHướng dẫn
Chương trình Secp256k1KeccakSecp256k11111111111111111111111111111Xác minh các hoạt động khôi phục khóa công khai secp256k1 (ecrecover).Hướng dẫn

Chương trình secp256k1 xử lý một lệnh. Byte đầu tiên của lệnh chứa số lượng khóa công khai cần kiểm tra. Sau đó, cấu trúc sau đây được tạo một lần cho mỗi khóa công khai, sau đó được tuần tự hóa và thêm vào dữ liệu lệnh.

Secp256k1SignatureOffsets
struct Secp256k1SignatureOffsets {
secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytes
secp_signature_instruction_index: u8, // instruction index to find signature
secp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytes
secp_pubkey_instruction_index: u8, // instruction index to find pubkey
secp_message_data_offset: u16, // offset to start of message data
secp_message_data_size: u16, // size of message data
secp_message_instruction_index: u8, // instruction index to find message data
}
Recovery verification pseudocode
process_instruction() {
for i in 0..count {
// i'th index values referenced:
instructions = &transaction.message().instructions
signature = instructions[secp_signature_instruction_index].data[secp_signature_offset..secp_signature_offset + 64]
recovery_id = instructions[secp_signature_instruction_index].data[secp_signature_offset + 64]
ref_eth_pubkey = instructions[secp_pubkey_instruction_index].data[secp_pubkey_offset..secp_pubkey_offset + 20]
message_hash = keccak256(instructions[secp_message_instruction_index].data[secp_message_data_offset..secp_message_data_offset + secp_message_data_size])
pubkey = ecrecover(signature, recovery_id, message_hash)
eth_pubkey = keccak256(pubkey[1..])[12..]
if eth_pubkey != ref_eth_pubkey {
return Error
}
}
return Success
}

Điều này cho phép người dùng chỉ định bất kỳ dữ liệu lệnh nào trong giao dịch cho dữ liệu chữ ký và tin nhắn. Bằng cách chỉ định một sysvar hướng dẫn đặc biệt, người dùng cũng có thể nhận dữ liệu từ chính giao dịch.

Chi phí của giao dịch sẽ tính số lượng chữ ký cần xác minh nhân với hệ số nhân chi phí xác minh chữ ký.

Chương trình secp256r1 được sử dụng để xác minh tối đa 8 chữ ký secp256r1.

Chương trìnhID chương trìnhMô tảHướng dẫn
Chương trình Secp256r1Secp256r1SigVerify1111111111111111111111111Xác minh tối đa 8 chữ ký secp256r1. Nhận một chữ ký, khóa công khai và tin nhắn. Trả về lỗi nếu có lỗi.Hướng dẫn

Chương trình secp256r1 xử lý một hướng dẫn. u8 đầu tiên của instruction data là số lượng chữ ký cần kiểm tra, theo sau là một byte đệm. Sau đó, cấu trúc sau đây được tạo cho mỗi chữ ký, sau đó được tuần tự hóa và thêm vào instruction data.

Secp256r1SignatureOffsets
struct Secp256r1SignatureOffsets {
signature_offset: u16, // offset to compact secp256r1 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to compressed public key of 33 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u16, // index of instruction data to get message data
}

Giá trị S thấp được áp dụng cho tất cả các chữ ký để tránh tính dễ thay đổi chữ ký ngẫu nhiên.

Signature verification psuedocode
process_instruction() {
if data.len() < SIGNATURE_OFFSETS_START {
return Error
}
num_signatures = data[0] as usize
if num_signatures == 0 || num_signatures > 8 {
return Error
}
expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_START
if data.len() < expected_data_size {
return Error
}
for i in 0..num_signatures {
offsets = parse_signature_offsets(data, i)
signature = get_data_slice(data, instruction_datas, offsets.signature_instruction_index, offsets.signature_offset, SIGNATURE_SERIALIZED_SIZE)
if s > half_curve_order {
return Error
}
pubkey = get_data_slice(data, instruction_datas, offsets.public_key_instruction_index, offsets.public_key_offset, COMPRESSED_PUBKEY_SERIALIZED_SIZE)
message = get_data_slice(data, instruction_datas, offsets.message_instruction_index, offsets.message_data_offset, offsets.message_data_size)
if !verify_signature(signature, pubkey, message) {
return Error
}
}
return Success
}

Các chương trình cốt lõi

Các chương trình trong danh sách dưới đây cung cấp chức năng cốt lõi của mạng.

Chương trìnhID chương trìnhMô tảHướng dẫn
System11111111111111111111111111111111Tạo tài khoản mới, phân bổ dữ liệu tài khoản, gán tài khoản cho các chương trình sở hữu, chuyển lamport từ các tài khoản thuộc sở hữu của System Program và thanh toán phí giao dịchSystemInstruction
VoteVote111111111111111111111111111111111111111Tạo và quản lý các tài khoản theo dõi trạng thái bỏ phiếu của validator và phần thưởngVoteInstruction
StakeStake11111111111111111111111111111111111111Tạo và quản lý các tài khoản đại diện cho stake và phần thưởng cho việc ủy quyền cho các validatorStakeInstruction
ConfigConfig1111111111111111111111111111111111111Thêm dữ liệu cấu hình vào chuỗi, theo sau là danh sách các khóa công khai được phép sửa đổi nó. Không giống như các chương trình khác, chương trình Config không định nghĩa bất kỳ hướng dẫn riêng lẻ nào. Nó chỉ có một hướng dẫn ngầm: "store". Dữ liệu hướng dẫn của nó là một tập hợp các khóa kiểm soát quyền truy cập vào tài khoản và dữ liệu được lưu trữ bên trongConfigInstruction
Compute BudgetComputeBudget111111111111111111111111111111Thiết lập giới hạn đơn vị tính toán và giá cho các giao dịch, cho phép người dùng kiểm soát tài nguyên tính toán và phí ưu tiênComputeBudgetInstruction
Address Lookup TableAddressLookupTab1e1111111111111111111111111Quản lý bảng tra cứu địa chỉ, cho phép các giao dịch tham chiếu nhiều tài khoản hơn so với những gì có thể phù hợp trong danh sách tài khoản của giao dịchProgramInstruction
ZK ElGamal ProofZkE1Gama1Proof11111111111111111111111111111Cung cấp xác minh bằng chứng zero-knowledge cho dữ liệu được mã hóa ElGamal

Is this page helpful?

Quản lý bởi

© 2025 Solana Foundation.
Đã đăng ký bản quyền.
Kết nối