Tutorials
No Results
Tutorial Thumbnail Image

Beginner · 15 minutes or less

Create an Asset using Go

This tutorial demonstrates the steps involved in creating a basic Algorand Standard Asset (ASA). This tutorial can be completed on its own or can be done in conjunction with the follow-up tutorials: Asset Reconfigure, Opt-In, Asset Transfer, Asset Freeze, Asset Revoke, and Asset Destroy. Completing this tutorial will set you up for the subsequent four tutorials. Only two accounts are required to create an ASA in this tutorial, but we will need three accounts total for the subsequent four tutorials.

Completed code for this tutorial can be found at the bottom of the page. A complete set of code for all ASA tutorials can be found here CreateNewAccounts.go and TutorialAssetExample.go.

Requirements

Recommended sequence, if you are new to ASA:

Optional:

Background

Algorand Standard Assets (ASA) allow developers to create fungible and non-fungible assets with a few method calls. ASA’s are highly customizable with parameters that allow developers to define total issuance of an asset, name of asset, units of an asset, as well as access controls privileges over an asset.

There are a few items to be aware of before getting started with assets as documented in the ASA feature guide overview on the developer portal.

Also, see more information on decimals.

Note: Copy off the AssetID , from this tutorial as it will be used in subsequent tutorials.

Steps

1. Instantiate Algod Wrapper

In this step, we are passing in the token, server, and port values from a local node or local sandbox instance. You can also connect to remote node using a third-party serice. loadAccounts() and PrettyPrint() functions will be described in the next step.

// Main function to demonstrate ASA examples
func main() {
    // Initialize an algodClient
    algodClient, err := algod.MakeClient(algodAddress, algodToken)
    if err != nil {
        return
    }
    // Get network-related transaction parameters and assign
    txParams, err := algodClient.SuggestedParams()
    if err != nil {
        fmt.Printf("error getting suggested tx params: %s\n", err)
        return
    }
    // Get pre-defined set of keys for example
    sks, pks := loadAccounts()

    // Print asset info for newly created asset.
    PrettyPrint(txParams)
    PrettyPrint(sks)
    PrettyPrint(pks)
}


Learn More
- Connect to an Algorand Node
- Algorand Node Setup

2. Recover, define and print Accounts, utility functions and structures

Hardcoding and recovering accounts in this way is not advised, for security purposes, but is sufficient for this tutorial.

Note: If you have not already done so, use this tutorial to Create Accounts

This tutorial will use TestNet accounts that have been pre-created the Create Accounts tutorial. Be sure to dispense Algos to these accounts before continuing, using the TestNet Dispenser.

package main

import (
    "crypto/ed25519"
//  b64 "encoding/base64"
    json "encoding/json"
    "fmt"

    "github.com/algorand/go-algorand-sdk/client/algod"
//  "github.com/algorand/go-algorand-sdk/crypto"
    "github.com/algorand/go-algorand-sdk/mnemonic"
//  "github.com/algorand/go-algorand-sdk/transaction"
    "github.com/algorand/go-algorand-sdk/types"
)

// UPDATE THESE VALUES

// const algodAddress = "Your ADDRESS"
// const algodToken = "Your TOKEN"

// hackathon
// const algodAddress = "http://hackathon.algodev.network:9100"
// const algodToken = "ef920e2e7e002953f4b29a8af720efe8e4ecc75ff102b165e0472834b25832c1"

// sandbox
const algodAddress = "http://localhost:4001"
const algodToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

var txHeaders = append([]*algod.Header{}, &algod.Header{"Content-Type", "application/json"})

