def euclid(x, y): a = ScratchVar(TealType.uint64) b = ScratchVar(TealType.uint64) tmp = ScratchVar(TealType.uint64) start = If(x < y, Seq(a.store(y), b.store(x)), Seq(a.store(x), b.store(y))) cond = b.load() > Int(0) step = Seq(tmp.store(b.load()), b.store(Mod(a.load(), b.load())), a.store(tmp.load())) return Seq(For(start, cond, step).Do(Seq()), a.load())
def make_return(e): if e.type_of() == TealType.uint64: return e if e.type_of() == TealType.bytes: return Len(e) if e.type_of() == TealType.anytype: x = ScratchVar(TealType.anytype) return Seq(x.store(e), Int(1337)) # TealType.none: return Seq(e, Int(1337))
def while_continue_accumulation(n): i = ScratchVar(TealType.uint64) return Seq( i.store(Int(0)), While(i.load() < n).Do( Seq( i.store(i.load() + Int(1)), Continue(), )), Return(i.load()), )
def abi_sum(to_sum: abi.DynamicArray[abi.Uint64], *, output: abi.Uint64) -> Expr: i = ScratchVar(TealType.uint64) value_at_index = abi.Uint64() return Seq( output.set(0), For(i.store(Int(0)), i.load() < to_sum.length(), i.store(i.load() + Int(1))).Do( Seq( to_sum[i.load()].store_into(value_at_index), output.set(output.get() + value_at_index.get()), )), )
def approval(): # Checks that the app call sender is the creator of this app is_app_creator = Txn.sender() == Global.creator_address() verify = Seq( Pop( # In this example, we don't actually care about the result of the # verification function, just pop it off the stack Ed25519Verify( # Calls the ed25519 verify opcode on what is # normally some bytes that should be signed and the signature Txn.application_args[0], # Bytes signed Txn.application_args[1], # Signature Txn.sender() # Public key of signer ) ), # Return 1 so the transaction is approved Int(1) ) return Cond( [Txn.application_id() == Int(0), Return(Int(1))], [Txn.on_completion() == OnComplete.DeleteApplication, Return(is_app_creator)], [Txn.on_completion() == OnComplete.UpdateApplication, Return(is_app_creator)], [Txn.on_completion() == OnComplete.CloseOut, Return(Int(1))], [Txn.on_completion() == OnComplete.OptIn, Return(Int(1))], [Txn.application_args.length()>Int(0), Return(verify)], [Txn.application_args.length()==Int(0), Return(Int(1))] )
def sing(count): return Seq( # Each call to Log takes the bytestring passed and logs the message # itoa is a subroutine in the util.py file, it converts an integer to a bytestring # representing the ascii numberic characters Log(Concat(itoa(count), Bytes(" Bottles of beer on the wall"))), Log(Concat(itoa(count), Bytes(" Bottles of beer"))), Log(Bytes("Take one down, pass it around")), Log(Concat(itoa(count-Int(1)), Bytes(" Bottles of beer on the wall"))) )
def approval(): if subdef.return_type == TealType.none: result = ScratchVar(TealType.uint64) part1 = [subr_caller(), result.store(Int(1337))] else: result = ScratchVar(subdef.return_type) part1 = [result.store(subr_caller())] part2 = [make_log(result.load()), make_return(result.load())] return Seq(*(part1 + part2))
def root_closeness(A, B, C, X): left = ScratchVar(TealType.uint64) right = ScratchVar(TealType.uint64) return Seq( left.store(A * X * X + C), right.store(B * X), If(left.load() < right.load()).Then(right.load() - left.load()).Else(left.load() - right.load()), )
def user_guide_snippet_ILLEGAL_recursion(): from pyteal import If, Int, ScratchVar, Seq, Subroutine, TealType @Subroutine(TealType.none) def ILLEGAL_recursion(i: ScratchVar): return (If(i.load() == Int(0)).Then(i.store( Int(1))).ElseIf(i.load() == Int(1)).Then(i.store(Int(0))).Else( Seq(i.store(i.load() - Int(2)), ILLEGAL_recursion(i)))) i = ScratchVar(TealType.uint64) return Seq(i.store(Int(15)), ILLEGAL_recursion(i), Int(1))
def escrow_account(note): precondition = And( Global.group_size() == Int(1), Txn.note() == Bytes(note), # Safety checks Txn.rekey_to() == Global.zero_address(), Txn.close_remainder_to() == Global.zero_address(), Txn.fee() <= Int(FEE), ) return Seq([Assert(precondition), Return(Int(1))])
def user_guide_snippet_dynamic_scratch_var() -> pt.Expr: """ The user guide docs use the test to illustrate `DynamicScratchVar` usage. If the test breaks, then the user guide docs must be updated along with the test. """ from pyteal import Assert, Int, DynamicScratchVar, ScratchVar, Seq, TealType s = ScratchVar(TealType.uint64) d = DynamicScratchVar(TealType.uint64) return Seq( d.set_index(s), s.store(Int(7)), d.store(d.load() + Int(3)), Assert(s.load() == Int(10)), Int(1), )
def approval(): preps, calls = self._prepare_n_calls() # when @ABIReturnSubroutine is void: # invocation is an Expr of TealType.none # otherwise: # it is a ComputedValue invocation = self.subr(*calls) if output: invocation = output.set(invocation) if self.mode == Mode.Signature: results = [invocation, Pop(output.encode()), Int(1)] else: results = [invocation, abi.MethodReturn(output), Int(1)] else: results = [invocation, Int(1)] return Seq(*(preps + results))
def logicsig(a: int, p: int, q: int) -> Expr: """ Choices * (a, p, q) = (1, 5, 7) * compiling on program version 5 and * with assembleConstants = True results in Logic-Sig Contract Account Address: WO3TQD3WBSDKB6WEHUMSEBFH53GZVVXYGPWYDWKUZCKEXTVCDNDHJGG6II """ assert all( isinstance(x, int) and p < q and a > 0 and x >= 0 for x in (a, p, q)), f"require non-negative ints a, p, q with p < q but got {a, p, q}" b, c = a * (p + q), a * p * q msg = Bytes(f"Can you factor {a} * x^2 - {b} * x + {c} ?") A, B, C = Int(a), Int(b), Int(c) X1 = Btoi(Arg(0)) X2 = Btoi(Arg(1)) C1 = ScratchVar(TealType.uint64) C2 = ScratchVar(TealType.uint64) SUM = ScratchVar(TealType.uint64) PRIZE = ScratchVar(TealType.uint64) return Seq( Pop(msg), C1.store(root_closeness(A, B, C, X1)), C2.store(root_closeness(A, B, C, X2)), SUM.store(C1.load() + C2.load()), PRIZE.store(calculate_prize(SUM.load())), And( Txn.type_enum() == TxnType.Payment, Txn.close_remainder_to() == Global.zero_address(), X1 != X2, PRIZE.load(), Txn.amount() == PRIZE.load(), ), )
def approval(): # Checks that the app call sender is the creator of this app is_app_creator = Txn.sender() == Global.creator_address() # Create a scratch var for iteration i = ScratchVar() # Set up the components of the for loop # start at 99 because thats how the song goes init = i.store(Int(99)) # this is the condition that will be evaluated in the for loop # the for loop will terminate when this returns false cond = i.load()>Int(97) # this is the decrement portion of this for loop, just subtracts 1 for every loop iteration iter = i.store(i.load() - Int(1)) log = Seq( # Call the for loop with the components we defined above For(init, cond, iter).Do( # sing is called with the current value of i, # it doesn't return anything so it is fine to include in # the `Do` portion of the loop sing(i.load()) ), # Return 1 so the transaction will pass Int(1) ) return Cond( [Txn.application_id() == Int(0), Return(Int(1))], [Txn.on_completion() == OnComplete.DeleteApplication, Return(is_app_creator)], [Txn.on_completion() == OnComplete.UpdateApplication, Return(is_app_creator)], [Txn.on_completion() == OnComplete.CloseOut, Return(Int(1))], [Txn.on_completion() == OnComplete.OptIn, Return(Int(1))], [Txn.on_completion() == OnComplete.NoOp, Return(log)], )
def approval_program(): # On application create, put the creator key in global storage on_create = Seq([App.globalPut(KEY_CREATOR, Txn.sender()), Int(1)]) # Closeout on validator does nothing on_closeout = Return(Int(1)) # Opt in on validator does nothing on_opt_in = Return(Int(1)) on_swap_deposit = Assert( And( # Group has 3 transactions Global.group_size() == Int(3), # This ApplicationCall is the 1st transaction Txn.group_index() == Int(0), # No additional actions are needed from this transaction Txn.on_completion() == OnComplete.NoOp, # Has one additional account attached Txn.accounts.length() == Int(1), # Has two application arguments Txn.application_args.length() == Int(2), # Second txn to manager # Is of type ApplicationCall Gtxn[1].type_enum() == TxnType.ApplicationCall, # No additional actions needed Gtxn[1].on_completion() == OnComplete.NoOp, # Has one additional account attached Gtxn[1].accounts.length() == Int(1), # Has two application arguments Gtxn[1].application_args.length() == Int(2), # Additional account is same in both calls Txn.accounts[1] == Gtxn[1].accounts[1], # Application argument is same in both calls Txn.application_args[0] == Gtxn[1].application_args[0], Txn.application_args[1] == Gtxn[1].application_args[1], # Third txn to escrow # Is of type AssetTransfer Gtxn[2].type_enum() == TxnType.AssetTransfer, Gtxn[2].sender() == Global.zero_address(), Gtxn[2].asset_receiver() == Txn.accounts[1], )) program = Cond( [Txn.application_id() == Int(0), on_create], [Txn.on_completion() == OnComplete.CloseOut, on_closeout], [Txn.on_completion() == OnComplete.OptIn, on_opt_in], [ Txn.application_args[0] == TRANSACTION_TYPE_SWAP_DEPOSIT_TOKEN1_TO_TOKEN2, on_swap_deposit ], [ Txn.application_args[0] == TRANSACTION_TYPE_SWAP_DEPOSIT_TOKEN2_TO_TOKEN1, on_swap_deposit_2 ], [ Txn.application_args[0] == TRANSACTION_TYPE_ADD_LIQUIDITY_DEPOSIT, on_add_liquidity_deposit ], [ Txn.application_args[0] == TRANSACTION_TYPE_WITHDRAW_LIQUIDITY, on_withdraw_liquidity ], [Txn.application_args[0] == TRANSACTION_TYPE_REFUND, on_refund], [ Txn.application_args[0] == TRANSACTION_TYPE_WITHDRAW_PROTOCOL_FEES, on_withdraw_protocol_fees ], ) return
def ILLEGAL_recursion(i: ScratchVar): return (If(i.load() == Int(0)).Then(i.store( Int(1))).ElseIf(i.load() == Int(1)).Then(i.store(Int(0))).Else( Seq(i.store(i.load() - Int(2)), ILLEGAL_recursion(i))))
def subr_caller(): preps, calls = self._prepare_n_calls() invocation = self.subr(*calls) if preps: return Seq(*(preps + [invocation])) return invocation