Algorand Smart Contract Layer1 (ASC1) and Oracles

Pablo Yabo
7 min readJan 23, 2020

--

Overview

At the end of 2019, Algorand released in record time the Algorand Smart Contract Layer1 (ASC1), a new paradigm shift for smart contracts. Rand Labs has been researching this technology to incorporate it in Algo Explorer and add ways to interact with it using My Algo Algorand Wallet.

The first part of this article goes through our understanding of ASC1. The second part addresses oracle data in ASC1 showing a way to insert signed data from the outside world with a small example.

General Logic

The ASC1 is a simple logical predicate that verifies or not. ASC1s can have jumps but cannot cycle nor make function calls. It can only access the transaction group data it belongs to and some global parameters. The transaction size is limited to 1k making it the size limit of the Algorand smart contracts. Algorand uses a stack-based notation where users put the parameters on the stack before executing the opcode. Users can make arithmetic operations, verify transactions, group transaction fields, make hash operations, verify Ed25519 signatures, and other related operations.

For a detailed list of what Algorand’s Transaction Execution Approval Language (TEAL) can do and its limitations refer to this TEAL manual.

ASC Creation

After a user writes an ASC1 and compiles it, the address where the smart contract lives is created, but neither the code nor the address are stored in the blockchain until a transaction interacts with the ASC1. For the rest of the users, the contract is just an address indistinguishable from any other account address. Any change to the ASC1 code will modify the compilation of it and thus result in a different generated address. The only way to obtain the same address generated by an ASC1 is by compiling the same TEAL code.

We are witnessing a completely new concept compared to the rest of the public blockchains. While other networks store the smart contract in the blockchain before interacting with it, on Algorand users can create an escrow ASC1 and give it only to the beneficiary. In this case, the beneficiary will need to publish the smart contract to the blockchain with the correct parameters if he/she wants to cash in the funds in the escrow. Only after a successful transaction is broadcasted, the smart contract becomes public for the rest.

ASC1 Transactions

Considering that the ASC1 is just an account with funds and some logic attached, users looking to get funds from it must generate a transaction specifying the origin address of the transaction, from, as the ASC1 address (the address generated from the compiled TEAL code). The transaction fields and the group it belongs to among the ASC1 arguments must make the ASC1 predicates evaluate true for the transaction to be valid and included in the blockchain.

The transaction body contains the ASC1 code alongside the required arguments needed to verify the predicates.

Lease String

This transaction parameter is used to mutually exclude transactions. For instance, ASC1 can leverage the lease parameter to enable recurring payments. In this case, the ASC1 requires transactions to include a specific lease (like a lock code) to be valid. Once a transaction with the correct lease is approved by the ASC1, future transactions with the same lease code will not validate for the rest of the approved transaction validity period. This type of use case would enable an account to spend a certain amount of funds for a specific recurring period (i.e. every 600,000 blocks). Once spent using a transaction with the correct lease, no more transactions will be valid for the remainder of the period. You would have to wait for the next valid block period to start before sending a new valid transaction to spend the amount again. Refer to periodic-payment-escrow.teal.tmpl that implements this logic.

Oracles

We have been looking into ways of inserting outside information into the blockchain using ASC1. There is an opcode called ed25519verify that can make the trick.

The opcode ed25519verify receives 3 parameters: data, signature and public key. As it is right now, this opcode requires the inclusion of the TEAL program in data that is signed.

Taking advantage of this opcode, an oracle can sign a result of the outside world (jointly with the TEAL code) while the ASC1 can verify that the signature comes from the oracle.

We strongly recommend the Algorand team should add a new opcode to insert oracle data without signing the TEAL code to allow third-party oracles to provide information for different ASC1s at the same time.

Example: Oracle Using ed25519verify

The following illustrates how to write an ASC1 with oracle input. This example is limited to interpret valid oracle outcomes while not addressing the consequences of the oracle not generating the correct signature or users not claiming the funds. If any of these situations happen in this specific example, the funds would get stuck forever. It is possible to address these situations by adding a round limit to claim the funds. After that round, any participating account can create a transaction splitting the funds. Refer to split.teal for an example using group transactions to split the funds.

Code

