Programda saat almak
Bir saat almak (yani, mevcut zamanı) iki şekilde yapılabilir:
SYSVAR_CLOCK_PUBKEY
'i bir komuta geçirmek- Komut içinde Clock'a doğrudan erişmek.
Her iki yöntemi de bilmek güzel, çünkü bazı eski programlar hala SYSVAR_CLOCK_PUBKEY
'i bir hesap olarak bekliyor.
Komut içinde bir hesap olarak saat geçirme
Başlatma için bir hesap ve sysvar pubkey alan bir komut oluşturalım.
use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
account_info::{next_account_info, AccountInfo},
clock::Clock,
entrypoint,
entrypoint::ProgramResult,
msg,
pubkey::Pubkey,
sysvar::Sysvar,
};
entrypoint!(process_instruction);
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct HelloState {
is_initialized: bool,
}
// Gereken hesaplar
/// 1. [imzalayıcı, yazılabilir] Ödeyici
/// 2. [yazılabilir] Merhaba durumu hesabı
/// 3. [] Saat sys var
pub fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
let accounts_iter = &mut accounts.iter();
// Ödeyici hesabı
let _payer_account = next_account_info(accounts_iter)?;
// Merhaba durumu hesabı
let hello_state_account = next_account_info(accounts_iter)?;
// Saat sysvar
let sysvar_clock_pubkey = next_account_info(accounts_iter)?;
let mut hello_state = HelloState::try_from_slice(&hello_state_account.data.borrow())?;
hello_state.is_initialized = true;
hello_state.serialize(&mut &mut hello_state_account.data.borrow_mut()[..])?;
msg!("Hesap başlatıldı :)");
// [AccountInfo] türünü [Clock] olarak dönüştürme
let clock = Clock::from_account_info(&sysvar_clock_pubkey)?;
// Zaman damgasını alma
let current_timestamp = clock.unix_timestamp;
msg!("Güncel Zaman Damgası: {}", current_timestamp);
Ok(())
}
ipucu
Şimdi saatin sysvar genel adresini istemci aracılığıyla geçiyoruz.
import {
clusterApiUrl,
Connection,
Keypair,
LAMPORTS_PER_SOL,
PublicKey,
SystemProgram,
SYSVAR_CLOCK_PUBKEY,
Transaction,
TransactionInstruction,
sendAndConfirmTransaction,
} from "@solana/web3.js";
(async () => {
const programId = new PublicKey(
"77ezihTV6mTh2Uf3ggwbYF2NyGJJ5HHah1GrdowWJVD3",
);
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const latestBlockHash = await connection.getLatestBlockhash();
// 1 SOL ödünç verme
const feePayer = Keypair.generate();
await connection.confirmTransaction(
{
blockhash: latestBlockHash.blockhash,
lastValidBlockHeight: latestBlockHash.lastValidBlockHeight,
signature: await connection.requestAirdrop(
feePayer.publicKey,
LAMPORTS_PER_SOL,
),
},
"confirmed",
);
// Merhaba durumu hesabı
const helloAccount = Keypair.generate();
const accountSpace = 1; // çünkü sadece bir boolean değişken vardır
const rentRequired =
await connection.getMinimumBalanceForRentExemption(accountSpace);
// Merhaba durumu hesabı için alan tahsis etme
const allocateHelloAccountIx = SystemProgram.createAccount({
fromPubkey: feePayer.publicKey,
lamports: rentRequired,
newAccountPubkey: helloAccount.publicKey,
programId: programId,
space: accountSpace,
});
// Saat Sys Var'ı geçirme
const passClockIx = new TransactionInstruction({
programId: programId,
keys: [
{
isSigner: true,
isWritable: true,
pubkey: feePayer.publicKey,
},
{
isSigner: false,
isWritable: true,
pubkey: helloAccount.publicKey,
},
{
isSigner: false,
isWritable: false,
pubkey: SYSVAR_CLOCK_PUBKEY,
},
],
});
const transaction = new Transaction();
transaction.add(allocateHelloAccountIx, passClockIx);
const txHash = await sendAndConfirmTransaction(connection, transaction, [
feePayer,
helloAccount,
]);
console.log(`İşlem başarılı. TxHash: ${txHash}`);
})();
Saat'e doğrudan erişim
Aynı komutu oluşturalım, ancak istemci tarafından SYSVAR_CLOCK_PUBKEY
beklemeyelim.
use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
account_info::{next_account_info, AccountInfo},
clock::Clock,
entrypoint,
entrypoint::ProgramResult,
msg,
pubkey::Pubkey,
sysvar::Sysvar,
};
entrypoint!(process_instruction);
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct HelloState {
is_initialized: bool,
}
// Gereken hesaplar
/// 1. [imzalayıcı, yazılabilir] Ödeyici
/// 2. [yazılabilir] Merhaba durumu hesabı
pub fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
let accounts_iter = &mut accounts.iter();
// Ödeyici hesabı
let _payer_account = next_account_info(accounts_iter)?;
// Merhaba durumu hesabı
let hello_state_account = next_account_info(accounts_iter)?;
// Saat'e doğrudan erişim
let clock = Clock::get()?;
let mut hello_state = HelloState::try_from_slice(&hello_state_account.data.borrow())?;
hello_state.is_initialized = true;
hello_state.serialize(&mut &mut hello_state_account.data.borrow_mut()[..])?;
msg!("Hesap başlatıldı :)");
// Zaman damgasını alma
let current_timestamp = clock.unix_timestamp;
msg!("Güncel Zaman Damgası: {}", current_timestamp);
Ok(())
}
bilgi
İstemci tarafındaki komut, artık sadece durumu ve ödeyici hesaplarını geçmesi gerekiyor.
import {
clusterApiUrl,
Connection,
Keypair,
LAMPORTS_PER_SOL,
PublicKey,
SystemProgram,
Transaction,
TransactionInstruction,
} from "@solana/web3.js";
(async () => {
const programId = new PublicKey(
"4ZEdbCtb5UyCSiAMHV5eSHfyjq3QwbG3yXb6oHD7RYjk",
);
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const latestBlockHash = await connection.getLatestBlockhash();
// 1 SOL ödünç verme
const feePayer = Keypair.generate();
await connection.confirmTransaction(
{
blockhash: latestBlockHash.blockhash,
lastValidBlockHeight: latestBlockHash.lastValidBlockHeight,
signature: await connection.requestAirdrop(
feePayer.publicKey,
LAMPORTS_PER_SOL,
),
},
"confirmed",
);
// Merhaba durumu hesabı
const helloAccount = Keypair.generate();
const accountSpace = 1; // çünkü sadece bir boolean değişken vardır
const rentRequired =
await connection.getMinimumBalanceForRentExemption(accountSpace);
// Merhaba durumu hesabı için alan tahsis etme
const allocateHelloAccountIx = SystemProgram.createAccount({
fromPubkey: feePayer.publicKey,
lamports: rentRequired,
newAccountPubkey: helloAccount.publicKey,
programId: programId,
space: accountSpace,
});
const initIx = new TransactionInstruction({
programId: programId,
keys: [
{
isSigner: true,
isWritable: true,
pubkey: feePayer.publicKey,
},
{
isSigner: false,
isWritable: true,
pubkey: helloAccount.publicKey,
},
],
});
const transaction = new Transaction();
transaction.add(allocateHelloAccountIx, initIx);
const txHash = await sendAndConfirmTransaction(connection, transaction, [
feePayer,
helloAccount,
]);
console.log(`İşlem başarılı. TxHash: ${txHash}`);
})();