DEV Community

Gealber Morales
Gealber Morales

Posted on • Originally published at gealber.com

4

Sending transaction in TON blockchain(Golang)

In this small recipe you can see how to send a transaction through the TON blockchain using tonutils-go. Our goal in this tutorial is to be able to send the transaction and receive the transaction hash.

Requirements

  1. Golang installed.

Recipe

Importing the wallet

package main

import (
    "context"
    "encoding/base64"
    "errors"
    "log"
    "strings"

    "github.com/xssnick/tonutils-go/address"
    "github.com/xssnick/tonutils-go/liteclient"
    "github.com/xssnick/tonutils-go/tlb"
    "github.com/xssnick/tonutils-go/ton"
    "github.com/xssnick/tonutils-go/ton/wallet"
    tonwallet "github.com/xssnick/tonutils-go/ton/wallet"
)

func main() {
    // initialize connection pool.
    testnetConfigURL := "https://ton-blockchain.github.io/testnet-global.config.json"
    conn := liteclient.NewConnectionPool()
    ctx := context.Background()
    err := conn.AddConnectionsFromConfigUrl(ctx, testnetConfigURL)
    if err != nil {
        panic(err)
    }

    // initialize api client.
    api := ton.NewAPIClient(conn)

    // // importing wallet.
    seedStr := "<WALLET_SEED>" // if you don't have one you can generate it with tonwallet.NewSeed().
    seed := strings.Split(seedStr, " ")

    wallet, err := tonwallet.FromSeed(api, seed, wallet.V4R2)
    if err != nil {
        panic(err)
    }

    log.Println("WALLET ADDRESS: ", wallet.Address().String())

    // preparing for transaction...

}

Enter fullscreen mode Exit fullscreen mode

In order to receive testnet tons you can use the Telegram Bot: @testgiver_ton_bot, where you will be requested to provide the wallet address.

Preparing transaction




     // previous part
    // preparing for transaction...

    // getting latest master chain.
    block, err := api.CurrentMasterchainInfo(ctx)
    if err != nil {
        panic(err)
    }

    // amount of transaction to be made.
    var (
        amount        uint64 = 1e9                                                // 1e9 Nano TONs = 1TON.
        walletAddress string = "EQC9n6aFb2oxQPMTPrHOnZDFcvvC2YLYIgBUms2yAB_LcAtv" // wallet address to which we are goin to make the transaction.
        comment       string = "Payment"
    )

    balance, err := wallet.GetBalance(ctx, block)
    if err != nil {
        panic(err)
    }

    log.Println("AVAILABLE BALANCE", balance)

    // check if we have enough balance.
    if balance.NanoTON().Uint64() < amount {
        panic(errors.New("insufficient balance"))
    }

    // parse address, in case we receive an invalid address.
    addr, err := address.ParseAddr(walletAddress)
    if err != nil {
        panic(err)
    }

    // Now we can use the method Transfer that the library provides.
    // Which absolutely fine, the problem is that we WANT to retrieve the hash of the transaction.
    // Currently the Transfer method doesn't not return the hash of the transaction, because it gives you
    // the option to not wait for the transaction to finish. This is my assumption of course.
    // So let's try to wait for the transaction and to retrieve the hash of the transaction.
    // For that purpose the library provides us with a method called SendManyWaitTxHash.

    // creating cell for comment.
    body, err := tonwallet.CreateCommentCell(comment)
    if err != nil {
        panic(err)
    }

    txn, err := wallet.SendManyWaitTxHash(ctx, []*tonwallet.Message{
        {
            Mode: 1,
            InternalMessage: &tlb.InternalMessage{
                IHRDisabled: true,
                Bounce:      false, // we don't want the transaction to bounce, but you can change it to true if you want.
                DstAddr:     addr,  // destination address.
                Amount:      tlb.FromNanoTONU(amount),
                Body:        body,
            },
        },
    })
    if err != nil {
        panic(err)
    }

    // now we can use this transaction hash to search
    // the transaction in tonscan explorer.
    txnHash := base64.StdEncoding.EncodeToString(txn)
    log.Println("TXN HASH: ", txnHash)

