BARU: Helius mengakuisisi Light Protocol
Biaya Prioritas: Memahami Mekanisme Biaya Transaksi Solana
Blog/Dasar-Dasar

Biaya Prioritas: Memahami Mekanisme Biaya Transaksi Solana

Developer Experience Engineer0xIchigo di X0xIchigo di LinkedIn0xIchigo di GitHub
Bacaan 10 menit

Apa yang dibahas dalam artikel ini?

Solana itu cepat. Namun, bahkan pada blockchain tercepat yang tersedia, pengguna menginginkan pemrosesan transaksi yang optimal untuk transaksi penting. Biaya prioritas memastikan transaksi pengguna ditempatkan di bagian depan antrean urutan eksekusi. Biaya ini merupakan biaya tambahan opsional yang dapat ditambahkan pengguna ke transaksi mereka.

Artikel ini membahas secara singkat berbagai aspek pemrosesan transaksi di Solana. Pembahasannya mencakup transaksi, siklus hidupnya, dan cara kerja biaya transaksi. Selanjutnya, artikel ini membahas biaya prioritas, cara menerapkannya secara terprogram, dan praktik terbaik.

Transaksi dan Siklus Hidupnya

Transaksi digunakan untuk memanggil program Solana dan menerapkan perubahan status. Transaksi merupakan kumpulan instruksi (yaitu, perintah untuk satu pemanggilan program) yang memberi tahu validator tindakan apa yang harus dilakukan, pada akun mana, dan apakah izin yang diperlukan tersedia.

Secara umum, siklus hidup transaksi di Solana adalah sebagai berikut:

  • Pengguna memiliki tujuan yang jelas untuk tindakan yang ingin dilakukan. Misalnya, Alice ingin mengirim 10 SOL kepada Bob
  • Pengguna membuat transaksi untuk tindakan yang diinginkan. Misalnya, Alice membuat transaksi dengan instruksi untuk mentransfer 10 SOL dari akunnya ke akun Bob. Alice juga menyertakan blockhash terbaru dan menandatangani transaksi menggunakan kunci privatnya
  • Pengguna mengirim transaksi ke jaringan. Kemudian, mereka menerima informasi apakah transaksi tersebut berhasil ditambahkan. Misalnya, Alice mengirim transaksi dengan status komitmen dikonfirmasi. Setelah transaksi dikonfirmasi, ia menerima tanda tangan transaksi. Alice dapat menggunakan tanda tangan transaksi ini di penjelajah blok, seperti Orb, untuk melihat bahwa ia berhasil mengirim 10 SOL kepada Bob. Saldo akunnya berkurang 10 SOL, sedangkan saldo akun Bob bertambah 10 SOL

Saat mengirim transaksi yang telah ditandatangani ke jaringan, pengguna memakai penyedia RPC seperti Helius. RPC Helius menerima transaksi tersebut dan memeriksa jadwal leader saat ini. Di Solana, hanya validator tertentu yang bertanggung jawab menambahkan entri ke ledger pada waktu tertentu. Leader bertanggung jawab memproduksi blok untuk slot saat ini dan ditugaskan untuk empat slot berturut-turut. Transaksi yang telah ditandatangani dikirim kepada leader saat ini dan dua leader berikutnya.

Leader saat ini memvalidasi transaksi yang telah ditandatangani dan menjalankan langkah prapemrosesan lainnya sebelum menjadwalkan transaksi untuk dieksekusi. Tidak seperti L1 lain semisal Ethereum, Solana tidak memiliki antrean transaksi global. Sebagian besar validator menggunakan implementasi scheduler yang disediakan oleh Solana Labs. Namun, validator yang menjalankan klien validator Jito menggunakan pseudo-mempool (yaitu, MempoolStream) untuk mengurutkan transaksi. Scheduler default bersifat multi-thread, dengan setiap thread mengelola antrean transaksi yang menunggu untuk dieksekusi. Transaksi diurutkan ke dalam blok dengan menggabungkan metode first-in-first-out (FIFO) dan biaya prioritas. Perlu diperhatikan bahwa pengurutan ini pada dasarnya bersifat nondeterministik karena transaksi ditetapkan ke thread eksekusi secara agak acak.