// Parameters:
// - TMPL_ADDRA: Address beting for Team A.
// - TMPL_ADDRB: Address beting for Team B.
// - TMPL_ADDR_ORACLE: Oracle Address.
// - TMPL_FEE: maximum fee used by the limit order transaction.
txn TypeEnum
int 1 // Payment (either Algos-out in trade or Algos redeemed at timeout)
==
global GroupSize
int 1
==
&&
// if arg 0 == 0 then send to TMPL_ADDRA
arg 0
byte base64 MA==
==
txn CloseRemainderTo
addr TMPL_ADDRA
==
&&
txn Receiver
addr TMPL_ADDRA
==
&&
// if arg 0 == 1 then send to TMPL_ADDRB
arg 0
byte base64 MQ==
==
txn CloseRemainderTo
addr TMPL_ADDRB
==
&&
txn Receiver
addr TMPL_ADDRB
==
&&
||
// global verifications
&&
txn Fee
int TMPL_FEE
<=
&&
// verify oracle signature
arg 0
arg 1
addr TMPL_ADDR_ORACLE
ed25519verify
&&

Logic

In summary, the ASC1 can be expressed in this way:

tx type == Pay && GroupSize == 1 &&
((data == 0 && to == TMPL_ADDRA && close == TMPL_ADDRA) ||
(data == 1 && to == TMPL_ADDRB && close == TMPL_ADDRB)) &&
ed25519verify(data, signature, oracle TMPL_ADDR_ORACLE) &&
ok fee

The first and the last lines are general verifications. The interesting part of the ASC1 is that the algos go to TMPL_ADDRA if data is 0 or to TMPL_ADDRB if it is 1 and the data signature is verified with ed25519verify opcode.

Oracle Keys

A key file testkey.key is generated with algokey tool for the oracle:

$ ./algokey generate -f testkey.key | grep “Public key”Public key: SVDICE2QVOMQPYCYRJGRBOZPLYGF5DQOK3FFHL26FUOBQLWBKDH3EAQS3U

Compilation

The following parameters are used for the template:

TMPL_ADDRA:
BKJX2U52PKL27XS42VO4SJW5BBFBYDCN7NYAW6BUEKF7EBYX5XV5CKAPT4
TMPL_ADDRB:
36WZVNA6YA77V2MGGLJBT2YQG3RQVX6UWJ3P6E7FWNAV4IGMK3ZVVNBLVQ
TMPL_ADDR_ORACLE:
SVDICE2QVOMQPYCYRJGRBOZPLYGF5DQOK3FFHL26FUOBQLWBKDH3EAQS3U
TMPL_FEE:
10000

You can download the specialized version oracle.teal or the template oracle.teal.tmpl

Compiling the ASC1 gets the address:

$ ./goal clerk compile oracle.teal
oracle.teal:
JDYOTGQ6D2CLH4EBOJLUNV5TYJS3DZSJHNQV6ESEEHFF76I6OUI53JR7H4

You can check that there is nothing special about the address on Algo Explorer. It is just like any other account address.

Signing to Verify with ed25519verify

The dsign tool inside the go-algorand node source code is used to sign the message. We were not able to sign the message directly with the tool as it is, but the code was very useful to find a way to do it. We suggested a change in the code on this pull request. You can use the modified code there to sign messages. If you need some help just ping us at hello@algoexplorer.io. Here, we use our modified version of dsign tool.

Update March-2020:

Now it is possible to use goal tool to get the same results.

Case 1: ADDRA Wins

First, the ASC1 address is funded. Then, the signature of the data is created:

Data: msg file contains exactly 1 byte with a “0”

Code: oracle.teal

$ ~/go/bin/dsign testkey.key ~/node/oracle.teal msg LjbN+UgzmYG6vWKQuOkJKk69DBrJFY7IM0yblgeiZl5OOtZPlAf/ujTVl4FTAA5oa0/1npNtNDHvhxmY4pb/BA==

Update March-2020:

$ ./goal clerk tealsign --keyfile oracle.key --contract-addr JDYOTGQ6D2CLH4EBOJLUNV5TYJS3DZSJHNQV6ESEEHFF76I6OUI53JR7H4 --data-b64 MA==

Then, send a close transaction from the ASC1 account to ADDRA to transfer all funds. The following signature and message “0” (base64 is MA==) is used:

