Ethereum Token Transfer, Block Monitoring, and Raw Transaction Sending with Golang – Part 2

·

Introduction

The remaining topics are straightforward, with challenges similar to those covered in the previous article. Below, we explore Ethereum token transfers, block monitoring, and raw transaction broadcasting using Golang.


Ethereum Token Transfer

// Testnet tutorial: https://goethereumbook.org/zh/transfer-tokens/
client, _ := ethclient.Dial("https://rinkeby.infura.io")

// Set ETH value to 0 for token transfers (source: tokenfactory.surge.sh)
EthValue := big.NewInt(0)

// Use the article's address to avoid conflicts
toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")

// Token contract address
tokenAddress := common.HexToAddress("0x28b149020d2152179873ec60bed6bf7cd705775d")

// Function signature
transferFnSignature := []byte("transfer(address,uint256)")

// Generate method ID hash
hash := sha3.New384()
hash.Write(transferFnSignature)
methID := hash.Sum(nil)[:4]

// Pad recipient address
paddedAddress := common.LeftPadBytes(toAddress.Bytes(), 32)

// Token amount (1000 tokens with 18 decimals)
Number := new(big.Int)
Number.SetString("1000000000000000000000", 10)

// Encode data
var data []byte
data = append(data, methID...)
data = append(data, paddedAddress...)
data = append(data, common.LeftPadBytes(Number.Bytes(), 32)...)

// Estimate gas
gasLimit, _ := client.EstimateGas(context.Background(), ethereum.CallMsg{
    To:   &toAddress,
    Data: data,
})
logrus.Info("Ethereum Gas Limit:", gasLimit)

// Create transaction
tx := types.NewTx(&types.LegacyTx{
    Nonce:    246,
    GasPrice: EthValue,
    Gas:      gasLimit,
    To:       &tokenAddress,
    Value:    EthValue,
    Data:     make([]byte, 0),
})
logrus.Info(tx)

Key Notes:

👉 Master Ethereum token transfers with this step-by-step guide


Monitoring New Blocks

// Requires an API token (replace with your own)
client, _ := ethclient.Dial("wss://eth-mainnet.ws.alchemyapi.io/ws/")

// Create channel for block headers
heads := make(chan *types.Header)

// Subscribe to new headers
sub, _ := client.SubscribeNewHead(context.Background(), heads)

// Monitor events
for {
    select {
    case err := <-sub.Err():
        logrus.Error("Subscribe Block Error:", err)
    case header := <-heads:
        logrus.Info("Header Hash:", header.Hash().Hex())
        
        // Fetch full block
        block, _ := client.BlockByHash(context.Background(), header.Hash())
        logrus.Info("Block Hash:", block.Hash().String())
    }
}

Important:


Broadcasting Raw Transactions

client, _ := ethclient.Dial("https://rinkeby.infura.io")

// Raw transaction hex
rawTx := "f86d8202b28477359400825208944592d8f8d7b001e72cb26a73e4fa1806a51ac79d880de0b6b3a7640000802ca05924bde7ef10aa88db9c66dd4f5fb16b46dff2319b9968be983118b57bb50562a001b24b31010004f13d9a26b320845257a6cfc2bf819a3d55e3fc86263c5f0772"

// Decode and parse
RawTX, _ := hex.DecodeString(rawTx)
tx := new(types.Transaction)
rlp.DecodeBytes(RawTX, &tx)

// Broadcast
if err := client.SendTransaction(context.Background(), tx); err != nil {
    logrus.Error("SendTransaction Error:", err)
    return
}
logrus.Info("Transaction Hash:", tx.Hash().Hex())

👉 Explore advanced Ethereum transaction techniques


FAQ

Q: How do I handle gas fees for token transfers?
A: Use EstimateGas with the token contract’s transfer method data.

Q: Why does WebSocket monitoring fail?
A: Ensure your endpoint includes a valid API token (e.g., from Alchemy or Infura).

Q: What’s the difference between ETH and token transfers?
A: Token transfers set Value to 0 and interact with the token contract’s ABI.


Conclusion

This guide covered token transfers, block monitoring, and raw transactions. For further learning, refer to Ethereum’s official documentation.