def logcat(some_bytes, an_int): catted = pt.ScratchVar(pt.TealType.bytes) return pt.Seq( catted.store(pt.Concat(some_bytes, pt.Itob(an_int))), pt.Log(catted.load()), catted.load(), )
def string_mult(): s = pt.ScratchVar(pt.TealType.bytes) return pt.Seq( s.store(pt.Txn.application_args[0]), subr_string_mult(s, pt.Btoi(pt.Txn.application_args[1])), pt.Log(s.load()), pt.Int(100), )
def test_wrap_handler_bare_call(): BARE_CALL_CASES = [ dummy_doing_nothing, safe_clear_state_delete, pt.Approve(), pt.Log(pt.Bytes("message")), ] for bare_call in BARE_CALL_CASES: wrapped: pt.Expr = ASTBuilder.wrap_handler(False, bare_call) expected: pt.Expr match bare_call: case pt.Expr(): if bare_call.has_return(): expected = bare_call else: expected = pt.Seq(bare_call, pt.Approve()) case pt.SubroutineFnWrapper() | pt.ABIReturnSubroutine(): expected = pt.Seq(bare_call(), pt.Approve()) case _: raise pt.TealInputError("how you got here?") wrapped_assemble = assemble_helper(wrapped) wrapped_helper = assemble_helper(expected) with pt.TealComponent.Context.ignoreExprEquality(): assert wrapped_assemble == wrapped_helper ERROR_CASES = [ ( pt.Int(1), f"bare appcall handler should be TealType.none not {pt.TealType.uint64}.", ), ( returning_u64, f"subroutine call should be returning TealType.none not {pt.TealType.uint64}.", ), ( mult_over_u64_and_log, "subroutine call should take 0 arg for bare-app call. this subroutine takes 2.", ), ( eine_constant, f"abi-returning subroutine call should be returning void not {pt.abi.Uint64TypeSpec()}.", ), ( take_abi_and_log, "abi-returning subroutine call should take 0 arg for bare-app call. this abi-returning subroutine takes 1.", ), ( 1, "bare appcall can only accept: none type Expr, or Subroutine/ABIReturnSubroutine with none return and no arg", ), ] for error_case, error_msg in ERROR_CASES: with pytest.raises(pt.TealInputError) as bug: ASTBuilder.wrap_handler(False, error_case) assert error_msg in str(bug)
def test_log(): arg = pt.Bytes("message") expr = pt.Log(arg) assert expr.type_of() == pt.TealType.none assert not expr.has_return() expected = pt.TealSimpleBlock( [pt.TealOp(arg, pt.Op.byte, '"message"'), pt.TealOp(expr, pt.Op.log)] ) actual, _ = expr.__teal__(avm5Options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) assert actual == expected with pytest.raises(pt.TealInputError): expr.__teal__(avm4Options)
def test_log_invalid(): with pytest.raises(pt.TealTypeError): pt.Log(pt.Int(7))
def fn_log_add(a: pt.abi.Uint64, b: pt.abi.Uint32) -> pt.Expr: return pt.Seq(pt.Log(pt.Itob(a.get() + b.get())), pt.Return())
def take_abi_and_log(tb_logged: pt.abi.String): return pt.Log(tb_logged.get())
def mult_over_u64_and_log(a: pt.Expr, b: pt.Expr): return pt.Log(pt.Itob(a * b))
def dummy_doing_nothing(): return pt.Seq(pt.Log(pt.Bytes("a message")))
def lots_o_vars(): z = pt.Int(0) one = pt.ScratchVar() two = pt.ScratchVar() three = pt.ScratchVar() four = pt.ScratchVar() five = pt.Bytes("five") six = pt.Bytes("six") seven = pt.Bytes("seven") eight = pt.Bytes("eight") nine = pt.Bytes("nine") ten = pt.Bytes("ten") eleven = pt.Bytes("eleven") twelve = pt.Bytes("twelve") int_cursor = pt.DynamicScratchVar(pt.TealType.uint64) bytes_cursor = pt.DynamicScratchVar(pt.TealType.bytes) thirteen = pt.ScratchVar(pt.TealType.uint64, 13) fourteen = pt.ScratchVar(pt.TealType.bytes, 14) fifteen = pt.ScratchVar(pt.TealType.uint64) sixteen = pt.ScratchVar(pt.TealType.bytes) leet = pt.Int(1337) ngl = pt.Bytes("NGL: ") return (pt.If( pt.Or(pt.App.id() == pt.Int(0), pt.Txn.application_args.length() == pt.Int(0))).Then( pt.Int(1)).Else( pt.Seq( one.store(pt.Int(1)), two.store(pt.Bytes("two")), three.store(pt.Int(3)), four.store(pt.Bytes("four")), pt.App.localPut(z, five, pt.Int(5)), pt.App.localPut(z, six, six), pt.App.localPut(z, seven, pt.Int(7)), pt.App.localPut(z, eight, eight), pt.App.globalPut(nine, pt.Int(9)), pt.App.globalPut(ten, ten), pt.App.globalPut(eleven, pt.Int(11)), pt.App.globalPut(twelve, twelve), one.store(one.load() + leet), two.store(pt.Concat(ngl, two.load())), three.store(three.load() + leet), four.store(pt.Concat(ngl, four.load())), pt.App.localPut(z, five, leet + pt.App.localGet(z, five)), pt.App.localPut( z, six, pt.Concat(ngl, pt.App.localGet(z, six))), pt.App.localPut(z, seven, pt.App.localGet(z, seven)), pt.App.localPut( z, eight, pt.Concat(ngl, pt.App.localGet(z, eight))), pt.App.globalPut(nine, leet + pt.App.globalGet(nine)), pt.App.globalPut( ten, pt.Concat(ngl, pt.App.globalGet(ten))), pt.App.globalPut(eleven, leet + pt.App.globalGet(eleven)), pt.App.globalPut( twelve, pt.Concat(ngl, pt.App.globalGet(twelve))), thirteen.store(pt.Btoi(pt.Txn.application_args[0])), fourteen.store(pt.Txn.application_args[1]), fifteen.store(pt.Btoi(pt.Txn.application_args[2])), sixteen.store(pt.Txn.application_args[3]), pt.Pop(one.load()), pt.Pop(two.load()), pt.Pop(three.load()), pt.Pop(four.load()), pt.Pop(pt.App.localGet(z, five)), pt.Pop(pt.App.localGet(z, six)), pt.Pop(pt.App.localGet(z, seven)), pt.Pop(pt.App.localGet(z, eight)), pt.Pop(pt.App.globalGet(nine)), pt.Pop(pt.App.globalGet(ten)), pt.Pop(pt.App.globalGet(eleven)), pt.Pop(pt.App.globalGet(twelve)), int_cursor.set_index(thirteen), pt.Log(pt.Itob(int_cursor.load())), bytes_cursor.set_index(fourteen), pt.Log(bytes_cursor.load()), int_cursor.set_index(fifteen), pt.Log(pt.Itob(int_cursor.load())), bytes_cursor.set_index(sixteen), pt.Log(bytes_cursor.load()), leet, )))
def mixed_annotations(x: pt.Expr, y: pt.Expr, z: pt.ScratchVar) -> pt.Expr: return pt.Seq( z.store(x), pt.Log(pt.Concat(y, pt.Bytes("="), pt.Itob(x))), x, )
def logcat_dynamic(first: pt.ScratchVar, an_int): return pt.Seq( first.store(pt.Concat(first.load(), pt.Itob(an_int))), pt.Log(first.load()), )