Skip to content

Commit

Permalink
Merge pull request #65 from jannotti/avm-7
Browse files Browse the repository at this point in the history
AVM 7 spec changes
  • Loading branch information
algofoundation authored Aug 4, 2022
2 parents e3c8953 + 8e62fc5 commit a9f6164
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 109 deletions.
104 changes: 62 additions & 42 deletions dev/TEAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ programs, AVM code is versioned. When new opcodes are introduced, or
behavior is changed, a new version is introduced. Programs carrying
old versions are executed with their original semantics. In the AVM
bytecode, the version is an incrementing integer, currently 6, and
denoted vX throughout this document. User friendly version numbers
that correspond to programmer expectations, such as `AVM 1.0` map to
these integers. AVM 0.9 is v4. AVM 1.0 is v5. AVM 1.1 is v6.
denoted vX throughout this document.

## Execution Modes

Expand Down Expand Up @@ -188,6 +186,9 @@ _available_.
associated account of a contract that was created earlier in the
group is _available_.

* Since v7, the account associated with any contract present in the
`txn.ForeignApplications` field is _available_.

## Constants

Constants can be pushed onto the stack in two different ways:
Expand Down Expand Up @@ -275,10 +276,13 @@ return stack matches the name of the input value.
| `sha256` | SHA256 hash of value A, yields [32]byte |
| `keccak256` | Keccak256 hash of value A, yields [32]byte |
| `sha512_256` | SHA512_256 hash of value A, yields [32]byte |
| `sha3_256` | SHA3_256 hash of value A, yields [32]byte |
| `ed25519verify` | for (data A, signature B, pubkey C) verify the signature of ("ProgData" \|\| program_hash \|\| data) against the pubkey => {0 or 1} |
| `ed25519verify_bare` | for (data A, signature B, pubkey C) verify the signature of the data against the pubkey => {0 or 1} |
| `ecdsa_verify v` | for (data A, signature B, C and pubkey D, E) verify the signature of the data against the pubkey => {0 or 1} |
| `ecdsa_pk_recover v` | for (data A, recovery id B, signature C, D) recover a public key |
| `ecdsa_pk_decompress v` | decompress pubkey A into components X, Y |
| `vrf_verify s` | Verify the proof B of message A against pubkey C. Returns vrf output and verification flag. |
| `+` | A plus B. Fail on overflow. |
| `-` | A minus B. Fail if B > A. |
| `/` | A divided by B (truncated division). Fail if B == 0. |
Expand All @@ -298,8 +302,8 @@ return stack matches the name of the input value.
| `!=` | A is not equal to B => {0 or 1} |
| `!` | A == 0 yields 1; else 0 |
| `len` | yields length of byte value A |
| `itob` | converts uint64 A to big endian bytes |
| `btoi` | converts bytes A as big endian to uint64 |
| `itob` | converts uint64 A to big-endian byte array, always of length 8 |
| `btoi` | converts big-endian byte array A to uint64. Fails if len(A) > 8. Padded by leading 0s if len(A) < 8. |
| `%` | A modulo B. Fail if B == 0. |
| `\|` | A bitwise-or B |
| `&` | A bitwise-and B |
Expand All @@ -310,10 +314,10 @@ return stack matches the name of the input value.
| `divw` | A,B / C. Fail if C == 0 or if result overflows. |
| `divmodw` | W,X = (A,B / C,D); Y,Z = (A,B modulo C,D) |
| `expw` | A raised to the Bth power as a 128-bit result in two uint64s. X is the high 64 bits, Y is the low. Fail if A == B == 0 or if the results exceeds 2^128-1 |
| `getbit` | Bth bit of (byte-array or integer) A. |
| `setbit` | Copy of (byte-array or integer) A, with the Bth bit set to (0 or 1) C |
| `getbyte` | Bth byte of A, as an integer |
| `setbyte` | Copy of A with the Bth byte set to small integer (between 0..255) C |
| `getbit` | Bth bit of (byte-array or integer) A. If B is greater than or equal to the bit length of the value (8*byte length), the program fails |
| `setbit` | Copy of (byte-array or integer) A, with the Bth bit set to (0 or 1) C. If B is greater than or equal to the bit length of the value (8*byte length), the program fails |
| `getbyte` | Bth byte of A, as an integer. If B is greater than or equal to the array length, the program fails |
| `setbyte` | Copy of A with the Bth byte set to small integer (between 0..255) C. If B is greater than or equal to the array length, the program fails |
| `concat` | join A and B |

