Accounts
So erstellen Sie ein Systemkonto
Erstellen Sie ein Konto, das dem Systemprogramm gehört. Die Solana-Laufzeit gewährt dem Besitzer eines Kontos Zugriff darauf in seine Daten schreiben oder Lamports übertragen. Beim Erstellen eines Kontos müssen wir einen festen Speicherplatz in Bytes vorbelegen (Raum
) und genügend Lamports, um die Miete zu decken. Miete sind Kosten, die anfallen, um Konten auf Solana am Leben zu erhalten.
import {
SystemProgram,
Keypair,
Transaction,
sendAndConfirmTransaction,
Connection,
clusterApiUrl,
LAMPORTS_PER_SOL,
} from "@solana/web3.js";
(async () => {
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const fromPubkey = Keypair.generate();
// Airdrop SOL for transferring lamports to the created account
const airdropSignature = await connection.requestAirdrop(
fromPubkey.publicKey,
LAMPORTS_PER_SOL
);
await connection.confirmTransaction(airdropSignature);
// amount of space to reserve for the account
const space = 0;
// Seed the created account with lamports for rent exemption
const rentExemptionAmount =
await connection.getMinimumBalanceForRentExemption(space);
const newAccountPubkey = Keypair.generate();
const createAccountParams = {
fromPubkey: fromPubkey.publicKey,
newAccountPubkey: newAccountPubkey.publicKey,
lamports: rentExemptionAmount,
space,
programId: SystemProgram.programId,
};
const createAccountTransaction = new Transaction().add(
SystemProgram.createAccount(createAccountParams)
);
await sendAndConfirmTransaction(connection, createAccountTransaction, [
fromPubkey,
newAccountPubkey,
]);
})();
const createAccountParams = {
fromPubkey: fromPubkey.publicKey,
newAccountPubkey: newAccountPubkey.publicKey,
lamports: rentExemptionAmount,
space,
programId: SystemProgram.programId,
};
const createAccountTransaction = new Transaction().add(
SystemProgram.createAccount(createAccountParams)
);
await sendAndConfirmTransaction(connection, createAccountTransaction, [
fromPubkey,
newAccountPubkey,
]);
use solana_client::rpc_client::RpcClient;
use solana_program::system_instruction;
use solana_sdk::commitment_config::CommitmentConfig;
use solana_sdk::native_token::LAMPORTS_PER_SOL;
use solana_sdk::signature::{Keypair, Signer};
fn main() {
let rpc_url = String::from("https://api.devnet.solana.com");
let connection = RpcClient::new_with_commitment(rpc_url, CommitmentConfig::confirmed());
let from_keypair = Keypair::new();
let from_pubkey = Signer::pubkey(&from_keypair);
match connection.request_airdrop(&from_pubkey, LAMPORTS_PER_SOL) {
Ok(sig) => loop {
if let Ok(confirmed) = connection.confirm_transaction(&sig) {
if confirmed {
println!("Transaction: {} Status: {}", sig, confirmed);
break;
}
}
},
Err(_) => println!("Error requesting airdrop"),
};
let space = 0;
let rent_exemption_amount = connection
.get_minimum_balance_for_rent_exemption(space)
.unwrap();
let new_account_keypair = Keypair::new();
let new_account_pubkey = Signer::pubkey(&new_account_keypair);
let create_account_ix = system_instruction::create_account(
&from_pubkey,
&new_account_pubkey,
rent_exemption_amount,
space as u64,
&from_pubkey,
);
let (recent_blockhash, _) = connection.get_recent_blockhash().unwrap();
let create_account_tx = solana_sdk::transaction::Transaction::new_signed_with_payer(
&[create_account_ix],
Some(&from_pubkey),
&[&from_keypair, &new_account_keypair],
recent_blockhash,
);
match connection.send_and_confirm_transaction(&create_account_tx) {
Ok(sig) => loop {
if let Ok(confirmed) = connection.confirm_transaction(&sig) {
if confirmed {
println!("Transaction: {} Status: {}", sig, confirmed);
break;
}
}
},
Err(_) => println!("Error creating system account"),
};
}
let create_account_ix = system_instruction::create_account(
&from_pubkey,
&new_account_pubkey,
rent_exemption_amount,
space as u64,
&from_pubkey,
);
let (recent_blockhash, _) = connection.get_recent_blockhash().unwrap();
let create_account_tx = solana_sdk::transaction::Transaction::new_signed_with_payer(
&[create_account_ix],
Some(&from_pubkey),
&[&from_keypair, &new_account_keypair],
recent_blockhash,
);
match connection.send_and_confirm_transaction(&create_account_tx) {
Ok(sig) => loop {
if let Ok(confirmed) = connection.confirm_transaction(&sig) {
if confirmed {
println!("Transaction: {} Status: {}", sig, confirmed);
break;
}
}
},
Err(_) => println!("Error creating system account"),
};
So berechnen Sie die Kontokosten
Um Konten auf Solana am Leben zu erhalten, fallen Speicherkosten an, die als [Miete] 2 bezeichnet werden. Ein Konto kann vollständig befreit werden aus der Mieteinziehung durch Hinterlegung von mindestens zwei Jahresmieten. Für die Berechnung müssen Sie berücksichtigen die Datenmenge, die Sie im Konto speichern möchten.
import { Connection, clusterApiUrl } from "@solana/web3.js";
(async () => {
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
// length of data in the account to calculate rent for
const dataLength = 1500;
const rentExemptionAmount =
await connection.getMinimumBalanceForRentExemption(dataLength);
console.log({
rentExemptionAmount,
});
})();
use solana_client::rpc_client::RpcClient;
use solana_sdk::commitment_config::CommitmentConfig;
fn main() {
let rpc_url = String::from("https://api.devnet.solana.com");
let connection = RpcClient::new_with_commitment(rpc_url, CommitmentConfig::confirmed());
let data_length = 1500;
let rent_exemption_amount = connection
.get_minimum_balance_for_rent_exemption(data_length)
.unwrap();
println!("rent exemption amount: {}", rent_exemption_amount);
}
solana rent 1500
So erstellen Sie Konten mit Seeds
Sie können createAccountWithSeed
verwenden, um Ihre Konten zu verwalten, anstatt eine Reihe verschiedener Schlüsselpaare zu erstellen.
Generieren
import { PublicKey, SystemProgram } from "@solana/web3.js";
(async () => {
let basePubkey = new PublicKey(
"G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY"
);
let seed = "robot001";
let programId = SystemProgram.programId;
console.log(
`${(
await PublicKey.createWithSeed(basePubkey, seed, programId)
).toBase58()}`
);
})();
PublicKey.createWithSeed(basePubkey, seed, programId);
use solana_program::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, Signer};
fn main() {
let base_pubkey = Keypair::new().pubkey();
let seed = "robot001";
let program_id = solana_program::system_program::id();
let derived_pubkey = Pubkey::create_with_seed(&base_pubkey, seed, &program_id).unwrap();
println!("account pubkey: {:?}", derived_pubkey);
}
use solana_program::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, Signer};
fn main() {
let base_pubkey = Keypair::new().pubkey();
let seed = "robot001";
let program_id = solana_program::system_program::id();
let derived_pubkey = Pubkey::create_with_seed(&base_pubkey, seed, &program_id).unwrap();
println!("account pubkey: {:?}", derived_pubkey);
}
Erstellen
import {
PublicKey,
SystemProgram,
Connection,
clusterApiUrl,
Transaction,
Keypair,
sendAndConfirmTransaction,
LAMPORTS_PER_SOL,
} from "@solana/web3.js";
import * as bs58 from "bs58";
(async () => {
// connection
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
// 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
const feePayer = Keypair.fromSecretKey(
bs58.decode(
"588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
)
);
// G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
const base = Keypair.fromSecretKey(
bs58.decode(
"4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
)
);
let basePubkey = base.publicKey;
let seed = "robot001";
let programId = SystemProgram.programId;
let derived = await PublicKey.createWithSeed(basePubkey, seed, programId);
const tx = new Transaction().add(
SystemProgram.createAccountWithSeed({
fromPubkey: feePayer.publicKey, // funder
newAccountPubkey: derived,
basePubkey: basePubkey,
seed: seed,
lamports: 1e8, // 0.1 SOL
space: 0,
programId: programId,
})
);
console.log(
`txhash: ${await sendAndConfirmTransaction(connection, tx, [
feePayer,
base,
])}`
);
})();
const tx = new Transaction().add(
SystemProgram.createAccountWithSeed({
fromPubkey: feePayer.publicKey, // funder
newAccountPubkey: derived,
basePubkey: basePubkey,
seed: seed,
lamports: 1e8, // 0.1 SOL
space: 0,
programId: owner,
})
);
console.log(
`txhash: ${await sendAndConfirmTransaction(connection, tx, [feePayer, base])}`
);
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
use solana_program::system_instruction;
use solana_sdk::commitment_config::CommitmentConfig;
use solana_sdk::native_token::LAMPORTS_PER_SOL;
use solana_sdk::signature::{Keypair, Signer};
fn main() {
let rpc_url = String::from("https://api.devnet.solana.com");
let connection = RpcClient::new_with_commitment(rpc_url, CommitmentConfig::confirmed());
let fee_payer_keypair = Keypair::new();
let fee_payer_pubkey = Signer::pubkey(&fee_payer_keypair);
let base_keypair = Keypair::new();
let base_pubkey = Signer::pubkey(&base_keypair);
let seed = "robot001";
let program_id = solana_program::system_program::id();
let derived_pubkey = Pubkey::create_with_seed(&base_pubkey, seed, &program_id).unwrap();
match connection.request_airdrop(&fee_payer_pubkey, LAMPORTS_PER_SOL) {
Ok(sig) => loop {
if let Ok(confirmed) = connection.confirm_transaction(&sig) {
if confirmed {
println!("Transaction: {} Status: {}", sig, confirmed);
break;
}
}
},
Err(_) => println!("Error requesting airdrop"),
};
let ix = system_instruction::create_account_with_seed(
&fee_payer_pubkey,
&derived_pubkey,
&base_pubkey,
seed,
LAMPORTS_PER_SOL / 10,
0,
&program_id,
);
let (recent_blockhash, _) = connection.get_recent_blockhash().unwrap();
let tx = solana_sdk::transaction::Transaction::new_signed_with_payer(
&[ix],
Some(&fee_payer_pubkey),
&[&fee_payer_keypair, &base_keypair],
recent_blockhash,
);
match connection.send_and_confirm_transaction(&tx) {
Ok(sig) => loop {
if let Ok(confirmed) = connection.confirm_transaction(&sig) {
if confirmed {
println!("Transaction: {} Status: {}", sig, confirmed);
break;
}
}
},
Err(_) => println!("Error creating account with seed"),
};
}
let derived_pubkey = Pubkey::create_with_seed(&base_pubkey, seed, &program_id).unwrap();
let ix = system_instruction::create_account_with_seed(
&fee_payer_pubkey,
&derived_pubkey,
&base_pubkey,
seed,
LAMPORTS_PER_SOL / 10,
0,
&program_id,
);
let tx = solana_sdk::transaction::Transaction::new_signed_with_payer(
&[ix],
Some(&fee_payer_pubkey),
&[&fee_payer_keypair, &base_keypair],
recent_blockhash,
);
Transferieren
import {
PublicKey,
SystemProgram,
Connection,
clusterApiUrl,
Transaction,
Keypair,
sendAndConfirmTransaction,
LAMPORTS_PER_SOL,
} from "@solana/web3.js";
import * as bs58 from "bs58";
(async () => {
// connection
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
// 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
const feePayer = Keypair.fromSecretKey(
bs58.decode(
"588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
)
);
// G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
const base = Keypair.fromSecretKey(
bs58.decode(
"4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
)
);
let basePubkey = base.publicKey;
let seed = "robot001";
let programId = SystemProgram.programId;
let derived = await PublicKey.createWithSeed(basePubkey, seed, programId);
const tx = new Transaction().add(
SystemProgram.transfer({
fromPubkey: derived,
basePubkey: basePubkey,
toPubkey: Keypair.generate().publicKey, // create a random receiver
lamports: 0.01 * LAMPORTS_PER_SOL,
seed: seed,
programId: programId,
})
);
console.log(
`txhash: ${await sendAndConfirmTransaction(connection, tx, [
feePayer,
base,
])}`
);
})();
const tx = new Transaction().add(
SystemProgram.transfer({
fromPubkey: derived,
basePubkey: basePubkey,
toPubkey: Keypair.generate().publicKey, // create a random receiver
lamports: 0.01 * LAMPORTS_PER_SOL,
seed: seed,
programId: programId,
})
);
console.log(
`txhash: ${await sendAndConfirmTransaction(connection, tx, [feePayer, base])}`
);
TIP
Only an account owned by system program can transfer via system program.
So erstellen Sie PDAs
Vom Programm abgeleitete Adresses (PDA) sind wie eine normale Adresse, jedoch mit mit den folgenden Unterschieden:
- Abfall von der ed25519-Kurve
- Verwendung des Programms zum Signieren anstelle des privaten Schlüssels
Hinweis: PDA-Konten können nur im Programm erstellt werden. Die Adresse kann clientseitig erstellt werden.
TIP
Obwohl PDA von einer Programm-ID abgeleitet wird, bedeutet dies nicht, dass der PDA demselben Programm gehört. (Nehmen Sie ein Beispiel: Sie können Ihren PDA als Token-Konto initialisieren, das ein Konto ist, das dem Token-Programm gehört.)
Generieren Sie einen PDA
findProgramAddress
fügt am Ende Ihres Seeds ein zusätzliches Byte hinzu. Es beginnt bei 255 bis 0 und gibt den ersten öffentlichen Schlüssel außerhalb der Kurve zurück. Sie erhalten immer dasselbe Ergebnis, wenn Sie dieselbe Programm-ID übergeben und Samen.
import { PublicKey } from "@solana/web3.js";
(async () => {
const programId = new PublicKey(
"G1DCNUQTSGHehwdLCAmRyAG8hf51eCHrLNUqkgGKYASj"
);
let [pda, bump] = await PublicKey.findProgramAddress(
[Buffer.from("test")],
programId
);
console.log(`bump: ${bump}, pubkey: ${pda.toBase58()}`);
// you will find the result is different from `createProgramAddress`.
// It is expected because the real seed we used to calculate is ["test" + bump]
})();
use solana_program::pubkey::Pubkey;
use std::str::FromStr;
fn main() {
let program_id = Pubkey::from_str("G1DCNUQTSGHehwdLCAmRyAG8hf51eCHrLNUqkgGKYASj").unwrap();
let (pda, bump_seed) = Pubkey::find_program_address(&[b"test"], &program_id);
println!("pda: {}, bump: {}", pda, bump_seed);
}
Erstellen Sie einen PDA
Unten ist ein Beispielprogramm zum Erstellen eines PDA-Kontos, das dem Programm gehört, und ein Beispiel zum Aufrufen des Programms mit dem Client.
Program
Das Folgende zeigt eine einzelne Anweisung system_instruction::create_account
, die ein Konto mit zugewiesener Datengröße von space
, rent_lamports
Anzahl von Lamports für den abgeleiteten PDA erstellt. Dies wird mit dem PDA unter Verwendung von "invoke_signed" signiert, ähnlich wie oben beschrieben.
use solana_program::{
account_info::next_account_info, account_info::AccountInfo, entrypoint,
entrypoint::ProgramResult, program::invoke_signed, pubkey::Pubkey, system_instruction, sysvar::{rent::Rent, Sysvar}
};
entrypoint!(process_instruction);
fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let payer_account_info = next_account_info(account_info_iter)?;
let pda_account_info = next_account_info(account_info_iter)?;
let rent_sysvar_account_info = &Rent::from_account_info(next_account_info(account_info_iter)?)?;
// find space and minimum rent required for account
let space = instruction_data[0];
let bump = instruction_data[1];
let rent_lamports = rent_sysvar_account_info.minimum_balance(space.into());
invoke_signed(
&system_instruction::create_account(
&payer_account_info.key,
&pda_account_info.key,
rent_lamports,
space.into(),
program_id
),
&[
payer_account_info.clone(),
pda_account_info.clone()
],
&[&[&payer_account_info.key.as_ref(), &[bump]]]
)?;
Ok(())
}
invoke_signed(
&system_instruction::create_account(
&payer_account_info.key,
&pda_account_info.key,
rent_lamports,
space.into(),
program_id
),
&[
payer_account_info.clone(),
pda_account_info.clone()
],
&[&[&payer_account_info.key.as_ref(), &[bump]]]
)?;
Client
import {
clusterApiUrl,
Connection,
Keypair,
Transaction,
SystemProgram,
PublicKey,
TransactionInstruction,
LAMPORTS_PER_SOL,
SYSVAR_RENT_PUBKEY,
} from "@solana/web3.js";
(async () => {
// program id
const programId = new PublicKey(
"7ZP42kRwUQ2zgbqXoaXzAFaiQnDyp6swNktTSv8mNQGN"
);
// connection
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
// setup fee payer
const feePayer = Keypair.generate();
const feePayerAirdropSignature = await connection.requestAirdrop(
feePayer.publicKey,
LAMPORTS_PER_SOL
);
await connection.confirmTransaction(feePayerAirdropSignature);
// setup pda
let [pda, bump] = await PublicKey.findProgramAddress(
[feePayer.publicKey.toBuffer()],
programId
);
console.log(`bump: ${bump}, pubkey: ${pda.toBase58()}`);
const data_size = 0;
let tx = new Transaction().add(
new TransactionInstruction({
keys: [
{
pubkey: feePayer.publicKey,
isSigner: true,
isWritable: true,
},
{
pubkey: pda,
isSigner: false,
isWritable: true,
},
{
pubkey: SYSVAR_RENT_PUBKEY,
isSigner: false,
isWritable: false,
},
{
pubkey: SystemProgram.programId,
isSigner: false,
isWritable: false,
},
],
data: Buffer.from(new Uint8Array([data_size, bump])),
programId: programId,
})
);
console.log(`txhash: ${await connection.sendTransaction(tx, [feePayer])}`);
})();
let tx = new Transaction().add(
new TransactionInstruction({
keys: [
{
pubkey: feePayer.publicKey,
isSigner: true,
isWritable: true,
},
{
pubkey: pda,
isSigner: false,
isWritable: true,
},
{
pubkey: SYSVAR_RENT_PUBKEY,
isSigner: false,
isWritable: false,
},
{
pubkey: SystemProgram.programId,
isSigner: false,
isWritable: false,
},
],
data: Buffer.from(new Uint8Array([data_size, bump])),
programId: programId,
})
);
console.log(`txhash: ${await connection.sendTransaction(tx, [feePayer])}`);
So signieren Sie mit einem PDA
PDAs können nur innerhalb des Programms signiert werden. Unten ist ein Programm Beispiel mit einem PDA signieren und das Programm mit dem Client aufrufen.
Programm
Das Folgende zeigt eine einzelne Anweisung, die SOL von einem PDA überträgt wurde von der Saat Escrow
auf ein Konto übergeben. invoke_signed
ist verwendet, um mit dem PDA zu unterschreiben.
use solana_program::{
account_info::next_account_info, account_info::AccountInfo, entrypoint,
entrypoint::ProgramResult, program::invoke_signed, pubkey::Pubkey, system_instruction,
};
entrypoint!(process_instruction);
fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let pda_account_info = next_account_info(account_info_iter)?;
let to_account_info = next_account_info(account_info_iter)?;
let system_program_account_info = next_account_info(account_info_iter)?;
// pass bump seed for saving compute budget
let bump_seed = instruction_data[0];
invoke_signed(
&system_instruction::transfer(
&pda_account_info.key,
&to_account_info.key,
100_000_000, // 0.1 SOL
),
&[
pda_account_info.clone(),
to_account_info.clone(),
system_program_account_info.clone(),
],
&[&[b"escrow", &[bump_seed]]],
)?;
Ok(())
}
invoke_signed(
&system_instruction::transfer(
&pda_account_info.key,
&to_account_info.key,
100_000_000, // 0.1 SOL
),
&[
pda_account_info.clone(),
to_account_info.clone(),
system_program_account_info.clone(),
],
&[&[b"escrow", &[bump_seed]]],
)?;
Client
import {
clusterApiUrl,
Connection,
Keypair,
Transaction,
SystemProgram,
PublicKey,
TransactionInstruction,
LAMPORTS_PER_SOL,
} from "@solana/web3.js";
import * as bs58 from "bs58";
(async () => {
// program id
const programId = new PublicKey(
"4wQC2yuVt4rbcPeYLK8WngqbYLg7UAahVjRFrK3NBjP6"
);
// connection
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
// setup fee payer
const feePayer = Keypair.generate();
const feePayerAirdropSignature = await connection.requestAirdrop(
feePayer.publicKey,
LAMPORTS_PER_SOL
);
await connection.confirmTransaction(feePayerAirdropSignature);
// setup pda
let [pda, bump] = await PublicKey.findProgramAddress(
[Buffer.from("escrow")],
programId
);
console.log(`bump: ${bump}, pubkey: ${pda.toBase58()}`);
// require 1 SOL for the transfering in the program
const pdaAirdropSignature = await connection.requestAirdrop(
pda,
LAMPORTS_PER_SOL
);
await connection.confirmTransaction(pdaAirdropSignature);
// create a random `to`
const to = Keypair.generate();
console.log(`receiver: ${to.publicKey.toBase58()}`);
let tx = new Transaction().add(
new TransactionInstruction({
keys: [
{
pubkey: pda,
// Leave `false` here although we need a pda as a signer.
// It will be escalated on program if we use invoke_signed.
isSigner: false,
isWritable: true,
},
{
pubkey: to.publicKey,
isSigner: false,
isWritable: true,
},
{
pubkey: SystemProgram.programId,
isSigner: false,
isWritable: false,
},
],
data: Buffer.from(new Uint8Array([bump])),
programId: programId,
})
);
console.log(`txhash: ${await connection.sendTransaction(tx, [feePayer])}`);
})();
let tx = new Transaction().add(
new TransactionInstruction({
keys: [
{
pubkey: pda,
// Leave `false` here although we need a pda as a signer.
// It will be escalated on program if we use invoke_signed.
isSigner: false,
isWritable: true,
},
{
pubkey: to.publicKey,
isSigner: false,
isWritable: true,
},
{
pubkey: SystemProgram.programId,
isSigner: false,
isWritable: false,
},
],
data: Buffer.from(new Uint8Array([bump])),
programId: programId,
})
);
console.log(`txhash: ${await connection.sendTransaction(tx, [feePayer])}`);
So erhalten Sie Programmkonten
Gibt alle Konten zurück, die einem Programm gehören. Weitere Informationen zu getProgramAccounts
und seiner Konfiguration finden Sie im Anleitungsabschnitt.
import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
(async () => {
const MY_PROGRAM_ID = new PublicKey(
"6a2GdmttJdanBkoHt7f4Kon4hfadx4UTUgJeRkCaiL3U"
);
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const accounts = await connection.getProgramAccounts(MY_PROGRAM_ID);
console.log(`Accounts for program ${MY_PROGRAM_ID}: `);
console.log(accounts);
/*
// Output
Accounts for program 6a2GdmttJdanBkoHt7f4Kon4hfadx4UTUgJeRkCaiL3U:
[
{
account: {
data: <Buffer 60 06 66 ca 2c 1d c7 85 04 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 fc>,
executable: false,
lamports: 1064880,
owner: [PublicKey],
rentEpoch: 228
},
pubkey: PublicKey {
_bn: <BN: 82fc5b91154dc5c840cb464ba6a89212d0fd789367c0a1488fb1941d78f9727a>
}
},
{
account: {
data: <Buffer 60 06 66 ca 2c 1d c7 85 03 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 fd>,
executable: false,
lamports: 1064880,
owner: [PublicKey],
rentEpoch: 229
},
pubkey: PublicKey {
_bn: <BN: 404dc1fe368cf194f20cf3c681a071c61893ced98f65cda12ba5a147e984e669>
}
}
]
*/
})();
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
use solana_sdk::commitment_config::CommitmentConfig;
use std::str::FromStr;
fn main() {
let rpc_url = String::from("https://api.devnet.solana.com");
let connection = RpcClient::new_with_commitment(rpc_url, CommitmentConfig::confirmed());
let program_id = Pubkey::from_str("6a2GdmttJdanBkoHt7f4Kon4hfadx4UTUgJeRkCaiL3U").unwrap();
let accounts = connection.get_program_accounts(&program_id).unwrap();
println!("accounts for {}, {:?}", program_id, accounts);
}
curl https://api.devnet.solana.com -X POST -H "Content-Type: application/json" -d '
{"jsonrpc":"2.0", "id":1, "method":"getProgramAccounts", "params":["6a2GdmttJdanBkoHt7f4Kon4hfadx4UTUgJeRkCaiL3U"]}
'
# Output
# {"jsonrpc":"2.0","result":[{"account":{"data":"fe2kiXpgfrjWQjCPX3n5MB339Ayqav75ej","executable":false,"lamports":1064880,"owner":"6a2GdmttJdanBkoHt7f4Kon4hfadx4UTUgJeRkCaiL3U","rentEpoch":228},"pubkey":"9pKBrUtJU9GNmct6T2BQtiKqvubtjS9D2if2bm1P8TQd"},{"account":{"data":"fe2kiXpgfrjVs7hiZJNVFsbJUuhXhFx3pQ","executable":false,"lamports":1064880,"owner":"6a2GdmttJdanBkoHt7f4Kon4hfadx4UTUgJeRkCaiL3U","rentEpoch":229},"pubkey":"5L1rztbopmgGMWPKb2efoGyhGnrBJm6K53Hf9S4nxdHr"}],"id":1}
So schließen Sie Konten
Sie können ein Konto schließen (alle gespeicherten Daten löschen), indem Sie alle SOL. (Weitere Informationen finden Sie unter rent)
Programm
use solana_program::{
account_info::next_account_info, account_info::AccountInfo, entrypoint,
entrypoint::ProgramResult, pubkey::Pubkey,
};
entrypoint!(process_instruction);
fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let source_account_info = next_account_info(account_info_iter)?;
let dest_account_info = next_account_info(account_info_iter)?;
let dest_starting_lamports = dest_account_info.lamports();
**dest_account_info.lamports.borrow_mut() = dest_starting_lamports
.checked_add(source_account_info.lamports())
.unwrap();
**source_account_info.lamports.borrow_mut() = 0;
let mut source_data = source_account_info.data.borrow_mut();
source_data.fill(0);
Ok(())
}
let dest_starting_lamports = dest_account_info.lamports();
**dest_account_info.lamports.borrow_mut() = dest_starting_lamports
.checked_add(source_account_info.lamports())
.unwrap();
**source_account_info.lamports.borrow_mut() = 0;
let mut source_data = source_account_info.data.borrow_mut();
source_data.fill(0);
Client
import {
Keypair,
Connection,
Transaction,
SystemProgram,
TransactionInstruction,
PublicKey,
clusterApiUrl,
LAMPORTS_PER_SOL,
} from "@solana/web3.js";
(async function () {
// connection
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
// setup fee payer
const feePayer = Keypair.generate();
const feePayerAirdropSignature = await connection.requestAirdrop(
feePayer.publicKey,
LAMPORTS_PER_SOL
);
await connection.confirmTransaction(feePayerAirdropSignature);
// remember to deploy your program first
const programId = new PublicKey(
"An47uBJ8kY7hzKPzDyRoFSsDHkZFY9vkfUGpTViWqLFz"
);
// 1. create an account to your program
let newAccount = Keypair.generate();
console.log(`new account: ${newAccount.publicKey.toBase58()}`);
let createNewAccountTx = new Transaction().add(
SystemProgram.createAccount({
fromPubkey: feePayer.publicKey,
newAccountPubkey: newAccount.publicKey,
lamports: 1e8, // 0.1 SOL
space: 10, // a random value
programId: programId,
})
);
console.log(
`create account txhash: ${await connection.sendTransaction(
createNewAccountTx,
[feePayer, newAccount]
)}`
);
// 2. close your account
let closeAccountTx = new Transaction().add(
new TransactionInstruction({
keys: [
{
pubkey: newAccount.publicKey,
isSigner: false,
isWritable: true,
},
{
pubkey: feePayer.publicKey,
isSigner: false,
isWritable: true,
},
],
programId: programId,
})
);
console.log(
`close account txhash: ${await connection.sendTransaction(closeAccountTx, [
feePayer,
])}`
);
})();
// 1. create an account to your program
let createNewAccountTx = new Transaction().add(
SystemProgram.createAccount({
fromPubkey: feePayer.publicKey,
newAccountPubkey: newAccount.publicKey,
lamports: 1e8, // 0.1 SOL
space: 10, // a random value
programId: programId,
})
);
// 2. close your account
let closeAccountTx = new Transaction().add(
new TransactionInstruction({
keys: [
{
pubkey: newAccount.publicKey,
isSigner: false,
isWritable: true,
},
{
pubkey: feePayer.publicKey,
isSigner: false,
isWritable: true,
},
],
programId: programId,
})
);
So erhalten Sie den Kontostand
import {
clusterApiUrl,
Connection,
PublicKey,
LAMPORTS_PER_SOL,
} from "@solana/web3.js";
(async () => {
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
let wallet = new PublicKey("G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY");
console.log(
`${(await connection.getBalance(wallet)) / LAMPORTS_PER_SOL} SOL`
);
})();
console.log(`${(await connection.getBalance(wallet)) / LAMPORTS_PER_SOL} SOL`);
use solana_client::rpc_client::RpcClient;
use solana_program::native_token::LAMPORTS_PER_SOL;
use solana_program::pubkey::Pubkey;
use solana_sdk::commitment_config::CommitmentConfig;
use std::str::FromStr;
fn main() {
let rpc_url = String::from("https://api.devnet.solana.com");
let connection = RpcClient::new_with_commitment(rpc_url, CommitmentConfig::confirmed());
let wallet = Pubkey::from_str("G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY").unwrap();
let balance = connection.get_balance(&wallet).unwrap();
println!(
"The account {}, has {} SOL ",
wallet,
balance / LAMPORTS_PER_SOL
);
}
connection.get_balance(&wallet).unwrap();
from solana.publickey import Keypair
from solana.rpc.api import Client
client = Client("https://api.devnet.solana.com")
key_pair = Keypair()
public_key = key_pair.public_key
print(client.get_balance(public_key))
client = Client("https://api.devnet.solana.com")
key_pair = Keypair()
public_key = key_pair.public_key
client.get_balance(public_key)
TIP
If you want to get a token balance, you will need to know the address of token account. For more information, see Token References