Building web3 on Algorand

Developer Environment - Setup

Integrated Development Environment (IDE)

The Algorand Community provide many IDEs for development.

VSCode Extention

Sandbox

Algorand Sandbox provides APIs to Algorand infrastructure running locally on your workstation. Docker Desktop is required.

Install

Open a new terminal window and navigate to your desired install directory.

git clone https://github.com/algorand/sandbox
cd sandbox

Starting a local private Algorand network

ℹ️ Recommended Most developers should begin their development process using a local private network. See later section for starting and syncing with a public Algorand network.

./sandbox up dev -v

Sandbox in dev mode provides the following infrastructure components:

Tool Description
algod ledger nodes
goal CLI tool + transaction builder
kmd wallet (key manager)
indexer blockchain queries

ℹ️ Notice indexer is not provided when Sandbox is started on a public Algorand network. User a third-party API provider in this mode.

Default Accounts

Sandbox running as a local private network provides three (3) default accounts when the network is initialized. You may view these accounts at anytime using the following command:

./sandbox goal account list

Sample output:

[online]    QYL3G7H63N3JUH6LUX3LPHWOW6AT2XYQ6GD4E3OP7KBTFKWXGTF7FW3VM4  QYL3G7H63N3JUH6LUX3LPHWOW6AT2XYQ6GD4E3OP7KBTFKWXGTF7FW3VM4  4000000000000000 microAlgos
[online]    RCJBNCQOMRBBBDG4TEVOYKUQMCFMLZ2RUWBQP3HARYBJRH5YBYRP52MFKI  RCJBNCQOMRBBBDG4TEVOYKUQMCFMLZ2RUWBQP3HARYBJRH5YBYRP52MFKI  4000000000000000 microAlgos
[online]    457AGKGZUM5QC5ESLXMGL5YD3I2A7MJDRNPYFBHKJ3PGLZMS4SQYXQBMOE  457AGKGZUM5QC5ESLXMGL5YD3I2A7MJDRNPYFBHKJ3PGLZMS4SQYXQBMOE  2000000000000000 microAlgos

ℹ️ Notice These pre-funded accounts are stored within the default wallet maintained by kmd

Set environment variables for default account addresses for CLI usage:

ADDR1=$($SANDBOX goal account list | awk 'FNR==1{ print $2 }')
ADDR2=$($SANDBOX goal account list | awk 'FNR==2{ print $2 }')
ADDR3=$($SANDBOX goal account list | awk 'FNR==3{ print $2 }')

Display an account Balance Record using:

./sandbox goal account dump --account $ADDR1

First Transaction

Send your first transaction using the goal CLI tool:

./sandbox goal clerk send --amount 123456789 --from $ADDR1 --to $ADDR2
./sandbox goal account dump --account $ADDR1

ℹ️ Notice the --amount flag specifies the unit of microAlgos. 1 ALGO is 1_000_000 microAlgo.

Query Confirmed Transactions

Use curl to query the Indexer for all transactions:

curl "localhost:8980/v2/transactions?pretty"

REST APIs

algod node

Sandbox provides goal as the primary CLI tool for building, signing and sending transactions. SDKs provide clients to algod for accessing REST APIs using:

  • Address: http://localhost:4001
  • Token: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

KMD wallet

Sandbox provides kmd the key management daemon for storing private keys and signing transactions. SDKs provide clients for accessing REST APIs using:

  • Address: http://localhost:4002
  • Token: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

ℹ️ Notice goal will automatically start kmd when requesting transaction signing. SDK clients must ensure kmd is running to successfully access the REST APIs.

Indexer

Sandbox provides indexer as the primary query tool for committed blockchain data. SDKs provide clients for accessing REST APIs using:

  • Address: http://localhost:8980

ℹ️ Notice A token is not required

SDKs

Algorand provides SDKs in four languages:

Algorand Community supported SDKs are avilable in many additional languages.

Install Python SDK

