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:

  1. Import our necessary modules
  2. Define our AlgodClient to initiate a connection to the chain
  3. Define our account's address and private key that we will be sending transactions from
  4. Define an amount of Algorand to send
  5. Obtain the params needed for all transactions
  6. Generate a new account for testing, so we have an address to send testnet Algorand to
  7. Define our payment transaction and its parameters
  8. Sign the transaction with our private key
  9. Assign the result of sending our signed transaction with the send_transaction() function from the AlgodClient class
  10. 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)

Quiz

Question 1

What function is used to generate a new account in the Algorand Go SDK?





Question 2

Which function is used to convert a private key to a mnemonic in the Algorand Go SDK?





Question 3

How do you convert an amount in Algos to microAlgos in the Algorand Go SDK?

amount := 1.001

// Convert Algos -> MicroAlgos:
microAlgoAmount := uint64(types.ToMicroAlgos(algos))




Question 4

Which function is used to sign a transaction in the Algorand Go SDK?





Code Editor