Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ Alternatively, if you want to start from scratch you can do the following:
4. Install Algorand Python into your project `poetry add algorand-python`
5. Create a contract in a (e.g.) `contract.py` file:
```python
from algopy import ARC4Contract, arc4
class HelloWorldContract(ARC4Contract):
from algopy import Contract, arc4
class HelloWorldContract(Contract):
@arc4.abimethod
def hello(self, name: arc4.String) -> arc4.String:
return "Hello, " + name
Expand Down
40 changes: 40 additions & 0 deletions changelog.d/20260122_170552_bobby.lat_arc4_contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!--
A new scriv changelog fragment.

Uncomment the section that is right (remove the HTML comment wrapper).
For top level release notes, leave all the headers commented out.
-->

<!--
### Removed

- A bullet item for the Removed category.

-->

### Added

- Added `algopy.Contract` as an alias of `algopy.arc4.ARC4Contract` for convenience.

### Changed

- Non-ARC-4 contract class is renamed as `algopy.BaseContract`

<!--
### Deprecated

- A bullet item for the Deprecated category.

-->
<!--
### Fixed

- A bullet item for the Fixed category.

-->
<!--
### Security

- A bullet item for the Security category.

-->
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ Alternatively, if you want to start from scratch you can do the following:
4. Install Algorand Python into your project `poetry add algorand-python`
5. Create a contract in a (e.g.) `contract.py` file:
```python
from algopy import ARC4Contract, arc4
class HelloWorldContract(ARC4Contract):
from algopy import Contract, arc4
class HelloWorldContract(Contract):
@arc4.abimethod
def hello(self, name: arc4.String) -> arc4.String:
return "Hello, " + name
Expand Down
4 changes: 2 additions & 2 deletions docs/lg-arc28.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ To emit an ARC-28 event in Algorand Python you can use the `emit` function, whic
Here's an example contract that emits events:

```python
from algopy import ARC4Contract, arc4
from algopy import Contract, arc4

class Swapped(arc4.Struct):
a: arc4.UInt64
b: arc4.UInt64

class EventEmitter(ARC4Contract):
class EventEmitter(Contract):
@arc4.abimethod
def emit_swapped(self, a: arc4.UInt64, b: arc4.UInt64) -> None:
arc4.emit(Swapped(b, a))
Expand Down
16 changes: 8 additions & 8 deletions docs/lg-arc4.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

[ARC-4](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0004.md) defines a set of encodings and behaviors for authoring and interacting with an Algorand Smart Contract. It is not the only way to author a smart contract, but adhering to it will make it easier for other clients and users to interop with your contract.

To author an arc4 contract you should extend the `ARC4Contract` base class.
To author an arc4 contract you should extend the `Contract` base class.

```python
from algopy import ARC4Contract
from algopy import Contract

class HelloWorldContract(ARC4Contract):
class HelloWorldContract(Contract):
...
```

Expand All @@ -27,10 +27,10 @@ A method that should not be externally available can be optionally annotated wit
Method docstrings will be used when outputting ARC-32 or ARC-56 application specifications, the following docstrings styles are supported ReST, Google, Numpydoc-style and Epydoc.

```python
from algopy import ARC4Contract, subroutine, arc4, public
from algopy import Contract, subroutine, arc4, public


class HelloWorldContract(ARC4Contract):
class HelloWorldContract(Contract):
@arc4.abimethod(create="disallow", allow_actions=["NoOp", "OptIn"], name="external_name")
def hello(self, name: arc4.String) -> arc4.String:
return self.hello_impl() + name
Expand All @@ -51,7 +51,7 @@ class HelloWorldContract(ARC4Contract):

Algorand Smart Contracts only have two possible programs that are invoked when making an ApplicationCall Transaction (`appl`). The "clear state" program which is called when using an OnComplete action of `ClearState` or the "approval" program which is called for all other OnComplete actions.

Routing is required to dispatch calls handled by the approval program to the relevant ABI methods. When extending `ARC4Contract`, the routing code is automatically generated for you by the PuyaPy compiler.
Routing is required to dispatch calls handled by the approval program to the relevant ABI methods. When extending `Contract`, the routing code is automatically generated for you by the PuyaPy compiler.

## Types

Expand Down Expand Up @@ -202,13 +202,13 @@ These types can only be used as parameters, and not as return types.
from algopy import (
Account,
Application,
ARC4Contract,
Contract,
Asset,
arc4,
gtxn,
)

