Accounts

システムアカウントの作り方

System Programopen in new windowが所有するアカウントを作成します。Solanaランタイムは、アカウントの所有者に、そのデータへの書き込みアクセスまたはランポートの転送アクセスを許可します。 アカウントを作成するとき、固定バイトストレージ (space) と、家賃をカバーするのに十分なランポートを事前に割り当てる必要があります Rentopen in new windowは、Solana でアカウントを維持するために発生する費用です

Press </> button to view full source
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,
  ]);
})();
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"),
    };
}

アカウント費用の計算方法

Solana でアカウントを維持すると、rentopen in new windowと呼ばれるストレージ コストが発生します。 口座は、少なくとも 2 年分のrentを入金することにより、rentの徴収を完全に免除することができます。 計算には、アカウントに保存する予定のデータの量を考慮が必要です。

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

シード付きアカウントを作成する方法

さまざまなキーペアを作成する代わりに、createAccountWithSeedを使用してアカウントを管理できます。

生成

Press </> button to view full source
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()}`
  );
})();
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);
}

作成

Press </> button to view full source
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,
    ])}`
  );
})();
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"),
    };
}

送信

Press </> button to view full source
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,
    ])}`
  );
})();

TIP

システムプログラムが所有するアカウントのみ、システムプログラム経由で移行できます。

PDA の作成方法

Program derived address(PDA)open in new window は、通常のアドレスと似ていますが、次の違いがあります:

  1. ed25519 曲線上に存在しない(オフカーブである)
  2. 秘密鍵の代わりにプログラムを使用して署名する

Note: アカウントは、プログラムでのみ作成できます。アドレスはクライアント側で作成できます。

TIP

PDA はプログラム ID によって派生しますが、PDA が同じプログラムによって所有されているという意味ではありません。 (例を挙げると、トークン プログラムが所有するアカウントであるトークン アカウントとして PDA を初期化できます)

PDAの生成

findProgramAddress は、シードの最後に余分なバイトを追加します。 255 から 0 まで開始し、オフカーブの最初の公開鍵を返します。 同じプログラム ID とシードを渡すと、常に同じ結果が得られます。

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);
}

Create a PDA

以下は、プログラムが所有する PDA アカウントを作成するためのサンプル プログラムと、クライアントでプログラムを呼び出すためのサンプルです。

Program

以下は、単一の instruction system_instruction::create_accountを示しています。これは、割り当てられた space, rent_lamports の量のPDAを作成します。これは上記と同様に、invoke_signedを使用してPDAで署名されます。

Press </> button to view full source
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(())
}

Client

Press </> button to view full source
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])}`);
})();

PDAで署名する方法

PDA は、プログラム内でのみ署名できます。以下は、PDA で署名し、クライアントでプログラムを呼び出すプログラムの例です。

Program

以下は、シード escrowによって派生した PDA から渡されたアカウントに SOL を転送する単一の instruction を示しています。 invoke_signedは、PDA での署名に使用されます。

Press </> button to view full source
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(())
}

Client

Press </> button to view full source
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])}`);
})();

program accountの取得方法

programが所有するすべてのアカウントを返します。getProgramAccountsとその構成の詳細については、guides sectionを参照してください。

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}

accountの閉鎖

すべての SOL を削除することで、アカウントを閉じる(すべての保存データを消去する)ことができます。(詳細については、rentopen in new windowを参照してください)

Program

Press </> button to view full source
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(())
}

Client

Press </> button to view full source
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 newAccountKeypair = Keypair.generate();
  console.log(`new account: ${newAccountKeypair.publicKey.toBase58()}`);

  let createNewAccountTx = new Transaction().add(
    SystemProgram.createAccount({
      fromPubkey: feePayer.publicKey,
      newAccountPubkey: newAccountKeypair.publicKey,
      lamports: 1e8, // 0.1 SOL
      space: 10, // a random value
      programId: programId,
    })
  );
  console.log(
    `create account txhash: ${await connection.sendTransaction(
      createNewAccountTx,
      [feePayer, newAccountKeypair]
    )}`
  );

  // 2. close your account
  let closeAccountTx = new Transaction().add(
    new TransactionInstruction({
      keys: [
        {
          pubkey: newAccountKeypair.publicKey,
          isSigner: false,
          isWritable: true,
        },
        {
          pubkey: feePayer.publicKey,
          isSigner: false,
          isWritable: true,
        },
      ],
      programId: programId,
    })
  );
  console.log(
    `close account txhash: ${await connection.sendTransaction(closeAccountTx, [
      feePayer,
    ])}`
  );
})();

accountの残高を取得する方法

Press </> button to view full source
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`
  );
})();
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
    );
}
from solders.keypair import Keypair
from solana.rpc.api import Client

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

key_pair = Keypair()
public_key = key_pair.pubkey()

print(client.get_balance(public_key))
// clang++ get_balance.cpp -o get_balance -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();

  auto public_key = key_pair.public_key;
  std::cout << "public_key = " << public_key.to_base58() << std::endl;

  uint64_t balance = connection.get_balance(public_key).unwrap();
  std::cout << "balance = " << balance << std::endl;

  return 0;
}

TIP

トークンの残高を取得したい場合は、トークンアカウントのアドレスを知る必要があります。詳細については、Token Referencesを参照してください。

Last Updated:
Contributors: PokoPoko2ry