Program
Di Solana, smart contract disebut sebagai program. Program adalah sebuah akun stateless yang berisi kode yang dapat dieksekusi. Kode ini diorganisir ke dalam fungsi yang disebut instruksi. Pengguna berinteraksi dengan program dengan mengirimkan transaksi yang berisi satu atau lebih instruksi. Sebuah transaksi dapat mencakup instruksi dari beberapa program.
Ketika program di-deploy, Solana menggunakan LLVM untuk mengompilasi program tersebut ke dalam format executable and linkable (ELF). File ELF berisi binary program dalam format Solana Bytecode Format (sBPF) dan disimpan on-chain dalam akun yang dapat dieksekusi.
sBPF adalah versi kustom Solana dari bytecode eBPF.
Menulis program
Mayoritas program ditulis dalam Rust, dengan dua pendekatan pengembangan yang umum:
- Anchor: Anchor adalah framework yang dirancang untuk pengembangan Solana yang cepat dan mudah. Framework ini menggunakan Rust macros untuk mengurangi kode boilerplate—menjadikannya pilihan yang bagus untuk pemula.
- Native Rust: Menulis program dalam Rust tanpa memanfaatkan framework apapun. Pendekatan ini menawarkan fleksibilitas lebih tetapi dengan kompleksitas yang lebih tinggi.
Memperbarui program
Untuk memodifikasi program yang sudah ada, sebuah akun harus ditunjuk sebagai upgrade authority. (Biasanya akun yang sama yang awalnya men-deploy program tersebut.) Jika upgrade authority dicabut dan diatur ke null, program tersebut tidak dapat lagi diperbarui.
Memverifikasi program
Solana mendukung verifiable builds, yang memungkinkan pengguna untuk memeriksa apakah kode on-chain program cocok dengan kode sumber publiknya. Framework Anchor menyediakan dukungan bawaan untuk membuat build yang dapat diverifikasi.
Untuk memeriksa apakah program yang ada sudah diverifikasi, cari ID programnya di Solana Explorer. Alternatifnya, Anda dapat menggunakan Ellipsis Labs Solana Verifiable Build CLI, untuk memverifikasi program on-chain secara independen.
Program bawaan
The System Program
The System Program adalah satu-satunya akun yang dapat membuat akun baru. Secara default, semua akun baru dimiliki oleh System Program, meskipun banyak yang ditetapkan pemilik baru saat pembuatan. The System Program melakukan fungsi-fungsi utama berikut:
| Fungsi | Deskripsi |
|---|---|
| Pembuatan Akun Baru | Hanya System Program yang dapat membuat akun baru. |
| Alokasi Ruang | Menetapkan kapasitas byte untuk bidang data setiap akun. |
| Menetapkan Kepemilikan Program | Setelah System Program membuat akun, ia dapat menetapkan kembali pemilik program yang ditunjuk ke program account yang berbeda. Begitulah cara program kustom mengambil kepemilikan akun baru yang dibuat oleh System Program. |
| Transfer SOL | Mentransfer lamports (SOL) dari System Accounts ke akun lain. |
Alamat system program adalah 11111111111111111111111111111111.
Program loader
Setiap program dimiliki oleh program lain—yaitu loader-nya. Loader digunakan untuk men-deploy, men-deploy ulang, mengupgrade atau menutup program. Loader juga digunakan untuk menyelesaikan program dan mentransfer otoritas program.
Saat ini ada lima program loader, seperti yang ditunjukkan dalam tabel di bawah ini.
| Loader | Program ID | Catatan | Tautan Instruksi |
|---|---|---|---|
| native | NativeLoader1111111111111111111111111111111 | Memiliki empat loader lainnya | — |
| v1 | BPFLoader1111111111111111111111111111111111 | Instruksi manajemen dinonaktifkan, tetapi program masih berjalan | — |
| v2 | BPFLoader2111111111111111111111111111111111 | Instruksi manajemen dinonaktifkan, tetapi program masih berjalan | Instruksi |
| v3 | BPFLoaderUpgradeab1e11111111111111111111111 | Program dapat diperbarui setelah deployment. Program yang dapat dieksekusi disimpan di akun data program terpisah | Instruksi |
| v4 | LoaderV411111111111111111111111111111111111 | Dalam pengembangan (belum dirilis) | Instruksi |
Program yang di-deploy dengan loader-v3 atau loader-v4 dapat dimodifikasi setelah deployment, sebagaimana ditentukan oleh otoritas upgrade-nya.
Ketika program baru di-deploy, versi loader terbaru akan digunakan secara default.
Program terprakompilasi
Selain program loader, Solana menyediakan program terprakompilasi berikut.
Verifikasi tanda tangan ed25519
Program ed25519 digunakan untuk memverifikasi satu atau lebih tanda tangan ed25519.
| Program | Program ID | Deskripsi | Instruksi |
|---|---|---|---|
| Program Ed25519 | Ed25519SigVerify111111111111111111111111111 | Memverifikasi tanda tangan ed25519. Jika ada tanda tangan gagal, error akan dikembalikan. | Instruksi |
Program ed25519 memproses sebuah instruksi. Byte pertama dari instruction data berisi jumlah tanda tangan yang akan diperiksa, diikuti oleh satu byte padding. Setelah itu, struktur berikut diserialisasi, satu untuk setiap tanda tangan yang akan diperiksa.
struct Ed25519SignatureOffsets {signature_offset: u16, // offset to ed25519 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to public key of 32 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionsinstruction_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}
Verifikasi pemulihan secp256k1
Program secp256k1 digunakan untuk memverifikasi operasi pemulihan kunci publik secp256k1.
| Program | Program ID | Deskripsi | Instruksi |
|---|---|---|---|
| Program Secp256k1 | KeccakSecp256k11111111111111111111111111111 | Memverifikasi operasi pemulihan kunci publik secp256k1 (ecrecover). | Instruksi |
Program secp256k1 memproses sebuah instruksi. Byte pertama dari instruksi berisi jumlah kunci publik yang akan diperiksa. Setelah itu, struktur berikut dibuat sekali untuk setiap kunci publik, kemudian diserialisasi dan ditambahkan ke instruction data.
struct Secp256k1SignatureOffsets {secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytessecp_signature_instruction_index: u8, // instruction index to find signaturesecp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytessecp_pubkey_instruction_index: u8, // instruction index to find pubkeysecp_message_data_offset: u16, // offset to start of message datasecp_message_data_size: u16, // size of message datasecp_message_instruction_index: u8, // instruction index to find message data}
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionssignature = 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}
Ini memungkinkan pengguna untuk menentukan instruction data apa pun dalam transaksi untuk data tanda tangan dan pesan. Dengan menentukan sysvar instruksi khusus, seseorang juga dapat menerima data dari transaksi itu sendiri.
Biaya transaksi akan menghitung jumlah tanda tangan yang diverifikasi dikalikan dengan pengali biaya verifikasi tanda tangan.
Program secp256r1 digunakan untuk memverifikasi hingga 8 tanda tangan secp256r1.
| Program | Program ID | Deskripsi | Instruksi |
|---|---|---|---|
| Program Secp256r1 | Secp256r1SigVerify1111111111111111111111111 | Memverifikasi hingga 8 tanda tangan secp256r1. Mengambil tanda tangan, kunci publik, dan pesan. Mengembalikan error jika ada yang gagal. | Instruksi |
Program secp256r1 memproses sebuah instruksi. u8 pertama dari instruksi adalah
jumlah tanda tangan yang akan diperiksa, diikuti oleh satu byte padding. Setelah
itu, struktur berikut dibuat untuk setiap tanda tangan, kemudian diserialisasi
dan ditambahkan ke instruction data.
struct Secp256r1SignatureOffsets {signature_offset: u16, // offset to compact secp256r1 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to compressed public key of 33 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
Nilai S rendah diberlakukan untuk semua tanda tangan untuk menghindari kemungkinan kerentanan tanda tangan.
process_instruction() {if data.len() < SIGNATURE_OFFSETS_START {return Error}num_signatures = data[0] as usizeif num_signatures == 0 || num_signatures > 8 {return Error}expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_STARTif 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}
Program inti
Program dalam daftar di bawah ini menyediakan fungsionalitas inti jaringan.
| Program | Program ID | Deskripsi | Instruksi |
|---|---|---|---|
| System | 11111111111111111111111111111111 | Membuat akun baru, mengalokasikan data akun, menetapkan akun ke program pemilik, mentransfer lamport dari akun yang dimiliki Program System, dan membayar biaya transaksi | SystemInstruction |
| Vote | Vote111111111111111111111111111111111111111 | Membuat dan mengelola akun yang melacak status voting validator dan rewards | VoteInstruction |
| Stake | Stake11111111111111111111111111111111111111 | Membuat dan mengelola akun yang mewakili stake dan rewards untuk delegasi ke validator | StakeInstruction |
| Config | Config1111111111111111111111111111111111111 | Menambahkan data konfigurasi ke chain, diikuti oleh daftar kunci publik yang diizinkan untuk memodifikasinya. Tidak seperti program lain, program Config tidak mendefinisikan instruksi individual. Program ini hanya memiliki satu instruksi implisit: "store". Data instruksinya adalah sekumpulan kunci yang mengatur akses ke akun dan data yang disimpan di dalamnya | ConfigInstruction |
| Compute Budget | ComputeBudget111111111111111111111111111111 | Menetapkan batas dan harga unit komputasi untuk transaksi, memungkinkan pengguna mengontrol sumber daya komputasi dan biaya prioritas | ComputeBudgetInstruction |
| Address Lookup Table | AddressLookupTab1e1111111111111111111111111 | Mengelola tabel pencarian alamat, yang memungkinkan transaksi mereferensikan lebih banyak akun daripada yang biasanya muat dalam daftar akun transaksi | ProgramInstruction |
| ZK ElGamal Proof | ZkE1Gama1Proof11111111111111111111111111111 | Menyediakan verifikasi bukti zero-knowledge untuk data terenkripsi ElGamal | — |
Is this page helpful?