// Accounts to be used through examples
func loadAccounts() (map[int][]byte, map[int]string) {
    // Shown for demonstration purposes. NEVER reveal secret keys and mnemonics in practice.
    // Change these mnemonic values to use the accounts created previously.

    // Paste in mnemonic phrases for all three accounts
    // mnemonic1 := "PASTE your phrase for account 1"
    // mnemonic2 := "PASTE your phrase for account 2"
    // mnemonic3 := "PASTE your phrase for account 3"

    mnemonic1 := "portion never forward pill lunch organ biology weird catch curve isolate plug innocent skin grunt bounce clown mercy hole eagle soul chunk type absorb trim"
    mnemonic2 := "place blouse sad pigeon wing warrior wild script problem team blouse camp soldier breeze twist mother vanish public glass code arrow execute convince ability there"
    mnemonic3 := "image travel claw climb bottom spot path roast century also task cherry address curious save item clean theme amateur loyal apart hybrid steak about blanket"

    mnemonics := []string{mnemonic1, mnemonic2, mnemonic3}
    pks := map[int]string{1: "", 2: "", 3: ""}
    var sks = make(map[int][]byte)

    for i, m := range mnemonics {
        var err error
        sk, err := mnemonic.ToPrivateKey(m)
        sks[i+1] = sk
        if err != nil {
            fmt.Printf("Issue with account %d private key conversion.", i+1)
        }
        // derive public address from Secret Key.
        pk := sk.Public()
        var a types.Address
        cpk := pk.(ed25519.PublicKey)
        copy(a[:], cpk[:])
        pks[i+1] = a.String()
        fmt.Printf("Loaded Key %d: %s\n", i+1, pks[i+1])
    }
    return sks, pks
}

// Function that waits for a given txId to be confirmed by the network
func waitForConfirmation(algodClient algod.Client, txID string) {
    nodeStatus, err := algodClient.Status()
    if err != nil {
        fmt.Printf("error getting algod status: %s\n", err)
        return
    }
    lastRound := nodeStatus.LastRound
    for {
        pt, err := algodClient.PendingTransactionInformation(txID)
        if err != nil {
            fmt.Printf("waiting for confirmation... (pool error, if any): %s\n", err)
            continue
        }
        if pt.ConfirmedRound > 0 {
            fmt.Printf("Transaction "+pt.TxID+" confirmed in round %d\n", pt.ConfirmedRound)
            break
        }
        lastRound++
        algodClient.StatusAfterBlock(lastRound)
    }
}

// PrettyPrint prints Go structs
func PrettyPrint(data interface{}) {
    var p []byte
    //    var err := error
    p, err := json.MarshalIndent(data, "", "\t")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("%s \n", p)
}

    // Debug console should look similar to this...

    // Loaded Key 1: THQHGD4HEESOPSJJYYF34MWKOI57HXBX4XR63EPBKCWPOJG5KUPDJ7QJCM
    // Loaded Key 2: AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU
    // Loaded Key 3: 3ZQ3SHCYIKSGK7MTZ7PE7S6EDOFWLKDQ6RYYVMT7OHNQ4UJ774LE52AQCU
    // {
    //  "fee": 1,
    //  "genesisID": "testnet-v1.0",
    //  "genesishashb64": "SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
    //  "lastRound": 4268229,
    //  "consensusVersion": "https://github.com/algorandfoundation/specs/tree/4a9db6a25595c6fd097cf9cc137cc83027787eaa"
    // }
    // {
    //  "1": "QkWlt0yawnHOIvkgkQ3tbEo6KudsGmDRYtlQ1OeieN2Z4HMPhyEk58kpxgu+MspyO/PcN+Xj7ZHhUKz3JN1VHg==",
    //  "2": "Lg1Ge0vafd1jv8FbrXcwDEJnbnA9kIpH68XQUoY88SUCWtLBvxyj+BMf96v0jNvrns7vMml+KmvcBZzqGlkLFg==",
    //  "3": "iuM5VLAiDUsfFLsr0QG8d7KB1/jXdlIBeA9IKAXAoXreYbkcWEKkZX2Tz95Py8Qbi2WocPRxirJ/cdsOUT//Fg=="
    // }
    // {
    //  "1": "THQHGD4HEESOPSJJYYF34MWKOI57HXBX4XR63EPBKCWPOJG5KUPDJ7QJCM",
    //  "2": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU",
    //  "3": "3ZQ3SHCYIKSGK7MTZ7PE7S6EDOFWLKDQ6RYYVMT7OHNQ4UJ774LE52AQCU"
    // }


Learn More
- Algorand Standalone Account Creation Methods

3. Define Asset Create Transaction Parameters

We need to define the Create Asset Transaction parameters. Paste this snippet at the end of the main function.

