Use Nonce
For trigger durable nonce, we need to do two steps
  1. 1.
    put instruction, advanced nonce to the first instruction in the tx
  2. 2.
    use the blockhash(nonce) which store in the nonce account as a recent blockhash
Now I use a transfer as a real thing we want to do and use durable nonce mechanism.
The nonce wich stored in the nonce account will be changed after you used.
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/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})
​
func main() {
// you created before
nonceAccountPubkey := common.PublicKeyFromString("CJBP7wJcYbPqfhvtSmLBUf4VzBqJbgC776Wr7CzUCd1m")
​
c := client.NewClient("http://localhost:8899")
​
// fetch nonce
accountInfo, err := c.GetAccountInfo(
context.Background(),
nonceAccountPubkey.ToBase58(),
)
if err != nil {
log.Fatalf("failed to get account info, err: %v", err)
}
nonceAccount, err := sysprog.NonceAccountDeserialize(accountInfo.Data)
if err != nil {
log.Fatalf("failed to deserialize nonce account, err: %v", err)
}
​
// create a random account
to := types.NewAccount()
​
tx, err := types.NewTransaction(types.NewTransactionParam{
Message: types.NewMessage(types.NewMessageParam{
FeePayer: feePayer.PublicKey,
// here must use the nonce account's nonce as a recent blockhash
RecentBlockhash: nonceAccount.Nonce.ToBase58(),
Instructions: []types.Instruction{
// you need to put this instruction in the first
sysprog.AdvanceNonceAccount(sysprog.AdvanceNonceAccountParam{
Nonce: nonceAccountPubkey,
Auth: feePayer.PublicKey, // nonce account's owner
}),
// now put the instrucitons you really want to do
// here I use transfer as a example
sysprog.Transfer(sysprog.TransferParam{
From: feePayer.PublicKey,
To: to.PublicKey,
Amount: 1e9,
}),
},
}),
Signers: []types.Account{feePayer},
})
if err != nil {
log.Fatalf("failed to create raw transaction, err: %v", err)
}
​
sig, err := c.SendTransaction(context.Background(), tx)
if err != nil {
log.Fatalf("failed to send transaction, err: %v", err)
}
​
fmt.Println("txhash", sig)
}
​
Copy link