Create Mint (Token)

What is mint ? You can treat a mint as a erc20 contract address. In the other words, USDT, SRM and RAY ... all of them are mint.

There are two instructions you need to know before you want to create a mint.

System Program - Create Account

sysprog.CreateAccount(sysprog.CreateAccountParam{
	From:     feePayer.PublicKey,         // from, funder
	New:      mint.PublicKey, 	      // new account
	Owner:    common.TokenProgramID,      // owner, 
	Lamports: rentExemptionBalance,       // init lamports
	Space:    tokenprog.MintAccountSize,  // init space
}),

both from and new need to sign the tx.

mint is the account which owned by token program so we assign token program id as owner

init balance charge from from . usually use the number of rent exemption. we can get the number from rpc method,GetMinimumBalanceForRentExemption

sizedepends on which account you want to create. Here we use the account size of mint.

Token Program - Initialize Mint

tokenprog.InitializeMint(tokenprog.InitializeMintParam{
	Decimals:   8,
	Mint:       mint.PublicKey,
	MintAuth:   alice.PublicKey,
	FreezeAuth: nil,
}),

decimals is the decimals of token.

mint account is the account we created before, pass it to here

mint auth is the auth can mint token, if you want to mint more token in the future, the mint auth must sign the tx to auth the action.

freeze auth a token can be frozen by the auth, if you don't need it, you pass an empty pubkey.

Full Code:

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/portto/solana-go-sdk/client"
	"github.com/portto/solana-go-sdk/common"
	"github.com/portto/solana-go-sdk/program/sysprog"
	"github.com/portto/solana-go-sdk/program/tokenprog"
	"github.com/portto/solana-go-sdk/rpc"
	"github.com/portto/solana-go-sdk/types"
)

var feePayer, _ = types.AccountFromBytes([]byte{178, 244, 76, 4, 247, 41, 113, 40, 111, 103, 12, 76, 195, 4, 100, 123, 88, 226, 37, 56, 209, 180, 92, 77, 39, 85, 78, 202, 121, 162, 88, 29, 125, 155, 223, 107, 139, 223, 229, 82, 89, 209, 27, 43, 108, 205, 144, 2, 74, 159, 215, 57, 198, 4, 193, 36, 161, 50, 160, 119, 89, 240, 102, 184})

var alice, _ = types.AccountFromBytes([]byte{196, 114, 86, 165, 59, 177, 63, 87, 43, 10, 176, 101, 225, 42, 129, 158, 167, 43, 81, 214, 254, 28, 196, 158, 159, 64, 55, 123, 48, 211, 78, 166, 127, 96, 107, 250, 152, 133, 208, 224, 73, 251, 113, 151, 128, 139, 86, 80, 101, 70, 138, 50, 141, 153, 218, 110, 56, 39, 122, 181, 120, 55, 86, 185})

func main() {
	c := client.NewClient(rpc.LocalnetRPCEndpoint)

	// create an mint account
	mint := types.NewAccount()
	fmt.Println("mint:", mint.PublicKey.ToBase58())

	// get init balance
	rentExemptionBalance, err := c.GetMinimumBalanceForRentExemption(
		context.Background(),
		tokenprog.MintAccountSize,
	)
	if err != nil {
		log.Fatalf("get min balacne for rent exemption, err: %v", err)
	}

	res, err := c.GetRecentBlockhash(context.Background())
	if err != nil {
		log.Fatalf("get recent block hash error, err: %v\n", err)
	}
	tx, err := types.NewTransaction(types.NewTransactionParam{
		Message: types.NewMessage(types.NewMessageParam{
			FeePayer:        feePayer.PublicKey,
			RecentBlockhash: res.Blockhash,
			Instructions: []types.Instruction{
				sysprog.CreateAccount(sysprog.CreateAccountParam{
					From:     feePayer.PublicKey,
					New:      mint.PublicKey,
					Owner:    common.TokenProgramID,
					Lamports: rentExemptionBalance,
					Space:    tokenprog.MintAccountSize,
				}),
				tokenprog.InitializeMint(tokenprog.InitializeMintParam{
					Decimals:   8,
					Mint:       mint.PublicKey,
					MintAuth:   alice.PublicKey,
					FreezeAuth: nil,
				}),
			},
		}),
		Signers: []types.Account{feePayer, mint},
	})
	if err != nil {
		log.Fatalf("generate tx error, err: %v\n", err)
	}

	txhash, err := c.SendTransaction(context.Background(), tx)
	if err != nil {
		log.Fatalf("send tx error, err: %v\n", err)
	}

	log.Println("txhash:", txhash)
}

Last updated