Skip to content

Commit

Permalink
AVM 8 (#439)
Browse files Browse the repository at this point in the history
* upping max teal version

* adding program page related ops (#412)

* adding program page related ops

* Add Replace (#413)

* Add Replace

* Remove replace auto-import

* Use scripts/generate_init.py

* Add more tests to replace, substring, and extract (#1)

Co-authored-by: Michael Diamant <michaeldiamant@users.noreply.github.com>

* Add Block (#415)

* Add Block

# Conflicts:
#	pyteal/ir/ops.py

* Disable flake8 errors on formatted lines

* Add past version failure check

* Remove unnecessary ignore Expr equality context

* Add JsonRef (#417)

* Add JsonRef

* Use named class methods to specify value type

* Remove unnecessary ignore Expr equality context

* Fix docstring link

* Add Base64Decode (#418)

* Add Base64Decode

* Remove unnecessary ignore Expr equality context

* Support Secp256r1 curve (#423)

* Support Secp256r1 curve

* Fix type errors in ecdsa tests

* Fix typo

* Test Secp256k1 curve against TEAL 5 instead

* Add compile check to `MultiValue` class

* Use `MultiValue` compile checks instead of inheritance

* Add VrfVerify (#419)

* Add VrfVerify

# Conflicts:
#	pyteal/ast/__init__.py
#	pyteal/ir/ops.py

* Tidy with `MultiValue`’s compile check

* Add `Sha3_256` (#425)

* Add sha3_256

* Add crypto docs

* Support `FirstValidTime` transaction field (#424)

* Add first valid time factory and update min version

* Include FirstValidTime in txn tests

* Add transaction field docs

* Add `Ed25519Verify_Bare` (#426)

* Add ed25519verify_bare

* Fix typos in Ed25519 docstrings (#2)

* Add crypto doc for Ed25519Verify_Bare

Co-authored-by: Michael Diamant <michaeldiamant@users.noreply.github.com>

* AVM Boxes Ops in Pyteal (#438)

* add box ops

* full support on ops

* first set of test, add versioning in multi

* remove some seemingly not necessary code?

* update testcase

* check invalid arguments

* finish testcase

* move stuffs to app

* version check trick

* verifyTealVersion apply

* error message

* update docs structures

* period

* update doc

* update doc

* update doc

* per pr review on implementation

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* hex box size goes wild

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* warning about MBR

* wording

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* emphasize

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* Update docs/state.rst

Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>

* polishing

* remove redundant box_put doc segment

* per zeph pr review

* use note and warning

* per zeph's pr review

* Update docs/state.rst

Co-authored-by: Michael Diamant <michaeldiamant@users.noreply.github.com>

* creating boxes

* Update docs/state.rst

Co-authored-by: Michael Diamant <michaeldiamant@users.noreply.github.com>

* per pr review

* table for state types

Co-authored-by: Ben Guidarelli <ben.guidarelli@gmail.com>
Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>
Co-authored-by: Michael Diamant <michaeldiamant@users.noreply.github.com>

* Merge Teal7 to AVM8, and consolidate Teal to AVM versioning  (#470)

* swapping base64 modes to match the rest (#446)

* Merge master into teal7 (#450)

* AVM 7:  Address integration branch feedback (#452)

* Add Execute Method (#444)

* adding execute method to allow omission of begin/submit for common use case

* exec docstring

* update testcase

Co-authored-by: Hang Su <hang.su@algorand.com>

* Merge branch 'master' into teal7 (#463)

* fix misspelling of uint (#431)

* fix misspelling of uint

* Clarify minimum Python version management docs (#435)

* Foreign prefix on App and Asset arrays (#440)

* replacing foreignapps with applications

* fix assets as well

* Add Execute Method (#444)

* adding execute method to allow omission of begin/submit for common use case

* exec docstring

* update testcase

Co-authored-by: Hang Su <hang.su@algorand.com>

Co-authored-by: Ben Guidarelli <ben.guidarelli@gmail.com>
Co-authored-by: Hang Su <hang.su@algorand.com>

* Consolidate TEAL and AVM versioning (#441)

* fix misspelling of uint (#431)

* fix misspelling of uint

* Clarify minimum Python version management docs (#435)

* Convert TEAL version references to program version by hand

* Replace `teal#Options` with `avm#Options`

* Deprecate `*_TEAL_VERSION` in favor of `*_PROGRAM_VERSION`

* Fix docs typo

Co-authored-by: Michael Diamant <michaeldiamant@users.noreply.github.com>

* Minor `versions.rst` changes

* Fix `verifyTealVersion` in new opcode files

* Fix linter errors

* Fix language discrepencies introduced by the merge

* Remove incorrect avm replacement

* Fix inconsistent language introduced by merge

Co-authored-by: Ben Guidarelli <ben.guidarelli@gmail.com>
Co-authored-by: Michael Diamant <michaeldiamant@users.noreply.github.com>

* max program version

Co-authored-by: Ben Guidarelli <ben.guidarelli@gmail.com>
Co-authored-by: Michael Diamant <michaeldiamant@users.noreply.github.com>
Co-authored-by: Jacob Daitzman <jdtzmn@gmail.com>

* change according to https://github.com/algorand/go-algorand/pull/4323/files (#488)

* Changes to avm8 docs (#546)

* Support new AVM 8 account parameters (#555)

* CHANGELOG.md

* Frame Ops to `avm8` branch PR (#585)

* add frame ops to avm8 branch

* specify FRAME_POINTER_VERSION in frame-op branch

* per review comments

* per review comments

* per review comments, depth -> frame_depth

* take bury out

* pop popn

* unexport use of frame ops

* hide FRAME_POINTER_VERISON

* CHANGELOG 0.20.0

Co-authored-by: Ben Guidarelli <ben.guidarelli@gmail.com>
Co-authored-by: Jacob Daitzman <jdtzmn@gmail.com>
Co-authored-by: Hang Su <hang.su@algorand.com>
Co-authored-by: Hang Su <87964331+ahangsu@users.noreply.github.com>
Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>
Co-authored-by: Jason Paulos <jasonpaulos@users.noreply.github.com>
  • Loading branch information
7 people committed Nov 3, 2022
1 parent 597ed7d commit bdcdd5c
Show file tree
Hide file tree
Showing 15 changed files with 1,318 additions and 114 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Unreleased

# 0.20.0

## Added
* adding program page related ops ([#412](https://github.com/algorand/pyteal/pull/412))
* Add Replace ([#413](https://github.com/algorand/pyteal/pull/413))
* Add Block ([#415](https://github.com/algorand/pyteal/pull/415))
* Add JsonRef ([#417](https://github.com/algorand/pyteal/pull/417))
* Add Base64Decode ([#418](https://github.com/algorand/pyteal/pull/418))
* Support Secp256r1 curve ([#423](https://github.com/algorand/pyteal/pull/423))
* Add VrfVerify ([#419](https://github.com/algorand/pyteal/pull/419))
* Add Sha3_256 ([#425](https://github.com/algorand/pyteal/pull/425))
* Support FirstValidTime transaction field ([#424](https://github.com/algorand/pyteal/pull/424))
* Add Ed25519Verify_Bare ([#426](https://github.com/algorand/pyteal/pull/426))
* AVM Boxes Ops in Pyteal ([#438](https://github.com/algorand/pyteal/pull/438))
* Support new AVM 8 account parameters ([#555](https://github.com/algorand/pyteal/pull/555))

## Changed
* Changes to avm8 docs ([#546](https://github.com/algorand/pyteal/pull/546))

# 0.19.0

## Added
Expand Down
176 changes: 166 additions & 10 deletions docs/state.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,30 @@ PyTeal can be used to write `Stateful Algorand Smart Contracts <https://develope
as well. Stateful contracts, also known as applications, can access and manipulate state on the
Algorand blockchain.

State consists of key-value pairs, where keys are byte slices and values can be integers or byte
slices. There are multiple types of state that an application can use.
There are multiple types of state that an application can use.
State consists of key-value pairs, where keys are byte slices and values vary by type of state.

=================== ===================== ===============================================
Type of State Type of Key Type of Value
=================== ===================== ===============================================
Global State :any:`TealType.bytes` :any:`TealType.uint64` or :any:`TealType.bytes`
Local State :any:`TealType.bytes` :any:`TealType.uint64` or :any:`TealType.bytes`
Boxes :any:`TealType.bytes` :any:`TealType.bytes`
=================== ===================== ===============================================

State Operation Table
---------------------

================== ==================== ====================== ==================== ======================
Context Write Read Delete Check If Exists
================== ==================== ====================== ==================== ======================
Current App Global :any:`App.globalPut` :any:`App.globalGet` :any:`App.globalDel` :any:`App.globalGetEx`
Current App Local :any:`App.localPut` :any:`App.localGet` :any:`App.localDel` :any:`App.localGetEx`
Other App Global :any:`App.globalGetEx` :any:`App.globalGetEx`
Other App Local :any:`App.localGetEx` :any:`App.localGetEx`
================== ==================== ====================== ==================== ======================
================== ======================= ======================== ======================== ===================== =======================
Context Create Write Read Delete Check If Exists
================== ======================= ======================== ======================== ===================== =======================
Current App Global :any:`App.globalPut` :any:`App.globalGet` :any:`App.globalDel` :any:`App.globalGetEx`
Current App Local :any:`App.localPut` :any:`App.localGet` :any:`App.localDel` :any:`App.localGetEx`
Other App Global :any:`App.globalGetEx` :any:`App.globalGetEx`
Other App Local :any:`App.localGetEx` :any:`App.localGetEx`
Current App Boxes :any:`App.box_create` :any:`App.box_put` :any:`App.box_extract` :any:`App.box_delete` :any:`App.box_length`
:any:`App.box_put` :any:`App.box_replace` :any:`App.box_get` :any:`App.box_get`
================== ======================= ======================== ======================== ===================== =======================

Global State
------------
Expand Down Expand Up @@ -244,3 +254,149 @@ For example:
otherAppOtherAccountRole,
If(otherAppOtherAccountRole.hasValue(), otherAppOtherAccountRole.value(), Bytes("none"))
])
Box Storage
-----------

Box storage consists of key-value pairs that are stored in an application's local context.

The app account's minimum balance requirement (MBR) is increased with each additional box, and each additional byte in the box's name and allocated size.

.. warning::

If one deletes an application with outstanding boxes, the MBR is not recoverable from the deleted app account.
It is recommended that *before* app deletion, all box storage be deleted, and funds previously allocated to the MBR be withdrawn.

Box sizes and names cannot be changed after initial allocation, but they can be deleted and re-allocated.
Boxes are only visible to the application itself; in other words, an application cannot read from or write to another application's boxes on-chain.

The following sections explain how to work with boxes.

.. _Creating Boxes:

Creating Boxes
~~~~~~~~~~~~~~

To create a box, use :any:`App.box_create`, or :any:`App.box_put` method.

For :any:`App.box_create`, the first argument is the box name, and the second argument is the byte size to be allocated.

:any:`App.box_create` creates a new box with the specified name and byte length. New boxes will contain a byte string of all zeros. Performing this operation on a box that already exists will not change its contents.

If successful, :any:`App.box_create` will return :code:`0` if the box already existed, otherwise it will return :code:`1`. A failure will occur if you attempt to create a box that already exists with a different size.

For example:

.. code-block:: python
# Allocate a box called "BoxA" of byte size 100 and ignore the return value
Pop(App.box_create(Bytes("BoxA"), Int(100)))
# Allocate a box called "BoxB" of byte size 90, asserting that it didn't exist before.
Assert(App.box_create(Bytes("BoxB"), Int(90))
For :any:`App.box_put`, the first argument is the box name to create or to write to, and the second argument is the bytes to write.
.. note::
If the box exists, then :any:`App.box_put` will write the contents to the box
(fails when the content length is **not identical** to the existing box's byte size);
otherwise, it will create a box containing exactly the same input bytes.
.. code-block:: python
# create a 42 bytes length box called `poemLine` with content
App.box_put(Bytes("poemLine"), Bytes("Of that colossal wreck, boundless and bare"))
# write to box `poemLine` with new value
App.box_put(Bytes("poemLine"), Bytes("The lone and level sands stretch far away."))
Writing to a Box
~~~~~~~~~~~~~~~~
To write to a box, use :any:`App.box_replace`, or :any:`App.box_put` method.
:any:`App.box_replace` writes bytes of certain length from a start index in a box.
The first argument is the box name to write into, the second argument is the starting index to write,
and the third argument is the replacement bytes. For example:
.. code-block:: python
# replace 2 bytes starting from the 0'th byte by `Ne` in the box named `wordleBox`
App.box_replace(Bytes("wordleBox"), Int(0), Bytes("Ne"))
:any:`App.box_put` writes the full contents to a pre-existing box, as is mentioned in `Creating Boxes`_.
.. _Reading from a Box:
Reading from a Box
~~~~~~~~~~~~~~~~~~
To read from a box, use :any:`App.box_extract`, or :any:`App.box_get` method.
:any:`App.box_extract` reads bytes of a certain length from a start index in a Box.
The first argument is the box name to read from, the second argument is the starting index to read,
and the third argument is the length of bytes to extract. For example:
.. code-block:: python
# extract a segment of length 10 starting at the 5th byte in a box named `NoteBook`
App.box_extract(Bytes("NoteBook"), Int(5), Int(10))
:any:`App.box_get` gets the full contents of a box.
The only argument is the box name, and it returns a :any:`MaybeValue` containing:
- a boolean value indicating if the box exists
- the full contents of the box.
For example:
.. code-block:: python
# get the full contents from a box named `NoteBook`, asserting that it exists
Seq(
contents := App.box_get(Bytes("NoteBook")),
Assert(contents.hasValue()),
contents.value()
)
Deleting a Box
~~~~~~~~~~~~~~
To delete a box, use :any:`App.box_delete` method. The only argument is the box name.
:any:`App.box_delete` will return :code:`1` if the box already existed, otherwise it will return :code:`0`. Deleting a nonexistent box is allowed, but has no effect.
For example:
.. code-block:: python
# delete the box `boxToRemove`, asserting that it existed prior to this
Assert(App.box_delete(Bytes("boxToRemove")))
# delete the box `mightExist` and ignore the return value
Pop(App.box_delete(Bytes("mightExist")))
Checking if a Box Exists and Reads its Length
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To check the existence of a box, use the :any:`App.box_length` method.
The only argument is the box name, and it returns a :any:`MaybeValue` containing:
- a boolean value indicating if the box exists
- the actual byte size of the box.
For example:
.. code-block:: python
# get the length of the box `someBox`, and assert that the box exists
Seq(
length := App.box_length(Bytes("someBox")),
Assert(length.hasValue()),
length.value()
)
.. note::
:any:`App.box_get` can also check the existence of a box as mentioned in `Reading from a Box`_.
7 changes: 7 additions & 0 deletions pyteal/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ __all__ = [
"BitwiseOr",
"BitwiseXor",
"Block",
"BoxCreate",
"BoxDelete",
"BoxExtract",
"BoxGet",
"BoxLen",
"BoxPut",
"BoxReplace",
"Break",
"Btoi",
"Bytes",
Expand Down
17 changes: 17 additions & 0 deletions pyteal/ast/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from pyteal.ast.gitxn import Gitxn, GitxnExpr, GitxnaExpr, InnerTxnGroup
from pyteal.ast.gload import ImportScratchValue
from pyteal.ast.global_ import Global, GlobalField

from pyteal.ast.app import App, AppField, OnComplete, AppParam, AppParamObject
from pyteal.ast.asset import (
AssetHolding,
Expand All @@ -33,6 +34,15 @@
AssetParamObject,
)
from pyteal.ast.acct import AccountParam, AccountParamObject
from pyteal.ast.box import (
BoxCreate,
BoxDelete,
BoxExtract,
BoxReplace,
BoxLen,
BoxGet,
BoxPut,
)

# inner txns
from pyteal.ast.itxn import InnerTxnBuilder, InnerTxn, InnerTxnAction
Expand Down Expand Up @@ -175,6 +185,13 @@
"LeafExpr",
"Addr",
"Bytes",
"BoxCreate",
"BoxDelete",
"BoxReplace",
"BoxExtract",
"BoxLen",
"BoxGet",
"BoxPut",
"Int",
"EnumInt",
"MethodSignature",
Expand Down

0 comments on commit bdcdd5c

Please sign in to comment.