SetAccountを使用してアカウント状態を直接シードする方法を示します。トランザクションを実行せずに行えます。これは、多数のアカウントをテスト用に準備する際、エアドロップやランタイムを通じたファンディングよりも大幅に高速です。
基本的なアカウントのセットアップ
package mytestimport ("testing"litesvm "github.com/LiteSVM/litesvm-go"solana "github.com/gagliardetto/solana-go")func TestBasicAccountSetup(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()// Calculate minimum balance for rent exemption.accountData := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}minBalance, err := svm.MinimumBalanceForRentExemption(len(accountData))if err != nil {t.Fatal(err)}t.Logf("minimum balance for %d bytes: %d lamports", len(accountData), minBalance)// Owner program (system program in this trivial example).owner := solana.SystemProgramIDtestAddr := solana.NewWallet().PublicKey()// Build the account handle, then store it.acct, err := litesvm.NewAccount(minBalance, accountData, owner, false, 0)if err != nil {t.Fatal(err)}defer acct.Close()if err := svm.SetAccount(testAddr, acct); err != nil {t.Fatal(err)}t.Log("account state set successfully")// Retrieve the account back.retrieved := svm.GetAccount(testAddr)if retrieved == nil {t.Fatal("expected account to exist")}defer retrieved.Close()t.Logf(" address: %s", testAddr)t.Logf(" lamports: %d", retrieved.Lamports())t.Logf(" owner: %s", retrieved.Owner())t.Logf(" executable: %v", retrieved.Executable())t.Logf(" data: %v", retrieved.Data())// Or just read the balance.bal, _, err := svm.Balance(testAddr)if err != nil {t.Fatal(err)}t.Logf("balance: %d lamports", bal)}
複数アカウントのセットアップ
func TestMultipleAccounts(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()owner := solana.SystemProgramID// Set up 5 accounts with different data payloads.addrs := make([]solana.PublicKey, 5)for i := range addrs {addrs[i] = solana.NewWallet().PublicKey()data := []byte{byte(i), byte(i + 1), byte(i + 2)}rent, err := svm.MinimumBalanceForRentExemption(len(data))if err != nil {t.Fatal(err)}acct, err := litesvm.NewAccount(rent, data, owner, false, 0)if err != nil {t.Fatal(err)}if err := svm.SetAccount(addrs[i], acct); err != nil {acct.Close()t.Fatal(err)}acct.Close()t.Logf("account %d: %s", i, addrs[i])}// Verify each account.for i, addr := range addrs {a := svm.GetAccount(addr)if a == nil {t.Fatalf("account %d missing", i)}t.Logf(" account %d: %d lamports, data[0]=%d", i, a.Lamports(), a.Data()[0])a.Close()}}
program data account のセットアップ
構造体のレイアウトをアカウントのdataにシリアライズすることで、プログラムが所有するデータアカウントをセットアップします。このスニペットでは追加でencoding/binaryをインポートします:
import "encoding/binary"func TestProgramDataAccount(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()programID := solana.NewWallet().PublicKey()dataAddr := solana.NewWallet().PublicKey()// Example layout: [u8 discriminator, u64 counter, 32-byte owner pubkey]data := make([]byte, 1+8+32)data[0] = 0x01 // discriminatorbinary.LittleEndian.PutUint64(data[1:9], 100) // counter// copy(data[9:], ownerPubkey[:]) // ownerrent, err := svm.MinimumBalanceForRentExemption(len(data))if err != nil {t.Fatal(err)}acct, err := litesvm.NewAccount(rent, data, programID, false, 0)if err != nil {t.Fatal(err)}defer acct.Close()if err := svm.SetAccount(dataAddr, acct); err != nil {t.Fatal(err)}t.Logf("program data account set up: %s", dataAddr)}
SetAccountは、アカウントの一括セットアップにおいてトランザクションを実行するよりも高速であり、
テストコードを状態構築のための配管処理ではなく、テスト対象の振る舞いに集中させることができます。
重要なポイント
- 直接の状態書き込み -
SetAccountはランタイムを経由せずにアカウント状態を書き込みます。 - レント免除 - アカウントを構築する前に、
MinimumBalanceForRentExemptionを使用して必要なlamportを計算してください。 - 所有権 -
NewAccountが返すハンドルはあなたが引き続き所有します。SetAccount実行後、SVMは独自のコピーを保持します。使用が完了したら、あなたのハンドルをクローズしてください。 - 検証 - ハンドルに読み戻すには
GetAccountを、lamportのみの確認にはBalanceを使用してください。
Is this page helpful?