Sem 7

MetaMask, Transactions and Sepolia

Lab decks 6, 7 and 8: setting up a MetaMask wallet, enabling test networks, Etherscan, getting Sepolia ETH from a faucet, sending a transaction and reading its gas fee, then querying Sepolia through an Alchemy RPC endpoint with raw JSON-RPC calls from PowerShell.

Setting up the wallet (MetaMask)Search on YouTube

MetaMask is a browser-extension (and mobile) wallet for Ethereum and other chains. It holds your keys, shows balances and signs transactions. The deck walks through setup with screenshots:

  1. Go to metamask.io and click Get MetaMask.
  2. Choose Browser Extension and your browser (Chrome, Firefox, Brave; the deck uses Microsoft Edge with the Chrome Web Store).
  3. Click Get, then Add extension. Edge warns the extension can read and change data on all websites, display notifications, and modify copied and pasted data.
  4. Choose Create a new wallet (the other option is "I have an existing wallet").
  5. Pick Use Secret Recovery Phrase (instead of Continue with Google, Apple or Telegram).
  6. Create a MetaMask password (at least 8 characters). Tick "If I lose this password, MetaMask can't reset it". The password unlocks MetaMask on this device only.
  7. Save your Secret Recovery Phrase: tap to reveal the 12 words, write them down in order, keep them safe. Make sure no one is watching your screen.
  8. Confirm your Secret Recovery Phrase by filling the missing words in the right order. MetaMask shows "Perfect. Never share this phrase with anyone, ever."
  9. On "Help improve MetaMask", untick "Gather basic usage data" and "Product updates" if you want, then Continue.
  10. "Your wallet is ready!": click Open wallet. Pin the extension to the toolbar.

The password only unlocks the wallet on one device. The Secret Recovery Phrase (seed phrase) is the wallet. Anyone with it controls all your accounts. MetaMask cannot reset either one.

The wallet opens on Account 1 with an address like 0xc32BB...4A2B7. The home screen shows "Fund your wallet", buttons Buy, Swap, Send, Receive, and tabs Tokens, Perps, DeFi, NFTs, Activity.

Enabling test networksSearch on YouTube

  1. Open the menu (three lines). You can also choose Open full screen.
  2. Go to Networks (Manage networks).
  3. Turn on Show test networks. Sepolia, Linea Sepolia, MegaETH Testnet and Monad Testnet appear.
  4. In the network selector, choose Sepolia under Testnets.

Block explorer (Etherscan)Search on YouTube

A block explorer is a website that shows blocks, transactions and addresses of a chain. etherscan.io is the Ethereum mainnet explorer. Its home page shows ETH price, market cap, transaction count, gas price, last finalised block, latest blocks and latest transactions.

Search your wallet address. A new address shows ETH balance 0, no transactions sent, and "There are no matching entries".

For the testnet use https://sepolia.etherscan.io/.

Making your first transactionSearch on YouTube

Two types of testnetsSearch on YouTube

Public testnetsSimulated testnets
Like SepoliaProvided by service providers like Tenderly
Need volunteers to run the blockchainEasy to set up, instant faucets
Transactions work the same as on public testnets
No volunteers needed; the provider manages the chain

Getting Sepolia ETH from a faucetSearch on YouTube

A faucet gives free test ETH. The lab uses the Google Cloud Web3 faucet:

https://cloud.google.com/application/web3/faucet/ethereum/sepolia
  1. Select network Ethereum Sepolia.
  2. Paste the wallet address (the "Ironman" account in the deck).
  3. Click Get 0.05 Sepolia ETH. The tokens are queued, then "Transaction complete! Check your wallet address" shows the recipient and transaction hash.
  4. Check the wallet: with Sepolia selected, it shows 0.0500 SepoliaETH.
  5. Check the address on sepolia.etherscan.io: balance 0.05 ETH and one incoming transaction.

Sending ETH between accountsSearch on YouTube

The deck sends 0.01 SepoliaETH from account "Ironman" to account "Spiderman":

  1. Click Send, choose the recipient, enter 0.01.
  2. The review screen shows From, To and Network (Sepolia). It also shows Network fee (about 0.0001 SepoliaETH), Speed (Market, about 12 sec), Max fee and Nonce 0 (the sender's first transaction).
  3. Confirm. Spiderman's wallet now shows 0.0100 SepoliaETH.
  4. On Etherscan, Ironman's address lists two transactions: the faucet deposit (IN) and the transfer (OUT).

Gas feeSearch on YouTube

Open the transaction on Etherscan. The deck highlights these fields:

FieldValue in the lab
Value0.01 ETH
Transaction feesmall amount in ETH (gas used times gas price)
Gas limit and usage by txn21,000 used (66.67% of the limit)
Gas feesBase, Max (about 2.97 Gwei) and Max Priority (1.5 Gwei)
Burnt and txn savingspart of the fee is burnt; unused max fee is saved

Transaction fee=gas used×effective gas price\text{Transaction fee} = \text{gas used} \times \text{effective gas price}

A plain ETH transfer always uses 21,000 gas. Here the limit was 31,500 (0x7b0c), so 21,000 is 66.67% of it. Gas is priced in Gwei: 1 Gwei=1091\ \text{Gwei} = 10^9 Wei and 1 ETH=10181\ \text{ETH} = 10^{18} Wei.

Interacting with the Sepolia testnetSearch on YouTube

Prerequisites: a MetaMask wallet, funds from a faucet, one transaction between accounts, and that transaction viewed on Etherscan.

How an application talks to a public chainSearch on YouTube

Your application (with a wallet address field and an "Explore" button) cannot talk to the Ethereum Sepolia network directly. It sends an HTTP request (or a WebSocket message) to an RPC infrastructure provider. The provider runs nodes on the network.

Your application ──HTTP POST (JSON-RPC request)──▶ Alchemy node (RPC) ──▶ Sepolia public testnet
 (PowerShell:
  Invoke-RestMethod / Invoke-WebRequest)

Getting a Sepolia RPC URLSearch on YouTube

Get one free from Alchemy:

  1. Sign in at alchemy.com.
  2. Create an app (the deck's is "Jaiganesh's First App").
  3. Open Endpoints. Under Ethereum, copy the Ethereum Sepolia HTTPS URL, of the form https://eth-sepolia.g.alchemy.com/v2/<API_KEY>.
  4. App Settings has Rotate API key if the key leaks. The old key stops working shortly after rotation.

The API key is part of the URL. Treat the RPC URL as a secret; the deck blurs it in every screenshot.

JSON-RPC methods usedSearch on YouTube

1. Network / blockchain information

RPC methodWhat it gives
eth_chainIdChain ID
eth_blockNumberLatest block number
eth_getBlockByNumberDetails of a block
eth_getBlockByHashBlock using its hash
eth_gasPriceCurrent gas price
eth_getBlockTransactionCountByNumberNumber of transactions in a block

2. Account information

RPC methodWhat it gives
eth_getBalanceETH balance
eth_getTransactionCountNumber of transactions / nonce
eth_getCodeWhether an address contains contract code
eth_getStorageAtRead contract storage

3. Transaction information

  • eth_getTransactionByHash returns the sender, receiver, value, gas, nonce, transaction data and block information.
  • eth_getTransactionReceipt tells whether the transaction was successfully included. It gives status, gas used, block number and transaction logs.

4. Sending transactions: eth_sendRawTransaction.

Four groups of RPC calls: "Never Ask Twice, Send": Network, Account, Transaction, Send.

JSON-RPC structureSearch on YouTube

{"jsonrpc":"2.0","method":"SOME_METHOD_NAME","params":[...],"id":1}
KeyMeaning
jsonrpc: "2.0"Says "I am speaking JSON-RPC version 2.0"
methodWhat you are asking it to do (get balance, send transaction, get block and dozens more)
paramsArguments for that method (empty for eth_chainId; the wallet address for eth_getBalance)
idA request label, so you can match responses to requests when you send several

The deck works directly in PowerShell to understand the logic. Invoke-RestMethod sends HTTP/HTTPS requests to REST APIs and parses the JSON response into PowerShell objects.

Network queriesSearch on YouTube

eth_chainIdSearch on YouTube

$RPC_URL="YOUR_SEPOLIA_RPC_URL"

$body = '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'

Invoke-RestMethod `
    -Uri $RPC_URL `
    -Method Post `
    -ContentType "application/json" `
    -Body $body
PartRole
-Uri (the RPC_URL variable)Where to send the request; the variable is only for convenience
-Method PostUse the HTTP POST method
-ContentType "application/json"The content sent is JSON
-Body (the body variable)The data to send
` (backtick)PowerShell line continuation

Result: 0xaa36a7. In decimal that is 11155111, the Sepolia chain ID.

The same call with curl on Linux:

curl -s -X POST "$RPC_URL" -H "Content-Type: application/json" \
     -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'

eth_blockNumberSearch on YouTube

$body = '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":2}'

Result 0xb13404. Convert hex to decimal in PowerShell:

[Convert]::ToInt64("B13404", 16)     # 11613188

Every number in Ethereum JSON-RPC is a hex string with 0x. Convert it before reading it.

eth_getBlockByNumberSearch on YouTube

$body = '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0xb13404",false],"id":4}'

The second parameter: false returns only transaction hashes, true returns full transaction objects. By default Invoke-RestMethod truncates long JSON output. Expand it:

$body = '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0xb13404",true],"id":4}'
$response = Invoke-RestMethod -Uri $RPC_URL -Method Post -ContentType "application/json" -Body $body
$response | ConvertTo-Json -Depth 5

The block shows hash, parentHash, sha3Uncles, miner, stateRoot, transactionsRoot, receiptsRoot, logsBloom, difficulty (0x0 after the move to Proof of Stake), number, gasLimit, gasUsed and timestamp.

eth_getBlockByHashSearch on YouTube

$BLOCK_HASH="0x...4db87e"
$body = "{`"jsonrpc`":`"2.0`",`"method`":`"eth_getBlockByHash`",`"params`":[`"$BLOCK_HASH`",false],`"id`":5}"

The body is in double quotes so $BLOCK_HASH expands. Inner quotes are escaped with a backtick.

eth_gasPriceSearch on YouTube

$body = '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":6}'

Result 0x3ea60403. The value is in Wei. 1 ETH = 1,000,000,000,000,000,000 Wei (101810^{18}).

eth_getBlockTransactionCountByNumberSearch on YouTube

$body = '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByNumber","params":["0xb12F70"],"id":7}'

Result 0x61 = 97 transactions in block 11612016. Etherscan shows the same "97 transactions" for that block.

Account queriesSearch on YouTube

eth_getBalanceSearch on YouTube

$ADDRESS="0x...2B7"
$body = '{"jsonrpc":"2.0","method":"eth_getBalance","params":["' + $ADDRESS + '","latest"],"id":8}'
$result = Invoke-RestMethod -Uri $RPC_URL -Method Post -ContentType "application/json" -Body $body
$result

"latest" is the block tag: the balance at the newest block. Result 0x8deb4b5219eda0 Wei. Make it readable:

Write-Host "Address: $ADDRESS"
Write-Host "Balance (Wei): $($result.result)"
$balanceWei = [System.Numerics.BigInteger]::Parse(
    $result.result.Substring(2),
    [System.Globalization.NumberStyles]::AllowHexSpecifier
)
Write-Host "Balance (ETH): $([double]$balanceWei / 1e18)"

Substring(2) strips the 0x. Divide by 1e18 to get ETH. MetaMask shows 0.0399 SepoliaETH.

In the deck's screenshot the ETH line prints a negative number. BigInteger.Parse with AllowHexSpecifier treats a leading hex digit of 8 to F as a sign bit. Prefix a "0" ("0" + $result.result.Substring(2)) to always get a positive value.

eth_getTransactionCountSearch on YouTube

$body = '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["' + $ADDRESS + '","latest"],"id":9}'

Result 0x1: Ironman has sent one transaction, so its next nonce is 1. Received transactions do not count.

eth_getCodeSearch on YouTube

$body = '{"jsonrpc":"2.0","method":"eth_getCode","params":["' + $ADDRESS + '","latest"],"id":10}'

Result 0x. 0x means no contract bytecode exists at that address.

EOA (Externally Owned Account)Contract account
A normal walletCreated when a contract is deployed (by a deployment transaction)
Controlled by a private key (MetaMask, your seed phrase)Has bytecode stored at the address: compiled program logic
Has no code: only a balance and a nonceHas no private key; controlled entirely by its code
What you created when you generated a wallet address

eth_getStorageAtSearch on YouTube

Needs a deployed smart contract, so the deck leaves it for later. Reference snippet:

$CONTRACT="0xYOUR_CONTRACT_ADDRESS"
$SLOT="0x0"
$body = '{"jsonrpc":"2.0","method":"eth_getStorageAt","params":["' + $CONTRACT + '","' + $SLOT + '","latest"],"id":11}'
$result = Invoke-RestMethod -Uri $RPC_URL -Method Post -ContentType "application/json" -Body $body
$result

Transaction queriesSearch on YouTube

eth_getTransactionByHashSearch on YouTube

The Ironman to Spiderman transaction:

$TX_HASH="0x50e5f5f7f696bbe1eabf95cd5c903a226ff7f4857840a4d69a19a62755da79a3"
$body = '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["' + $TX_HASH + '"],"id":12}'
$result = Invoke-RestMethod -Uri $RPC_URL -Method Post -ContentType "application/json" -Body $body
$result

Result fields (hex) include: type 0x2, chainId 0xaa36a7 (11155111), nonce 0x0, gas 0x7b0c (31500), maxFeePerGas 0xb1034988 (2969782664 Wei), maxPriorityFeePerGas 0x59682f00, to, value 0x2386f26fc10000 (0.01 ETH). Then come accessList, input 0x, signature r, s, yParity, v, hash, blockHash, blockNumber 0xb12f70, transactionIndex 0x3, from, gasPrice.

Invoke-WebRequest returns the raw response instead of parsed objects:

$response = Invoke-WebRequest -Uri $RPC_URL -Method Post -ContentType "application/json" -Body $body
$response.Content

PowerShell shows "Security Warning: Script Execution Risk" because it parses the page. Answer Y, or add -UseBasicParsing. Pretty-print with an online JSON parser, or:

$response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 10

eth_getTransactionReceiptSearch on YouTube

Gives the execution result (receipt) after the transaction is included in a block.

$body = '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["' + $TX_HASH + '"],"id":13}'
$response = Invoke-WebRequest -Uri $RPC_URL -Method Post -ContentType "application/json" -Body $body
$response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 10

In the lab: type 0x2, status 0x1, gasUsed 0x5208 (21000), contractAddress null.

FieldMeaning
typeTransaction type; 0x2 = EIP-1559
status0x1 = success, 0x0 = reverted/failed
transactionHashUnique transaction identifier
transactionIndexPosition of the transaction inside the block
blockHashHash of the containing block
blockNumberNumber of the containing block
fromTransaction sender
toTransaction recipient
gasUsedGas actually consumed
effectiveGasPriceGas price actually applied
cumulativeGasUsedTotal gas used by transactions up to this one in the block
logsEvents emitted during execution
logsBloomBloom filter for the logs
contractAddressAddress of a newly deployed contract; null for normal transactions

Reference: "JSON-RPC API" on ethereum.org.

What to do and check in the lab:

  1. Install MetaMask, create a wallet, store the 12-word phrase offline, enable test networks and select Sepolia.
  2. Claim 0.05 Sepolia ETH from the Google Cloud faucet and confirm it in MetaMask and on sepolia.etherscan.io.
  3. Create a second account and send 0.01 SepoliaETH to it. Note the nonce (0) and the gas used (21,000) on Etherscan.
  4. Create an Alchemy app and copy the Sepolia HTTPS endpoint.
  5. In PowerShell call eth_chainId (expect 0xaa36a7 = 11155111), eth_blockNumber, eth_gasPrice, eth_getBalance, eth_getTransactionCount and eth_getCode (expect 0x).
  6. Fetch your transfer with eth_getTransactionByHash and eth_getTransactionReceipt; read status and gasUsed.

Quick self-testSearch on YouTube

Viva: what is the difference between the MetaMask password and the Secret Recovery Phrase?

The password only unlocks MetaMask on one device. The 12-word Secret Recovery Phrase regenerates the wallet's keys on any device. Anyone with the phrase controls the funds, and MetaMask cannot reset either.

What is a faucet, and which one did the lab use?

A service that gives free test tokens for a testnet. The lab used the Google Cloud Web3 Ethereum Sepolia faucet, which gives 0.05 Sepolia ETH.

Distinguish public and simulated testnets.

Public testnets like Sepolia are run by volunteer nodes. Simulated testnets are provided by services like Tenderly: easy setup, instant faucets, same transaction behaviour, managed by the provider.

How much gas does a plain ETH transfer use, and how is the fee computed?

21,000 gas. Fee = gas used × effective gas price, usually quoted in Gwei (1 Gwei = 10910^9 Wei).

Why does an application need an RPC provider such as Alchemy?

The app cannot join the peer-to-peer network itself. It sends JSON-RPC requests over HTTP or WebSocket to a node run by the provider, which reads from or broadcasts to Sepolia.

Write the JSON-RPC body for the chain ID and give the Sepolia answer.

{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}. The answer is 0xaa36a7, which is 11155111.

What is the purpose of the id field in a JSON-RPC request?

It labels the request so the response with the same id can be matched to it when several requests are sent.

Viva: eth_getCode returns 0x for your address. What does that tell you?

No contract bytecode exists there, so it is an Externally Owned Account controlled by a private key, not a contract account.

What does eth_getTransactionCount return, and how does it relate to the nonce?

The number of transactions sent from the address. It equals the nonce the next transaction must use. After one send it returns 0x1.

In a transaction receipt, what do status 0x0 and contractAddress null mean?

status 0x0 means the transaction reverted (failed). contractAddress null means it was a normal transaction, not a contract deployment.

  • MetaMask setup: install extension, create wallet, set password, save and confirm the 12-word Secret Recovery Phrase, enable test networks, select Sepolia.
  • Etherscan (sepolia.etherscan.io for the testnet) shows addresses, blocks, transactions and fees.
  • The Google Cloud faucet gives 0.05 Sepolia ETH; the lab sent 0.01 ETH between accounts with nonce 0 and 21,000 gas.
  • Apps reach the chain through an RPC provider (Alchemy) with JSON-RPC 2.0 over HTTP POST: jsonrpc, method, params, id.
  • Network calls: eth_chainId (0xaa36a7 = 11155111), eth_blockNumber, eth_getBlockByNumber/Hash, eth_gasPrice, eth_getBlockTransactionCountByNumber.
  • Account calls: eth_getBalance (Wei, 1 ETH = 101810^{18} Wei), eth_getTransactionCount (nonce), eth_getCode (0x = EOA), eth_getStorageAt.
  • Transaction calls: eth_getTransactionByHash, eth_getTransactionReceipt (status 0x1 success, type 0x2 EIP-1559), eth_sendRawTransaction.