Payment Transactions
package main
import (
"fmt"
"github.com/algorand/go-algorand-sdk/crypto"
"github.com/algorand/go-algorand-sdk/mnemonic"
)
func main() {
// METHOD 1: Create a New Account
newAccount := crypto.GenerateAccount()
fmt.Printf("Private Key: %s\n", newAccount.PrivateKey)
fmt.Printf("Address: %s\n", newAccount.Address.String())
// Convert Private Key to Mnemonic
mnemo, err := mnemonic.FromPrivateKey(newAccount.PrivateKey)
if err != nil {
fmt.Printf("Error converting private key to mnemonic: %s\n", err)
return
}
fmt.Println("Mnemonic:", mnemo)
// METHOD 2: Use Mnemonic to Obtain Private Key
// Assuming mnemonicPhrase is obtained securely and already exists
mnemonicPhrase := "brown repeat amazing april survey fish gospel brown bless core deny plate admit burden pistol device shuffle sadness genius answer hurt analyst foot above annual"
privKey, err := mnemonic.ToPrivateKey(mnemonicPhrase)
if err != nil {
fmt.Printf("Error retrieving private key from mnemonic: %s\n", err)
return
}
fmt.Printf("Private Key from Mnemonic: %s\n", privKey)
}
When developing in Go with the Algorand SDK, there are two primary methods for obtaining a private key and address which are necessary for signing transactions. The private key is typically managed in byte slice format and is essential for the creation and signing of transactions.
Method 1: Create a New Account and Obtain the Private Key and Address Directly
In the Algorand Go SDK, you use the crypto.GenerateAccount()
function to generate a new account. This function returns an account object that contains both the private key and the address, not in a tuple like Python, but directly accessible via the account object properties. Once you have this account, you can print the private key and the address. These details can then be used to sign transactions or manage Algorand assets.
After generating a new account, you can fund it by sending Algos to the generated address. This can be done through the Algorand dispenser for testnet, which is available at https://bank.testnet.algorand.network/. Remember that all accounts require a minimum balance of 0.1 Algo to remain active, and each transaction typically costs a fee of 0.001 Algo.
For wallet applications, if you need to derive the mnemonic from the private key, you can use the mnemonic.FromPrivateKey()
function provided by the Go SDK. This function converts the private key into a human-readable mnemonic phrase.
Method 2: Convert an Existing Mnemonic to a Private Key
If you already possess a mnemonic and need to derive the corresponding private key, you can utilize the mnemonic.ToPrivateKey(mnemonic string)
function. This function takes a string mnemonic and returns the corresponding private key. It is crucial to ensure that the mnemonic is correctly formatted, enclosed in quotes, and that it includes spaces between the words as expected in standard mnemonic phrases.
Using the Account for Transactions
Once you have an account with funds, you can use the AlgodClient
to initiate a connection to the Algorand blockchain. This setup allows you to interact with the blockchain, send transactions, and check account details. You might engage in various transaction types such as sending Algos to another account, rekeying the account (which changes the authoritative private key for the account), or closing the account (transferring all remaining Algos to another account). Each of these actions can be encapsulated within a payment transaction using the Algorand Go SDK.
This text should provide a clear, non-code explanation of the key processes involved in using the Algorand Go SDK for creating and managing accounts, as well as performing transactions.
package main
import (
"context"
"crypto/ed25519"
"encoding/base64"
"fmt"
"log"
"math/rand"
"time"
"github.com/algorand/go-algorand-sdk/client/v2/algod"
"github.com/algorand/go-algorand-sdk/crypto"
"github.com/algorand/go-algorand-sdk/future"
"github.com/algorand/go-algorand-sdk/types"
)
func main() {
fmt.Println("Starting transaction...")
algodAddress := "https://testnet-api.algonode.cloud"
algodToken := ""
algodClient, err := algod.MakeClient(algodAddress, algodToken)
if err != nil {
log.Fatalf("Failed to make algod v2 client: %v", err)
}
// Existing account details
address := "I3BHPDWGH63J47JBG2P7RJLOGD3L3HEBOI4KKUKSV3MZSYFX4VFDIDYSMU"
privateKeyB64 := "6KitD65Q7V6ZDB29EEx1YtoBeqy0PDt+78Ga4DchXItGwneOxj+2nn0hNp/4pW4w9r2cgXI4pVFSrtmZYLflSg=="
// Decode the base64 private key into ed25519.PrivateKey
decodedPk, err := base64.StdEncoding.DecodeString(privateKeyB64)
if err != nil {
log.Fatalf("Failed to decode base64 private key: %v", err)
}
ed25519PrivateKey := ed25519.PrivateKey(decodedPk)
algos := 1.001
// Convert Algos -> MicroAlgos:
microAlgoAmount := uint64(types.ToMicroAlgos(algos))
// Fetch the suggested transaction parameters (v2 style)
txParams, err := algodClient.SuggestedParams().Do(context.Background())
if err != nil {
log.Fatalf("Error getting suggested tx params: %v", err)
}
// Create a random note
rand.Seed(time.Now().UnixNano())
note := []byte(fmt.Sprintf("Random note: %d", rand.Int()))
// Create a payment transaction
tx, err := future.MakePaymentTxn(
address, // From
crypto.GenerateAccount().Address.String(), // To (for demonstration)
microAlgoAmount, // Amount (microAlgos)
note, // Note
"", // CloseRemainderTo
txParams,
)
if err != nil {
log.Fatalf("Failed to create payment transaction: %v", err)
}
// Sign the transaction: returns (signedTxBytes, txID, err)
txID, signedTxBytes, err := crypto.SignTransaction(ed25519PrivateKey, tx)
if err != nil {
log.Fatalf("Failed to sign transaction: %v", err)
}
fmt.Printf("Signed transaction with TxID: %s\n", txID)
// Send the transaction
algodClient.SendRawTransaction(signedTxBytes).Do(context.Background())
fmt.Printf("Transaction sent. TxID: %s\n", txID)
}
Steps:
- Import our necessary modules
- Define our
AlgodClient
to initiate a connection to the chain - Define our account's address and private key that we will be sending transactions from
- Define an amount of Algorand to send
- Obtain the params needed for all transactions
- Generate a new account for testing, so we have an address to send testnet Algorand to
- Define our payment transaction and its parameters
- Sign the transaction with our private key
- Assign the result of sending our signed transaction with the
send_transaction()
function from theAlgodClient
class - Print the transaction ID for reference on an explorer like allo.info, https://testnet.explorer.perawallet.app/, https://www.blockpack.app/#/explorer/home, or https://app.dappflow.org/explorer/home
In the Algorand SDKs, when we want to reference an amount of Algo, that amount needs to be in a format called "Microalgo"; Microalgo is essentially an amount of Algo times 1,000,000. Meaning that 1 Algo would be 1,000,000 Microalgo, and the transaction fee of 0.001 Algo is 1,000 Microalgo.
Instead of manually calculating the microalgo amount each time, what we can do is use the algos_to_microalgos()
function, and pass in the amount of Algo as an argument.
The PaymentTransaction
class comes with a lot of functionality, aside from simple payment transactions of an amount of Algo to more advanced features, including:
- the ability to rekey your account to another (giving them full access, and losing your access)
- closing your account (send all of your remaining Algo to them)