class Reference(ARC4Contract):
class Reference(Contract):
@arc4.abimethod
def with_transactions(
self,
Expand Down
12 changes: 6 additions & 6 deletions docs/lg-calling-apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ If the ARC-4 method returns an ARC-4 result then the result will be a tuple of t
If the ARC-4 method does not return a result, or if the result type is not fully qualified then just the inner transaction is returned.

```python
from algopy import Application, ARC4Contract, String, arc4, subroutine
from algopy import Application, Contract, String, arc4, subroutine

class HelloWorld(ARC4Contract):
class HelloWorld(Contract):

@arc4.abimethod()
def greet(self, name: String) -> String:
Expand Down Expand Up @@ -89,9 +89,9 @@ If the compiled programs and state allocation fields need to be customized (for
this can be done by passing a [`algopy.CompiledContract`](#algopy.CompiledContract) via the `compiled` keyword argument.

```python
from algopy import ARC4Contract, String, arc4, subroutine
from algopy import Contract, String, arc4, subroutine

class HelloWorld(ARC4Contract):
class HelloWorld(Contract):

@arc4.abimethod()
def greet(self, name: String) -> String:
Expand All @@ -116,9 +116,9 @@ If the compiled programs need to be customized (for example due to [template var
this can be done by passing a [`algopy.CompiledContract`](#algopy.CompiledContract) via the `compiled` keyword argument.

```python
from algopy import Application, ARC4Contract, String, arc4, subroutine
from algopy import Application, Contract, String, arc4, subroutine

class NewApp(ARC4Contract):
class NewApp(Contract):

@arc4.abimethod()
def greet(self, name: String) -> String:
Expand Down
4 changes: 2 additions & 2 deletions docs/lg-compile.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ For example, the following contract has `UInt64` and `Bytes` template variables.

```{code-block} python
:caption: templated_contract.py
from algopy import ARC4Contract, Bytes, TemplateVar, UInt64, arc4
from algopy import Contract, Bytes, TemplateVar, UInt64, arc4


class TemplatedContract(ARC4Contract):
class TemplatedContract(Contract):

@arc4.abimethod
def my_method(self) -> UInt64:
Expand Down
6 changes: 3 additions & 3 deletions docs/lg-data-structures.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ However Puya will support reading and writing parts of a box

```python
import typing
from algopy import Box, FixedArray, Struct, UInt64, arc4, size_of
from algopy import Box, Contract, FixedArray, Struct, UInt64, arc4, size_of



class BigStruct(Struct):
count: UInt64 # 8 bytes
large_array: FixedArray[UInt64, typing.Literal[512]] # 4096 bytes

class Contract(arc4.ARC4Contract):
class Contract(Contract):

def __init__(self) -> None:
self.box = Box(BigStruct)
Expand Down Expand Up @@ -179,7 +179,7 @@ This is a regular python tuple
```python
import algopy

class SomeContract(algopy.arc4.ARC4Contract):
class SomeContract(algopy.Contract):
@algopy.arc4.abimethod()
def get_array(self) -> algopy.ImmutableArray[algopy.UInt64]:
arr = algopy.ReferenceArray[algopy.UInt64]()
Expand Down
4 changes: 2 additions & 2 deletions docs/lg-logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ If you want to emit ARC-28 events in the logs then there is a [purpose-built fun
Here's an example contract that uses the log method in various ways:

```python
from algopy import BigUInt, Bytes, Contract, log, op
from algopy import BigUInt, Bytes, BaseContract, log, op

class MyContract(Contract):
class MyContract(BaseContract):
def approval_program(self) -> bool:
log(0)
log(b"1")
Expand Down
4 changes: 2 additions & 2 deletions docs/lg-migration-4-5.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ Individual methods can be forced to use the original behaviour by setting the `r
on `arc4.abimethod` e.g.

```python
from algopy import arc4, Account, Application, Asset
from algopy import arc4, Account, Application, Asset, Contract

class MyContract(arc4.ARC4Contract):
class MyContract(Contract):
@arc4.abimethod(resource_encoding="index")
def my_abi_method(self, app: Application, asset: Asset, account: Account) -> None:
...
Expand Down
16 changes: 8 additions & 8 deletions docs/lg-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ Once declared, you can interact with the box via its instance methods.

```python
import typing as t
from algopy import Box, arc4, Contract, op
from algopy import Box, arc4, BaseContract, op


class MyContract(Contract):
class MyContract(BaseContract):
def __init__(self) -> None:
self.box_a = Box(arc4.StaticArray[arc4.UInt32, t.Literal[20]], key=b"a")

Expand All @@ -129,10 +129,10 @@ class MyContract(Contract):
In addition to being able to set and read the box value, there are operations for extracting and replacing just a portion of the box data which is useful for minimizing the amount of reads and writes required, but also allows you to interact with byte arrays which are longer than the AVM can support (currently 4096).

```python
from algopy import Box, Contract, Global, Txn
from algopy import Box, BaseContract, Global, Txn


class MyContract(Contract):
class MyContract(BaseContract):
def approval_program(self) -> bool:
my_blob = Box(Bytes, key=b"blob")

Expand Down Expand Up @@ -162,9 +162,9 @@ A custom `key_prefix` can optionally be provided, with the default being to use
The key can be a `Bytes` value, or anything that can be converted to `Bytes`. The final box name is the combination of `key_prefix + key`.

```python
from algopy import BoxMap, Contract, Account, Txn, String
from algopy import BoxMap, BaseContract, Account, Txn, String

class MyContract(Contract):
class MyContract(BaseContract):
def __init__(self) -> None:
self.my_map = BoxMap(Account, String, key_prefix=b"a_")

Expand Down Expand Up @@ -200,13 +200,13 @@ To use scratch storage you need to [register the scratch storage that you want t
For example:

```python
from algopy import Bytes, Contract, UInt64, op, urange
from algopy import Bytes, BaseContract, UInt64, op, urange

TWO = 2
TWENTY = 20


class MyContract(Contract, scratch_slots=(1, TWO, urange(3, TWENTY))):
class MyContract(BaseContract, scratch_slots=(1, TWO, urange(3, TWENTY))):
def approval_program(self) -> bool:
op.Scratch.store(1, UInt64(5))

Expand Down
32 changes: 17 additions & 15 deletions docs/lg-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ An [Algorand smart contract](https://dev.algorand.co/concepts/smart-contracts/ap
consists of two distinct "programs"; an approval program, and a
clear-state program. These are tied together in Algorand Python as a single class.

All contracts must inherit from the base class `algopy.Contract` - either directly or indirectly,
which can include inheriting from `algopy.ARC4Contract`.
All contracts must inherit from the base class `algopy.BaseContract` - either directly or indirectly,
which can include inheriting from `algopy.ARC4Contract` or its alias, `algopy.Contract`.

The life-cycle of a smart contract matches the semantics of Python classes when you consider
deploying a smart contract as "instantiating" the class. Any calls to that smart contract are made
Expand All @@ -111,7 +111,7 @@ definitions. Forward type declarations are allowed.
Example:

```python
class MyContract(algopy.Contract):
class MyContract(algopy.BaseContract):
foo: algopy.UInt64 # okay
bar = algopy.UInt64(1) # not allowed

Expand All @@ -129,8 +129,8 @@ abstract methods are unimplemented.

### Contract class configuration

When defining a contract subclass you can pass configuration options to the `algopy.Contract`
base class [per the API documentation](./api-algopy.md#algopy.Contract).
When defining a contract subclass you can pass configuration options to the `algopy.BaseContract`
base class [per the API documentation](./api-algopy.md#algopy.BaseContract).

Namely you can pass in:

Expand All @@ -147,23 +147,23 @@ Full example:
GLOBAL_UINTS = 3

class MyContract(
algopy.Contract,
algopy.BaseContract,
name="CustomName",
scratch_slots=[5, 25, algopy.urange(110, 115)],
state_totals=algopy.StateTotals(local_bytes=1, local_uints=2, global_bytes=4, global_uints=GLOBAL_UINTS),
):
...
```

### Example: Simplest possible `algopy.Contract` implementation
### Example: Simplest possible `algopy.BaseContract` implementation

For a non-ARC-4 contract, the contract class must implement an `approval_program` and
a `clear_state_program` method.

As an example, this is a valid contract that always approves:

```python
class Contract(algopy.Contract):
class Contract(algopy.BaseContract):
def approval_program(self) -> bool:
return True

Expand All @@ -181,7 +181,7 @@ Here is a very simple example contract that maintains a counter of how many time
been called (including on create).

```python
class Counter(algopy.Contract):
class Counter(algopy.BaseContract):
def __init__(self) -> None:
self.counter = algopy.UInt64(0)

Expand Down Expand Up @@ -209,12 +209,12 @@ Some things to note:
- Any methods other than `__init__`, `approval_program` or `clear_state_program` must be decorated
with `@subroutine`.

### Example: Simplest possible `algopy.ARC4Contract` implementation
### Example: Simplest possible `algopy.Contract` implementation

And here is a valid ARC-4 contract:

```python
class ABIContract(algopy.ARC4Contract):
class ABIContract(algopy.Contract):
pass
```

Expand All @@ -231,7 +231,7 @@ A default `clear_state_program` is implemented which always approves, but this c
```python
import algopy

class ARC4Counter(algopy.ARC4Contract):
class ARC4Counter(algopy.Contract):
def __init__(self) -> None:
self.counter = algopy.UInt64(0)

Expand All @@ -255,9 +255,11 @@ Things to note here:
- The default options for `abimethod` is to only allow `NoOp` as an on-completion-action, so we
don't need to check this manually.
- The current call count is returned from the `invoke` method.
- Every method in an `ARC4Contract` except for the optional `__init__` and `clear_state_program`
methods must be decorated with one of `algopy.arc4.abimethod`, `algopy.arc4.baremethod`, or
`algopy.subroutine`. `subroutines` won't be directly callable through the default router.
- Every method in an `Contract` except for the optional `__init__` and `clear_state_program`
methods must be decorated with one of `algopy.arc4.baremethod`, `algopy.arc4.abimethod`
(or its alias, `public`), to indicate that they are externally callable. Other methods which won't
be directly callable through the default router can be optionally decorated with
`algopy.subroutine` decorator.

See the [ARC-4 section](lg-arc4.md) of this language guide for more info on the above.

Expand Down
Loading
Loading