Simple Python Conversion to Algorand - Algorand

Simple Python Conversion to Algorand

I am working toward converting the logic programmed in Python to PyTeal or Algorand Python. The program is a simple game, where the user pays a specified amount x in the example below 7. If the payment amount is correct, the game generates a random number from 0 to 9. If the number is 7 the user wins 70, else the user wins 0.

I’m consistently running into errors with the PyTeal logic. I’m looking for a base description of the necessary elements of the language, so I can re-write my python script for processing on Algorand. Any suggestions or guidance would be appreciated.

Python Code

import random

# x is the payment received by the smart contract
x = 7

# if the amount received is equal to 7, the following logic proceeds
if x == 7:
    # one random number is generated
    h = random.randint(0,9)
    print(h)

# Scoring
    a = 0
    if h == 7:
        print('reward = 70')
    else:
        print('better luck next time')

PyTeal

from pyteal import *

# Check if the payment received is equal to 7
Txn.amount() == Int(7),

# Generate a pseudo-random number using the round number as a seed
Int(0) <= Global.round() % Int(10) <= Int(9),
if Global.round() % Int(10) == Int(7):
    App.localPut(Int(0), Bytes("h"), Int(70))
else:
    App.localPut(Int(0), Bytes("h"), Int(0))

# Print the compiled TEAL program
print(compileTeal(program, mode=Mode.Application))

Error

Traceback (most recent call last):
  File "/Users/brianhaney/Desktop/game2.py", line 6, in <module>
    Txn.amount() == int(7),
    ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/brianhaney/myenv/lib/python3.12/site-packages/pyteal/ast/expr.py", line 67, in __eq__
    return Eq(self, other)
           ^^^^^^^^^^^^^^^
AttributeError: 'int' object has no attribute 'type_of'

Revised Code

from pyteal import *

# Define the TEAL program logic
program = And(
    # Check if the payment received is equal to 7
    Txn.amount() == Int(7),

# Generate a pseudo-random number using the round number as a seed
    And(Int(0) <= Global.round(), Global.round() <= Int(9)),

If(Global.round() == Int(7)).Then(
        App.localPut(Int(0), Bytes("h"), Int(70))
    ).Else(
        App.localPut(Int(0), Bytes("h"), Int(0))
    )
)

# Print the compiled TEAL program
print(compileTeal(program, mode=Mode.Application))

New Error

Traceback (most recent call last):
  File "/Users/brianhaney/Desktop/Slot/algo-game/game2.py", line 4, in <module>
    program = And(
              ^^^^
  File "/Users/brianhaney/Desktop/ArbBot/myenv/lib/python3.12/site-packages/pyteal/ast/naryexpr.py", line 106, in And
    return NaryExpr(Op.logic_and, TealType.uint64, TealType.uint64, args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/brianhaney/Desktop/ArbBot/myenv/lib/python3.12/site-packages/pyteal/ast/naryexpr.py", line 29, in __init__
    require_type(arg, inputType)
  File "/Users/brianhaney/Desktop/ArbBot/myenv/lib/python3.12/site-packages/pyteal/types.py", line 38, in require_type
    raise TealTypeError(actual, expected)
pyteal.TealTypeError: TealType.none while expected TealType.uint64

Try this:

from pyteal import *

# Define the TEAL program logic
#program = And(
    # Check if the payment received is equal to 7
    ##Txn.amount() == Int(7),

# Generate a pseudo-random number using the round number as a seed
    ##Int(0) <= Global.round(), Global.round() <= Int(9),
program = Seq(
    If(And(Txn.amount() == Int(7), Int(0) <= Global.round(), Global.round() <= Int(9), Global.round() == Int(7))).Then(
        App.localPut(Int(0), Bytes("h"), Int(70))
    ).Else(
        App.localPut(Int(0), Bytes("h"), Int(0))
    ),
    Return(Int(1))
)
#)

# Print the compiled TEAL program
print(compileTeal(program, mode=Mode.Application))

Where the random number is generated?

The Global.round() gives you back the actual round when the last block was created. It is NOT random at all, I thought you want to use it only for test purposes. Of course, it should be reduced to a number between 0 and 9 by getting the remainder, i.e. using Mod(Global.round(), Int(10)).

Additional Resources

Usage and Best Practices for Randomness Beacon
Algorand Randomness Beacon GitHub

Upcoming bootcamps: Algorand Foundation Events

All setup is EASY when using codespace:

pipx install algokit
algokit localnet start
docker ps
# before "algokit explore" make ports public on the "Ports" tab
algokit explore
# to try out the localnet environment