Enter fullscreen mode Exit fullscreen mode

Now with this transaction hash we can go into testnet tonscan and search for it.

All the code

package main

import (
    "context"
    "encoding/base64"
    "errors"
    "log"
    "strings"

    "github.com/xssnick/tonutils-go/address"
    "github.com/xssnick/tonutils-go/liteclient"
    "github.com/xssnick/tonutils-go/tlb"
    "github.com/xssnick/tonutils-go/ton"
    "github.com/xssnick/tonutils-go/ton/wallet"
    tonwallet "github.com/xssnick/tonutils-go/ton/wallet"
)

func main() {
    // initialize connection pool.
    testnetConfigURL := "https://ton-blockchain.github.io/testnet-global.config.json"
    conn := liteclient.NewConnectionPool()
    ctx := context.Background()
    err := conn.AddConnectionsFromConfigUrl(ctx, testnetConfigURL)
    if err != nil {
        panic(err)
    }

    // initialize api client.
    api := ton.NewAPIClient(conn)

    // // importing wallet.
    seedStr := "<WALLET_SEED>" // if you don't have one you can generate it with tonwallet.NewSeed().
    seed := strings.Split(seedStr, " ")

    wallet, err := tonwallet.FromSeed(api, seed, wallet.V4R2)
    if err != nil {
        panic(err)
    }

    log.Println("WALLET ADDRESS: ", wallet.Address().String())

    // getting latest master chain.
    block, err := api.CurrentMasterchainInfo(ctx)
    if err != nil {
        panic(err)
    }

    // amount of transaction to be made.
    var (
        amount        uint64 = 1e9                                                // 1e9 Nano TONs = 1TON.
        walletAddress string = "EQC9n6aFb2oxQPMTPrHOnZDFcvvC2YLYIgBUms2yAB_LcAtv" // wallet address to which we are goin to make the transaction.
        comment       string = "Payment"
    )

    balance, err := wallet.GetBalance(ctx, block)
    if err != nil {
        panic(err)
    }

    log.Println("AVAILABLE BALANCE", balance)

    // check if we have enough balance.
    if balance.NanoTON().Uint64() < amount {
        panic(errors.New("insufficient balance"))
    }

    // parse address, in case we receive an invalid address.
    addr, err := address.ParseAddr(walletAddress)
    if err != nil {
        panic(err)
    }

    // Now we can use the method Transfer that the library provides.
    // Which absolutely fine, the problem is that we WANT to retrieve the hash of the transaction.
    // Currently the Transfer method doesn't not return the hash of the transaction, because it gives you
    // the option to not wait for the transaction to finish. This is my assumption of course.
    // So let's try to wait for the transaction and to retrieve the hash of the transaction.
    // For that purpose the library provides us with a method called SendManyWaitTxHash.

    // creating cell for comment.
    body, err := tonwallet.CreateCommentCell(comment)
    if err != nil {
        panic(err)
    }

    txn, err := wallet.SendManyWaitTxHash(ctx, []*tonwallet.Message{
        {
            Mode: 1,
            InternalMessage: &tlb.InternalMessage{
                IHRDisabled: true,
                Bounce:      false, // we don't want the transaction to bounce, but you can change it to true if you want.
                DstAddr:     addr,  // destination address.
                Amount:      tlb.FromNanoTONU(amount),
                Body:        body,
            },
        },
    })
    if err != nil {
        panic(err)
    }

    // now we can use this transaction hash to search
    // the transaction in tonscan explorer.
    txnHash := base64.StdEncoding.EncodeToString(txn)
    log.Println("TXN HASH: ", txnHash)
}

Enter fullscreen mode Exit fullscreen mode

That's all :)!!

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay