Sending Transactions

วิธี send SOL

การที่เราจะส่ง SOL ได้นั้นเราต้องใช้ SystemProgramopen in new window.

Press </> button to view full source
const transferTransaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: fromKeypair.publicKey,
    toPubkey: toKeypair.publicKey,
    lamports: lamportsToSend,
  })
);

await sendAndConfirmTransaction(connection, transferTransaction, [fromKeypair]);
transaction = Transaction().add(transfer(TransferParams(
    from_pubkey=sender.pubkey(),
    to_pubkey=receiver.pubkey(),
    lamports=1_000_000)
))

client.send_transaction(transaction, sender)

const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: publicKey,
    toPubkey: Keypair.generate().publicKey,
    lamports: 1_000_000,
  })
);

const signature = await sendTransaction(transaction, connection);

await connection.confirmTransaction(signature, "processed");
system_instruction::transfer(&from, &to, lamports_to_send);
solana transfer --from <KEYPAIR> <RECIPIENT_ACCOUNT_ADDRESS> 0.001 --allow-unfunded-recipient --url https://api.devnet.solana.com --fee-payer <KEYPAIR>

วิธี send SPL-Tokens

ใช้ Token Programopen in new window เพื่อส่ง SPL Tokens ในการที่จะส่ง SPL token, เราต้องรู้ SPL token account address เราสามารถหา address และส่ง tokens ได้ด้วยตัวอย่างต่อไปนี้

Press </> button to view full source
// Add token transfer instructions to transaction
const transaction = new web3.Transaction().add(
  splToken.Token.createTransferInstruction(
    splToken.TOKEN_PROGRAM_ID,
    fromTokenAccount.address,
    toTokenAccount.address,
    fromWallet.publicKey,
    [],
    1
  )
);

// Sign transaction, broadcast, and confirm
await web3.sendAndConfirmTransaction(connection, transaction, [fromWallet]);
const transaction = new Transaction().add(
  Token.createTransferInstruction(
    TOKEN_PROGRAM_ID,
    fromTokenAccount.address,
    toTokenAccount.address,
    fromWallet.publicKey,
    [],
    1
  )
);

const signature = await sendTransaction(transaction, connection);

await connection.confirmTransaction(signature, "processed");
$ spl-token transfer AQoKYV7tYpTrFZN6P5oUufbQKAUr9mNYGe1TTJC9wajM 50 vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg
Transfer 50 tokens
  Sender: 7UX2i7SucgLMQcfZ75s3VXmZZY4YRUyJN9X1RgfMoDUi
  Recipient: vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg
  Recipient associated token account: F59618aQB8r6asXeMcB9jWuY6NEx1VduT9yFo1GTi1ks

Signature: 5a3qbvoJQnTAxGPHCugibZTbSu7xuTgkxvF4EJupRjRXGgZZrnWFmKzfEzcqKF2ogCaF4QKVbAtuFx7xGwrDUcGd

วิธีคำนวณหา transaction cost

จำนวนของ signatures จะเอาไว้ใช้คำนวณค่าใช้จ่าย transaction cost ถ้าไม่ได้มีการสร้าง account ก็จะมี transaction cost ตามนั้นเลย แต่ถ้าจะหาค่าใช้จ่ายสำหรับการสร้าง account ด้วยให้ลองไปดูที่ การคำนวณ rent exemption

ตัวอย่าง 2 ตัวข้างล่างจะแสดงให้เห็นวิธีที่ใช้คำนวณ transaction cost ที่เป็นไปได้ทั้ง 2 แบบ

ตัวอย่างแรกจะใช้ getEstimatedFee ที่เป็น method ใหม่ของ class Transaction และตัวอย่างที่สองจะใช้ getFeeForMessage ที่มาแทนที่ getFeeCalculatorForBlockhash ใน class Connection

getEstimatedFee

Press </> button to view full source
const recentBlockhash = await connection.getLatestBlockhash();

const transaction = new Transaction({
  recentBlockhash: recentBlockhash.blockhash,
}).add(
  SystemProgram.transfer({
    fromPubkey: payer.publicKey,
    toPubkey: payee.publicKey,
    lamports: 10,
  })
);