Open a new terminal window.

pip3 install py-algorand-sdk

Account Generation

Open 1-acount_generation.py

from algosdk import account, mnemonic

def generate_algorand_keypair():
    private_key, address = account.generate_account()
    print("My address: {}".format(address))
    print("My private key: {}".format(private_key))
    print("My passphrase: {}".format(mnemonic.from_private_key(private_key)))

generate_algorand_keypair()

Account balance

Open 2-account_balance.py

Create KMD client and connect to default wallet

# define sandbox values for kmd client
kmd_address = "http://localhost:4002"
kmd_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
kmd_client = kmd.KMDClient(kmd_token, kmd_address)

# connect to default wallet
wallet = Wallet("unencrypted-default-wallet", "", kmd_client)

Create algod client

# define sandbox values for algod client
algod_address = "http://localhost:4001"
algod_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
algod_client = algod.AlgodClient(algod_token, algod_address)

Check balance

# check account balance
account_info = algod_client.account_info(addr1)
print("addr1 balance: {} microAlgos".format(account_info.get('amount')) + "\n")

ℹ️ Notice Before sending transactions to the Algorand network, the account must be funded to cover required transaction fees. Use the Algorand TestNet Dispenser. ​

Payment transaction

Open 3-payment_transaction.py

build unsigned transaction

params = algod_client.suggested_params()
receiver = addr2
note = "Hello World".encode()
amount = 1000000
unsigned_txn = transaction.PaymentTxn(addr1, params, receiver, amount, None, note)

sign transaction

signed_txn = unsigned_txn.sign(wallet.export_key(addr1))

submit transaction

txid = algod_client.send_transaction(signed_txn)
print("Successfully sent transaction with txID: {}".format(txid))

Asset Creation (ASA)

Open 4-create_asset.py

unsigned_txn = AssetConfigTxn(sender=addr1,
        sp=params,
        total=10000,   # Fungible tokens have total issuance greater than 1
        default_frozen=False,
        unit_name="FUNTOK",
        asset_name="Fun Token",
        manager=addr1,
        strict_empty_address_check=False,
        reserve="",
        freeze="",
        clawback="",
        url="https://path/to/my/fungible/asset/metadata.json",
        metadata_hash="", # Typically include hash of metadata.json (bytes) 
        decimals=2    # Fungible tokens typically have decimals greater than 0
)

Asset Optin

By default the creator account is optin to hold the asset, all other accounts must make an asset optin transaction for each asset they desire to hold.

Open 5-assest_optin.py

# build unsigned transaction
params = algod_client.suggested_params()
sender = addr2
index = 5 # this is the asset-index returned by asset_create.py
unsigned_txn = transaction.AssetOptInTxn(sender, params, index)

Atomic Transactions

Atomic transactions enforce execution of a defined set of ordered transations will either all succeed, else no state transitions will persist upon failure of any transaction therein. Typically used in asset swaps and smart contract calls.

Swap ALGO for FUNTOK

Open 6-atomic_transaction.py

build unsigned payment transaction

params = algod_client.suggested_params()
sender = addr2
receiver = addr1
amount = 1000000
txn_1 = transaction.PaymentTxn(sender, params, receiver, amount)

build unsigned asset transfer transaction

sender = addr1
receiver = addr2
amount = 10
index = 5   # this is the asset-index returned by asset_create.py 
txn_2 = transaction.AssetTransferTxn(sender, params, receiver, amount, index)
group transactions
gid = transaction.calculate_group_id([txn_1, txn_2])
txn_1.group = gid
txn_2.group = gid

sign transaction

stxn_1 = txn_1.sign(wallet.export_key(addr2))    
stxn_2 = txn_2.sign(wallet.export_key(addr1))

assemble transaction group

signed_group = [stxn_1, stxn_2]

submit atomic transaction group

txid = algod_client.send_transactions(signed_group)

Smart Contracts

Programs

State Schema

Deploying

Calling