Lesson 04 · Web3 with Go & Polygon

Reading a Transaction

One of your mission's success criteria is literally: "Read a transaction on Polygonscan and explain what every field means." Today we do exactly that — but from Go. When a share sale settles, your backend will need to fetch the transaction, confirm it succeeded, and pull the details for a receipt or an audit log. Every field you learn here is a field your client's records will depend on.

The win A Go program that fetches any transaction by its hash, prints who sent it, to whom, how much, and — crucially — whether it succeeded. You'll be able to open the same hash on Polygonscan and match every number.

A transaction is a signed instruction

From Lesson 03: a transaction is the only thing that changes state. Once mined, it's identified forever by its hash — a 32-byte fingerprint like 0x8f2c…a91b. Give go-ethereum that hash and it hands you back the whole transaction.

The fields, and what they mean

from / to
Sender and recipient addresses. If to is empty, the transaction is deploying a contract — that's how you'll create your share token.
value
Native POL moved, in wei. A pure token transfer often has value 0 — the shares move in the data, not the value.
nonce
A per-sender counter: this account's 0th, 1st, 2nd… transaction. It fixes ordering and blocks replay — the same signed tx can't be mined twice.
gas / gas price
Gas is the max work allowed; gas price is what you pay per unit. Fee = gas used × gas price. This is the anti-spam meter from Lesson 03, made concrete.
data (input / calldata)
The payload telling a contract what to do — e.g. the encoded call transfer(0xABC, 40). Empty for a plain POL send.

Fetch it in Go

Grab any recent tx hash from Amoy Polygonscan and drop it in.

main.go

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
)

func main() {
	client, err := ethclient.Dial("https://rpc-amoy.polygon.technology/")
	if err != nil {
		log.Fatalf("could not connect: %v", err)
	}
	defer client.Close()

	ctx := context.Background()
	hash := common.HexToHash("0xPUT_A_REAL_AMOY_TX_HASH_HERE")

	tx, isPending, err := client.TransactionByHash(ctx, hash)
	if err != nil {
		log.Fatalf("could not fetch tx: %v", err)
	}

	fmt.Printf("pending?   %v\n", isPending)
	fmt.Printf("to:        %v\n", tx.To())      // nil = contract creation
	fmt.Printf("value:     %s wei\n", tx.Value())
	fmt.Printf("nonce:     %d\n", tx.Nonce())
	fmt.Printf("gas limit: %d\n", tx.Gas())
	fmt.Printf("gas price: %s wei\n", tx.GasPrice())
	fmt.Printf("data len:  %d bytes\n", len(tx.Data()))
}

Notice something missing: the transaction object doesn't tell you if it succeeded.

Did it succeed? Ask the receipt

A transaction and its receipt are two different things. The receipt is written after execution and holds the outcome: status, gas actually used, and the logs (events) the contract emitted. For your backend, Status == 1 is the difference between "the shares moved" and "it reverted, do not update our records."

add to main.go

	receipt, err := client.TransactionReceipt(ctx, hash)
	if err != nil {
		log.Fatalf("could not fetch receipt: %v", err)
	}
	fmt.Printf("status:    %d  (1 = success, 0 = reverted)\n", receipt.Status)
	fmt.Printf("gas used:  %d\n", receipt.GasUsed)
	fmt.Printf("logs:      %d event(s) emitted\n", len(receipt.Logs))
You did it You can now pull any transaction apart from Go and prove whether it worked. Those Logs are a preview of the future: when your share token emits a Transfer event, that's how your backend will hear that a sale happened.
Transaction vs receipt — don't confuse them The transaction is the request (to, value, data). The receipt is the result (status, gas used, logs). A transaction that reverted still exists on-chain and still cost gas — only the receipt's Status reveals it failed.

Check yourself

1. Where do you find whether a transaction succeeded?

2. A transaction with an empty to field is…

3. What is the nonce for?

4. A token transfer's details usually ride in the transaction's…

Primary source · read this next
Ethereum Development with Go — Querying Transactions, then Transaction Receipts. The exact go-ethereum calls we used, from our backbone book.

I'm your teacher — ask me anything. Want to decode that data field into a readable function call? Curious how "gas price" became "base fee + tip" after EIP-1559? Want to open a real share-transfer tx together and read it line by line? Just ask.