algorand / algorand/pyteal

ABI: ABI Subroutine Improvements

Open
#352 0 comments 0 reactions 0 assignees View on GitHub
new-feature-request Team Scytale
Dominant language
Python
Stars
288
Forks
138
PR merge metrics
No merged PRs in 30d

Description

## Problem

Usage of ABI subroutines is more verbose than necessary. For example, consider these 2 cases:

```python
Int65 = Tuple2[Bool, Uint64]

@ABIReturnSubroutine
def int65_negate(x: Int65, *, output: Int65):
x0 = Bool()
x1 = Uint64()
z0 = Bool()
z1 = Uint64()
return Seq(
x0.set(x[0]),
x1.set(x[1]),
z0.set(Not(x0.get())),
z1.set(x1.get()),
output.set(z0, z1),
)
# can't just call:
# return output.set(Not(x[0].get()), x[1])

Complex130 = Tuple2[Int65, Int65]

# @ABIReturnSubroutines defined "previously":
# * int65_sub()
# * int65_add()
# * int65_mult()

@ABIReturnSubroutine
def complex130_mult(x: Complex130, y: Complex130, *, output: Complex130):
x0 = make(Int65)
x1 = make(Int65)
y0 = make(Int65)
y1 = make(Int65)
t1 = make(Int65)
t2 = make(Int65)
t3 = make(Int65)
t4 = make(Int65)
z0 = make(Int65)
z1 = make(Int65)
return pt.Seq(
x0.set(x[0]),
x1.set(x[1]),
y0.set(y[0]),
y1.set(y[1]),
t1.set(int65_mult(x0, y0)),
t2.set(int65_mult(x1, y1)),
t3.set(int65_mult(x0, y1)),
t4.set(int65_mult(x1, y0)),
z0.set(int65_sub(t1, t2)),
z1.set(int65_add(t3, t4)),
output.set(z0, z1),
)
# can't just call:
# return output.set(
# int65_sub(int65_mult(x[0], y[0]), int65_mult(x[1], y[1])),
# int65_add(int65_mult(x[0], y[1]), int65_mult(x[1], y[0])),
# )
```

* the first example is illegal for 2 reasons:
1. [**CANNOT set() WITH Expr**] we are attempting `Tuple.set(Expr, ...)` - i.e, attempting to set a tuple with an an element that is neither a `ComputedValue` nor a `BaseType`, but an `Expr`
2. [**CANNOT get() Expr FROM ComputedValue**] we are attempting `TupleElement.get()` - which does not exist
* [**CANNOT chain ABIReturnSubroutine**] the second example is illegal because we are attempting to supply a `ComputedValue` as input to an `ABIReturnSubroutine` and only `Expr | ScratchVar | abi.BaseType` are acceptable.

## Solution

As pointed out above, there are 3 categorical problems here:

1. [**CANNOT set() WITH Expr**]
2. [**CANNOT get() Expr FROM ComputedValue**]
3. [**CANNOT chain ABIReturnSubroutine**]

It appears that (3) is easier than (1) and (2) because it only involves making `ABIReturnSubroutine` accept `ComputedValue` params. However, in solving this problem, it is likely that (2) will need to be solved as well.

## Dependencies

None

## Urgency

Medium - though these additions are not strictly necessary for PyTEAL developers, they can allow more succinctness, and reduce the chance of programming error (generally speaking, less lines of code is correlated with less bugs).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.