Uncomment these imports at the top of the code:

- b64 "encoding/base64"

- "github.com/algorand/go-algorand-sdk/transaction"

- "github.com/algorand/go-algorand-sdk/crypto"

    // Create an Asset
    // uncomment these imports at the top
    //  -   b64 "encoding/base64"
    //  -   "github.com/algorand/go-algorand-sdk/transaction"
    //  -   "github.com/algorand/go-algorand-sdk/crypto"
    fee := txParams.Fee
    firstRound := txParams.LastRound
    lastRound := txParams.LastRound + 1000
    genHash := b64.StdEncoding.EncodeToString(txParams.GenesisHash)
    genID := txParams.GenesisID

    // Create an asset
    // Set parameters for asset creation transaction
    creator := pks[1]
    assetName := "latinum"
    unitName := "latinum"
    assetURL := "https://path/to/my/asset/details"
    assetMetadataHash := "thisIsSomeLength32HashCommitment"
    defaultFrozen := false
    decimals := uint32(0)
    totalIssuance := uint64(1000)
    manager := pks[2]
    reserve := pks[2]
    freeze := pks[2]
    clawback := pks[2]
    note := []byte(nil)


Learn More
- Algorand Asset Parameters
- Common Transaction Fields

4. Create an ASA transaction object

Use the MakeAssetCreateTxn transaction method to create an Asset.

    txn, err := transaction.MakeAssetCreateTxn(creator, fee, firstRound, lastRound, note,
        genID, genHash, totalIssuance, decimals, defaultFrozen, manager, reserve, freeze, clawback,
        unitName, assetName, assetURL, assetMetadataHash)
    if err != nil {
        fmt.Printf("Failed to make asset: %s\n", err)
        return
    }
    fmt.Printf("Asset created AssetName: %s\n", txn.AssetConfigTxnFields.AssetParams.AssetName)

5. Sign Transaction

Sign the transaction.

    txid, stx, err := crypto.SignTransaction(sks[1], txn)
    if err != nil {
        fmt.Printf("Failed to sign transaction: %s\n", err)
        return
    }
    fmt.Printf("Transaction ID: %s\n", txid)

6. Send Create ASA Transaction to the Blockchain and print the Tx and Assets IDs

Broadcast the transaction to the blockchain.

    // Broadcast the transaction to the network
    sendResponse, err := algodClient.SendRawTransaction(stx)
    if err != nil {
        fmt.Printf("failed to send transaction: %s\n", err)
        return
    }

    // Wait for transaction to be confirmed
    waitForConfirmation(algodClient, sendResponse.TxID)

    // Retrieve asset ID by grabbing the max asset ID
    // from the creator account's holdings.
    act, err := algodClient.AccountInformation(pks[1], txHeaders...)
    if err != nil {
        fmt.Printf("failed to get account information: %s\n", err)
        return
    }
    assetID := uint64(0)
    for i, _ := range act.AssetParams {
        if i > assetID {
            assetID = i
        }
    }
    fmt.Printf("Asset ID from AssetParams: %d\n", assetID)

    // Retrieve asset info.
    assetInfo, err := algodClient.AssetInformation(assetID, txHeaders...)

    // Print asset info for newly created asset.
    PrettyPrint(assetInfo)

7. Check the transaction on a block explorer

Once you’ve completed these steps your output should look like this:

Loaded Key 1: THQHGD4HEESOPSJJYYF34MWKOI57HXBX4XR63EPBKCWPOJG5KUPDJ7QJCM
Loaded Key 2: AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU
Loaded Key 3: 3ZQ3SHCYIKSGK7MTZ7PE7S6EDOFWLKDQ6RYYVMT7OHNQ4UJ774LE52AQCU
{
    "fee": 1,
    "genesisID": "testnet-v1.0",
    "genesishashb64": "SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
    "lastRound": 6108309,
    "consensusVersion": "https://github.com/algorandfoundation/specs/tree/4a9db6a25595c6fd097cf9cc137cc83027787eaa",
    "minFee": 1000
} 
{
    "1": "QkWlt0yawnHOIvkgkQ3tbEo6KudsGmDRYtlQ1OeieN2Z4HMPhyEk58kpxgu+MspyO/PcN+Xj7ZHhUKz3JN1VHg==",
    "2": "Lg1Ge0vafd1jv8FbrXcwDEJnbnA9kIpH68XQUoY88SUCWtLBvxyj+BMf96v0jNvrns7vMml+KmvcBZzqGlkLFg==",
    "3": "iuM5VLAiDUsfFLsr0QG8d7KB1/jXdlIBeA9IKAXAoXreYbkcWEKkZX2Tz95Py8Qbi2WocPRxirJ/cdsOUT//Fg=="
} 
{
    "1": "THQHGD4HEESOPSJJYYF34MWKOI57HXBX4XR63EPBKCWPOJG5KUPDJ7QJCM",
    "2": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU",
    "3": "3ZQ3SHCYIKSGK7MTZ7PE7S6EDOFWLKDQ6RYYVMT7OHNQ4UJ774LE52AQCU"
} 
Asset created AssetName: latinum
Transaction ID: 6PQZDFX422ATWB2ESKGH7VIXQFX6VUY5MUNVACHQHZESBJIR6QQQ
Transaction 6PQZDFX422ATWB2ESKGH7VIXQFX6VUY5MUNVACHQHZESBJIR6QQQ confirmed in round 6108313
Asset ID from AssetParams: 332920
{
    "creator": "THQHGD4HEESOPSJJYYF34MWKOI57HXBX4XR63EPBKCWPOJG5KUPDJ7QJCM",
    "total": 1000,
    "decimals": 0,
    "defaultfrozen": false,
    "unitname": "latinum",
    "assetname": "latinum",
    "url": "https://path/to/my/asset/details",
    "metadatahash": "dGhpc0lzU29tZUxlbmd0aDMySGFzaENvbW1pdG1lbnQ=",
    "managerkey": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU",
    "reserveaddr": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU",
    "freezeaddr": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU",
    "clawbackaddr": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU"
} 

You can check the asset creation transaction on a block explorer for reference.

Note: Copy off the AssetID , as it will be used in subsequent tutorials.


Learn More
- Algorand Block Explorers

8. Complete Example

Here is the completed code to Create an Asset.

package main

import (
    "crypto/ed25519"
    b64 "encoding/base64"
    json "encoding/json"
    "fmt"

    "github.com/algorand/go-algorand-sdk/client/algod"
    "github.com/algorand/go-algorand-sdk/crypto"
    "github.com/algorand/go-algorand-sdk/mnemonic"
    "github.com/algorand/go-algorand-sdk/transaction"
    "github.com/algorand/go-algorand-sdk/types"
)

// UPDATE THESE VALUES

// const algodAddress = "Your ADDRESS"
// const algodToken = "Your TOKEN"

// sandbox
const algodAddress = "http://localhost:4001"
const algodToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

var txHeaders = append([]*algod.Header{}, &algod.Header{"Content-Type", "application/json"})

// Accounts to be used through examples
func loadAccounts() (map[int][]byte, map[int]string) {
    // Shown for demonstration purposes. NEVER reveal secret mnemonics in practice.
    // Change these values to use the accounts created previously.

    // Paste in mnemonic phrases for all three accounts
    // mnemonic1 := "PASTE your phrase for account 1"
    // mnemonic2 := "PASTE your phrase for account 2"
    // mnemonic3 := "PASTE your phrase for account 3"

    mnemonic1 := "portion never forward pill lunch organ biology weird catch curve isolate plug innocent skin grunt bounce clown mercy hole eagle soul chunk type absorb trim"
    mnemonic2 := "place blouse sad pigeon wing warrior wild script problem team blouse camp soldier breeze twist mother vanish public glass code arrow execute convince ability there"
    mnemonic3 := "image travel claw climb bottom spot path roast century also task cherry address curious save item clean theme amateur loyal apart hybrid steak about blanket"

    mnemonics := []string{mnemonic1, mnemonic2, mnemonic3}
    pks := map[int]string{1: "", 2: "", 3: ""}
    var sks = make(map[int][]byte)

    for i, m := range mnemonics {
        var err error
        sk, err := mnemonic.ToPrivateKey(m)
        sks[i+1] = sk
        if err != nil {
            fmt.Printf("Issue with account %d private key conversion.", i+1)
        }
        // derive public address from Secret Key.
        pk := sk.Public()
        var a types.Address
        cpk := pk.(ed25519.PublicKey)
        copy(a[:], cpk[:])
        pks[i+1] = a.String()
        fmt.Printf("Loaded Key %d: %s\n", i+1, pks[i+1])
    }
    return sks, pks
}

// Function that waits for a given txId to be confirmed by the network
func waitForConfirmation(algodClient algod.Client, txID string) {
    nodeStatus, err := algodClient.Status()
    if err != nil {
        fmt.Printf("error getting algod status: %s\n", err)
        return
    }
    lastRound := nodeStatus.LastRound
    for {
        pt, err := algodClient.PendingTransactionInformation(txID)
        if err != nil {
            fmt.Printf("waiting for confirmation... (pool error, if any): %s\n", err)
            continue
        }
        if pt.ConfirmedRound > 0 {
            fmt.Printf("Transaction "+pt.TxID+" confirmed in round %d\n", pt.ConfirmedRound)
            break
        }
        lastRound++
        algodClient.StatusAfterBlock(lastRound)
    }
}

// PrettyPrint prints Go structs
func PrettyPrint(data interface{}) {
    var p []byte
    //    var err := error
    p, err := json.MarshalIndent(data, "", "\t")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("%s \n", p)
}

// Main function to demonstrate ASA examples
func main() {
    // Initialize an algodClient
    algodClient, err := algod.MakeClient(algodAddress, algodToken)
    if err != nil {
        return
    }

    // Get network-related transaction parameters and assign
    txParams, err := algodClient.SuggestedParams()
    if err != nil {
        fmt.Printf("error getting suggested tx params: %s\n", err)
        return
    }

    // Get pre-defined set of keys for example
    sks, pks := loadAccounts()

    // Print asset info for newly created asset.
    PrettyPrint(txParams)
    PrettyPrint(sks)
    PrettyPrint(pks)
    // note: you would not normally show secret keys for security reasons,
    // they are shown here for tutorial clarity

    // Debug console should look similar to this...

    // Loaded Key 1: THQHGD4HEESOPSJJYYF34MWKOI57HXBX4XR63EPBKCWPOJG5KUPDJ7QJCM
    // Loaded Key 2: AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU
    // Loaded Key 3: 3ZQ3SHCYIKSGK7MTZ7PE7S6EDOFWLKDQ6RYYVMT7OHNQ4UJ774LE52AQCU
    // {
    //  "fee": 1,
    //  "genesisID": "testnet-v1.0",
    //  "genesishashb64": "SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
    //  "lastRound": 4268229,
    //  "consensusVersion": "https://github.com/algorandfoundation/specs/tree/4a9db6a25595c6fd097cf9cc137cc83027787eaa"
    // }
    // {
    //  "1": "QkWlt0yawnHOIvkgkQ3tbEo6KudsGmDRYtlQ1OeieN2Z4HMPhyEk58kpxgu+MspyO/PcN+Xj7ZHhUKz3JN1VHg==",
    //  "2": "Lg1Ge0vafd1jv8FbrXcwDEJnbnA9kIpH68XQUoY88SUCWtLBvxyj+BMf96v0jNvrns7vMml+KmvcBZzqGlkLFg==",
    //  "3": "iuM5VLAiDUsfFLsr0QG8d7KB1/jXdlIBeA9IKAXAoXreYbkcWEKkZX2Tz95Py8Qbi2WocPRxirJ/cdsOUT//Fg=="
    // }
    // {
    //  "1": "THQHGD4HEESOPSJJYYF34MWKOI57HXBX4XR63EPBKCWPOJG5KUPDJ7QJCM",
    //  "2": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU",
    //  "3": "3ZQ3SHCYIKSGK7MTZ7PE7S6EDOFWLKDQ6RYYVMT7OHNQ4UJ774LE52AQCU"
    // }

    // Create an Asset
    // uncomment these imports at the top
    //  -   b64 "encoding/base64"
    //  -   "github.com/algorand/go-algorand-sdk/transaction"
    //  -   "github.com/algorand/go-algorand-sdk/crypto"
    fee := txParams.Fee
    firstRound := txParams.LastRound
    lastRound := txParams.LastRound + 1000
    genHash := b64.StdEncoding.EncodeToString(txParams.GenesisHash)
    genID := txParams.GenesisID

    // Create an asset
    // Set parameters for asset creation transaction
    creator := pks[1]
    assetName := "latinum"
    unitName := "latinum"
    assetURL := "https://path/to/my/asset/details"
    assetMetadataHash := "thisIsSomeLength32HashCommitment"
    defaultFrozen := false
    decimals := uint32(0)
    totalIssuance := uint64(1000)
    manager := pks[2]
    reserve := pks[2]
    freeze := pks[2]
    clawback := pks[2]
    note := []byte(nil)
    txn, err := transaction.MakeAssetCreateTxn(creator, fee, firstRound, lastRound, note,
        genID, genHash, totalIssuance, decimals, defaultFrozen, manager, reserve, freeze, clawback,
        unitName, assetName, assetURL, assetMetadataHash)
    if err != nil {
        fmt.Printf("Failed to make asset: %s\n", err)
        return
    }
    fmt.Printf("Asset created AssetName: %s\n", txn.AssetConfigTxnFields.AssetParams.AssetName)

    txid, stx, err := crypto.SignTransaction(sks[1], txn)
    if err != nil {
        fmt.Printf("Failed to sign transaction: %s\n", err)
        return
    }
    fmt.Printf("Transaction ID: %s\n", txid)
    // Broadcast the transaction to the network
    sendResponse, err := algodClient.SendRawTransaction(stx)
    if err != nil {
        fmt.Printf("failed to send transaction: %s\n", err)
        return
    }

    // Wait for transaction to be confirmed
    waitForConfirmation(algodClient, sendResponse.TxID)

    // Retrieve asset ID by grabbing the max asset ID
    // from the creator account's holdings.
    act, err := algodClient.AccountInformation(pks[1], txHeaders...)
    if err != nil {
        fmt.Printf("failed to get account information: %s\n", err)
        return
    }
    assetID := uint64(0)
    for i, _ := range act.AssetParams {
        if i > assetID {
            assetID = i
        }
    }
    fmt.Printf("Asset ID from AssetParams: %d\n", assetID)

    // Retrieve asset info.
    assetInfo, err := algodClient.AssetInformation(assetID, txHeaders...)

    // Print asset info for newly created asset.
    PrettyPrint(assetInfo)
    // // terminal output should look similar to this
    // // Asset created AssetName: latinum
    // // Transaction ID: 4P4ACUIZTWYGFPSRZ6BPD4P64XZCYN2ZOHO33N4V7TYE2KWWDA4Q
    // // Transaction 4P4ACUIZTWYGFPSRZ6BPD4P64XZCYN2ZOHO33N4V7TYE2KWWDA4Q confirmed in round 4308303
    // // Asset ID from AssetParams: 151771
    // // {
    // //   "creator": "THQHGD4HEESOPSJJYYF34MWKOI57HXBX4XR63EPBKCWPOJG5KUPDJ7QJCM",
    // //   "total": 1000,
    // //   "decimals": 0,
    // //   "defaultfrozen": false,
    // //   "unitname": "latinum",
    // //   "assetname": "latinum",
    // //   "url": "https://path/to/my/asset/details",
    // //   "metadatahash": "dGhpc0lzU29tZUxlbmd0aDMySGFzaENvbW1pdG1lbnQ=",
    // //   "managerkey": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU",
    // //   "reserveaddr": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU",
    // //   "freezeaddr": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU",
    // //   "clawbackaddr": "AJNNFQN7DSR7QEY766V7JDG35OPM53ZSNF7CU264AWOOUGSZBMLMSKCRIU"
    // // }
}

Note: Copy off the AssetID , as it will be used in subsequent tutorials.

Next Tutorial: Change Asset Manager Tutorial

asa

assets

asset creation

standalone accounts

go

create assets

algorand standard assets

v1 api

April 11, 2020