From 2a66a431c6b1030071ee8d7e7b0895c11db65296 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Sat, 16 Jul 2022 10:58:36 -0400 Subject: [PATCH 1/3] adding execute method to allow omission of begin/submit for common use case --- pyteal/ast/itxn.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pyteal/ast/itxn.py b/pyteal/ast/itxn.py index af7704198..af40437ad 100644 --- a/pyteal/ast/itxn.py +++ b/pyteal/ast/itxn.py @@ -180,6 +180,11 @@ def SetField(cls, field: TxnField, value: Union[Expr, List[Expr]]) -> Expr: ] ) + @classmethod + def Execute(cls, fields: Dict[TxnField, Union[Expr, List[Expr]]]) -> Expr: + """Performs a single transaction given fields passed in""" + return Seq(cls.Begin(), cls.SetFields(fields), cls.Submit()) + @classmethod def SetFields(cls, fields: Dict[TxnField, Union[Expr, List[Expr]]]) -> Expr: """Set multiple fields of the current inner transaction. From 75aa838af4e9478a8233ed4b02a7bef85f195d05 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Wed, 20 Jul 2022 15:06:13 -0400 Subject: [PATCH 2/3] exec docstring --- pyteal/ast/itxn.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pyteal/ast/itxn.py b/pyteal/ast/itxn.py index af40437ad..2f5d2f064 100644 --- a/pyteal/ast/itxn.py +++ b/pyteal/ast/itxn.py @@ -182,7 +182,23 @@ def SetField(cls, field: TxnField, value: Union[Expr, List[Expr]]) -> Expr: @classmethod def Execute(cls, fields: Dict[TxnField, Union[Expr, List[Expr]]]) -> Expr: - """Performs a single transaction given fields passed in""" + """Performs a single transaction given fields passed in. + + A convenience method that accepts fields to submit a single inner transaction, which is equivalent to: + + .. code-block:: python + + InnerTxnBuilder.Begin() + InnerTxnBuilder.SetFields(fields) + InnerTxnBuilder.End() + + Requires TEAL version 5 or higher. This operation is only permitted in application mode. + + Args: + fields: A dictionary whose keys are fields to set and whose values are the value each + field should take. Each value must evaluate to a type that is compatible with the + field being set. + """ return Seq(cls.Begin(), cls.SetFields(fields), cls.Submit()) @classmethod From 296dbbde58d1e36ab872efc366af2685165e6606 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Wed, 20 Jul 2022 17:33:16 -0400 Subject: [PATCH 3/3] update testcase --- pyteal/ast/itxn_test.py | 62 ++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/pyteal/ast/itxn_test.py b/pyteal/ast/itxn_test.py index af9c3a79c..2e9c01a75 100644 --- a/pyteal/ast/itxn_test.py +++ b/pyteal/ast/itxn_test.py @@ -92,28 +92,29 @@ def test_InnerTxnBuilder_SetField(): expr.__teal__(teal4Options) -def test_InnerTxnBuilder_SetFields(): - cases = ( - ({}, pt.Seq()), - ( - {pt.TxnField.amount: pt.Int(5)}, - pt.InnerTxnBuilder.SetField(pt.TxnField.amount, pt.Int(5)), - ), - ( - { - pt.TxnField.type_enum: pt.TxnType.Payment, - pt.TxnField.close_remainder_to: pt.Txn.sender(), - }, - pt.Seq( - pt.InnerTxnBuilder.SetField(pt.TxnField.type_enum, pt.TxnType.Payment), - pt.InnerTxnBuilder.SetField( - pt.TxnField.close_remainder_to, pt.Txn.sender() - ), +ITXN_FIELDS_CASES = [ + ({}, pt.Seq()), + ( + {pt.TxnField.amount: pt.Int(5)}, + pt.InnerTxnBuilder.SetField(pt.TxnField.amount, pt.Int(5)), + ), + ( + { + pt.TxnField.type_enum: pt.TxnType.Payment, + pt.TxnField.close_remainder_to: pt.Txn.sender(), + }, + pt.Seq( + pt.InnerTxnBuilder.SetField(pt.TxnField.type_enum, pt.TxnType.Payment), + pt.InnerTxnBuilder.SetField( + pt.TxnField.close_remainder_to, pt.Txn.sender() ), ), - ) + ), +] + - for fields, expectedExpr in cases: +def test_InnerTxnBuilder_SetFields(): + for fields, expectedExpr in ITXN_FIELDS_CASES: expr = pt.InnerTxnBuilder.SetFields(fields) assert expr.type_of() == pt.TealType.none assert not expr.has_return() @@ -134,4 +135,27 @@ def test_InnerTxnBuilder_SetFields(): expr.__teal__(teal4Options) +def test_InnerTxnBuilder_Execute(): + for fields, expectedExpr in ITXN_FIELDS_CASES: + expr = pt.InnerTxnBuilder.Execute(fields) + + expected, _ = pt.Seq( + pt.InnerTxnBuilder.Begin(), + expectedExpr, + pt.InnerTxnBuilder.Submit(), + ).__teal__(teal5Options) + expected.addIncoming() + expected = pt.TealBlock.NormalizeBlocks(expected) + + actual, _ = expr.__teal__(teal5Options) + actual.addIncoming() + actual = pt.TealBlock.NormalizeBlocks(actual) + + with pt.TealComponent.Context.ignoreExprEquality(): + assert actual == expected + + with pytest.raises(pt.TealInputError): + expr.__teal__(teal4Options) + + # txn_test.py performs additional testing