Saat transaksi dieksekusi, transaksi tersebut disebarkan melalui Turbine, dan biayanya dibayarkan sebagaimana mestinya.

Cara Kerja Biaya Transaksi di Solana

Biaya transaksi adalah biaya kecil yang dibayarkan untuk memproses transaksi di Solana. Leader saat ini memproses transaksi yang dikirim melalui jaringan untuk menghasilkan entri ledger. Ketika transaksi dikonfirmasi sebagai bagian dari status, biaya dibayarkan untuk mendukung desain ekonomi Solana. Biaya transaksi memberikan manfaat mendasar bagi Solana. Biaya tersebut:

  • Memberikan kompensasi kepada validator
  • Mengurangi penggunaan ruang jaringan dengan memberlakukan biaya real-time untuk transaksi
  • Memberikan stabilitas ekonomi jangka panjang bagi jaringan melalui biaya minimum yang diterima protokol

Dalam jangka pendek, Solana mengandalkan imbalan berbasis protokol yang bersifat inflasioner untuk mengamankan jaringan. Untuk mewujudkannya, jaringan memiliki tingkat inflasi global terjadwal guna memberi imbalan kepada validator. Dalam jangka panjang, Solana mengandalkan biaya transaksi untuk mempertahankan keamanan. Bagian tetap (awalnya ditetapkan sebesar 50%) dari setiap biaya transaksi dibakar, sedangkan sisanya dikirim kepada leader saat ini. Solana membakar biaya untuk memperkuat nilai SOL sekaligus mencegah validator jahat menyensor transaksi.

Biaya transaksi dihitung berdasarkan biaya dasar per tanda tangan yang ditetapkan secara statis serta sumber daya komputasi yang digunakan selama transaksi, yang diukur dalam Compute Units (CU). Biaya dasar ini dapat berkisar antara 50% hingga 1000% dari target lamport per tanda tangan. Target default per tanda tangan saat ini ditetapkan sebesar 10.000. Setiap transaksi mendapat alokasi anggaran CU maksimum yang disebut Compute Budget. Jika anggaran ini terlampaui, runtime akan menghentikan transaksi dan menampilkan error. Anggaran maksimum per transaksi adalah 1,4 juta CU, sedangkan batas ruang blok adalah 48 juta CU.

Apa itu biaya prioritas?

Karena keterbatasan tersebut, transaksi dengan beban komputasi tinggi dapat memenuhi ruang blok dan menunda transaksi lain. Solana memperkenalkan biaya opsional agar sebuah transaksi dapat memprioritaskan dirinya dibandingkan transaksi lain dalam antrean leader. Biaya ini disebut biaya prioritas. Membayar biaya ini secara efektif meningkatkan prioritas transaksi Anda sehingga eksekusinya lebih cepat. Hal ini berguna untuk transaksi yang sensitif terhadap waktu atau bernilai tinggi. Prioritas biaya sebuah transaksi ditentukan oleh jumlah compute unit yang diminta. Semakin banyak compute unit yang diminta transaksi, semakin tinggi biaya yang harus dibayarkan untuk mempertahankan prioritasnya dalam antrean transaksi. Pengenaan biaya yang lebih tinggi untuk lebih banyak compute unit mencegah spam transaksi dengan beban komputasi tinggi.

Biaya prioritas merupakan hasil perkalian compute budget transaksi dengan harga compute unit-nya yang diukur dalam micro-lamport: priorityFees = computeBudget * computeUnitPrice

Compute Budget

computeBudget menentukan jumlah maksimum compute unit yang dapat digunakan sebuah transaksi, biaya yang terkait dengan berbagai operasi yang mungkin dilakukan transaksi, dan batas operasional yang harus dipatuhi transaksi. Operasi berikut menimbulkan biaya komputasi:

  • Menjalankan instruksi SBF
  • Meneruskan data antarprogram
  • Memanggil system call (misalnya, logging, membuat alamat program, CPI)