const fees = await transaction.getEstimatedFee(connection);
console.log(`Estimated SOL transfer cost: ${fees} lamports`);
// Estimated SOL transfer cost: 5000 lamports

getFeeForMessage

Press </> button to view full source
const message = new Message(messageParams);

const fees = await connection.getFeeForMessage(message);
console.log(`Estimated SOL transfer cost: ${fees.value} lamports`);
// Estimated SOL transfer cost: 5000 lamports

วิธีเพิ่ม memo ใน transaction

transaction ใดๆ สามารถเพิ่ม message โดยใช้ memo programopen in new window. ในตอนนี้ programID จาก Memo Program ต้องเพิ่มเองด้วย address นี้ MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr.

Press </> button to view full source
const transferTransaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: fromKeypair.publicKey,
    toPubkey: toKeypair.publicKey,
    lamports: lamportsToSend,
  })
);

await transferTransaction.add(
  new TransactionInstruction({
    keys: [{ pubkey: fromKeypair.publicKey, isSigner: true, isWritable: true }],
    data: Buffer.from("Data to send in transaction", "utf-8"),
    programId: new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),
  })
);

await sendAndConfirmTransaction(connection, transferTransaction, [fromKeypair]);
const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: publicKey,
    toPubkey: Keypair.generate().publicKey,
    lamports: 10,
  })
);

await transaction.add(
  new TransactionInstruction({
    keys: [{ pubkey: publicKey, isSigner: true, isWritable: true }],
    data: Buffer.from("Data to send in transaction", "utf-8"),
    programId: new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),
  })
);

const signature = await sendTransaction(transaction, connection);

await connection.confirmTransaction(signature, "processed");
solana transfer --from <KEYPAIR> <RECIPIENT_ACCOUNT_ADDRESS> 0.5 --allow-unfunded-recipient --url https://api.devnet.solana.com --fee-payer <KEYPAIR> --with-memo <MEMO>

วิธีเปลี่ยน compute budget สำหรับ transaction

Compute budget สำหรับหนึ่ง transaction สามารถเปลี่ยนได้โดยการเพิ่ม instruction ด้วยการเรียกไปที่ Compute Budget Program โดยปกติแล้ว compute budget คือค่าของ 200k compute units * จำนวน instructions, ด้วยค่าสูงสุดที่ 1.4M compute units ถ้าเราใช้ compute น้อยเราก็จะจ่าย transaction costs น้อยลงไปด้วย

Note: การที่จะเปลี่ยน compute budget สำหรับ transaction คุณต้องไปทำที่ หนึ่งในสามคำสั่งแรกของ instruction ใน transaction ตรง instruction ที่เอาไว้เปลี่ยนค่า budget

Press </> button to view full source
const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({ 
  units: 1000000 
});

const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ 
  microLamports: 1 
});

const transaction = new Transaction()
.add(modifyComputeUnits)
.add(addPriorityFee)
.add(
    SystemProgram.transfer({
      fromPubkey: payer.publicKey,
      toPubkey: toAccount,
      lamports: 10000000,
    })
  );
let txn = submit_transaction(
  &connection,
  &wallet_signer,
  // Array of instructions: 0: Set Compute Unit Limt, 1: Set Prioritization Fee, 
  // 2: Do something, 3: Do something else
  [ComputeBudgetInstruction::set_compute_unit_limit(1_000_000u32),
  ComputeBudgetInstruction::set_compute_unit_price(1u32),
  Instruction::new_with_borsh(PROG_KEY, &0u8, accounts.to_vec()),
  Instruction::new_with_borsh(PROG_KEY, &0u8, accounts.to_vec())].to_vec(),
)?;

ตัวอย่าง Program Logs:

[ 1] Program ComputeBudget111111111111111111111111111111 invoke [1]
[ 2] Program ComputeBudget111111111111111111111111111111 success
[ 3]
[ 4] Program ComputeBudget111111111111111111111111111111 invoke [1]
[ 5] Program ComputeBudget111111111111111111111111111111 success
Last Updated: 8/18/2022, 1:52:33 AM
Contributors: Todsaporn Banjerdkit