Lokal na Pag-gawa

Pagsisimula ng Lokal na Validator

Ang pagsubok sa iyong program code nang lokal ay maaaring maging mas maaasahan kaysa pagsubok sa devnet, at makakatulong sa iyong subukan bago ito subukan sa devnet.

Maaari mong i-setup ang iyong local-test-validator sa pamamagitan ng pag-install ng solana tool suite at tumatakbo

solana-test-validator

Ang mga pakinabang ng paggamit ng local-test-validator ay kinabibilangan ng:

  • Walang mga limitasyon sa rate ng RPC
  • Walang limitasyon sa airdrop
  • Direktang on-chain program deployment (--bpf-program ...)
  • I-clone ang mga account mula sa isang pampublikong cluster, kabilang ang mga programa (--clone ...)
  • Nako-configure ang pagpapanatili ng kasaysayan ng transaksyon (--limit-ledger-size ...)
  • Nako-configure na haba ng panahon (--slots-per-epoch ...)
  • Tumalon sa isang arbitrary slot (--warp-slot ...)

Kumokonekta sa Mga Environment

Kapag nagtatrabaho ka sa pagbuo ng Solana, kakailanganin mong kumonekta sa isang partikular na endpoint ng RPC API. May 3 pampublikong pag-gawa ang Solana environment:

  • mainnet-beta https://api.mainnet-beta.solana.com
  • devnet https://api.devnet.solana.com
  • testnet https://api.testnet.solana.com
Press </> button to view full source
import { clusterApiUrl, Connection } from "@solana/web3.js";

(async () => {
  const connection = new Connection(clusterApiUrl("mainnet-beta"), "confirmed");
})();
from solana.rpc.api import Client

client = Client("https://api.mainnet-beta.solana.com")
#include "solana.hpp"

using namespace many::solana;

int main() {
    Connection connection("https://api.mainnet-beta.solana.com");
    return 0;
}
use solana_client::rpc_client::RpcClient;
use solana_sdk::commitment_config::CommitmentConfig;

fn main() {
    let rpc_url = String::from("https://api.mainnet-beta.solana.com");
    let client = RpcClient::new_with_commitment(rpc_url, CommitmentConfig::confirmed());
}
solana config set --url https://api.mainnet-beta.solana.com

Sa wakas, maaari ka ring kumonekta sa isang pribadong kumpol, alinman sa isang lokal o tumatakbo nang malayuan kasama ang mga sumusunod:

Press </> button to view full source
import { Connection } from "@solana/web3.js";

(async () => {
  // This will connect you to your local validator
  const connection = new Connection("http://127.0.0.1:8899", "confirmed");
})();
from solana.rpc.api import Client

client = Client("http://127.0.0.1:8899")
#include "solana.hpp"

using namespace many::solana;

int main() {
    Connection connection("http://127.0.0.1:8899");
    return 0;
}
use solana_client::rpc_client::RpcClient;
use solana_sdk::commitment_config::CommitmentConfig;

fn main() {
    let rpc_url = String::from("http://127.0.0.1:8899");
    let client = RpcClient::new_with_commitment(rpc_url, CommitmentConfig::confirmed());
}
solana config set --url http://privaterpc.com

Pag-subscribe sa Mga Kaganapan

Nagbibigay ang mga websocket ng interface ng pub/sub kung saan maaari kang makinig sa ilang partikular na kaganapan. Sa halip na i-ping ang isang tipikal na HTTP endpoint sa isang agwat upang makakuha ng madalas na mga update, maaari mo na lang matanggap ang mga update na iyon kapag nangyari ang mga ito.

