Program

Di Solana, "smart contract" disebut program. Program di-deploy ke blockchain pada akun yang berisi binary executable program yang telah dikompilasi. Pengguna berinteraksi dengan program dengan mengirim transaksi yang berisi instruksi yang memberi tahu program apa yang harus dilakukan.

Poin Penting

  • Program adalah akun yang berisi kode executable, yang diorganisir ke dalam fungsi yang disebut instruksi.
  • Meskipun program bersifat stateless, mereka dapat menyertakan instruksi yang membuat dan memperbarui akun lain untuk menyimpan data.
  • Upgrade authority dapat memperbarui program. Setelah otoritas ini dihapus, program menjadi tidak dapat diubah.
  • Pengguna dapat memverifikasi data akun program on-chain cocok dengan kode sumbernya yang dipublikasikan melalui build yang dapat diverifikasi.

Program Solana sebagian besar ditulis dalam bahasa pemrograman Rust, dengan dua pendekatan umum untuk pengembangan:

  • Anchor: Framework yang dirancang untuk pengembangan program Solana. Framework ini menyediakan cara yang lebih cepat dan sederhana untuk menulis program, menggunakan macro Rust untuk mengurangi kode boilerplate. Untuk pemula, disarankan untuk memulai dengan framework Anchor.

  • Native Rust: Pendekatan ini melibatkan penulisan program Solana dalam Rust tanpa memanfaatkan framework apapun. Pendekatan ini menawarkan fleksibilitas lebih tetapi dengan kompleksitas yang lebih tinggi.

Memperbarui Program Solana

Untuk mempelajari lebih lanjut tentang men-deploy dan meng-upgrade program, lihat halaman deploying programs.

Program dapat dimodifikasi secara langsung oleh akun yang ditunjuk sebagai "upgrade authority", yang biasanya adalah akun yang awalnya men-deploy program tersebut. Jika upgrade authority dicabut dan diatur ke null, program menjadi tidak dapat diubah dan tidak dapat lagi diperbarui.

Program yang Dapat Diverifikasi

Build yang dapat diverifikasi memungkinkan siapa pun untuk memeriksa apakah kode on-chain suatu program cocok dengan kode sumbernya yang dipublikasikan, sehingga memungkinkan untuk mendeteksi perbedaan antara versi sumber dan versi yang di-deploy.

Komunitas pengembang Solana telah memperkenalkan alat-alat untuk mendukung build yang dapat diverifikasi, memungkinkan baik pengembang maupun pengguna untuk memverifikasi bahwa program on-chain secara akurat mencerminkan kode sumber mereka yang dibagikan secara publik.

  • Mencari Program Terverifikasi: Untuk memeriksa program terverifikasi dengan cepat, pengguna dapat mencari alamat program di Solana Explorer. Lihat contoh program terverifikasi di sini.

  • Alat Verifikasi: Solana Verifiable Build CLI oleh Ellipsis Labs memungkinkan pengguna untuk secara independen memverifikasi program on-chain terhadap kode sumber yang dipublikasikan.

  • Dukungan untuk Build yang Dapat Diverifikasi di Anchor: Anchor menyediakan dukungan bawaan untuk build yang dapat diverifikasi. Detail dapat ditemukan di dokumentasi Anchor.

Berkeley Packet Filter (BPF)

Solana menggunakan LLVM (Low Level Virtual Machine) untuk mengompilasi program menjadi file ELF (Executable and Linkable Format). File-file ini berisi versi kustom Solana dari bytecode eBPF, yang disebut "Solana Bytecode Format" (sBPF). File ELF berisi binary program dan disimpan on-chain dalam akun yang dapat dieksekusi ketika program di-deploy.

Program Bawaan

Program Loader

Setiap program itu sendiri dimiliki oleh program lain, yang merupakan loader-nya. Saat ini, ada lima program loader:

LoaderProgram IDCatatanTautan Instruksi
nativeNativeLoader1111111111111111111111111111111Memiliki empat loader lainnya
v1BPFLoader1111111111111111111111111111111111Instruksi manajemen dinonaktifkan, tetapi program tetap berjalan
v2BPFLoader2111111111111111111111111111111111Instruksi manajemen dinonaktifkan, tetapi program tetap berjalanInstruksi
v3BPFLoaderUpgradeab1e11111111111111111111111Sedang dihapuskan secara bertahapInstruksi
v4LoaderV411111111111111111111111111111111111v4 diharapkan menjadi loader standarInstruksi

Loader ini diperlukan untuk membuat dan mengelola program kustom:

  • Deploy program atau buffer baru
  • Menutup program atau buffer
  • Redeploy / upgrade program yang sudah ada
  • Mentransfer otoritas atas program
  • Menyelesaikan program

Loader-v3 dan loader-v4 mendukung modifikasi pada program setelah deployment awal. Izin untuk melakukannya diatur oleh otoritas program karena kepemilikan akun setiap program berada pada loader.

Program Terkompilasi

Program Ed25519

ProgramProgram IDDeskripsiInstruksi
Program Ed25519Ed25519SigVerify111111111111111111111111111Memverifikasi tanda tangan ed25519. Jika ada tanda tangan gagal, error akan dikembalikan.Instruksi

Program ed25519 memproses sebuah instruksi. Byte pertama u8 adalah hitungan jumlah tanda tangan yang akan diperiksa, diikuti oleh satu byte padding. Setelah itu, struct berikut diserialisasi, satu untuk setiap tanda tangan yang akan diperiksa.

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
}