### Byte Array Manipulation
Expand All @@ -323,10 +327,14 @@ return stack matches the name of the input value.
| `substring s e` | A range of bytes from A starting at S up to but not including E. If E < S, or either is larger than the array length, the program fails |
| `substring3` | A range of bytes from A starting at B up to but not including C. If C < B, or either is larger than the array length, the program fails |
| `extract s l` | A range of bytes from A starting at S up to but not including S+L. If L is 0, then extract to the end of the string. If S or S+L is larger than the array length, the program fails |
| `extract3` | A range of bytes from A starting at B up to but not including B+C. If B+C is larger than the array length, the program fails |
| `extract3` | A range of bytes from A starting at B up to but not including B+C. If B+C is larger than the array length, the program fails<br />`extract3` can be called using `extract` with no immediates. |
| `extract_uint16` | A uint16 formed from a range of big-endian bytes from A starting at B up to but not including B+2. If B+2 is larger than the array length, the program fails |
| `extract_uint32` | A uint32 formed from a range of big-endian bytes from A starting at B up to but not including B+4. If B+4 is larger than the array length, the program fails |
| `extract_uint64` | A uint64 formed from a range of big-endian bytes from A starting at B up to but not including B+8. If B+8 is larger than the array length, the program fails |
| `replace2 s` | Copy of A with the bytes starting at S replaced by the bytes of B. Fails if S+len(B) exceeds len(A)<br />`replace2` can be called using `replace` with 1 immediate. |
| `replace3` | Copy of A with the bytes starting at B replaced by the bytes of C. Fails if B+len(C) exceeds len(A)<br />`replace3` can be called using `replace` with no immediates. |
| `base64_decode e` | decode A which was base64-encoded using _encoding_ E. Fail if A is not base64 encoded with encoding E |
| `json_ref r` | key B's value, of type R, from a [valid](jsonspec.md) utf-8 encoded json object A |

The following opcodes take byte-array values that are interpreted as
big-endian unsigned integers. For mathematical operators, the
Expand Down Expand Up @@ -399,12 +407,12 @@ Some of these have immediate data in the byte or bytes after the opcode.
| `args` | Ath LogicSig argument |
| `txn f` | field F of current transaction |
| `gtxn t f` | field F of the Tth transaction in the current group |
| `txna f i` | Ith value of the array field F of the current transaction |
| `txna f i` | Ith value of the array field F of the current transaction<br />`txna` can be called using `txn` with 2 immediates. |
| `txnas f` | Ath value of the array field F of the current transaction |
| `gtxna t f i` | Ith value of the array field F from the Tth transaction in the current group |
| `gtxna t f i` | Ith value of the array field F from the Tth transaction in the current group<br />`gtxna` can be called using `gtxn` with 3 immediates. |
| `gtxnas t f` | Ath value of the array field F from the Tth transaction in the current group |
| `gtxns f` | field F of the Ath transaction in the current group |
| `gtxnsa f i` | Ith value of the array field F from the Ath transaction in the current group |
| `gtxnsa f i` | Ith value of the array field F from the Ath transaction in the current group<br />`gtxnsa` can be called using `gtxns` with 2 immediates. |
| `gtxnsas f` | Bth value of the array field F from the Ath transaction in the current group |
| `global f` | global field F |
| `load i` | Ith scratch space value. All scratch spaces are 0 at program start. |
Expand All @@ -417,14 +425,14 @@ Some of these have immediate data in the byte or bytes after the opcode.
| `gaid t` | ID of the asset or application created in the Tth transaction of the current group |
| `gaids` | ID of the asset or application created in the Ath transaction of the current group |