Untuk Pemanggilan Lintas Program (CPI), program yang dipanggil beroperasi dalam anggaran komputasi program pemanggil (yaitu, program induk). Jika program yang dipanggil menghabiskan seluruh sisa anggaran komputasi atau melampaui batas yang ditetapkan, seluruh rangkaian pemanggilan program akan gagal. Hal ini mencakup eksekusi transaksi awal yang memulai proses tersebut.

Compute budget saat ini dapat ditemukan di sini.

Cara Menerapkan Biaya Prioritas Secara Terprogram

Biaya prioritas transaksi ditetapkan dengan menetapkan sebuah instruksi SetComputeUnitPricehttps://github.com/solana-labs/solana/blob/2971e84ec87815adb1e4def95cbcd8d0d96845f5/sdk/src/compute_budget.rs#L59dan instruksi SetComputeUnitLimit yang bersifat opsional. Jika instruksi SetComputeUnitPrice tidak disediakan, transaksi akan menggunakan prioritas terendah secara default karena tidak ada biaya tambahan. Jika instruksi SetComputeUnitLimit tidak disediakan, batasnya dihitung dari hasil perkalian jumlah instruksi dalam transaksi dengan batas compute unit default. Runtime menggunakan harga compute unit dan batas compute unit untuk menghitung biaya prioritas yang digunakan untuk memprioritaskan transaksi tersebut.

Kita harus menambahkan instruksi ini ke transaksi yang diinginkan untuk menambahkan biaya prioritas secara terprogram. Dalam Javascript, bentuknya seperti berikut:

Kode
import {
  Keypair,
  Connection,
  PublicKey,
  Transaction,
  SystemProgram,
  LAMPORTS_PER_SOL,
  sendAndConfirmTransaction,
  ComputeBudgetProgram,
} from "@solana/web3.js";

async function main() {
  // Initialize an RPC client
  const clusterUrl = "http://127.0.0.1:8899";
  const connection = new Connection(clusterUrl, "confirmed");

  // Initialize new sender and receiver keypairs
  const fromKeypair = Keypair.generate();
  const toPubkey = new PublicKey(Keypair.generate().publicKey);

  // Airdrop SOL to the from_keypair
  const airdropAmount = 100 * LAMPORTS_PER_SOL;
  try {
    const signature = await connection.requestAirdrop(
      fromKeypair.publicKey,
      airdropAmount
    );
    console.log("Airdrop requested. Signature:", signature);
    await connection.confirmTransaction({
      signature,
      confirmation: "confirmed",
    });
  } catch (e) {
    console.error("Failed to request airdrop:", e);
    return;
  }

  // Check if airdrop was successful
  const balance = await connection.getBalance(fromKeypair.publicKey);
  if (balance < airdropAmount) {
    console.error(
      "Airdrop was not successful. The current balance is insufficient"
    );
    return;
  }

  // Airdrop SOL to the toPubkey
  const airdropAmountTo = 100 * LAMPORTS_PER_SOL; // 1 SOL in lamports
  try {
    const signature = await connection.requestAirdrop(toPubkey, airdropAmount);
    console.log("Airdrop requested. Signature:", signature);
    await connection.confirmTransaction({
      signature,
      confirmation: "confirmed",
    });
  } catch (e) {
    console.error("Failed to request airdrop:", e);
    return;
  }

  // Check if airdrop was successful
  const balanceTo = await connection.getBalance(toPubkey);
  if (balance < airdropAmount) {
    console.error(
      "Airdrop was not successful. The current balance is insufficient"
    );
    return;
  }

  console.log(`Account balance: ${balance / LAMPORTS_PER_SOL} SOL`);

  // Create the priority fee instructions
  const computePriceIx = ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: 1,
  });

  const computeLimitIx = ComputeBudgetProgram.setComputeUnitLimit({
    units: 200_000,
  });

  // Create the transfer instruction
  const transferIx = SystemProgram.transfer({
    fromPubkey: fromKeypair.publicKey,
    toPubkey,
    lamports: 100_000,
  });

  // Create the transaction with priority fees
  const transaction = new Transaction().add(
    computePriceIx,
    computeLimitIx,
    transferIx
  );

  // Fetch the recent blockhash and sign the transaction
  transaction.recentBlockhash = (
    await connection.getLatestBlockhash()
  ).blockhash;
  transaction.sign(fromKeypair);

  // Send the transaction
  try {
    const txid = await sendAndConfirmTransaction(connection, transaction, [
      fromKeypair,
    ]);
    console.log("Transaction sent successfully with signature", txid);
  } catch (e) {
    console.error("Failed to send transaction:", e);
  }
}

main();

Dalam cuplikan ini, kita:

  • Menyiapkan lingkungan pengujian menggunakan Localhost
  • Membuat dua wallet baru (yaitu, fromKeypair dan toPubkey)
  • Melakukan airdrop 100 SOL ke kedua wallet
  • Memastikan airdrop berhasil
  • Membuat instruksi biaya prioritas (yaitu, computePriceIx dan computeLimitIx)
  • Membuat instruksi transfer yang mengirim 100.000 lamport dari fromKeypair ke toPubkey
  • Membuat transaksi baru dan menambahkan semua instruksi ke dalamnya
  • Menyertakan blockhash terbaru ke transaksi dan menandatanganinya
  • Mengirim transaksi dan mengonfirmasi bahwa transaksi berhasil dikirim

Selesai—biaya prioritas hanyalah instruksi yang ditambahkan ke transaksi untuk membayar waktu eksekusi yang lebih cepat. Sebagian besar cuplikan ini mengonfigurasi lingkungan pengembangan dan dua wallet untuk mentransfer SOL di antara keduanya. Bagian yang kita perlukan adalah membuat instruksi untuk menambahkan biaya prioritas dan menyertakannya ke transaksi:

Kode
// Other code

const computePriceIx = ComputeBudgetProgram.setComputeUnitPrice({
	microLamports: 1,
});

const computeLimitIx = ComputeBudgetProgram.setComputeUnitLimit({
	units: 200_000,
});

// Other code

const transaction = new Transaction().add(computePriceIx, computeLimitIx, transferIx);

// Rest of the code

Praktik Terbaik

Urutan instruksi ini penting karena instruksi dijalankan secara berurutan. Misalnya, jika Anda memiliki transaksi yang melampaui batas komputasi default (yaitu, 200 ribu CU) sebelum memperluas batas komputasi, transaksi tersebut akan gagal. Misalkan kita memiliki transaksi berikut:

  • Instruksi 1 menggunakan 100 ribu
  • Instruksi 2 menggunakan 150 ribu
  • Instruksi 3 memperluas batas komputasi

Transaksi ini akan gagal kecuali instruksi 2 dan 3 ditukar. Karena itu, sebaiknya tambahkan instruksi batas komputasi sebelum menambahkan instruksi lain ke transaksi Anda. Ingat, Anda tidak perlu menggunakan instruksi SetComputeLimit jika ingin menambahkan biaya prioritas ke transaksi—instruksi tersebut sepenuhnya opsional. Penempatan instruksi SetComputePrice tidak berpengaruh.

Sebaiknya gunakan metode RPC getRecentPrioritizationFees untuk mendapatkan daftar biaya prioritas yang baru saja dibayarkan. Data ini dapat digunakan untuk memperkirakan biaya prioritas yang sesuai bagi transaksi, memastikan transaksi diproses oleh cluster, dan meminimalkan biaya yang dibayarkan. Sebagai alternatif, Helius menawarkan Priority Fee API baru, yang akan kita bahas di bagian berikutnya.

Transaksi juga sebaiknya hanya meminta jumlah minimum compute unit yang diperlukan untuk eksekusi guna meminimalkan biaya ini. Perhatikan bahwa biaya tidak disesuaikan ketika jumlah compute unit yang diminta melebihi total unit yang digunakan oleh transaksi.