Ang web3 ni Solana Connectionopen in new window sa ilalim ng hood ay bumubuo ng endpoint ng websocket at nagrerehistro ng websocket client kapag gumawa ka ng bagong ` Halimbawa ng koneksyon (tingnan ang source code ditoopen in new window).

Ang klase ng Connection ay naglalantad ng mga pub/sub na pamamaraan - lahat sila ay nagsisimula sa on, tulad ng mga emitter ng kaganapan. Kapag tinawag mo ang mga pamamaraan ng listener na ito, nagrerehistro ito ng bagong subscription sa websocket client ng instance na Connection na iyon. Ang halimbawang paraan ng pub/sub na ginagamit namin sa ibaba ay onAccountChangeopen in new window. Ibibigay ng callback ang na-update na data ng estado sa pamamagitan ng mga argumento (tingnan ang AccountChangeCallbackopen in new window bilang isang halimbawa).

Press </> button to view full source
import { clusterApiUrl, Connection, Keypair } from "@solana/web3.js";

(async () => {
  // Establish new connect to devnet - websocket client connected to devnet will also be registered here
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // Create a test wallet to listen to
  const wallet = Keypair.generate();

  // Register a callback to listen to the wallet (ws subscription)
  connection.onAccountChange(
    wallet.publicKey(),
    (updatedAccountInfo, context) =>
      console.log("Updated account info: ", updatedAccountInfo),
    "confirmed"
  );
})();
import asyncio
from solders.keypair import Keypair
from solana.rpc.websocket_api import connect

async def main():
    async with connect("wss://api.devnet.solana.com") as websocket:
        # Create a Test Wallet
        wallet = Keypair()
        # Subscribe to the Test wallet to listen for events
        await websocket.account_subscribe(wallet.pubkey())
        # Capture response from account subscription 
        first_resp = await websocket.recv()
        print("Subscription successful with id {}, listening for events \n".format(first_resp.result))
        updated_account_info = await websocket.recv()
        print(updated_account_info)
        
asyncio.run(main())
// clang++ on_account_change.cpp -o on_account_change -std=c++17 -lssl -lcrypto -lsodium

#include "solana.hpp"

using namespace many::solana;

int main() {
  Connection connection("https://api.devnet.solana.com");

  auto key_pair = Keypair::generate();

  int subscriptionId = connection.on_account_change(key_pair.public_key, [&](Result<Account> result) {
    Account account = result.unwrap();
    std::cout << "owner = " << account.owner.to_base58() << std::endl;
    std::cout << "lamports = " << account.lamports << std::endl;
    std::cout << "data = " << account.data << std::endl;
    std::cout << "executable = " << (account.executable ? "true" : "false") << std::endl;
  });

  sleep(1);

  std::string tx_hash = connection.request_airdrop(key_pair.public_key).unwrap();
  std::cout << "tx hash = " << tx_hash << std::endl;

  for (int i = 0; i < 10; i++) {
    connection.poll();
    sleep(1);
  }

  connection.remove_account_listener(subscriptionId);

  return 0;
}
use solana_client::pubsub_client::PubsubClient;
use solana_client::rpc_config::RpcAccountInfoConfig;
use solana_sdk::commitment_config::CommitmentConfig;
use solana_sdk::signature::{Keypair, Signer};

fn main() {
    let wallet = Keypair::new();
    let pubkey = Signer::pubkey(&wallet);
    let ws_url = String::from("wss://api.devnet.solana.com/");
    println!("{}", ws_url);
    if let Ok(subscription) = PubsubClient::account_subscribe(
        &ws_url,
        &pubkey,
        Some(RpcAccountInfoConfig {
            encoding: None,
            data_slice: None,
            commitment: Some(CommitmentConfig::confirmed()),
        }),
    ) {
        let (mut ws_client, receiver) = subscription;
        println!("Subscription successful, listening for events");
        let handle = std::thread::spawn(move || loop {
            println!("Waiting for a message");
            match receiver.recv() {
                Ok(message) => println!("{:?}", message),
                Err(err) => {
                    println!("Connection broke with {:}", err);
                    break;
                }
            }
        });
        handle.join().unwrap();
        ws_client.shutdown().unwrap()
    } else {
        println!("Errooooor");
    }
}

Pagkuha ng Test SOL

Kapag nagtatrabaho ka nang lokal, kailangan mo ng ilang SOL para makapagpadala mga transaksyon. Sa mga hindi mainnet na environment maaari kang makatanggap ng SOL sa pamamagitan ng i-airdrop ito sa iyong address

Press </> button to view full source
import { Connection, Keypair, LAMPORTS_PER_SOL } from "@solana/web3.js";

(async () => {
  const keypair = Keypair.generate();

  const connection = new Connection("http://127.0.0.1:8899", "confirmed");

  const signature = await connection.requestAirdrop(
    keypair.publicKey,
    LAMPORTS_PER_SOL
  );
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
  await connection.confirmTransaction({
      blockhash,
      lastValidBlockHeight,
      signature
    });
})();
from solders.keypair import Keypair
from solana.rpc.api import Client

wallet = Keypair()

client = Client("https://api.devnet.solana.com")

#Input Airdrop amount in LAMPORTS
client.request_airdrop(wallet.pubkey(), 1000000000)

#Airdrops 1 SOL
// clang++ request_airdrop.cpp -o request_airdrop -std=c++17 -lssl -lcrypto -lsodium

#include "solana.hpp"

using namespace many::solana;

int main() {
  Connection connection("https://api.devnet.solana.com");

  auto key_pair = Keypair::generate();

  std::string tx_hash = connection.request_airdrop(key_pair.public_key).unwrap();

  std::cout << "tx hash = " << tx_hash << std::endl;

  return 0;
}
use solana_client::rpc_client::RpcClient;
use solana_sdk::commitment_config::CommitmentConfig;
use solana_sdk::native_token::LAMPORTS_PER_SOL;
use solana_sdk::signature::{Keypair, Signer};

fn main() {
    let wallet = Keypair::new();
    let pubkey = Signer::pubkey(&wallet);
    let rpc_url = String::from("https://api.devnet.solana.com");
    let client = RpcClient::new_with_commitment(rpc_url, CommitmentConfig::confirmed());
    match client.request_airdrop(&pubkey, LAMPORTS_PER_SOL) {
        Ok(sig) => loop {
            if let Ok(confirmed) = client.confirm_transaction(&sig) {
                if confirmed {
                    println!("Transaction: {} Status: {}", sig, confirmed);
                    break;
                }
            }
        },
        Err(_) => println!("Error requesting airdrop"),
    };
}
solana airdrop 1

# Return
# "1 SOL"

Paggamit ng Mainnet Accounts at Programs

Kadalasan, umaasa ang mga lokal na pagsubok sa mga programa at account na available lang sa mainnet. Ang Solana CLI ay nagbibigay-daan sa parehong:

  • Mag-download ng Mga Programa at Account
  • Mag-load ng Mga Programa at Account sa isang lokal na validator

Paano mag-load ng mga account mula sa mainnet

Posibleng i-download ang SRM token mint account para mag-file:

Press </> button to view full source
# solana account -u <source cluster> --output <output format> --output-file <destination file name/path> <address of account to fetch>
solana account -u m --output json-compact --output-file SRM_token.json SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt

Ang paglo-load nito sa iyong localnet ay ginagawa sa pamamagitan ng pagpasa sa file ng account at patutunguhang address (sa lokal na cluster) kapag sinimulan ang validator:

Press </> button to view full source
# solana-test-validator --account <address to load the account to> <path to account file> --reset
solana-test-validator --account SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt SRM_token.json --reset

Paano mag-load ng mga programa mula sa mainnet

Katulad nito, posibleng i-download ang Serum Dex v3 program:

Press </> button to view full source
# solana program dump -u <source cluster> <address of account to fetch> <destination file name/path>
solana program dump -u m 9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin serum_dex_v3.so

Ang paglo-load nito sa iyong localnet ay tapos na sa pamamagitan ng pagpasa sa file ng programa at patutunguhang address (sa lokal na kumpol) kapag sinimulan ang validator:

Press </> button to view full source
# solana-test-validator --bpf-program <address to load the program to> <path to program file> --reset
solana-test-validator --bpf-program 9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin serum_dex_v3.so --reset
Last Updated:
Contributors: mh