**Transaction Fields**

#### Transaction Fields
##### Scalar Fields
| Index | Name | Type | In | Notes |
| - | ------ | -- | - | --------- |
| 0 | Sender | []byte | | 32 byte address |
| 1 | Fee | uint64 | | microalgos |
| 2 | FirstValid | uint64 | | round number |
| 3 | FirstValidTime | uint64 | | Causes program to fail; reserved for future use |
| 3 | FirstValidTime | uint64 | v7 | UNIX timestamp of block before txn.FirstValid. Fails if negative |
| 4 | LastValid | uint64 | | round number |
| 5 | Note | []byte | | Any data up to 1024 bytes |
| 6 | Lease | []byte | | 32 byte lease value |
Expand All @@ -437,19 +445,17 @@ Some of these have immediate data in the byte or bytes after the opcode.
| 13 | VoteLast | uint64 | | The last round that the participation key is valid. |
| 14 | VoteKeyDilution | uint64 | | Dilution for the 2-level participation key |
| 15 | Type | []byte | | Transaction type as bytes |
| 16 | TypeEnum | uint64 | | See table below |
| 16 | TypeEnum | uint64 | | Transaction type as integer |
| 17 | XferAsset | uint64 | | Asset ID |
| 18 | AssetAmount | uint64 | | value in Asset's units |
| 19 | AssetSender | []byte | | 32 byte address. Causes clawback of all value of asset from AssetSender if Sender is the Clawback address of the asset. |
| 19 | AssetSender | []byte | | 32 byte address. Source of assets if Sender is the Asset's Clawback address. |
| 20 | AssetReceiver | []byte | | 32 byte address |
| 21 | AssetCloseTo | []byte | | 32 byte address |
| 22 | GroupIndex | uint64 | | Position of this transaction within an atomic transaction group. A stand-alone transaction is implicitly element 0 in a group of 1 |
| 23 | TxID | []byte | | The computed ID for this transaction. 32 bytes. |
| 24 | ApplicationID | uint64 | v2 | ApplicationID from ApplicationCall transaction |
| 25 | OnCompletion | uint64 | v2 | ApplicationCall transaction on completion action |
| 26 | ApplicationArgs | []byte | v2 | Arguments passed to the application in the ApplicationCall transaction |
| 27 | NumAppArgs | uint64 | v2 | Number of ApplicationArgs |
| 28 | Accounts | []byte | v2 | Accounts listed in the ApplicationCall transaction |
| 29 | NumAccounts | uint64 | v2 | Number of Accounts |
| 30 | ApprovalProgram | []byte | v2 | Approval program |
| 31 | ClearStateProgram | []byte | v2 | Clear state program |
Expand All @@ -461,30 +467,41 @@ Some of these have immediate data in the byte or bytes after the opcode.
| 37 | ConfigAssetUnitName | []byte | v2 | Unit name of the asset |
| 38 | ConfigAssetName | []byte | v2 | The asset name |
| 39 | ConfigAssetURL | []byte | v2 | URL |
| 40 | ConfigAssetMetadataHash | []byte | v2 | 32 byte commitment to some unspecified asset metadata |
| 40 | ConfigAssetMetadataHash | []byte | v2 | 32 byte commitment to unspecified asset metadata |
| 41 | ConfigAssetManager | []byte | v2 | 32 byte address |
| 42 | ConfigAssetReserve | []byte | v2 | 32 byte address |
| 43 | ConfigAssetFreeze | []byte | v2 | 32 byte address |
| 44 | ConfigAssetClawback | []byte | v2 | 32 byte address |
| 45 | FreezeAsset | uint64 | v2 | Asset ID being frozen or un-frozen |
| 46 | FreezeAssetAccount | []byte | v2 | 32 byte address of the account whose asset slot is being frozen or un-frozen |
| 47 | FreezeAssetFrozen | uint64 | v2 | The new frozen value, 0 or 1 |
| 48 | Assets | uint64 | v3 | Foreign Assets listed in the ApplicationCall transaction |
| 49 | NumAssets | uint64 | v3 | Number of Assets |
| 50 | Applications | uint64 | v3 | Foreign Apps listed in the ApplicationCall transaction |
| 51 | NumApplications | uint64 | v3 | Number of Applications |
| 52 | GlobalNumUint | uint64 | v3 | Number of global state integers in ApplicationCall |
| 53 | GlobalNumByteSlice | uint64 | v3 | Number of global state byteslices in ApplicationCall |
| 54 | LocalNumUint | uint64 | v3 | Number of local state integers in ApplicationCall |
| 55 | LocalNumByteSlice | uint64 | v3 | Number of local state byteslices in ApplicationCall |
| 56 | ExtraProgramPages | uint64 | v4 | Number of additional pages for each of the application's approval and clear state programs. An ExtraProgramPages of 1 means 2048 more total bytes, or 1024 for each program. |
| 57 | Nonparticipation | uint64 | v5 | Marks an account nonparticipating for rewards |
| 58 | Logs | []byte | v5 | Log messages emitted by an application call (only with `itxn` in v5). Application mode only |
| 59 | NumLogs | uint64 | v5 | Number of Logs (only with `itxn` in v5). Application mode only |
| 60 | CreatedAssetID | uint64 | v5 | Asset ID allocated by the creation of an ASA (only with `itxn` in v5). Application mode only |
| 61 | CreatedApplicationID | uint64 | v5 | ApplicationID allocated by the creation of an application (only with `itxn` in v5). Application mode only |
| 62 | LastLog | []byte | v6 | The last message emitted. Empty bytes if none were emitted. Application mode only |
| 63 | StateProofPK | []byte | v6 | 64 byte state proof public key commitment.|
| 63 | StateProofPK | []byte | v6 | 64 byte state proof public key |
| 65 | NumApprovalProgramPages | uint64 | v7 | Number of Approval Program pages |
| 67 | NumClearStateProgramPages | uint64 | v7 | Number of ClearState Program pages |

