Logo

dev-resources.site

for different kinds of informations.

USDT transaction on Polygon(MATIC) network

Published at
5/15/2023
Categories
polygon
blockchain
usdt
go
Author
gealber
Categories
4 categories in total
polygon
open
blockchain
open
usdt
open
go
open
Author
7 person written this
gealber
open
USDT transaction on Polygon(MATIC) network

Polygon USDT

Introduction

This article is similar to our previous one, USDT transaction on Solana network, but in this case we are going to transfer USDT on Polygon(previously called MATIC) network.

Requirements

  1. Go installed, given that we are going to keep using Go for this job.

Code with comments

Ok so let's start, first let's import the libraries, mostly will be using go-ethereum.


package main

import (
    "context"
    "crypto/ecdsa"
    "errors"
    "fmt"
    "math/big"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/crypto"
    "github.com/ethereum/go-ethereum/ethclient"
    "golang.org/x/crypto/sha3"
)
Enter fullscreen mode Exit fullscreen mode

In this small recipe we'll use Alchemy RPC provider. Alchemy support several blockchains check it out in case you will need it.

Alchemy Dashboard

When you create a application in Alchemy they will provide you with an API-KEY, which will be needed for connecting to the RPC endpoint. Let's define some constants that we'll need.


// After imports....

const (
    // replace <API-KEY> with alchemy api key provided.
    AlchemyPolygonRPCEndpoint = "https://polygon-mainnet.g.alchemy.com/v2/<API-KEY>"

    // USDTTokenAddress is USDT contract address for the USDT token on Polygon
    // network. Can be checked in the following polygonscan link:
    // https://polygonscan.com/token/0xc2132d05d31c914a87c6611c10748aeb04b58e8f
    USDTTokenAddress = "0xc2132D05D31c914a87C6611C10748AEb04B58e8F"

    DefaultGasLimit uint64 = 100000
)
Enter fullscreen mode Exit fullscreen mode

Let's define our client and its constructor.


// Client for making transaction.
type Client struct {    
    client      *ethclient.Client
    publickKey  common.Address
    privateKey  *ecdsa.PrivateKey
}

// NewWithPrivateKey creates a new Client with the private key
// provided.
func NewWithPrivateKey(pKeyStr string) (*Client, error) {
    client, err := ethclient.Dial(AlchemyPolygonRPCEndpoint)
    if err != nil {
        return nil, err
    }

    privateKey, err := crypto.HexToECDSA(pKeyStr)
    if err != nil {
        return nil, err
    }

    publicKey := privateKey.Public()
    publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
    if !ok {
        return nil, errors.New("unable to convert publicKey to *ecdsa.PublicKey type")
    }

    // extracting public address of the wallet with the supplied private key.
    pubAddrs := crypto.PubkeyToAddress(*publicKeyECDSA)

    return &Client{     
        client:      client,
        publickKey:  pubAddrs,
        privateKey:  privateKey,
    }, nil
}
Enter fullscreen mode Exit fullscreen mode

The main method will be called TransferUSDT. One main difference in this method and the one from Solana article, is that we cannot send comment in the transaction.