$ ./goal clerk send -a 0 --from-program oracle.teal -t BKJX2U52PKL27XS42VO4SJW5BBFBYDCN7NYAW6BUEKF7EBYX5XV5CKAPT4 -c BKJX2U52PKL27XS42VO4SJW5BBFBYDCN7NYAW6BUEKF7EBYX5XV5CKAPT4 --fee 1000 -d testnet --argb64 MA== --argb64 LjbN+UgzmYG6vWKQuOkJKk69DBrJFY7IM0yblgeiZl5OOtZPlAf/ujTVl4FTAA5oa0/1npNtNDHvhxmY4pb/BA==Sent 0 MicroAlgos from account JDYOTGQ6D2CLH4EBOJLUNV5TYJS3DZSJHNQV6ESEEHFF76I6OUI53JR7H4 to address BKJX2U52PKL27XS42VO4SJW5BBFBYDCN7NYAW6BUEKF7EBYX5XV5CKAPT4, 
transaction ID: XWZLK6YBQ4H6BZUSONDOE5A66B4MASVBGVTL6B4HNWMBYQ7GHTBA. Fee set to 1000
Transaction XWZLK6YBQ4H6BZUSONDOE5A66B4MASVBGVTL6B4HNWMBYQ7GHTBA committed in round 4451591

Case 2: ADDRB Wins

The ASC1 is funded again and a signature of the data is created with ADDRB winning:

Data: msg file contains exactly 1 byte with a “1”

Code: oracle.teal

$ ~/go/bin/dsign testkey.key ~/node/oracle.teal msg 
DJ0FtmIaLCksr5WhPczcHIwn9ye4CGHFPn64z38ChorZ6r0Dvj6z1n2bV9gIMUe+UrN5lzNDYK7u3Cxh1SiQBg==

Update March-2020:

$ ./goal clerk tealsign --keyfile oracle.key --contract-addr JDYOTGQ6D2CLH4EBOJLUNV5TYJS3DZSJHNQV6ESEEHFF76I6OUI53JR7H4 --data-b64 MQ==

Then, send a close transaction from the ASC1 account to ADDRB to transfer all funds. The following signature and message “1” (base64 is MQ==) is used:

$ ./goal clerk send -a 0 --from-program oracle.teal -t 36WZVNA6YA77V2MGGLJBT2YQG3RQVX6UWJ3P6E7FWNAV4IGMK3ZVVNBLVQ -c 36WZVNA6YA77V2MGGLJBT2YQG3RQVX6UWJ3P6E7FWNAV4IGMK3ZVVNBLVQ --fee 1000 -d testnet --argb64 MQ== --argb64 DJ0FtmIaLCksr5WhPczcHIwn9ye4CGHFPn64z38ChorZ6r0Dvj6z1n2bV9gIMUe+UrN5lzNDYK7u3Cxh1SiQBg==Sent 0 MicroAlgos from account JDYOTGQ6D2CLH4EBOJLUNV5TYJS3DZSJHNQV6ESEEHFF76I6OUI53JR7H4 to address 36WZVNA6YA77V2MGGLJBT2YQG3RQVX6UWJ3P6E7FWNAV4IGMK3ZVVNBLVQ, transaction ID: 2SKTS2SAQ2QTDV3PR45WV4NO6TQHT7S2BR73W6T3OJJHT7LVXKPQ. Fee set to 1000
Transaction 2SKTS2SAQ2QTDV3PR45WV4NO6TQHT7S2BR73W6T3OJJHT7LVXKPQ still pending as of round 4451877
Transaction 2SKTS2SAQ2QTDV3PR45WV4NO6TQHT7S2BR73W6T3OJJHT7LVXKPQ committed in round 4451879

Leading with Technological Innovation

Here we see the first stages of Algorand’s vision of smart contracts. The new paradigm in smart contracts is extremely revolutionary. The ability to conceal everything about any ASC1 until it is used brings great possibilities. For instance, escrows will now be deployed with complete privacy and thus security as no one will know anything about it till the escrow is executed. Furthermore, this new design makes the use of smart contracts easier compared to the complexity of Turing complete smart contracts of other blockchains. With ASC1s uses cases such as recurring transactions, allowance, collateralized credit, escrows, bets, and much more, are all much simpler to create and magnitudes of times more secure.

We are excited to see what type of uses cases the Algorand community starts building leveraging this new revolutionary technology. As always, Algorand keeps leading the technological innovation in the DeFi space and setting the standard of this movement.

--

--