##### Array Fields
| Index | Name | Type | In | Notes |
| - | ------ | -- | - | --------- |
| 26 | ApplicationArgs | []byte | v2 | Arguments passed to the application in the ApplicationCall transaction |
| 28 | Accounts | []byte | v2 | Accounts listed in the ApplicationCall transaction |
| 48 | Assets | uint64 | v3 | Foreign Assets listed in the ApplicationCall transaction |
| 50 | Applications | uint64 | v3 | Foreign Apps listed in the ApplicationCall transaction |
| 58 | Logs | []byte | v5 | Log messages emitted by an application call (only with `itxn` in v5). Application mode only |
| 64 | ApprovalProgramPages | []byte | v7 | Approval Program as an array of pages |
| 66 | ClearStateProgramPages | []byte | v7 | ClearState Program as an array of pages |


Additional details in the [opcodes document](TEAL_opcodes.md#txn) on the `txn` op.

Expand Down Expand Up @@ -530,7 +547,7 @@ Asset fields include `AssetHolding` and `AssetParam` fields that are used in the
| 4 | AssetName | []byte | | Asset name |
| 5 | AssetURL | []byte | | URL with additional info about the asset |
| 6 | AssetMetadataHash | []byte | | Arbitrary commitment |
| 7 | AssetManager | []byte | | Manager commitment |
| 7 | AssetManager | []byte | | Manager address |
| 8 | AssetReserve | []byte | | Reserve address |
| 9 | AssetFreeze | []byte | | Freeze address |
| 10 | AssetClawback | []byte | | Clawback address |
Expand Down Expand Up @@ -606,6 +623,7 @@ Account fields used in the `acct_params_get` opcode.
| `app_params_get f` | X is field F from app A. Y is 1 if A exists, else 0 |
| `acct_params_get f` | X is field F from account A. Y is 1 if A owns positive algos, else 0 |
| `log` | write A to log state of the current application |
| `block f` | field F of block A. Fail unless A falls between txn.LastValid-1002 and the current round (exclusive) |

### Inner Transactions

Expand All @@ -626,7 +644,8 @@ In v5, inner transactions may perform `pay`, `axfer`, `acfg`, and
with the next instruction with, for example, `balance` and
`min_balance` checks. In v6, inner transactions may also perform
`keyreg` and `appl` effects. Inner `appl` calls fail if they attempt
to invoke a program with version less than v6.
to invoke a program with version less than v4, or if they attempt to
opt-in to an app with a ClearState Program less than v4.

In v5, only a subset of the transaction's header fields may be set: `Type`/`TypeEnum`,
`Sender`, and `Fee`. In v6, header fields `Note` and `RekeyTo` may
Expand Down Expand Up @@ -670,7 +689,7 @@ The assembler parses line by line. Ops that only take stack arguments
appear on a line by themselves. Immediate arguments follow the opcode
on the same line, separated by whitespace.

The first line may contain a special version pragma `#pragma version X`, which directs the assembler to generate AVM bytecode targeting a certain version. For instance, `#pragma version 2` produces bytecode targeting TEAL v2. By default, the assembler targets TEAL v1.
The first line may contain a special version pragma `#pragma version X`, which directs the assembler to generate bytecode targeting a certain version. For instance, `#pragma version 2` produces bytecode targeting v2. By default, the assembler targets v1.

Subsequent lines may contain other pragma declarations (i.e., `#pragma <some-specification>`), pertaining to checks that the assembler should perform before agreeing to emit the program bytes, specific optimizations, etc. Those declarations are optional and cannot alter the semantics as described in this document.

Expand Down Expand Up @@ -721,25 +740,26 @@ A compiled program starts with a varuint declaring the version of the compiled c

For version 1, subsequent bytes after the varuint are program opcode bytes. Future versions could put other metadata following the version identifier.

It is important to prevent newly-introduced transaction fields from
breaking assumptions made by older versions of the AVM. If one of the
transactions in a group will execute a program whose version predates
a given field, that field must not be set anywhere in the transaction
group, or the group will be rejected. For example, executing a version
1 program on a transaction with RekeyTo set to a nonzero address will
cause the program to fail, regardless of the other contents of the
program itself.
It is important to prevent newly-introduced transaction types and
fields from breaking assumptions made by programs written before they
existed. If one of the transactions in a group will execute a program
whose version predates a transaction type or field that can violate
expectations, that transaction type or field must not be used anywhere
in the transaction group.

Concretely, the above requirement is translated as follows: A v1
program included in a transaction group that includes a
ApplicationCall transaction or a non-zero RekeyTo field will fail
regardless of the program itself.

This requirement is enforced as follows:

* For every transaction, compute the earliest version that supports
all the fields and values in this transaction. For example, a
transaction with a nonzero RekeyTo field will be (at least) v2.

* Compute the largest version number across all the transactions in a group (of size 1 or more), call it `maxVerNo`. If any transaction in this group has a program with a version smaller than `maxVerNo`, then that TEAL program will fail.
all the fields and values in this transaction.

* Compute the largest version number across all the transactions in a group (of size 1 or more), call it `maxVerNo`. If any transaction in this group has a program with a version smaller than `maxVerNo`, then that program will fail.

In addition, applications must be version 6 or greater to be eligible
for being called in an inner transaction.
In addition, applications must be v4 or greater to be called in an inner transaction.

## Varuint

Expand Down
Loading

0 comments on commit a9f6164

Please sign in to comment.