Exploring the Algorand Sandbox
In this tutorial, you will explore the Algorand sandbox to get a deeper understanding of its functioning. The goal is to show you what information certain files contain, access the Docker containers and their files, or change network configurations. This tutorial complements the introduction tutorial for the sandbox created by Sam Abbassi. Make sure to follow the installation instructions in Sam’s tutorial to set up the Algorand sandbox.
Here’s an overview of what you will do:
- Start a default network
- Explore the
sandnet-v1
genesis file inside the Algod container - Explore configuration files
- Copy files into and outside the Algod container
- Use the TEAL debugger command tealdbg
Let’s get started!
Requirements
- Active Sandbox installation using this tutorial
Steps
Step 1: Start the Algorand sandbox with the default configuration
First, let’s make sure that your installation is working as expected. Therefore, start the node with the default configuration using the following command inside the sandbox folder.
./sandbox up
By default, the script will execute some commands like retrieving the node status. Here’s an overview of the node status:
As you can see, the node contains only one committed block because this is a new Algorand network. Also, note that the Genesis ID
points to an identifier called sandnet-v1
. In the next step, you’ll explore this genesis file.
Besides the node status, it will print all active accounts using goal account list
. You’ll find those accounts later in the genesis file.
[online] T5SVL76GT3NCUPV3J7D4QCFCWFAGZO6CTPZGSU5SXPISOR55ESOWFL26MY 4000000000000000 microAlgos
[offline] 2XMFQ6F5DREAA5MEP7WTMY276YMQS4HOLSOIVEPUAZ3477G6KSLAR4267A 1000000000000000 microAlgos
[offline] 4NRRJYWM7NYVAVPPW3XU5YI3A3RTZPXRIK7DNXDRP3NWUCKKWDQHXZ4RCA 4000000000000000 microAlgos
Next, let’s explore the genesis.json
file.
Step 2: Exploring the genesis.json file
Next, we want to retrieve the sandnet-v1
genesis file. Let’s learn how to enter a Docker container to explore the files inside the container, such as the genesis file and other configuration files. To do so, we have to tell the sandbox script to enter the Algod container. You can use the same command to enter other containers such as the indexer
or indexer-db
containers.
./sandbox enter algod
If you’re wondering how the enter command work, you can look at the sandbox
executable in your editor. At line 292 in the script, you’ll find the implementation details of the command. The command requires you to pass a container name, and the container name must match one of the active container’s names. Furthermore, the script will use the docker exec
command to open a Bash shell inside the container.
Now, let’s print all items inside the folder using the ls
command.
ls
You’ll get the following result.
Let’s take a look at the genesis file.
cat genesis.json
This command will print the contents of the genesis file. It contains all accounts that the goal account list
account has printed. On top of that, the network is named sandnet
, and the id equals v1
, which combined make up the genesis ID.
{
"alloc": [
{
"addr": "7777777777777777777777777777777777777777777777777774MSJUVU",
"comment": "RewardsPool",
"state": {
"algo": 125000000000000,
"onl": 2
}
},
{
"addr": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE",
"comment": "FeeSink",
"state": {
"algo": 100000,
"onl": 2
}
},
{
"addr": "5AO6OPZKSA3W3QXFFOA7ITXFFWZS4MFRTOVMXSFFWQWJLOYSQ44XYPKX6Y",
"comment": "Wallet1",
"state": {
"algo": 1000000000000000,
"onl": 1,
"sel": "OMpQJpMuambHxQ9QIq31B4mOaXNcyLXMl9TpYu3KzWE=",
"vote": "dLw/06AurPLaDWzLlwG5sUeqboFeQS3cFtZE+oL+Du8=",
"voteKD": 100,
"voteLst": 3000000
}
},
{
"addr": "T5SVL76GT3NCUPV3J7D4QCFCWFAGZO6CTPZGSU5SXPISOR55ESOWFL26MY",
"comment": "Wallet2",
"state": {
"algo": 4000000000000000,
"onl": 1,
"sel": "TL1+M4igP4jJVjVdqL4+tj6pDPHfiRoGBNPK38pPaXg=",
"vote": "zmXZ8jodrv+UhKGYpqUQmadkJdCF57r/MMw4DsvHN2I=",
"voteKD": 100,
"voteLst": 3000000
}
},
{
"addr": "4NRRJYWM7NYVAVPPW3XU5YI3A3RTZPXRIK7DNXDRP3NWUCKKWDQHXZ4RCA",
"comment": "Wallet3",
"state": {
"algo": 4000000000000000
}
},
{
"addr": "2XMFQ6F5DREAA5MEP7WTMY276YMQS4HOLSOIVEPUAZ3477G6KSLAR4267A",
"comment": "Wallet4",
"state": {
"algo": 1000000000000000
}
}
],
"fees": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE",
"id": "v1",
"network": "sandnet",
"proto": "https://github.com/algorandfoundation/specs/tree/65b4ab3266c52c56a0fa7d591754887d68faad0a",
"rwd": "7777777777777777777777777777777777777777777777777774MSJUVU"
}
So, what else can we find?
Step 3: Looking up Algorand config
Interestingly, we can find other files besides the genesis file. Inspect the contents of the algod.net
file using cat algod.net
results in the following output.
[::]:4001
This output refers to localhost:4001
which is the configured address to which the Algod API is exposed.
Alternatively, we can also inspect the algod.token
file. It will print the authorization token for making requests to the Algod API.
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
However, we don’t have to look for this information inside our container. Take a look at the sandbox/docker-compose.yml
file, which sets all these configuration parameters.
version: '3'
services:
algod:
container_name: "algorand-sandbox-algod"
build:
context: .
dockerfile: ./images/algod/Dockerfile
args:
CHANNEL: "${ALGOD_CHANNEL}"
URL: "${ALGOD_URL}"
BRANCH: "${ALGOD_BRANCH}"
SHA: "${ALGOD_SHA}"
BOOTSTRAP_URL: "${NETWORK_BOOTSTRAP_URL}"
GENESIS_FILE: "${NETWORK_GENESIS_FILE}"
TEMPLATE: "${NETWORK_TEMPLATE:-/tmp/images/algod/template.json}"
TOKEN: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
ALGOD_PORT: "4001"
KMD_PORT: "4002"
ports:
- 4001:4001
- 4002:4002
Actually, we can use this information to query the Algod API and retrieve, for instance, the node status manually instead of using goal node status
. It will print the same information as the info shown in the screenshot when starting the network for the first time.
curl localhost:4001/v1/status -H "X-Algo-API-Token: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Cool, let’s try to set up a custom network using your own genesis.json file.
Step 4: Copying files into and from the sandbox
In order to copy a file into your sandbox, let’s create a simple TEAL file called fee.teal
. This TEAL program will check if the transaction fee for a call to the stateless contract is equal to or less than 10,000 microAlgos. It’s a very simple demo contract that we will use in later steps to show the debugging functionality.
Make sure to create the fee.teal
file inside your sandbox folder to keep things simple. Paste the below contents in this file.
#pragma version 4
// Demo contract to check for fee equal to or lower than 10000
txn Fee
int 10000
<=
Good! Now, let’s copy this file to our debugger. We can use the copyTo
command for this.
copyTo <file> -> copy <file> into the algod. Useful for offline transactions, offline LogicSigs & TEAL work.
Here’s an example. If you placed the fee.teal
file in a different folder, make sure to pass the absolute path to this file.
./sandbox copyTo "fee.teal"
This command will now make a copy of the fee.teal
program and place it inside our algod
container. Under the hood, the command uses the docker cp
command.
docker cp "$1" "$(dc ps -q algod):/opt/data/$(basename $1)"
Now the file sits inside our Algod container at the following path /opt/<network>/Node
. This also the default path you enter when using ./sandbox enter algod
.
Ok, let’s generate a test transaction that we can use with our debugger. Let’s send a correct transaction with a fee of 9,999 which is below 10,000 microAlgos. We have to write the transaction to a file so we can later use it in our debugger with the -o
flag. Also, we have to pass the --dryrun-dump
flag to get the output in JSON format.
./sandbox goal clerk send -a 30000 --from-program fee.teal -c <address> -t <address> --fee 9999 -o fee.txn --dryrun-dump
./sandbox goal clerk send -a 30000 --from-program fee.teal -c YQN5DM7MHVRNIWAH3JYDFWEYC6LDH7PAW35I5SL4TXBNEP3TREOOFMBXXI -t YQN5DM7MHVRNIWAH3JYDFWEYC6LDH7PAW35I5SL4TXBNEP3TREOOFMBXXI --fee 9999 -o fee.txn --dryrun-dump
To show you how to retrieve this file, let’s copy it to our local machine from the container using copyFrom
.
./sandbox copyFrom fee.txn
Lastly, let’s use this file with the debugger. We can do it like this
./sandbox tealdbg debug fee.teal -d fee.txn
This will spin up a websocket connection which you can use with your Chrome DevTools.
tealdbg debug command called without --listen option therefore sandbox attached the option automatically!
2021/10/02 15:06:12 Using proto: https://github.com/algorandfoundation/specs/tree/bc36005dbd776e6d1eaf0c560619bb183215645c
2021/10/02 15:06:12 Run mode: logicsig
2021/10/02 15:06:12 ------------------------------------------------
2021/10/02 15:06:12 CDT debugger listening on: ws://0.0.0.0:9392/2733bbbf81e2892c20aa4004f6196de69816b4ad515f9e852a3ebee5713f7544
2021/10/02 15:06:12 Or open in Chrome:
2021/10/02 15:06:12 devtools://devtools/bundled/js_app.html?experiments=true&v8only=false&ws=0.0.0.0:9392/2733bbbf81e2892c20aa4004f6196de69816b4ad515f9e852a3ebee5713f7544
2021/10/02 15:06:12 ------------------------------------------------
The -d
option expects a dry-run
transaction to be passed. Therefore, we can pass the fee.txn
file which sits inside our Algod container.
You can learn more about debugging specifically by following this tutorial. It will explain how you can debug your TEAL program using the tealdbg
CLI tool.
That’s it!