Các chương trình

Trên Solana, "smart contract" được gọi là chương trình (programs). Chương trình được triển khai trên chuỗi vào các tài khoản chứa tệp nhị phân thực thi đã được biên dịch của chương trình. Người dùng tương tác với chương trình bằng cách gửi các giao dịch chứa chỉ thị để cho chương trình biết phải làm gì.

Điểm chính

  • Chương trình là các tài khoản chứa mã thực thi, được tổ chức thành các hàm gọi là chỉ thị (instructions).
  • Mặc dù chương trình không lưu trữ trạng thái, chúng có thể bao gồm các chỉ thị để tạo và cập nhật các tài khoản khác để lưu trữ dữ liệu.
  • Một quyền nâng cấp có thể cập nhật chương trình. Khi quyền này bị xóa bỏ, chương trình trở nên bất biến.
  • Người dùng có thể xác minh dữ liệu tài khoản chương trình trên chuỗi khớp với mã nguồn công khai thông qua các bản dựng có thể xác minh.

Viết chương trình Solana

Các chương trình Solana chủ yếu được viết bằng ngôn ngữ lập trình Rust, với hai cách tiếp cận phổ biến cho phát triển:

  • Anchor: Một framework được thiết kế cho việc phát triển chương trình Solana. Nó cung cấp cách viết chương trình nhanh hơn và đơn giản hơn, sử dụng các macro Rust để giảm mã soạn sẵn. Đối với người mới bắt đầu, khuyến nghị nên bắt đầu với framework Anchor.

  • Rust thuần: Cách tiếp cận này liên quan đến việc viết chương trình Solana bằng Rust mà không sử dụng bất kỳ framework nào. Nó 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 Solana

Để tìm hiểu thêm về việc triển khai và nâng cấp chương trình, xem trang triển khai chương trình.

Chương trình có thể được sửa đổi trực tiếp bởi một tài khoản được chỉ định là "quyền nâng cấp", thường là tài khoản đã triển khai chương trình ban đầu. Nếu quyền nâng cấp bị thu hồi và đặt thành None, chương trình trở nên bất biến và không thể cập nhật nữa.

Chương trình có thể xác minh

Các bản build có thể xác minh cho phép bất kỳ ai kiểm tra xem mã trên chuỗi của chương trình có khớp với mã nguồn công khai của nó hay không, giúp phát hiện sự khác biệt giữa phiên bản nguồn và phiên bản đã triển khai.

Cộng đồng nhà phát triển Solana đã giới thiệu các công cụ hỗ trợ bản build có thể xác minh, cho phép cả nhà phát triển và người dùng xác minh rằng các chương trình trên chuỗi phản ánh chính xác mã nguồn được chia sẻ công khai.

  • Tìm kiếm chương trình đã xác minh: Để nhanh chóng kiểm tra các chương trình đã xác minh, người dùng có thể tìm kiếm địa chỉ chương trình trên Solana Explorer. Xem ví dụ về chương trình đã xác minh tại đây.

  • Công cụ xác minh: Solana Verifiable Build CLI của Ellipsis Labs cho phép người dùng độc lập xác minh các chương trình trên chuỗi đối chiếu với mã nguồn đã công bố.

  • Hỗ trợ bản build có thể xác minh trong Anchor: Anchor cung cấp hỗ trợ tích hợp cho các bản build có thể xác minh. Chi tiết có thể được tìm thấy trong tài liệu Anchor.

Berkeley Packet Filter (BPF)

Solana sử dụng LLVM (Low Level Virtual Machine) để biên dịch chương trình thành các tệp ELF (Executable and Linkable Format). Các tệp này chứa phiên bản tùy chỉnh của Solana về bytecode eBPF, được gọi là "Solana Bytecode Format" (sBPF). Tệp ELF chứa mã nhị phân của chương trình và được lưu trữ trên chuỗi trong một tài khoản thực thi khi chương trình được triển khai.

Chương trình tích hợp sẵn

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, đó là trình tải của nó. Hiện tại, có năm chương trình tải:

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 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 chương trình vẫn thực thiHướng dẫn
v3BPFLoaderUpgradeab1e11111111111111111111111Đang dần bị loại bỏHướng dẫn
v4LoaderV411111111111111111111111111111111111v4 dự kiến sẽ trở thành trình tải tiêu chuẩnHướng dẫn

Các bộ tải này cần thiết để tạo và quản lý các chương trình tùy chỉnh:

  • Triển khai một chương trình hoặc bộ đệm mới
  • Đóng một chương trình hoặc bộ đệm
  • Triển khai lại / nâng cấp một chương trình hiện có
  • Chuyển quyền kiểm soát một chương trình
  • Hoàn tất một chương trình

Loader-v3 và loader-v4 hỗ trợ sửa đổi các chương trình sau khi triển khai ban đầu. Quyền thực hiện điều này được quản lý bởi thẩm quyền của chương trình vì quyền sở hữu tài khoản của mỗi chương trình thuộc về bộ tải.

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

Chương trình 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. Byte đầu tiên u8 là số lượng chữ ký cần kiểm tra, tiếp theo là một byte đệm. Sau đó, cấu trúc sau đượ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
}

Mã giả của quá trình xác minh chữ ký:

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
}

Chương trình 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 mà byte đầu tiên là số lượng của cấu trúc sau được tuần tự hóa trong 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
}

Mã giả của quá trình xác minh khôi phục:

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 dựa trên 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

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 vào chữ ký, khóa công khai và thông điệp. Trả về lỗi nếu có bất kỳ thất bại nào.Hướng dẫn

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

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
}

Mã giả của quá trình xác minh chữ ký:

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
}

Lưu ý: Giá trị S thấp được áp dụng cho tất cả các chữ ký để tránh khả năng biến đổi chữ ký không mong muốn.

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

Genesis của cụm Solana bao gồm danh sách các chương trình đặc biệt cung cấp các chức năng cốt lõi cho mạng lưới. Trước đây, chúng được gọi là các chương trình "native" và được phân phối cùng với mã validator.

Chương trìnhID Chương trìnhMô tảHướng dẫn
System Program11111111111111111111111111111111Tạ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ịch.SystemInstruction
Vote ProgramVote111111111111111111111111111111111111111Tạ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ưởng.VoteInstruction
Stake ProgramStake11111111111111111111111111111111111111Tạ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 validator.StakeInstruction
Config ProgramConfig1111111111111111111111111111111111111Thê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ác với các chương trình khác, Config program không định nghĩa bất kỳ instruction riêng lẻ nào. Nó chỉ có một instruction ngầm định: "store". Dữ liệu instruction 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 để lưu trữ trong đó.ConfigInstruction
Compute Budget ProgramComputeBudget111111111111111111111111111111Thiết lập giới hạn và giá đơn vị tính toán 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ên.ComputeBudgetInstruction
Address Lookup Table ProgramAddressLookupTab1e1111111111111111111111111Quả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 số lượng có thể đưa vào danh sách tài khoản của giao dịch.ProgramInstruction
ZK ElGamal Proof ProgramZkE1Gama1Proof11111111111111111111111111111Cung cấp xác minh bằng chứng zero-knowledge cho dữ liệu được mã hóa ElGamal.

Is this page helpful?