L2 Applications On Algorand: How to Make Your Own Coin
By: Evan Richard
Tags: Cryptocurrency, Developers, Blockchain, Algorand, From Our Team

THE IDEA

I often get asked this question:

WELL-MEANING FRIEND OR RELATIVE: Oh, Evan, you work in the cryptocurrencies industry? Oh-ho, are you making your own coin, when is EvanCoin coming, oh-ho?

ME: Ha-ha, oh, it’s not like that [blah blah blah]

Eventually I got fed up, now I answer:

ME: (suddenly intense) It will be coming very shortly and it will be built on Algorand.

This surprises people, but it really is that easy to build your own layer two application on Algorand! (A layer two application on Algorand will typically consist of an application that manipulates data using Algorand transaction’s note fields. This is as opposed to layer one code, the code that lives in the protocol itself.)

Today, I will show you a demo I made using the Algorand go SDK: examplecoin . The examplecoin demo lets you build your own personal coin on top of Algorand! In this demo I will initialize EvanCoin on the Algorand blockchain, and transfer some EvanCoin from one account to another. Checking out the Algorand developer documentation might help you follow along, too.

THE APPLICATION

You can find examplecoin on my GitHub. It allows a developer to initialize an example coin on the Algorand blockchain, and tabulate the current balances of any example coin on that chain, so long as the coin’s master key is known.

To do this, the examplecoin application uses the Note field of Algorand transactions. It places base64 encoded data in the note field, and uses Algorand’s account management to make sure the notes come from the correct accounts. The initialization of an examplecoin is a base64 blob placed in a transaction, as is the transfer of an examplecoin . Maybe it’s easier to explain with an example. Here are the examplecoin structs, which are barely more than “who’s sending to whom, and how much?”.

You can then take these structs and convert them into byte arrays, suitable for a transaction’s note field:

You can see more on the full GitHub repo. The idea is that you can then read in these byte arrays and get the NoteField structs back using msgpack.Decode .

Algorand layer two is very flexible, so I want to rephrase and restate what we are doing here: we are taking arbitrary data structures and posting them to the Algorand blockchain, reading back these data structures later, and using that to inform new data operations. This means that you, as an app developer, can build any application you like on top of Algorand. The blockchain is providing you with verifiable secure storage. This also means that, if this application were handling sensitive or private data, we would have to handle the fact that the data is being posted to the public chain.

But we don’t have to care, because this is my own personal examplecoin , EvanCoin. Let’s go make some coin and move it around.

EXAMPLE USAGE

Below is a snippet that produces the blob for initializing an examplecoin and transferring examplecoin to another account. The coinKey variable is the address determining the master of the examplecoin : you could sort of consider it analogous to an ERC20 contract address. The receiverKey is the account receiving the examplecoin . Since this demonstration is just for me, and I intend to keep all EvanCoin to myself (everyone keeps asking me for EvanCoin, too bad, they can’t have any), I’ll just create uint64(100) coins, and transfer half to another account I control. Here’s the snippet for that:

I’ve omitted some things, such as imports.

Running the above code, I get the following output blobs:

initNote looks like gqFpgaZzdXBwbHlkpHR5cGWhaQ==

transferNote looks like gqF0g6ZBbW91bnQyq2Rlc3RpbmF0aW9u2TozUTdKWDNUWVNNRjJNQlBZWjJHTTRHRjNQWFdMNFozNDIzNURHVExRQ1BVUFAzSTY0RldWTFozWTM0pnNvdXJjZdk6NUFRVTNTU05MVEVOTzQ0UFBLQ0ZHRUREVFNCUE5FQURLNFVFWEZEVFFMUVJPUjM3Q0JZN1ZDRktEVaR0eXBloXQ=

Now that we have these notes, we can post them to the chain. The SDK lets you transact easily. The go doc documentation for the SDK can explain more about transacting. Here, we’re going to focus on the Note field, where we can place our data. We will place the initNotesBytes64 blob in the Note field. (It’s important to know that the examplecoin demo will only inspect transactions that are to or from the master coinKey address. So, here both to and from are set to the coinKey address. Just one of the two matching would be sufficient when reading data back later, though.)

The go doc can tell you more about building and signing transactions.

Nice! The initialization blob has been posted. Now let’s transfer some EvanCoin. To do so, we do exactly the same as above, but this time using the transferNotesBytes64 blob, building it into a transaction and sending it to the network.

(We could have also used the goal commandline utility to post these notes: something like goal clerk send --amount 1 --noteb64 gqFpgaZzdXBwbHlkpHR5cGWhaQ== --from 5AQU3SSNLTENO44PPKCFGEDDTSBPNEADK4UEXFDTQLQROR37CBY7VCFKDU --to 5AQU3SSNLTENO44PPKCFGEDDTSBPNEADK4UEXFDTQLQROR37CBY7VCFKDU . For this article, though, we’ll stay within go .)

Success! Our transactions have been submitted. (I’m running this against my own private test network, created using goal , so I don’t have to worry about the fee market, or wait for transaction confirmation: I know my transactions will be included in the next ~5 second block. If I wanted to explicitly wait for transaction confirmation, I could use the SDK to query whether the transaction is pending or confirmed.)

I’ll run the examplecoin utility to tabulate the results. (I have omitted this step, but I also noted which the round range in which the transactions were confirmed, using algodClient ’s Status() call, so I know both transactions got posted between rounds 500 and 550. To make things run faster, examplecoin uses this info to inform the utility which blocks to look at.)

$ algorand-l2-examplecoin -verbose=false -coinkey=5AQU3SSNLTENO44PPKCFGEDDTSBPNEADK4UEXFDTQLQROR37CBY7VCFKDU -firstround=500 lastround=550

Wrote results into results.csv $ cat results.csv

5AQU3SSNLTENO44PPKCFGEDDTSBPNEADK4UEXFDTQLQROR37CBY7VCFKDU,50

3Q7JX3TYSMF2MBPYZ2GM4GF3PXWL4Z34235DGTLQCPUPP3I64FWVLZ3Y34,50

Success! I have 50 EvanCoin in one account and 50 EvanCoin in another account. 😎

GOTCHAS AND BRAINSTORMING

In this demo I assume the examplecoin utility will be used by very few users (just me) to manage very few accounts, so there’s a few scalability issues: using a csv rather than a database, for example, or trying to hold everyone’s running balance in memory as the results are tabulated.

utility will be used by very few users (just me) to manage very few accounts, so there’s a few scalability issues: using a rather than a database, for example, or trying to hold everyone’s running balance in memory as the results are tabulated. Currently the utility starts from scratch every time you run it, and overwrites the output file entirely. One could change it to use a preexisting output, and just scan along the chain from where it left off.

Since the utility needs to read every single block in a potentially large range of blocks, it needs to be run on a machine with an Algorand archival node or relay, so that the blocks that the utility needs are never pruned.

I have not audited any of this code for correctness or security, as it’s a quick toy demonstration. I wonder if someone can steal my precious EvanCoin? 😱

I mentioned briefly that this functionality is sort of analogous to named fungible tokens, similar (kind of) to ERC-20 . With some changes, one could probably tweak things to work like nonfungible tokens (NFTs).

. With some changes, one could probably tweak things to work like nonfungible tokens (NFTs). Code and data can be one and the same thing, can’t it? Can you picture a system that puts code on the chain as encoded data, executes it, and puts new code on the chain in response? A self-amending program? 🤔

THE END

Thanks, everyone, I hope this little demo helped or educated you in some way. We’re all in this together! 🎉