Sending Transactions — Web3

Sending Transactions Menulis data ke blockchain membutuhkan transaksi. Transaksi harus di-sign oleh private key, dikirim ke network, dan ditunggu sampai…

Sending Transactions

Menulis data ke blockchain membutuhkan transaksi. Transaksi harus di-sign oleh private key, dikirim ke network, dan ditunggu sampai di-mine ke dalam block.

Anatomy of a Transaction

// Setiap transaksi berisi:
{
  from: "0xYourAddress",     // Pengirim (signer)
  to: "0xRecipient",         // Tujuan (address / contract)
  value: "1000000000000000", // ETH dalam wei (0.001 ETH)
  data: "0x...",             // Encoded function call (untuk contract)
  gasLimit: 21000,           // Maksimal gas yang dipakai
  maxFeePerGas: "20000000000",      // Max fee per gas (EIP-1559)
  maxPriorityFeePerGas: "2000000000", // Tip untuk validator
  nonce: 42,                 // Transaction counter (anti-replay)
  chainId: 1,               // Network ID (1 = mainnet)
}

Kirim ETH (ethers.js)

async function sendETH() {
  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();

  const tx = await signer.sendTransaction({
    to: "0xRecipientAddress...",
    value: ethers.parseEther("0.01"), // 0.01 ETH
  });

  console.log("TX Hash:", tx.hash);
  // "0xabc123..." — transaksi sudah dikirim, belum tentu sukses

  // Tunggu transaksi di-mine (1 confirmation)
  const receipt = await tx.wait();
  console.log("Confirmed in block:", receipt.blockNumber);
  console.log("Gas used:", receipt.gasUsed.toString());
  console.log("Status:", receipt.status); // 1 = success, 0 = reverted
}

Panggil Contract Function

// Write function (butuh gas, butuh signer)
async function approveToken() {
  const contract = new ethers.Contract(tokenAddress, abi, signer);

  // Approve Uniswap untuk spend 1000 token
  const tx = await contract.approve(
    uniswapRouter,
    ethers.parseUnits("1000", 18)
  );

  // Tunggu konfirmasi
  const receipt = await tx.wait();

  if (receipt.status === 1) {
    console.log("Approve berhasil!");
  } else {
    console.log("Transaksi gagal (reverted)");
  }
}

Estimasi Gas

// Estimasi gas sebelum kirim (agar user tahu biaya)
const gasEstimate = await contract.approve.estimateGas(
  spenderAddress,
  ethers.parseUnits("1000", 18)
);
console.log("Estimated gas:", gasEstimate.toString());

// Harga gas saat ini
const feeData = await provider.getFeeData();
console.log("Gas price:", ethers.formatUnits(feeData.gasPrice, "gwei"), "gwei");

Error Handling

try {
  const tx = await contract.transfer(to, amount);
  await tx.wait();
} catch (error) {
  if (error.code === "ACTION_REJECTED") {
    console.log("User rejected di MetaMask");
  } else if (error.code === "INSUFFICIENT_FUNDS") {
    console.log("Saldo ETH tidak cukup untuk gas");
  } else if (error.reason) {
    // Revert reason dari smart contract
    console.log("Contract error:", error.reason);
  }
}

Transaction Lifecycle

  1. Build — Buat object transaksi
  2. Sign — User sign di wallet (MetaMask popup)
  3. Broadcast — Kirim ke mempool (pending)
  4. Mine — Validator masukkan ke block
  5. Confirm — Tunggu N block untuk finality

Yang akan kamu pelajari