// TransferUSDT make transaction of usdts to the specified address.
// The amount should be provided in 6 decimals.
// Meaning, 1 USDT should be represented as 1e6.
// ctx: context
// toAddressStrHex: hexadecimal representation of receiver address(Public Address)
// amount: usdt amount to be sent.
func (c *Client) TransferUSDT(
    ctx context.Context,
    toAddressStrHex string,
    amount uint64,
) (string, error) {
    // Retrieving pending nonce. The nonce, according to
    // ethereum glossary is a:
    // "An account nonce is a transaction counter in each account,
    // which is used to prevent replay attacks."
    nonce, err := c.client.PendingNonceAt(ctx, c.publickKey)
    if err != nil {
        return "", err
    }

    // given that we are going to transfer
    // usdts we don't need eths wei (0 eth).
    value := big.NewInt(0)

    // receiver address.
    toAddress := common.HexToAddress(toAddressStrHex)
    // usdt token address.
    tokenAddress := common.HexToAddress(USDTTokenAddress)

    // we will use the transfer method
    // on the smart contract associated with usdt token
    // in order to use this method, we need to provide the method id
    // this is how we get that number.
    // You could also check it here in this link
    // https://polygonscan.com/token/0xc2132d05d31c914a87c6611c10748aeb04b58e8f#writeProxyContract#F11
    transferFnSignature := []byte("transfer(address,uint256)")
    hash := sha3.NewLegacyKeccak256()
    hash.Write(transferFnSignature)
    methodID := hash.Sum(nil)[:4]

    // we need to add 32 bytes of zeros to our address.
    paddedAddress := common.LeftPadBytes(toAddress.Bytes(), 32)

    // we need to add 32 bytes of zeros to our amount of tokens.
    // we are assuming this amount of tokens is expressed in 6 decimals.
    // which are the decimals for usdt.
    amountBigInt := new(big.Int)
    amountBigInt.SetUint64(amount)
    paddedAmount := common.LeftPadBytes(amountBigInt.Bytes(), 32)

    // now let's put this three parts into
    // the data we are going to pass in the transaction
    // part one: methodID
    // part two: receiver address padded 32 bytes
    // part three: padded amount to be sent
    var data []byte
    data = append(data, methodID...)
    data = append(data, paddedAddress...)
    data = append(data, paddedAmount...)

    // retrieving suggested gas fees and gas price.
    tipCap, err := c.client.SuggestGasTipCap(ctx)
    if err != nil {
        return "", err
    }

    feeCap, err := c.client.SuggestGasPrice(ctx)
    if err != nil {
        return "", err
    }

    //  network ID for this client.
    chainID, err := c.client.NetworkID(ctx)
    if err != nil {
        return "", err
    }

    // creating our transaction, in this case we are going to use
    // dynamic fees txns instead of the legacy system.
    tx := types.NewTx(&types.DynamicFeeTx{
        ChainID:   chainID,
        Nonce:     nonce,
        GasTipCap: tipCap,
        GasFeeCap: feeCap,
        Gas:       DefaultGasLimit,
        To:        &tokenAddress,
        Value:     value,
        Data:      data,
    })

    // sign the transaction with our private key.
    signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(chainID), c.privateKey)
    if err != nil {
        return "", err
    }

    // send the transaction.
    err = c.client.SendTransaction(ctx, signedTx)
    if err != nil {
        return "", err
    }

    // return the hexadecimal representation of the txnHash.
    return signedTx.Hash().Hex(), nil
}
Enter fullscreen mode Exit fullscreen mode

Now writing the main function we got:


func main() {
    ctx := context.Background()
    client, err := NewWithPrivateKey("<PRIVATE-KEY>")
    if err != nil {
        panic(err)
    }

    txnHash, err := client.TransferUSDT(ctx, "<RECEIVER ADDRESS>", 1e6) // Sending 1 usdt.
    if err != nil {
        panic(err)
    }

    fmt.Println("TXN HASH: ", txnHash)
}
Enter fullscreen mode Exit fullscreen mode

That's all, feel free to join the parts :).

polygon Article's
30 articles in total
Favicon
Automating Limit Orders on Polygon with TypeScript, 0x, and Terraform
Favicon
Understanding the Role of Validators in Polygon Bridge Transactions
Favicon
Transferencia de tokens entre Ethereum y Polygon: Mejores prácticas con Polygon Bridge
Favicon
Exploring the Latest Updates and Features of Polygon Bridge
Favicon
How to Run a Polygon Node: A Complete Guide
Favicon
Polygon Blockchain
Favicon
Web3 UI For Simple Smart Contract
Favicon
Simple Smart Contract and Hardhat
Favicon
MATIC Transitions to POL: Key Insights for Polygon Users
Favicon
Sending and Monitoring Transactions on Kalp Studio
Favicon
FastLane’s ERC-4337 Support, Limitless x Etherspot, XION’s Walletless Blockchain, and Unichain Launch
Favicon
Deploying Your Solidity Smart Contract on the Polygon Blockchain Using Kalp Instant Deployer
Favicon
Creating Your Custodial Polygon Wallet on AMOY Network Using Kalp Studio
Favicon
Exploring POL: The Token Powering the Future of Decentralized Applications on Polygon
Favicon
Polygon Nodes: Types and Usage
Favicon
How Polygon AggLayer Emerges to be the Hub for Ethereum L2s
Favicon
Choose Antier for Top-tier Polygon CDK Implementation Services.
Favicon
How Polygon’s Aggregation Layer Brings a New Phase in Rollup Interoperability?
Favicon
How Polygon Blockchain works...
Favicon
How Polygon PoS is different from its zkEVM chain?
Favicon
Ethonline 2023, my experience, challenge, and Lessons Learnt
Favicon
Top Blockchain Platforms for Your dApp Development
Favicon
Purple-Paper
Favicon
Polygon Blockchain (Matic) | A Comprehensive Guide
Favicon
Sort's Web3 React Components Are Now Open Source!
Favicon
Verified Mainnet Polygon Contract
Favicon
Launch Alert! Wowen Modular Blockchain Network - Unleash the Power of Consensus Choice 🚀⛓️💻
Favicon
Power Tools for Blockchain UI Development: $3.5M Seed Round, An Innovative Revenue Model, and Open Access to Contract Data
Favicon
Build Together for Free with Sponsored Contracts on Sort
Favicon
USDT transaction on Polygon(MATIC) network

Featured ones: