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...

}

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)

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)
}

That’s all :)!!