Memulai

Suite pengujian Solana yang menjalankan solana-test-validator membutuhkan waktu beberapa detik per pengujian - Anda menunggu proses startup, koneksi RPC, dan round-trip jaringan. LiteSVM menjalankan pengujian yang sama dalam milidetik. Tidak ada proses eksternal, tidak ada jaringan, semuanya dalam memori di dalam test runner Anda.

litesvm-go adalah binding Go resmi. Tipe inti (PublicKey, Hash, Signature) langsung berasal dari gagliardetto/solana-go, sehingga nilai mengalir secara alami antara litesvm-go dan ekosistem Go Solana lainnya.

Persyaratan: Go 1.24+. Tidak perlu Rust toolchain - arsip statis bawaan sudah disertakan dalam modul dan dipilih secara otomatis oleh GOOS / GOARCH. Platform yang didukung: macOS (amd64, arm64), Linux (amd64, arm64; glibc atau musl), Windows (amd64).

Handle LiteSVM yang baru menyediakan airdrop, transaksi (legacy + v0), simulasi, baca/tulis akun, sysvar, compute budget, feature gate, time travel, program kustom, dan riwayat transaksi - semuanya didukung oleh inti Rust yang sama yang menggerakkan SDK Rust dan TypeScript.

Mulai Cepat

Instal modul

go get menyelesaikan dependensi ke dalam modul Go, jadi inisialisasi terlebih dahulu jika Anda belum memiliki go.mod:

go mod init mytest

Kemudian tambahkan modulnya:

go get github.com/LiteSVM/litesvm-go

Tarik juga solana-go untuk pembuatan keypair, instruksi, dan transaksi:

go get github.com/gagliardetto/solana-go

Pengguna Alpine / musl: tambahkan -tags musl ke perintah go build / go test Anda agar arsip bawaan yang tepat ditautkan.

Buat SVM Anda

package mytest
import (
"testing"
litesvm "github.com/LiteSVM/litesvm-go"
solana "github.com/gagliardetto/solana-go"
)
func TestSetup(t *testing.T) {
svm, err := litesvm.New()
if err != nil {
t.Fatal(err)
}
defer svm.Close()
// Fund a payer
priv, err := solana.NewRandomPrivateKey()
if err != nil {
t.Fatal(err)
}
payer := priv.PublicKey()
if err := svm.Airdrop(payer, 5_000_000_000); err != nil {
t.Fatal(err)
}
// Check the balance
lamports, ok, err := svm.Balance(payer)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("payer account missing")
}
t.Logf("balance: %d lamports", lamports)
}

litesvm.New() mengembalikan *LiteSVM dan sebuah error. Setiap titik masuk di litesvm-go mengikuti bentuk (value, error) yang sama; panik di sisi Rust ditangkap dan dikonversi menjadi error. Selalu gunakan defer svm.Close() agar handle Rust yang mendasarinya dilepaskan - atau andalkan finalizer, meskipun Close eksplisit lebih disarankan untuk pembersihan yang dapat diprediksi.

Memahami Handle

Setelah litesvm.New(), *LiteSVM yang dikembalikan mengekspos kelompok kemampuan berikut:

GrupMetode
AkunAirdrop, Balance, GetAccount, SetAccount, MinimumBalanceForRentExemption
TransaksiSendLegacyTransaction, SendVersionedTransaction, SimulateLegacyTransaction, SimulateVersionedTransaction, GetTransaction
BlockhashLatestBlockhash, ExpireBlockhash
ProgramAddProgram, AddProgramFromFile, AddProgramWithLoader
Waktu dan sysvarWarpToSlot, Clock, SetClock, Rent, SetRent, EpochSchedule, SetEpochSchedule, EpochRewards, ...
KonfigurasiSetSigverify, SetBlockhashCheck, SetTransactionHistory, SetLogBytesLimit, SetSysvars, SetBuiltins, ...
Komputasi dan fiturComputeBudget, SetComputeBudget, SetFeatureSet

LiteSVM yang baru sudah dilengkapi dengan program inti Solana (System Program, SPL Token, dll.) yang telah dimuat sebelumnya, sehingga transfer sederhana langsung berfungsi tanpa konfigurasi tambahan.

Mengirim Transaksi

Bangun instruksi dengan solana-go, marshal transaksinya, dan kirimkan byte-nya. litesvm-go menerima byte yang dikodekan dengan bincode yang dihasilkan oleh (*solana.Transaction).MarshalBinary:

package mytest
import (
"testing"
litesvm "github.com/LiteSVM/litesvm-go"
solana "github.com/gagliardetto/solana-go"
"github.com/gagliardetto/solana-go/programs/system"
)
func TestTransfer(t *testing.T) {
svm, err := litesvm.New()
if err != nil {
t.Fatal(err)
}
defer svm.Close()
priv, err := solana.NewRandomPrivateKey()
if err != nil {
t.Fatal(err)
}
payer := priv.PublicKey()
recipient := solana.NewWallet().PublicKey()
if err := svm.Airdrop(payer, 2_000_000_000); err != nil {
t.Fatal(err)
}
blockhash, err := svm.LatestBlockhash()
if err != nil {
t.Fatal(err)
}
ix := system.NewTransferInstruction(1_000_000_000, payer, recipient).Build()
tx, err := solana.NewTransaction(
[]solana.Instruction{ix},
blockhash,
solana.TransactionPayer(payer),
)
if err != nil {
t.Fatal(err)
}
if _, err := tx.Sign(func(k solana.PublicKey) *solana.PrivateKey {
if k.Equals(payer) {
return &priv
}
return nil
}); err != nil {
t.Fatal(err)
}
txBytes, err := tx.MarshalBinary()
if err != nil {
t.Fatal(err)
}
out, err := svm.SendLegacyTransaction(txBytes)
if err != nil {
t.Fatal(err)
}
defer out.Close()
if !out.IsOk() {
t.Fatalf("tx failed: %s\nlogs: %v", out.Error(), out.Logs())
}
lamports, _, err := svm.Balance(recipient)
if err != nil {
t.Fatal(err)
}
if lamports != 1_000_000_000 {
t.Fatalf("recipient balance = %d, want 1_000_000_000", lamports)
}
}

SendLegacyTransaction dan SendVersionedTransaction keduanya mengembalikan *TxOutcome baik saat transaksi berhasil maupun gagal. Panggil IsOk() sebelum membaca field yang hanya tersedia saat sukses, dan selalu gunakan defer out.Close() untuk melepaskan handle Rust.

Bekerja dengan TxOutcome

Setiap titik masuk send / simulate mengembalikan *TxOutcome. Handle yang sama membawa metadata untuk keberhasilan maupun kegagalan:

out, err := svm.SendLegacyTransaction(txBytes)
if err != nil {
t.Fatal(err)
}
defer out.Close()
if !out.IsOk() {
t.Fatalf("error: %s", out.Error())
}
_ = out.Signature() // solana.Signature
_ = out.ComputeUnits() // uint64
_ = out.Fee() // uint64
_ = out.Logs() // []string
_ = out.InnerInstructions()
// Programs that call set_return_data expose it here.
if pid, data, ok := out.ReturnData(); ok {
_ = pid
_ = data
}

Untuk SimulateLegacyTransaction / SimulateVersionedTransaction, *TxOutcome yang sama juga mengekspos PostAccounts() - status akun setelah eksekusi yang akan terjadi:

sim, err := svm.SimulateLegacyTransaction(txBytes)
if err != nil {
t.Fatal(err)
}
defer sim.Close()
posts, err := sim.PostAccounts()
if err != nil {
t.Fatal(err)
}
for _, p := range posts {
_ = p.Address
_ = p.Account.Lamports()
p.Account.Close()
}

Konfigurasi

litesvm-go mengekspos switch builder yang sama seperti crate Rust, yang ditampilkan sebagai metode Set*:

// Each setter returns an error. In tests where the values are known good,
// the calls are infallible and assigning to _ keeps the example readable;
// in production code, check the error or wrap with require.NoError(t, ...).
_ = svm.SetSigverify(false) // accept unsigned / badly-signed txs
_ = svm.SetBlockhashCheck(false) // skip recent-blockhash enforcement
_ = svm.SetTransactionHistory(0) // 0 disables dedup; any N caps history
_ = svm.SetLogBytesLimit(-1) // negative = unlimited
_ = svm.SetLamports(1 << 40) // default lamports for new accounts
_ = svm.SetSysvars() // reset sysvars to defaults
_ = svm.SetBuiltins() // reload built-in programs
_ = svm.SetDefaultPrograms() // reload SPL Token, Memo, etc.
_ = svm.SetPrecompiles() // enable ed25519 / secp256k1 precompiles
_ = svm.WithNativeMints() // seed wrapped-SOL mint

Catatan

Keamanan thread. Handle *LiteSVM tidak aman untuk digunakan secara bersamaan dari beberapa goroutine (tipe Rust yang mendasarinya bukan Sync, dan sebagian besar metode mengubah status internal). Batasi handle pada satu goroutine, atau lindungi dengan sync.Mutex.

Perilaku panik. Arsip rilis bawaan dibangun dengan immediate-abort: setiap panik di dalam Rust langsung mengakhiri proses host tanpa unwinding. Ini adalah pertukaran yang disengaja demi arsip yang lebih kecil. Jika Anda mengalaminya dalam praktik, silakan buka issue dengan reproducer.

Apa Selanjutnya

Ini mencakup handle inti - membuat akun, mengirim instruksi, dan membaca state. Untuk referensi lengkap metode per metode, lihat dokumentasi API. Untuk contoh yang dapat dijalankan (transfer SOL, pengaturan akun, pengujian program, logika berbasis waktu) lihat Contoh.

Is this page helpful?

Daftar Isi

Edit Halaman
© 2026 Yayasan Solana. Semua hak dilindungi.