Kode pseudo dari verifikasi tanda tangan:

for i in 0..signatures_count {
let Ed25519SignatureOffsets {
signature_offset,
signature_instruction_index,
public_key_offset,
public_key_instruction_index,
message_data_offset,
message_data_size,
message_instruction_index,
} = ...; // Deserialize from instruction
// Signature, pubkey and message data can be loaded from any instruction in the transaction
let signature = instruction_at(signature_instruction_index).data(signature_offset..signature_offset + 64);
let pubkey = instruction_at(public_key_instruction_index).data(public_key_offset..public_key_offset + 32);
let message = instruction_at(message_instruction_index).data(message_data_offset..message_data_offset + message_data_size);
if !ed25519::verify(pubkey, message, signature) {
return Error;
}
}

Program Secp256k1

ProgramProgram IDDeskripsiInstruksi
Program Secp256k1KeccakSecp256k11111111111111111111111111111Memverifikasi operasi pemulihan kunci publik secp256k1 (ecrecover).Instruksi

Program secp256k1 memproses instruksi yang mengambil byte pertama sebagai hitungan struct berikut yang diserialisasi dalam data instruksi:

struct Secp256k1SignatureOffsets {
signature_offset: u16, // offset to secp256k1 signature
signature_instruction_index: u16, // instruction index to find signature
eth_address_offset: u16, // offset to eth_address
eth_address_instruction_index: u16, // instruction index to find eth_address
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
}

Kode pseudo dari verifikasi pemulihan:

for i in 0..count {
let Secp256k1SignatureOffsets {
signature_offset,
signature_instruction_index,
eth_address_offset,
eth_address_instruction_index,
message_data_offset,
message_data_size,
message_instruction_index,
} = ...; // Deserialize from instruction
// Signature, eth_address and message data can be loaded from any instruction in the transaction
let signature = instruction_at(signature_instruction_index).data(signature_offset..signature_offset + 64);
let eth_address = instruction_at(eth_address_instruction_index).data(eth_address_offset..eth_address_offset + 20);
let message = instruction_at(message_instruction_index).data(message_data_offset..message_data_offset + message_data_size);
// construct the message that was signed
let mut signing_message = format!("\x19Ethereum Signed Message:\n{}", message.len());
signing_message.extend(message);
let message_hash = keccak256(&signing_message);
// recover the public key
let recovered_key = secp256k1_recover(signature, message_hash);
let eth_address_recovered = keccak256(recovered_key);
// check that the recovered key matches the given eth_address
if eth_address != eth_address_recovered {
return Error;
}
}

Ini memungkinkan pengguna untuk menentukan data instruksi 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

ProgramID ProgramDeskripsiInstruksi
Program Secp256r1Secp256r1SigVerify1111111111111111111111111Memverifikasi hingga 8 tanda tangan secp256r1. Mengambil tanda tangan, kunci publik, dan pesan. Mengembalikan error jika ada yang gagal.Instruksi

Program secp256r1 memproses instruksi. u8 pertama adalah jumlah tanda tangan yang akan diperiksa, diikuti oleh satu byte padding. Setelah itu, struktur berikut diserialisasi, satu untuk setiap tanda tangan yang akan diperiksa:

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
}

Kode semu dari verifikasi tanda tangan:

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
}

Catatan: Nilai S rendah diberlakukan untuk semua tanda tangan untuk menghindari kemungkinan malleability tanda tangan.

Program Inti

Genesis cluster Solana mencakup daftar program khusus yang menyediakan fungsionalitas inti untuk jaringan. Secara historis, program-program ini disebut sebagai program "native" dan dulunya didistribusikan bersama dengan kode validator.

ProgramID ProgramDeskripsiInstruksi
System Program11111111111111111111111111111111Membuat akun baru, mengalokasikan data akun, menetapkan akun ke program pemilik, mentransfer lamport dari akun yang dimiliki System Program, dan membayar biaya transaksi.SystemInstruction
Vote ProgramVote111111111111111111111111111111111111111Membuat dan mengelola akun yang melacak status voting validator dan rewards.VoteInstruction
Stake ProgramStake11111111111111111111111111111111111111Membuat dan mengelola akun yang mewakili stake dan rewards untuk delegasi ke validator.StakeInstruction
Config ProgramConfig1111111111111111111111111111111111111Menambahkan data konfigurasi ke chain, diikuti oleh daftar kunci publik yang diizinkan untuk memodifikasinya. Tidak seperti program lain, Config program 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 akan disimpan di dalamnya.ConfigInstruction
Compute Budget ProgramComputeBudget111111111111111111111111111111Menetapkan batas dan harga unit komputasi untuk transaksi, memungkinkan pengguna mengontrol sumber daya komputasi dan biaya prioritas.ComputeBudgetInstruction
Address Lookup Table ProgramAddressLookupTab1e1111111111111111111111111Mengelola tabel pencarian alamat, yang memungkinkan transaksi mereferensikan lebih banyak akun daripada yang biasanya muat dalam daftar akun transaksi.ProgramInstruction
ZK ElGamal Proof ProgramZkE1Gama1Proof11111111111111111111111111111Menyediakan verifikasi bukti zero-knowledge untuk data terenkripsi ElGamal.

Is this page helpful?

Daftar Isi

Edit Halaman