Beberapa penyedia wallet, seperti Phantom, menyadari bahwa dApp dapat menetapkan biaya transaksi prioritas. Namun, mereka tidak menyarankan praktik tersebut karena sering kali menimbulkan kerumitan yang tidak perlu bagi pengguna akhir. Sebaliknya, mereka menganjurkan developer dApp untuk membiarkan Phantom menerapkan biaya prioritas atas nama pengguna. Misalnya, Solfare mengatasi masalah ini dengan mendeteksi secara otomatis apakah Solana sedang mengalami beban tinggi, lalu sedikit menaikkan biaya untuk memprioritaskan transaksi Anda dibandingkan transaksi lain.

Helius Priority Fee API

Menghitung biaya prioritas menggunakan metode RPC getRecentPrioritizationFees secara intuitif masuk akal untuk menghitung biaya berdasarkan slot. Namun, hal ini dapat sulit dilakukan karena kondisi jaringan yang terus berubah dan karakteristik respons getRecentPrioritizationFees' (yaitu, menampilkan daftar nilai untuk 150 blok terakhir, yang hanya berguna untuk memperkirakan nilai minimum biaya yang perlu ditetapkan).

Helius Priority Fee API memperkenalkan metode baru, getPriorityFeeEstimate, yang menyederhanakan respons menjadi satu nilai dengan mempertimbangkan pasar biaya global dan lokal. Metode ini menggunakan serangkaian persentil yang telah ditentukan untuk menghasilkan estimasi. Persentil atau level ini berkisar dari NONE (persentil ke-0) hingga UNSAFE_MAX (persentil ke-100 dan diberi label tidak aman untuk mencegah pengguna menghabiskan dana secara tidak sengaja). Pengguna juga dapat memilih untuk menerima semua level prioritas dan menyesuaikan rentang yang digunakan dalam perhitungan ini melalui lookbackSlots. Dengan demikian, serupa dengan getRecentPrioritizationFees, pengguna dapat melihat sejumlah slot sebelumnya dalam perhitungan estimasi.

Sebagai contoh, kita dapat menghitung semua level biaya prioritas untuk program Jupiter v6 dengan skrip berikut:

Kode
const url = `https://mainnet.helius-rpc.com/?api-key=`;

const getRecentPrioritizationFees = async () => {
  const response = await fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "getPriorityFeeEstimate",
      params: [{
        "accountKeys": ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"],
        "options": {
            "includeAllPriorityFeeLevels": true,
        }
      }]
    }),
  });
  const data = await response.json();
  console.log("Fee: ", data);
};

getRecentPrioritizationFees();

Endpoint ini sedang dikembangkan secara aktif. Untuk informasi selengkapnya, kunjungi dokumentasi Helius.

Kesimpulan

Menelusuri dunia transaksi Solana mengungkap sistem canggih yang menyeimbangkan efisiensi jaringan dengan insentif ekonomi. Memahami cara kerja transaksi, termasuk biaya transaksi dan biaya prioritasnya, memungkinkan developer dan pengguna mengambil keputusan yang lebih tepat untuk mengoptimalkan interaksi mereka di Solana. Kemampuan menerapkan biaya prioritas secara terprogram membuka peluang baru bagi transaksi bernilai tinggi dan sensitif terhadap waktu. Hal ini memberikan fleksibilitas dan efisiensi yang lebih besar dalam operasional di Solana.

Jika Anda sudah membaca sejauh ini, terima kasih, anon! Pastikan untuk memasukkan alamat email Anda di bawah agar tidak pernah melewatkan informasi terbaru tentang perkembangan di Solana. Siap mempelajari lebih lanjut? Bergabunglah dengan Discord kami untuk mulai membangun masa depan di blockchain dengan performa tertinggi hari ini.

Sumber Daya Tambahan / Bacaan Lanjutan

Berlangganan Helius

Ikuti perkembangan terbaru dalam pengembangan Solana dan dapatkan pembaruan saat kami memublikasikan postingan

Gambar diperbesar