From b382dc6088637f529417ef39fc62b806501dc690 Mon Sep 17 00:00:00 2001 From: CiottiGiorgio Date: Mon, 4 Nov 2024 16:48:10 +0100 Subject: [PATCH 1/5] added uintN example. --- .../smart_contracts/arc4_types/contract.py | 17 +++ .../arc4_types/Arc4Types.approval.teal | 71 +++++++++-- .../artifacts/arc4_types/Arc4Types.arc32.json | 33 ++++- .../artifacts/arc4_types/arc4_types_client.py | 116 +++++++++++++++++- .../tests/arc4_types_integration_test.py | 10 ++ 5 files changed, 238 insertions(+), 9 deletions(-) diff --git a/projects/python-contract-examples/smart_contracts/arc4_types/contract.py b/projects/python-contract-examples/smart_contracts/arc4_types/contract.py index 1cf5d46..28b5505 100644 --- a/projects/python-contract-examples/smart_contracts/arc4_types/contract.py +++ b/projects/python-contract-examples/smart_contracts/arc4_types/contract.py @@ -20,6 +20,23 @@ def arc4_uint64(self, a: arc4.UInt64, b: arc4.UInt64) -> arc4.UInt64: return arc4.UInt64(c) + @abimethod() + def arc4_uint_n( + self, a: arc4.UInt8, b: arc4.UInt16, c: arc4.UInt32, d: arc4.UInt64 + ) -> arc4.UInt64: + """ + The encoding of arc4 integers will be smaller if it uses fewer bits. + Ultimately, they are all represented with native UInt64. + """ + assert a.bytes.length == 1 + assert b.bytes.length == 2 + assert c.bytes.length == 4 + assert d.bytes.length == 8 + + total = a.native + b.native + c.native + d.native + + return arc4.UInt64(total) + @abimethod() def arc4_address_properties(self, address: arc4.Address) -> UInt64: underlying_bytes = ( diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal index a4dd885..29f91fc 100644 --- a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal @@ -9,12 +9,13 @@ smart_contracts.arc4_types.contract.Arc4Types.approval_program: __puya_arc4_router__: proto 0 1 txn NumAppArgs - bz __puya_arc4_router___bare_routing@7 + bz __puya_arc4_router___bare_routing@8 method "arc4_uint64(uint64,uint64)uint64" + method "arc4_uint_n(uint8,uint16,uint32,uint64)uint64" method "arc4_address_properties(address)uint64" method "arc4_address_return(address)address" txna ApplicationArgs 0 - match __puya_arc4_router___arc4_uint64_route@2 __puya_arc4_router___arc4_address_properties_route@3 __puya_arc4_router___arc4_address_return_route@4 + match __puya_arc4_router___arc4_uint64_route@2 __puya_arc4_router___arc4_uint_n_route@3 __puya_arc4_router___arc4_address_properties_route@4 __puya_arc4_router___arc4_address_return_route@5 int 0 retsub @@ -34,7 +35,25 @@ __puya_arc4_router___arc4_uint64_route@2: int 1 retsub -__puya_arc4_router___arc4_address_properties_route@3: +__puya_arc4_router___arc4_uint_n_route@3: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + txna ApplicationArgs 2 + txna ApplicationArgs 3 + txna ApplicationArgs 4 + callsub arc4_uint_n + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___arc4_address_properties_route@4: txn OnCompletion ! assert // OnCompletion is NoOp @@ -50,7 +69,7 @@ __puya_arc4_router___arc4_address_properties_route@3: int 1 retsub -__puya_arc4_router___arc4_address_return_route@4: +__puya_arc4_router___arc4_address_return_route@5: txn OnCompletion ! assert // OnCompletion is NoOp @@ -65,16 +84,16 @@ __puya_arc4_router___arc4_address_return_route@4: int 1 retsub -__puya_arc4_router___bare_routing@7: +__puya_arc4_router___bare_routing@8: txn OnCompletion - bnz __puya_arc4_router___after_if_else@11 + bnz __puya_arc4_router___after_if_else@12 txn ApplicationID ! assert // is creating int 1 retsub -__puya_arc4_router___after_if_else@11: +__puya_arc4_router___after_if_else@12: int 0 retsub @@ -91,6 +110,44 @@ arc4_uint64: retsub +// smart_contracts.arc4_types.contract.Arc4Types.arc4_uint_n(a: bytes, b: bytes, c: bytes, d: bytes) -> bytes: +arc4_uint_n: + proto 4 1 + frame_dig -4 + len + int 1 + == + assert + frame_dig -3 + len + int 2 + == + assert + frame_dig -2 + len + int 4 + == + assert + frame_dig -1 + len + int 8 + == + assert + frame_dig -4 + btoi + frame_dig -3 + btoi + + + frame_dig -2 + btoi + + + frame_dig -1 + btoi + + + itob + retsub + + // smart_contracts.arc4_types.contract.Arc4Types.arc4_address_properties(address: bytes) -> uint64: arc4_address_properties: proto 1 1 diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json index 8d4ac00..591eb5f 100644 --- a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json @@ -5,6 +5,11 @@ "no_op": "CALL" } }, + "arc4_uint_n(uint8,uint16,uint32,uint64)uint64": { + "call_config": { + "no_op": "CALL" + } + }, "arc4_address_properties(address)uint64": { "call_config": { "no_op": "CALL" @@ -17,7 +22,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANwogICAgbWV0aG9kICJhcmM0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMoYWRkcmVzcyl1aW50NjQiCiAgICBtZXRob2QgImFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzcylhZGRyZXNzIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF91aW50NjRfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcHJvcGVydGllc19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANAogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF91aW50NjRfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGNhbGxzdWIgYXJjNF91aW50NjQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19wcm9wZXJ0aWVzX3JvdXRlQDM6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBjYWxsc3ViIGFyYzRfYWRkcmVzc19wcm9wZXJ0aWVzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcmV0dXJuX3JvdXRlQDQ6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBjYWxsc3ViIGFyYzRfYWRkcmVzc19yZXR1cm4KICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A3OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTE6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfdWludDY0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CmFyYzRfdWludDY0OgogICAgcHJvdG8gMiAxCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgKwogICAgaXRvYgogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19wcm9wZXJ0aWVzKGFkZHJlc3M6IGJ5dGVzKSAtPiB1aW50NjQ6CmFyYzRfYWRkcmVzc19wcm9wZXJ0aWVzOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHMKICAgIGJ1cnkgMQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF9hZGRyZXNzX3JldHVybihhZGRyZXNzOiBieXRlcykgLT4gYnl0ZXM6CmFyYzRfYWRkcmVzc19yZXR1cm46CiAgICBwcm90byAxIDEKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCg==", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAOAogICAgbWV0aG9kICJhcmM0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF91aW50X24odWludDgsdWludDE2LHVpbnQzMix1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJhcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzKXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3JldHVybihhZGRyZXNzKWFkZHJlc3MiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnQ2NF9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcmV0dXJuX3JvdXRlQDUKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludDY0X3JvdXRlQDI6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBjYWxsc3ViIGFyYzRfdWludDY0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnRfbl9yb3V0ZUAzOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgY2FsbHN1YiBhcmM0X3VpbnRfbgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANDoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3JldHVybgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDg6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMjoKICAgIGludCAwCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50NjQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF91aW50NjQ6CiAgICBwcm90byAyIDEKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICArCiAgICBpdG9iCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50X24oYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3VpbnRfbjoKICAgIHByb3RvIDQgMQogICAgZnJhbWVfZGlnIC00CiAgICBsZW4KICAgIGludCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgaW50IDIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgNAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludCA4CiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTQKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMwogICAgYnRvaQogICAgKwogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICArCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzOiBieXRlcykgLT4gdWludDY0OgphcmM0X2FkZHJlc3NfcHJvcGVydGllczoKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzczogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2FkZHJlc3NfcmV0dXJuOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { @@ -61,6 +66,32 @@ }, "desc": "Math operations (like a + b) are not supported on arc4.UInt64 types\nsince they are internally represented as byte arrays in the AVM. Use the .native property to perform arithmetic operations." }, + { + "name": "arc4_uint_n", + "args": [ + { + "type": "uint8", + "name": "a" + }, + { + "type": "uint16", + "name": "b" + }, + { + "type": "uint32", + "name": "c" + }, + { + "type": "uint64", + "name": "d" + } + ], + "readonly": false, + "returns": { + "type": "uint64" + }, + "desc": "The encoding of arc4 integers will be smaller if it uses fewer bits.\nUltimately, they are all represented with native UInt64." + }, { "name": "arc4_address_properties", "args": [ diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py index 6fb99bd..ae3314a 100644 --- a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py @@ -28,6 +28,11 @@ "no_op": "CALL" } }, + "arc4_uint_n(uint8,uint16,uint32,uint64)uint64": { + "call_config": { + "no_op": "CALL" + } + }, "arc4_address_properties(address)uint64": { "call_config": { "no_op": "CALL" @@ -40,7 +45,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANwogICAgbWV0aG9kICJhcmM0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMoYWRkcmVzcyl1aW50NjQiCiAgICBtZXRob2QgImFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzcylhZGRyZXNzIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF91aW50NjRfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcHJvcGVydGllc19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANAogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF91aW50NjRfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGNhbGxzdWIgYXJjNF91aW50NjQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19wcm9wZXJ0aWVzX3JvdXRlQDM6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBjYWxsc3ViIGFyYzRfYWRkcmVzc19wcm9wZXJ0aWVzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcmV0dXJuX3JvdXRlQDQ6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBjYWxsc3ViIGFyYzRfYWRkcmVzc19yZXR1cm4KICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A3OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTE6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfdWludDY0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CmFyYzRfdWludDY0OgogICAgcHJvdG8gMiAxCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgKwogICAgaXRvYgogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19wcm9wZXJ0aWVzKGFkZHJlc3M6IGJ5dGVzKSAtPiB1aW50NjQ6CmFyYzRfYWRkcmVzc19wcm9wZXJ0aWVzOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHMKICAgIGJ1cnkgMQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF9hZGRyZXNzX3JldHVybihhZGRyZXNzOiBieXRlcykgLT4gYnl0ZXM6CmFyYzRfYWRkcmVzc19yZXR1cm46CiAgICBwcm90byAxIDEKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCg==", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAOAogICAgbWV0aG9kICJhcmM0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF91aW50X24odWludDgsdWludDE2LHVpbnQzMix1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJhcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzKXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3JldHVybihhZGRyZXNzKWFkZHJlc3MiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnQ2NF9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcmV0dXJuX3JvdXRlQDUKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludDY0X3JvdXRlQDI6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBjYWxsc3ViIGFyYzRfdWludDY0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnRfbl9yb3V0ZUAzOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgY2FsbHN1YiBhcmM0X3VpbnRfbgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANDoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3JldHVybgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDg6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMjoKICAgIGludCAwCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50NjQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF91aW50NjQ6CiAgICBwcm90byAyIDEKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICArCiAgICBpdG9iCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50X24oYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3VpbnRfbjoKICAgIHByb3RvIDQgMQogICAgZnJhbWVfZGlnIC00CiAgICBsZW4KICAgIGludCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgaW50IDIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgNAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludCA4CiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTQKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMwogICAgYnRvaQogICAgKwogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICArCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzOiBieXRlcykgLT4gdWludDY0OgphcmM0X2FkZHJlc3NfcHJvcGVydGllczoKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzczogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2FkZHJlc3NfcmV0dXJuOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { @@ -83,6 +88,31 @@ }, "desc": "Math operations (like a + b) are not supported on arc4.UInt64 types\nsince they are internally represented as byte arrays in the AVM. Use the .native property to perform arithmetic operations." }, + { + "name": "arc4_uint_n", + "args": [ + { + "type": "uint8", + "name": "a" + }, + { + "type": "uint16", + "name": "b" + }, + { + "type": "uint32", + "name": "c" + }, + { + "type": "uint64", + "name": "d" + } + ], + "returns": { + "type": "uint64" + }, + "desc": "The encoding of arc4 integers will be smaller if it uses fewer bits.\nUltimately, they are all represented with native UInt64." + }, { "name": "arc4_address_properties", "args": [ @@ -200,6 +230,21 @@ def method() -> str: return "arc4_uint64(uint64,uint64)uint64" +@dataclasses.dataclass(kw_only=True) +class Arc4UintNArgs(_ArgsBase[int]): + """The encoding of arc4 integers will be smaller if it uses fewer bits. + Ultimately, they are all represented with native UInt64.""" + + a: int + b: int + c: int + d: int + + @staticmethod + def method() -> str: + return "arc4_uint_n(uint8,uint16,uint32,uint64)uint64" + + @dataclasses.dataclass(kw_only=True) class Arc4AddressPropertiesArgs(_ArgsBase[int]): address: str @@ -278,6 +323,41 @@ def arc4_uint64( ) return self + def arc4_uint_n( + self, + *, + a: int, + b: int, + c: int, + d: int, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """The encoding of arc4 integers will be smaller if it uses fewer bits. + Ultimately, they are all represented with native UInt64. + + Adds a call to `arc4_uint_n(uint8,uint16,uint32,uint64)uint64` ABI method + + :param int a: The `a` ABI parameter + :param int b: The `b` ABI parameter + :param int c: The `c` ABI parameter + :param int d: The `d` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = Arc4UintNArgs( + a=a, + b=b, + c=c, + d=d, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + def arc4_address_properties( self, *, @@ -511,6 +591,40 @@ def arc4_uint64( ) return result + def arc4_uint_n( + self, + *, + a: int, + b: int, + c: int, + d: int, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[int]: + """The encoding of arc4 integers will be smaller if it uses fewer bits. + Ultimately, they are all represented with native UInt64. + + Calls `arc4_uint_n(uint8,uint16,uint32,uint64)uint64` ABI method + + :param int a: The `a` ABI parameter + :param int b: The `b` ABI parameter + :param int c: The `c` ABI parameter + :param int d: The `d` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[int]: The result of the transaction""" + + args = Arc4UintNArgs( + a=a, + b=b, + c=c, + d=d, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + def arc4_address_properties( self, *, diff --git a/projects/python-contract-examples/tests/arc4_types_integration_test.py b/projects/python-contract-examples/tests/arc4_types_integration_test.py index ece30bf..7bedabe 100644 --- a/projects/python-contract-examples/tests/arc4_types_integration_test.py +++ b/projects/python-contract-examples/tests/arc4_types_integration_test.py @@ -157,6 +157,16 @@ def test_arc4_uint64( assert result.return_value == 3 +def test_arc4_uint_n( + arc4_types_app_client: Arc4TypesClient, +) -> None: + """Test the arc4_uint_n method""" + + result = arc4_types_app_client.arc4_uint_n(a=100, b=1_000, c=100_000, d=100_000) + + assert result.return_value == 201_100 + + def test_arc4_address_properties( arc4_types_app_client: Arc4TypesClient, creator: AddressAndSigner, From c9dcecd794cd4febbd9054fb834dc07f725c68f1 Mon Sep 17 00:00:00 2001 From: CiottiGiorgio Date: Mon, 4 Nov 2024 16:55:26 +0100 Subject: [PATCH 2/5] added biguintN example. --- .../smart_contracts/arc4_types/contract.py | 14 +++ .../arc4_types/Arc4Types.approval.teal | 66 +++++++++-- .../artifacts/arc4_types/Arc4Types.arc32.json | 29 ++++- .../artifacts/arc4_types/arc4_types_client.py | 105 +++++++++++++++++- .../tests/arc4_types_integration_test.py | 10 ++ 5 files changed, 215 insertions(+), 9 deletions(-) diff --git a/projects/python-contract-examples/smart_contracts/arc4_types/contract.py b/projects/python-contract-examples/smart_contracts/arc4_types/contract.py index 28b5505..9d0e886 100644 --- a/projects/python-contract-examples/smart_contracts/arc4_types/contract.py +++ b/projects/python-contract-examples/smart_contracts/arc4_types/contract.py @@ -37,6 +37,20 @@ def arc4_uint_n( return arc4.UInt64(total) + @abimethod() + def arc4_biguint_n(self, a: arc4.UInt128, b: arc4.UInt256, c: arc4.UInt512) -> arc4.UInt512: + """ + Integers with larger bit size are supported up to 512 bits. + Ultimately, they are all represented with native BigUInt. + """ + assert a.bytes.length == 16 + assert b.bytes.length == 32 + assert c.bytes.length == 64 + + total = a.native + b.native + c.native + + return arc4.UInt512(total) + @abimethod() def arc4_address_properties(self, address: arc4.Address) -> UInt64: underlying_bytes = ( diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal index 29f91fc..db20a79 100644 --- a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal @@ -9,13 +9,14 @@ smart_contracts.arc4_types.contract.Arc4Types.approval_program: __puya_arc4_router__: proto 0 1 txn NumAppArgs - bz __puya_arc4_router___bare_routing@8 + bz __puya_arc4_router___bare_routing@9 method "arc4_uint64(uint64,uint64)uint64" method "arc4_uint_n(uint8,uint16,uint32,uint64)uint64" + method "arc4_biguint_n(uint128,uint256,uint512)uint512" method "arc4_address_properties(address)uint64" method "arc4_address_return(address)address" txna ApplicationArgs 0 - match __puya_arc4_router___arc4_uint64_route@2 __puya_arc4_router___arc4_uint_n_route@3 __puya_arc4_router___arc4_address_properties_route@4 __puya_arc4_router___arc4_address_return_route@5 + match __puya_arc4_router___arc4_uint64_route@2 __puya_arc4_router___arc4_uint_n_route@3 __puya_arc4_router___arc4_biguint_n_route@4 __puya_arc4_router___arc4_address_properties_route@5 __puya_arc4_router___arc4_address_return_route@6 int 0 retsub @@ -53,7 +54,24 @@ __puya_arc4_router___arc4_uint_n_route@3: int 1 retsub -__puya_arc4_router___arc4_address_properties_route@4: +__puya_arc4_router___arc4_biguint_n_route@4: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + txna ApplicationArgs 2 + txna ApplicationArgs 3 + callsub arc4_biguint_n + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___arc4_address_properties_route@5: txn OnCompletion ! assert // OnCompletion is NoOp @@ -69,7 +87,7 @@ __puya_arc4_router___arc4_address_properties_route@4: int 1 retsub -__puya_arc4_router___arc4_address_return_route@5: +__puya_arc4_router___arc4_address_return_route@6: txn OnCompletion ! assert // OnCompletion is NoOp @@ -84,16 +102,16 @@ __puya_arc4_router___arc4_address_return_route@5: int 1 retsub -__puya_arc4_router___bare_routing@8: +__puya_arc4_router___bare_routing@9: txn OnCompletion - bnz __puya_arc4_router___after_if_else@12 + bnz __puya_arc4_router___after_if_else@13 txn ApplicationID ! assert // is creating int 1 retsub -__puya_arc4_router___after_if_else@12: +__puya_arc4_router___after_if_else@13: int 0 retsub @@ -148,6 +166,40 @@ arc4_uint_n: retsub +// smart_contracts.arc4_types.contract.Arc4Types.arc4_biguint_n(a: bytes, b: bytes, c: bytes) -> bytes: +arc4_biguint_n: + proto 3 1 + frame_dig -3 + len + int 16 + == + assert + frame_dig -2 + len + int 32 + == + assert + frame_dig -1 + len + int 64 + == + assert + frame_dig -3 + frame_dig -2 + b+ + frame_dig -1 + b+ + dup + len + int 64 + <= + assert // overflow + int 64 + bzero + b| + retsub + + // smart_contracts.arc4_types.contract.Arc4Types.arc4_address_properties(address: bytes) -> uint64: arc4_address_properties: proto 1 1 diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json index 591eb5f..e3ed17b 100644 --- a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json @@ -10,6 +10,11 @@ "no_op": "CALL" } }, + "arc4_biguint_n(uint128,uint256,uint512)uint512": { + "call_config": { + "no_op": "CALL" + } + }, "arc4_address_properties(address)uint64": { "call_config": { "no_op": "CALL" @@ -22,7 +27,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAOAogICAgbWV0aG9kICJhcmM0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF91aW50X24odWludDgsdWludDE2LHVpbnQzMix1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJhcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzKXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3JldHVybihhZGRyZXNzKWFkZHJlc3MiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnQ2NF9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcmV0dXJuX3JvdXRlQDUKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludDY0X3JvdXRlQDI6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBjYWxsc3ViIGFyYzRfdWludDY0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnRfbl9yb3V0ZUAzOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgY2FsbHN1YiBhcmM0X3VpbnRfbgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANDoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3JldHVybgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDg6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMjoKICAgIGludCAwCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50NjQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF91aW50NjQ6CiAgICBwcm90byAyIDEKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICArCiAgICBpdG9iCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50X24oYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3VpbnRfbjoKICAgIHByb3RvIDQgMQogICAgZnJhbWVfZGlnIC00CiAgICBsZW4KICAgIGludCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgaW50IDIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgNAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludCA4CiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTQKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMwogICAgYnRvaQogICAgKwogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICArCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzOiBieXRlcykgLT4gdWludDY0OgphcmM0X2FkZHJlc3NfcHJvcGVydGllczoKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzczogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2FkZHJlc3NfcmV0dXJuOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1Ygo=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAOQogICAgbWV0aG9kICJhcmM0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF91aW50X24odWludDgsdWludDE2LHVpbnQzMix1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJhcmM0X2JpZ3VpbnRfbih1aW50MTI4LHVpbnQyNTYsdWludDUxMil1aW50NTEyIgogICAgbWV0aG9kICJhcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzKXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3JldHVybihhZGRyZXNzKWFkZHJlc3MiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnQ2NF9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9iaWd1aW50X25fcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcHJvcGVydGllc19yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANgogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF91aW50NjRfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGNhbGxzdWIgYXJjNF91aW50NjQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDM6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBjYWxsc3ViIGFyYzRfdWludF9uCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2JpZ3VpbnRfbl9yb3V0ZUA0OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgY2FsbHN1YiBhcmM0X2JpZ3VpbnRfbgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3JldHVybgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMzoKICAgIGludCAwCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50NjQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF91aW50NjQ6CiAgICBwcm90byAyIDEKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICArCiAgICBpdG9iCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50X24oYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3VpbnRfbjoKICAgIHByb3RvIDQgMQogICAgZnJhbWVfZGlnIC00CiAgICBsZW4KICAgIGludCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgaW50IDIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgNAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludCA4CiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTQKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMwogICAgYnRvaQogICAgKwogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICArCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2JpZ3VpbnRfbihhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF9iaWd1aW50X246CiAgICBwcm90byAzIDEKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBpbnQgMTYKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgMzIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnQgNjQKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBiKwogICAgZnJhbWVfZGlnIC0xCiAgICBiKwogICAgZHVwCiAgICBsZW4KICAgIGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50IDY0CiAgICBiemVybwogICAgYnwKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzOiBieXRlcykgLT4gdWludDY0OgphcmM0X2FkZHJlc3NfcHJvcGVydGllczoKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzczogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2FkZHJlc3NfcmV0dXJuOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { @@ -92,6 +97,28 @@ }, "desc": "The encoding of arc4 integers will be smaller if it uses fewer bits.\nUltimately, they are all represented with native UInt64." }, + { + "name": "arc4_biguint_n", + "args": [ + { + "type": "uint128", + "name": "a" + }, + { + "type": "uint256", + "name": "b" + }, + { + "type": "uint512", + "name": "c" + } + ], + "readonly": false, + "returns": { + "type": "uint512" + }, + "desc": "Integers with larger bit size are supported up to 512 bits.\nUltimately, they are all represented with native BigUInt." + }, { "name": "arc4_address_properties", "args": [ diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py index ae3314a..d092cd3 100644 --- a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py @@ -33,6 +33,11 @@ "no_op": "CALL" } }, + "arc4_biguint_n(uint128,uint256,uint512)uint512": { + "call_config": { + "no_op": "CALL" + } + }, "arc4_address_properties(address)uint64": { "call_config": { "no_op": "CALL" @@ -45,7 +50,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAOAogICAgbWV0aG9kICJhcmM0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF91aW50X24odWludDgsdWludDE2LHVpbnQzMix1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJhcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzKXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3JldHVybihhZGRyZXNzKWFkZHJlc3MiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnQ2NF9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcmV0dXJuX3JvdXRlQDUKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludDY0X3JvdXRlQDI6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBjYWxsc3ViIGFyYzRfdWludDY0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnRfbl9yb3V0ZUAzOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgY2FsbHN1YiBhcmM0X3VpbnRfbgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANDoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3JldHVybgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDg6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMjoKICAgIGludCAwCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50NjQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF91aW50NjQ6CiAgICBwcm90byAyIDEKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICArCiAgICBpdG9iCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50X24oYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3VpbnRfbjoKICAgIHByb3RvIDQgMQogICAgZnJhbWVfZGlnIC00CiAgICBsZW4KICAgIGludCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgaW50IDIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgNAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludCA4CiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTQKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMwogICAgYnRvaQogICAgKwogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICArCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzOiBieXRlcykgLT4gdWludDY0OgphcmM0X2FkZHJlc3NfcHJvcGVydGllczoKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzczogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2FkZHJlc3NfcmV0dXJuOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1Ygo=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAOQogICAgbWV0aG9kICJhcmM0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF91aW50X24odWludDgsdWludDE2LHVpbnQzMix1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJhcmM0X2JpZ3VpbnRfbih1aW50MTI4LHVpbnQyNTYsdWludDUxMil1aW50NTEyIgogICAgbWV0aG9kICJhcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzKXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3JldHVybihhZGRyZXNzKWFkZHJlc3MiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnQ2NF9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9iaWd1aW50X25fcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcHJvcGVydGllc19yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANgogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF91aW50NjRfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGNhbGxzdWIgYXJjNF91aW50NjQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDM6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBjYWxsc3ViIGFyYzRfdWludF9uCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2JpZ3VpbnRfbl9yb3V0ZUA0OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgY2FsbHN1YiBhcmM0X2JpZ3VpbnRfbgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3JldHVybgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMzoKICAgIGludCAwCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50NjQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF91aW50NjQ6CiAgICBwcm90byAyIDEKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICArCiAgICBpdG9iCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50X24oYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3VpbnRfbjoKICAgIHByb3RvIDQgMQogICAgZnJhbWVfZGlnIC00CiAgICBsZW4KICAgIGludCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgaW50IDIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgNAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludCA4CiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTQKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMwogICAgYnRvaQogICAgKwogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICArCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2JpZ3VpbnRfbihhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF9iaWd1aW50X246CiAgICBwcm90byAzIDEKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBpbnQgMTYKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgMzIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnQgNjQKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBiKwogICAgZnJhbWVfZGlnIC0xCiAgICBiKwogICAgZHVwCiAgICBsZW4KICAgIGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50IDY0CiAgICBiemVybwogICAgYnwKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzOiBieXRlcykgLT4gdWludDY0OgphcmM0X2FkZHJlc3NfcHJvcGVydGllczoKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzczogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2FkZHJlc3NfcmV0dXJuOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { @@ -113,6 +118,27 @@ }, "desc": "The encoding of arc4 integers will be smaller if it uses fewer bits.\nUltimately, they are all represented with native UInt64." }, + { + "name": "arc4_biguint_n", + "args": [ + { + "type": "uint128", + "name": "a" + }, + { + "type": "uint256", + "name": "b" + }, + { + "type": "uint512", + "name": "c" + } + ], + "returns": { + "type": "uint512" + }, + "desc": "Integers with larger bit size are supported up to 512 bits.\nUltimately, they are all represented with native BigUInt." + }, { "name": "arc4_address_properties", "args": [ @@ -245,6 +271,20 @@ def method() -> str: return "arc4_uint_n(uint8,uint16,uint32,uint64)uint64" +@dataclasses.dataclass(kw_only=True) +class Arc4BiguintNArgs(_ArgsBase[int]): + """Integers with larger bit size are supported up to 512 bits. + Ultimately, they are all represented with native BigUInt.""" + + a: int + b: int + c: int + + @staticmethod + def method() -> str: + return "arc4_biguint_n(uint128,uint256,uint512)uint512" + + @dataclasses.dataclass(kw_only=True) class Arc4AddressPropertiesArgs(_ArgsBase[int]): address: str @@ -358,6 +398,38 @@ def arc4_uint_n( ) return self + def arc4_biguint_n( + self, + *, + a: int, + b: int, + c: int, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Integers with larger bit size are supported up to 512 bits. + Ultimately, they are all represented with native BigUInt. + + Adds a call to `arc4_biguint_n(uint128,uint256,uint512)uint512` ABI method + + :param int a: The `a` ABI parameter + :param int b: The `b` ABI parameter + :param int c: The `c` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = Arc4BiguintNArgs( + a=a, + b=b, + c=c, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + def arc4_address_properties( self, *, @@ -625,6 +697,37 @@ def arc4_uint_n( ) return result + def arc4_biguint_n( + self, + *, + a: int, + b: int, + c: int, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[int]: + """Integers with larger bit size are supported up to 512 bits. + Ultimately, they are all represented with native BigUInt. + + Calls `arc4_biguint_n(uint128,uint256,uint512)uint512` ABI method + + :param int a: The `a` ABI parameter + :param int b: The `b` ABI parameter + :param int c: The `c` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[int]: The result of the transaction""" + + args = Arc4BiguintNArgs( + a=a, + b=b, + c=c, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + def arc4_address_properties( self, *, diff --git a/projects/python-contract-examples/tests/arc4_types_integration_test.py b/projects/python-contract-examples/tests/arc4_types_integration_test.py index 7bedabe..3070a82 100644 --- a/projects/python-contract-examples/tests/arc4_types_integration_test.py +++ b/projects/python-contract-examples/tests/arc4_types_integration_test.py @@ -167,6 +167,16 @@ def test_arc4_uint_n( assert result.return_value == 201_100 +def test_arc4_biguint_n( + arc4_types_app_client: Arc4TypesClient, +) -> None: + """Test the arc4_uint_n method""" + + result = arc4_types_app_client.arc4_biguint_n(a=2**65, b=2**129, c=2**257) + + assert result.return_value == 2**65 + 2**129 + 2**257 + + def test_arc4_address_properties( arc4_types_app_client: Arc4TypesClient, creator: AddressAndSigner, From c2e0a79f56a97683aa50a9b79bac5cdab1dbe1a5 Mon Sep 17 00:00:00 2001 From: CiottiGiorgio Date: Mon, 4 Nov 2024 17:46:56 +0100 Subject: [PATCH 3/5] added bytes examples. --- .../smart_contracts/arc4_types/contract.py | 42 +- .../arc4_types/Arc4DynamicArray.approval.teal | 277 +++++++++ .../arc4_types/Arc4DynamicArray.arc32.json | 70 +++ .../arc4_types/Arc4DynamicArray.clear.teal | 5 + .../arc4_types/Arc4Types.approval.teal | 42 +- .../artifacts/arc4_types/Arc4Types.arc32.json | 21 +- .../arc4_types/arc4_dynamic_array_client.py | 565 ++++++++++++++++++ .../artifacts/arc4_types/arc4_types_client.py | 80 ++- .../tests/arc4_types_integration_test.py | 59 ++ 9 files changed, 1151 insertions(+), 10 deletions(-) create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.approval.teal create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.arc32.json create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.clear.teal create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_dynamic_array_client.py diff --git a/projects/python-contract-examples/smart_contracts/arc4_types/contract.py b/projects/python-contract-examples/smart_contracts/arc4_types/contract.py index 9d0e886..3d3e19b 100644 --- a/projects/python-contract-examples/smart_contracts/arc4_types/contract.py +++ b/projects/python-contract-examples/smart_contracts/arc4_types/contract.py @@ -1,7 +1,7 @@ # pyright: reportMissingModuleSource=false import typing as t -from algopy import ARC4Contract, GlobalState, UInt64, arc4, urange +from algopy import ARC4Contract, GlobalState, UInt64, arc4, urange, String, Bytes from algopy.arc4 import abimethod @@ -51,6 +51,13 @@ def arc4_biguint_n(self, a: arc4.UInt128, b: arc4.UInt256, c: arc4.UInt512) -> a return arc4.UInt512(total) + @abimethod() + def arc4_byte(self, a: arc4.Byte) -> arc4.Byte: + """ + An arc4.Byte is essentially an alias for an 8-bit integer. + """ + return arc4.Byte(a.native + 1) + @abimethod() def arc4_address_properties(self, address: arc4.Address) -> UInt64: underlying_bytes = ( @@ -123,6 +130,39 @@ def arc4_static_array(self) -> None: """ +class Arc4DynamicArray(ARC4Contract): + + @abimethod() + def arc4_dynamic_array(self, name: arc4.String) -> arc4.String: + """ + Dynamic Arrays have variable size and capacity. + They are similar to native Python lists because they can also append, extend, and pop. + """ + dynamic_string_array = arc4.DynamicArray[arc4.String](arc4.String("Hello")) + + extension = arc4.DynamicArray[arc4.String](arc4.String(" world"), arc4.String(", ")) + dynamic_string_array.extend(extension) + + dynamic_string_array.append(name) + dynamic_string_array.append(arc4.String("!")) + dynamic_string_array.pop() + + greeting = String() + for x in dynamic_string_array: + greeting += x.native + + return arc4.String(greeting) + + @abimethod() + def arc4_dynamic_bytes(self) -> arc4.DynamicBytes: + """arc4.DynamicBytes are essentially an arc4.DynamicArray[arc4.Bytes] and some convenience methods.""" + dynamic_bytes = arc4.DynamicBytes(b"\xFF\xFF\xFF") + + dynamic_bytes[0] = arc4.Byte(0) + + return dynamic_bytes + + class Todo(arc4.Struct): task: arc4.String completed: arc4.Bool diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.approval.teal b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.approval.teal new file mode 100644 index 0000000..1557272 --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.approval.teal @@ -0,0 +1,277 @@ +#pragma version 10 + +smart_contracts.arc4_types.contract.Arc4DynamicArray.approval_program: + callsub __puya_arc4_router__ + return + + +// smart_contracts.arc4_types.contract.Arc4DynamicArray.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + proto 0 1 + txn NumAppArgs + bz __puya_arc4_router___bare_routing@6 + method "arc4_dynamic_array(string)string" + method "arc4_dynamic_bytes()byte[]" + txna ApplicationArgs 0 + match __puya_arc4_router___arc4_dynamic_array_route@2 __puya_arc4_router___arc4_dynamic_bytes_route@3 + int 0 + retsub + +__puya_arc4_router___arc4_dynamic_array_route@2: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + callsub arc4_dynamic_array + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___arc4_dynamic_bytes_route@3: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + callsub arc4_dynamic_bytes + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___bare_routing@6: + txn OnCompletion + bnz __puya_arc4_router___after_if_else@10 + txn ApplicationID + ! + assert // is creating + int 1 + retsub + +__puya_arc4_router___after_if_else@10: + int 0 + retsub + + +// smart_contracts.arc4_types.contract.Arc4DynamicArray.arc4_dynamic_array(name: bytes) -> bytes: +arc4_dynamic_array: + proto 1 1 + byte 0x00010002000548656c6c6f + byte 0x000620776f726c6400022c20 + int 2 + callsub dynamic_array_concat_byte_length_head + frame_dig -1 + int 1 + callsub dynamic_array_concat_byte_length_head + byte 0x000121 + int 1 + callsub dynamic_array_concat_byte_length_head + callsub dynamic_array_pop_byte_length_head + dup + uncover 2 + pop + byte "" + swap + int 0 + extract_uint16 + int 0 + +arc4_dynamic_array_for_header@1: + frame_dig 3 + frame_dig 2 + < + bz arc4_dynamic_array_after_for@4 + frame_dig 0 + extract 2 0 + frame_dig 3 + dup + cover 2 + int 2 + * + dig 1 + swap + extract_uint16 + dup2 + extract_uint16 + int 2 + + + extract3 + extract 2 0 + frame_dig 1 + swap + concat + frame_bury 1 + int 1 + + + frame_bury 3 + b arc4_dynamic_array_for_header@1 + +arc4_dynamic_array_after_for@4: + frame_dig 1 + dup + len + itob + extract 6 2 + swap + concat + frame_bury 0 + retsub + + +// smart_contracts.arc4_types.contract.Arc4DynamicArray.arc4_dynamic_bytes() -> bytes: +arc4_dynamic_bytes: + proto 0 1 + byte 0x0003ffffff + byte 0x00 + replace2 2 + retsub + + +// _puya_lib.arc4.dynamic_array_pop_byte_length_head(array: bytes) -> bytes, bytes: +dynamic_array_pop_byte_length_head: + proto 1 2 + frame_dig -1 + int 0 + extract_uint16 + int 1 + - + dup + int 2 + * + frame_dig -1 + extract 2 0 + dup + dig 2 + extract_uint16 + swap + dup + len + swap + dup + dig 3 + uncover 3 + substring3 + cover 3 + dup + int 0 + dig 4 + substring3 + cover 2 + uncover 3 + int 2 + + + uncover 2 + substring3 + concat + dig 2 + itob + extract 6 2 + swap + uncover 3 + int 0 + callsub recalculate_head_for_elements_with_byte_length_head + concat + retsub + + +// _puya_lib.arc4.dynamic_array_concat_byte_length_head(array: bytes, new_items_bytes: bytes, new_items_count: uint64) -> bytes: +dynamic_array_concat_byte_length_head: + proto 3 1 + frame_dig -3 + int 0 + extract_uint16 + dup + frame_dig -1 + + + swap + int 2 + * + int 2 + + + swap + dup + itob + extract 6 2 + swap + frame_dig -3 + int 2 + dig 4 + substring3 + frame_dig -1 + int 2 + * + bzero + concat + frame_dig -3 + len + frame_dig -3 + uncover 5 + uncover 2 + substring3 + concat + frame_dig -2 + concat + swap + int 0 + callsub recalculate_head_for_elements_with_byte_length_head + concat + retsub + + +// _puya_lib.arc4.recalculate_head_for_elements_with_byte_length_head(array_head_and_tail: bytes, length: uint64, start_at_index: uint64) -> bytes: +recalculate_head_for_elements_with_byte_length_head: + proto 3 1 + frame_dig -2 + int 2 + * + dup + frame_dig -1 + int 2 + * + dup + cover 2 + frame_dig -3 + swap + extract_uint16 + frame_dig -1 + select + +recalculate_head_for_elements_with_byte_length_head_for_header@1: + frame_dig 1 + frame_dig 0 + < + bz recalculate_head_for_elements_with_byte_length_head_after_for@4 + frame_dig 2 + dup + itob + extract 6 2 + frame_dig -3 + frame_dig 1 + dup + cover 4 + uncover 2 + replace3 + dup + frame_bury -3 + dig 1 + extract_uint16 + int 2 + + + + + frame_bury 2 + int 2 + + + frame_bury 1 + b recalculate_head_for_elements_with_byte_length_head_for_header@1 + +recalculate_head_for_elements_with_byte_length_head_after_for@4: + frame_dig -3 + frame_bury 0 + retsub diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.arc32.json b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.arc32.json new file mode 100644 index 0000000..41922ee --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.arc32.json @@ -0,0 +1,70 @@ +{ + "hints": { + "arc4_dynamic_array(string)string": { + "call_config": { + "no_op": "CALL" + } + }, + "arc4_dynamic_bytes()byte[]": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0RHluYW1pY0FycmF5LmFwcHJvdmFsX3Byb2dyYW06CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0RHluYW1pY0FycmF5Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2CiAgICBtZXRob2QgImFyYzRfZHluYW1pY19hcnJheShzdHJpbmcpc3RyaW5nIgogICAgbWV0aG9kICJhcmM0X2R5bmFtaWNfYnl0ZXMoKWJ5dGVbXSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfZHluYW1pY19hcnJheV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAzCiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2R5bmFtaWNfYXJyYXlfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9keW5hbWljX2FycmF5CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMzoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgYXJjNF9keW5hbWljX2J5dGVzCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEwCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEwOgogICAgaW50IDAKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzREeW5hbWljQXJyYXkuYXJjNF9keW5hbWljX2FycmF5KG5hbWU6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF9keW5hbWljX2FycmF5OgogICAgcHJvdG8gMSAxCiAgICBieXRlIDB4MDAwMTAwMDIwMDA1NDg2NTZjNmM2ZgogICAgYnl0ZSAweDAwMDYyMDc3NmY3MjZjNjQwMDAyMmMyMAogICAgaW50IDIKICAgIGNhbGxzdWIgZHluYW1pY19hcnJheV9jb25jYXRfYnl0ZV9sZW5ndGhfaGVhZAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMQogICAgY2FsbHN1YiBkeW5hbWljX2FycmF5X2NvbmNhdF9ieXRlX2xlbmd0aF9oZWFkCiAgICBieXRlIDB4MDAwMTIxCiAgICBpbnQgMQogICAgY2FsbHN1YiBkeW5hbWljX2FycmF5X2NvbmNhdF9ieXRlX2xlbmd0aF9oZWFkCiAgICBjYWxsc3ViIGR5bmFtaWNfYXJyYXlfcG9wX2J5dGVfbGVuZ3RoX2hlYWQKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICBwb3AKICAgIGJ5dGUgIiIKICAgIHN3YXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDAKCmFyYzRfZHluYW1pY19hcnJheV9mb3JfaGVhZGVyQDE6CiAgICBmcmFtZV9kaWcgMwogICAgZnJhbWVfZGlnIDIKICAgIDwKICAgIGJ6IGFyYzRfZHluYW1pY19hcnJheV9hZnRlcl9mb3JANAogICAgZnJhbWVfZGlnIDAKICAgIGV4dHJhY3QgMiAwCiAgICBmcmFtZV9kaWcgMwogICAgZHVwCiAgICBjb3ZlciAyCiAgICBpbnQgMgogICAgKgogICAgZGlnIDEKICAgIHN3YXAKICAgIGV4dHJhY3RfdWludDE2CiAgICBkdXAyCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDIKICAgICsKICAgIGV4dHJhY3QzCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIDEKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSAxCiAgICBpbnQgMQogICAgKwogICAgZnJhbWVfYnVyeSAzCiAgICBiIGFyYzRfZHluYW1pY19hcnJheV9mb3JfaGVhZGVyQDEKCmFyYzRfZHluYW1pY19hcnJheV9hZnRlcl9mb3JANDoKICAgIGZyYW1lX2RpZyAxCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0RHluYW1pY0FycmF5LmFyYzRfZHluYW1pY19ieXRlcygpIC0+IGJ5dGVzOgphcmM0X2R5bmFtaWNfYnl0ZXM6CiAgICBwcm90byAwIDEKICAgIGJ5dGUgMHgwMDAzZmZmZmZmCiAgICBieXRlIDB4MDAKICAgIHJlcGxhY2UyIDIKICAgIHJldHN1YgoKCi8vIF9wdXlhX2xpYi5hcmM0LmR5bmFtaWNfYXJyYXlfcG9wX2J5dGVfbGVuZ3RoX2hlYWQoYXJyYXk6IGJ5dGVzKSAtPiBieXRlcywgYnl0ZXM6CmR5bmFtaWNfYXJyYXlfcG9wX2J5dGVfbGVuZ3RoX2hlYWQ6CiAgICBwcm90byAxIDIKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMQogICAgLQogICAgZHVwCiAgICBpbnQgMgogICAgKgogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgZHVwCiAgICBkaWcgMgogICAgZXh0cmFjdF91aW50MTYKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBzd2FwCiAgICBkdXAKICAgIGRpZyAzCiAgICB1bmNvdmVyIDMKICAgIHN1YnN0cmluZzMKICAgIGNvdmVyIDMKICAgIGR1cAogICAgaW50IDAKICAgIGRpZyA0CiAgICBzdWJzdHJpbmczCiAgICBjb3ZlciAyCiAgICB1bmNvdmVyIDMKICAgIGludCAyCiAgICArCiAgICB1bmNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGNvbmNhdAogICAgZGlnIDIKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICB1bmNvdmVyIDMKICAgIGludCAwCiAgICBjYWxsc3ViIHJlY2FsY3VsYXRlX2hlYWRfZm9yX2VsZW1lbnRzX3dpdGhfYnl0ZV9sZW5ndGhfaGVhZAogICAgY29uY2F0CiAgICByZXRzdWIKCgovLyBfcHV5YV9saWIuYXJjNC5keW5hbWljX2FycmF5X2NvbmNhdF9ieXRlX2xlbmd0aF9oZWFkKGFycmF5OiBieXRlcywgbmV3X2l0ZW1zX2J5dGVzOiBieXRlcywgbmV3X2l0ZW1zX2NvdW50OiB1aW50NjQpIC0+IGJ5dGVzOgpkeW5hbWljX2FycmF5X2NvbmNhdF9ieXRlX2xlbmd0aF9oZWFkOgogICAgcHJvdG8gMyAxCiAgICBmcmFtZV9kaWcgLTMKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgZHVwCiAgICBmcmFtZV9kaWcgLTEKICAgICsKICAgIHN3YXAKICAgIGludCAyCiAgICAqCiAgICBpbnQgMgogICAgKwogICAgc3dhcAogICAgZHVwCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgZnJhbWVfZGlnIC0zCiAgICBpbnQgMgogICAgZGlnIDQKICAgIHN1YnN0cmluZzMKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDIKICAgICoKICAgIGJ6ZXJvCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBmcmFtZV9kaWcgLTMKICAgIHVuY292ZXIgNQogICAgdW5jb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBpbnQgMAogICAgY2FsbHN1YiByZWNhbGN1bGF0ZV9oZWFkX2Zvcl9lbGVtZW50c193aXRoX2J5dGVfbGVuZ3RoX2hlYWQKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gX3B1eWFfbGliLmFyYzQucmVjYWxjdWxhdGVfaGVhZF9mb3JfZWxlbWVudHNfd2l0aF9ieXRlX2xlbmd0aF9oZWFkKGFycmF5X2hlYWRfYW5kX3RhaWw6IGJ5dGVzLCBsZW5ndGg6IHVpbnQ2NCwgc3RhcnRfYXRfaW5kZXg6IHVpbnQ2NCkgLT4gYnl0ZXM6CnJlY2FsY3VsYXRlX2hlYWRfZm9yX2VsZW1lbnRzX3dpdGhfYnl0ZV9sZW5ndGhfaGVhZDoKICAgIHByb3RvIDMgMQogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMgogICAgKgogICAgZHVwCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAyCiAgICAqCiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGZyYW1lX2RpZyAtMwogICAgc3dhcAogICAgZXh0cmFjdF91aW50MTYKICAgIGZyYW1lX2RpZyAtMQogICAgc2VsZWN0CgpyZWNhbGN1bGF0ZV9oZWFkX2Zvcl9lbGVtZW50c193aXRoX2J5dGVfbGVuZ3RoX2hlYWRfZm9yX2hlYWRlckAxOgogICAgZnJhbWVfZGlnIDEKICAgIGZyYW1lX2RpZyAwCiAgICA8CiAgICBieiByZWNhbGN1bGF0ZV9oZWFkX2Zvcl9lbGVtZW50c193aXRoX2J5dGVfbGVuZ3RoX2hlYWRfYWZ0ZXJfZm9yQDQKICAgIGZyYW1lX2RpZyAyCiAgICBkdXAKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAxCiAgICBkdXAKICAgIGNvdmVyIDQKICAgIHVuY292ZXIgMgogICAgcmVwbGFjZTMKICAgIGR1cAogICAgZnJhbWVfYnVyeSAtMwogICAgZGlnIDEKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMgogICAgKwogICAgKwogICAgZnJhbWVfYnVyeSAyCiAgICBpbnQgMgogICAgKwogICAgZnJhbWVfYnVyeSAxCiAgICBiIHJlY2FsY3VsYXRlX2hlYWRfZm9yX2VsZW1lbnRzX3dpdGhfYnl0ZV9sZW5ndGhfaGVhZF9mb3JfaGVhZGVyQDEKCnJlY2FsY3VsYXRlX2hlYWRfZm9yX2VsZW1lbnRzX3dpdGhfYnl0ZV9sZW5ndGhfaGVhZF9hZnRlcl9mb3JANDoKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0RHluYW1pY0FycmF5LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "Arc4DynamicArray", + "methods": [ + { + "name": "arc4_dynamic_array", + "args": [ + { + "type": "string", + "name": "name" + } + ], + "readonly": false, + "returns": { + "type": "string" + }, + "desc": "Dynamic Arrays have variable size and capacity.\nThey are similar to native Python lists because they can also append, extend, and pop." + }, + { + "name": "arc4_dynamic_bytes", + "args": [], + "readonly": false, + "returns": { + "type": "byte[]" + }, + "desc": "arc4.DynamicBytes are essentially an arc4.DynamicArray[arc4.Bytes] and some convenience methods." + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.clear.teal b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.clear.teal new file mode 100644 index 0000000..ac284db --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4DynamicArray.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +smart_contracts.arc4_types.contract.Arc4DynamicArray.clear_state_program: + int 1 + return diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal index db20a79..cf1936c 100644 --- a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.approval.teal @@ -9,14 +9,15 @@ smart_contracts.arc4_types.contract.Arc4Types.approval_program: __puya_arc4_router__: proto 0 1 txn NumAppArgs - bz __puya_arc4_router___bare_routing@9 + bz __puya_arc4_router___bare_routing@10 method "arc4_uint64(uint64,uint64)uint64" method "arc4_uint_n(uint8,uint16,uint32,uint64)uint64" method "arc4_biguint_n(uint128,uint256,uint512)uint512" + method "arc4_byte(byte)byte" method "arc4_address_properties(address)uint64" method "arc4_address_return(address)address" txna ApplicationArgs 0 - match __puya_arc4_router___arc4_uint64_route@2 __puya_arc4_router___arc4_uint_n_route@3 __puya_arc4_router___arc4_biguint_n_route@4 __puya_arc4_router___arc4_address_properties_route@5 __puya_arc4_router___arc4_address_return_route@6 + match __puya_arc4_router___arc4_uint64_route@2 __puya_arc4_router___arc4_uint_n_route@3 __puya_arc4_router___arc4_biguint_n_route@4 __puya_arc4_router___arc4_byte_route@5 __puya_arc4_router___arc4_address_properties_route@6 __puya_arc4_router___arc4_address_return_route@7 int 0 retsub @@ -71,7 +72,22 @@ __puya_arc4_router___arc4_biguint_n_route@4: int 1 retsub -__puya_arc4_router___arc4_address_properties_route@5: +__puya_arc4_router___arc4_byte_route@5: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + callsub arc4_byte + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___arc4_address_properties_route@6: txn OnCompletion ! assert // OnCompletion is NoOp @@ -87,7 +103,7 @@ __puya_arc4_router___arc4_address_properties_route@5: int 1 retsub -__puya_arc4_router___arc4_address_return_route@6: +__puya_arc4_router___arc4_address_return_route@7: txn OnCompletion ! assert // OnCompletion is NoOp @@ -102,16 +118,16 @@ __puya_arc4_router___arc4_address_return_route@6: int 1 retsub -__puya_arc4_router___bare_routing@9: +__puya_arc4_router___bare_routing@10: txn OnCompletion - bnz __puya_arc4_router___after_if_else@13 + bnz __puya_arc4_router___after_if_else@14 txn ApplicationID ! assert // is creating int 1 retsub -__puya_arc4_router___after_if_else@13: +__puya_arc4_router___after_if_else@14: int 0 retsub @@ -200,6 +216,18 @@ arc4_biguint_n: retsub +// smart_contracts.arc4_types.contract.Arc4Types.arc4_byte(a: bytes) -> bytes: +arc4_byte: + proto 1 1 + frame_dig -1 + btoi + int 1 + + + itob + extract 7 1 + retsub + + // smart_contracts.arc4_types.contract.Arc4Types.arc4_address_properties(address: bytes) -> uint64: arc4_address_properties: proto 1 1 diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json index e3ed17b..8fda8ad 100644 --- a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Types.arc32.json @@ -15,6 +15,11 @@ "no_op": "CALL" } }, + "arc4_byte(byte)byte": { + "call_config": { + "no_op": "CALL" + } + }, "arc4_address_properties(address)uint64": { "call_config": { "no_op": "CALL" @@ -27,7 +32,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAOQogICAgbWV0aG9kICJhcmM0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF91aW50X24odWludDgsdWludDE2LHVpbnQzMix1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJhcmM0X2JpZ3VpbnRfbih1aW50MTI4LHVpbnQyNTYsdWludDUxMil1aW50NTEyIgogICAgbWV0aG9kICJhcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzKXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3JldHVybihhZGRyZXNzKWFkZHJlc3MiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnQ2NF9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9iaWd1aW50X25fcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcHJvcGVydGllc19yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANgogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF91aW50NjRfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGNhbGxzdWIgYXJjNF91aW50NjQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDM6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBjYWxsc3ViIGFyYzRfdWludF9uCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2JpZ3VpbnRfbl9yb3V0ZUA0OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgY2FsbHN1YiBhcmM0X2JpZ3VpbnRfbgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3JldHVybgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMzoKICAgIGludCAwCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50NjQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF91aW50NjQ6CiAgICBwcm90byAyIDEKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICArCiAgICBpdG9iCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50X24oYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3VpbnRfbjoKICAgIHByb3RvIDQgMQogICAgZnJhbWVfZGlnIC00CiAgICBsZW4KICAgIGludCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgaW50IDIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgNAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludCA4CiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTQKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMwogICAgYnRvaQogICAgKwogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICArCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2JpZ3VpbnRfbihhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF9iaWd1aW50X246CiAgICBwcm90byAzIDEKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBpbnQgMTYKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgMzIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnQgNjQKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBiKwogICAgZnJhbWVfZGlnIC0xCiAgICBiKwogICAgZHVwCiAgICBsZW4KICAgIGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50IDY0CiAgICBiemVybwogICAgYnwKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzOiBieXRlcykgLT4gdWludDY0OgphcmM0X2FkZHJlc3NfcHJvcGVydGllczoKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzczogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2FkZHJlc3NfcmV0dXJuOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1Ygo=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTAKICAgIG1ldGhvZCAiYXJjNF91aW50NjQodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgImFyYzRfdWludF9uKHVpbnQ4LHVpbnQxNix1aW50MzIsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9iaWd1aW50X24odWludDEyOCx1aW50MjU2LHVpbnQ1MTIpdWludDUxMiIKICAgIG1ldGhvZCAiYXJjNF9ieXRlKGJ5dGUpYnl0ZSIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMoYWRkcmVzcyl1aW50NjQiCiAgICBtZXRob2QgImFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzcylhZGRyZXNzIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF91aW50NjRfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnRfbl9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYmlndWludF9uX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9ieXRlX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcmV0dXJuX3JvdXRlQDcKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludDY0X3JvdXRlQDI6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBjYWxsc3ViIGFyYzRfdWludDY0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnRfbl9yb3V0ZUAzOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgY2FsbHN1YiBhcmM0X3VpbnRfbgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9iaWd1aW50X25fcm91dGVANDoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGNhbGxzdWIgYXJjNF9iaWd1aW50X24KICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYnl0ZV9yb3V0ZUA1OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgY2FsbHN1YiBhcmM0X2J5dGUKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19wcm9wZXJ0aWVzX3JvdXRlQDY6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBjYWxsc3ViIGFyYzRfYWRkcmVzc19wcm9wZXJ0aWVzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcmV0dXJuX3JvdXRlQDc6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBjYWxsc3ViIGFyYzRfYWRkcmVzc19yZXR1cm4KICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMDoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE0CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE0OgogICAgaW50IDAKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3VpbnQ2NDoKICAgIHByb3RvIDIgMQogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X3VpbnRfbihhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiBieXRlcykgLT4gYnl0ZXM6CmFyYzRfdWludF9uOgogICAgcHJvdG8gNCAxCiAgICBmcmFtZV9kaWcgLTQKICAgIGxlbgogICAgaW50IDEKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBpbnQgMgogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludCA0CiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50IDgKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtNAogICAgYnRvaQogICAgZnJhbWVfZGlnIC0zCiAgICBidG9pCiAgICArCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ0b2kKICAgICsKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgKwogICAgaXRvYgogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYmlndWludF9uKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2JpZ3VpbnRfbjoKICAgIHByb3RvIDMgMQogICAgZnJhbWVfZGlnIC0zCiAgICBsZW4KICAgIGludCAxNgogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludCAzMgogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludCA2NAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGIrCiAgICBmcmFtZV9kaWcgLTEKICAgIGIrCiAgICBkdXAKICAgIGxlbgogICAgaW50IDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnQgNjQKICAgIGJ6ZXJvCiAgICBifAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYnl0ZShhOiBieXRlcykgLT4gYnl0ZXM6CmFyYzRfYnl0ZToKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICBpbnQgMQogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA3IDEKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzOiBieXRlcykgLT4gdWludDY0OgphcmM0X2FkZHJlc3NfcHJvcGVydGllczoKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzczogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2FkZHJlc3NfcmV0dXJuOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { @@ -119,6 +124,20 @@ }, "desc": "Integers with larger bit size are supported up to 512 bits.\nUltimately, they are all represented with native BigUInt." }, + { + "name": "arc4_byte", + "args": [ + { + "type": "byte", + "name": "a" + } + ], + "readonly": false, + "returns": { + "type": "byte" + }, + "desc": "An arc4.Byte is essentially an alias for an 8-bit integer." + }, { "name": "arc4_address_properties", "args": [ diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_dynamic_array_client.py b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_dynamic_array_client.py new file mode 100644 index 0000000..4bf7295 --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_dynamic_array_client.py @@ -0,0 +1,565 @@ +# flake8: noqa +# fmt: off +# mypy: disable-error-code="no-any-return, no-untyped-call, misc, type-arg" +# This file was automatically generated by algokit-client-generator. +# DO NOT MODIFY IT BY HAND. +# requires: algokit-utils@^1.2.0 +import base64 +import dataclasses +import decimal +import typing +from abc import ABC, abstractmethod + +import algokit_utils +import algosdk +from algosdk.v2client import models +from algosdk.atomic_transaction_composer import ( + AtomicTransactionComposer, + AtomicTransactionResponse, + SimulateAtomicTransactionResponse, + TransactionSigner, + TransactionWithSigner +) + +_APP_SPEC_JSON = r"""{ + "hints": { + "arc4_dynamic_array(string)string": { + "call_config": { + "no_op": "CALL" + } + }, + "arc4_dynamic_bytes()byte[]": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0RHluYW1pY0FycmF5LmFwcHJvdmFsX3Byb2dyYW06CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0RHluYW1pY0FycmF5Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2CiAgICBtZXRob2QgImFyYzRfZHluYW1pY19hcnJheShzdHJpbmcpc3RyaW5nIgogICAgbWV0aG9kICJhcmM0X2R5bmFtaWNfYnl0ZXMoKWJ5dGVbXSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfZHluYW1pY19hcnJheV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAzCiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2R5bmFtaWNfYXJyYXlfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9keW5hbWljX2FycmF5CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMzoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgYXJjNF9keW5hbWljX2J5dGVzCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEwCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEwOgogICAgaW50IDAKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzREeW5hbWljQXJyYXkuYXJjNF9keW5hbWljX2FycmF5KG5hbWU6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF9keW5hbWljX2FycmF5OgogICAgcHJvdG8gMSAxCiAgICBieXRlIDB4MDAwMTAwMDIwMDA1NDg2NTZjNmM2ZgogICAgYnl0ZSAweDAwMDYyMDc3NmY3MjZjNjQwMDAyMmMyMAogICAgaW50IDIKICAgIGNhbGxzdWIgZHluYW1pY19hcnJheV9jb25jYXRfYnl0ZV9sZW5ndGhfaGVhZAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMQogICAgY2FsbHN1YiBkeW5hbWljX2FycmF5X2NvbmNhdF9ieXRlX2xlbmd0aF9oZWFkCiAgICBieXRlIDB4MDAwMTIxCiAgICBpbnQgMQogICAgY2FsbHN1YiBkeW5hbWljX2FycmF5X2NvbmNhdF9ieXRlX2xlbmd0aF9oZWFkCiAgICBjYWxsc3ViIGR5bmFtaWNfYXJyYXlfcG9wX2J5dGVfbGVuZ3RoX2hlYWQKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICBwb3AKICAgIGJ5dGUgIiIKICAgIHN3YXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDAKCmFyYzRfZHluYW1pY19hcnJheV9mb3JfaGVhZGVyQDE6CiAgICBmcmFtZV9kaWcgMwogICAgZnJhbWVfZGlnIDIKICAgIDwKICAgIGJ6IGFyYzRfZHluYW1pY19hcnJheV9hZnRlcl9mb3JANAogICAgZnJhbWVfZGlnIDAKICAgIGV4dHJhY3QgMiAwCiAgICBmcmFtZV9kaWcgMwogICAgZHVwCiAgICBjb3ZlciAyCiAgICBpbnQgMgogICAgKgogICAgZGlnIDEKICAgIHN3YXAKICAgIGV4dHJhY3RfdWludDE2CiAgICBkdXAyCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDIKICAgICsKICAgIGV4dHJhY3QzCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIDEKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSAxCiAgICBpbnQgMQogICAgKwogICAgZnJhbWVfYnVyeSAzCiAgICBiIGFyYzRfZHluYW1pY19hcnJheV9mb3JfaGVhZGVyQDEKCmFyYzRfZHluYW1pY19hcnJheV9hZnRlcl9mb3JANDoKICAgIGZyYW1lX2RpZyAxCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0RHluYW1pY0FycmF5LmFyYzRfZHluYW1pY19ieXRlcygpIC0+IGJ5dGVzOgphcmM0X2R5bmFtaWNfYnl0ZXM6CiAgICBwcm90byAwIDEKICAgIGJ5dGUgMHgwMDAzZmZmZmZmCiAgICBieXRlIDB4MDAKICAgIHJlcGxhY2UyIDIKICAgIHJldHN1YgoKCi8vIF9wdXlhX2xpYi5hcmM0LmR5bmFtaWNfYXJyYXlfcG9wX2J5dGVfbGVuZ3RoX2hlYWQoYXJyYXk6IGJ5dGVzKSAtPiBieXRlcywgYnl0ZXM6CmR5bmFtaWNfYXJyYXlfcG9wX2J5dGVfbGVuZ3RoX2hlYWQ6CiAgICBwcm90byAxIDIKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMQogICAgLQogICAgZHVwCiAgICBpbnQgMgogICAgKgogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgZHVwCiAgICBkaWcgMgogICAgZXh0cmFjdF91aW50MTYKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBzd2FwCiAgICBkdXAKICAgIGRpZyAzCiAgICB1bmNvdmVyIDMKICAgIHN1YnN0cmluZzMKICAgIGNvdmVyIDMKICAgIGR1cAogICAgaW50IDAKICAgIGRpZyA0CiAgICBzdWJzdHJpbmczCiAgICBjb3ZlciAyCiAgICB1bmNvdmVyIDMKICAgIGludCAyCiAgICArCiAgICB1bmNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGNvbmNhdAogICAgZGlnIDIKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICB1bmNvdmVyIDMKICAgIGludCAwCiAgICBjYWxsc3ViIHJlY2FsY3VsYXRlX2hlYWRfZm9yX2VsZW1lbnRzX3dpdGhfYnl0ZV9sZW5ndGhfaGVhZAogICAgY29uY2F0CiAgICByZXRzdWIKCgovLyBfcHV5YV9saWIuYXJjNC5keW5hbWljX2FycmF5X2NvbmNhdF9ieXRlX2xlbmd0aF9oZWFkKGFycmF5OiBieXRlcywgbmV3X2l0ZW1zX2J5dGVzOiBieXRlcywgbmV3X2l0ZW1zX2NvdW50OiB1aW50NjQpIC0+IGJ5dGVzOgpkeW5hbWljX2FycmF5X2NvbmNhdF9ieXRlX2xlbmd0aF9oZWFkOgogICAgcHJvdG8gMyAxCiAgICBmcmFtZV9kaWcgLTMKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgZHVwCiAgICBmcmFtZV9kaWcgLTEKICAgICsKICAgIHN3YXAKICAgIGludCAyCiAgICAqCiAgICBpbnQgMgogICAgKwogICAgc3dhcAogICAgZHVwCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgZnJhbWVfZGlnIC0zCiAgICBpbnQgMgogICAgZGlnIDQKICAgIHN1YnN0cmluZzMKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDIKICAgICoKICAgIGJ6ZXJvCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBmcmFtZV9kaWcgLTMKICAgIHVuY292ZXIgNQogICAgdW5jb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBpbnQgMAogICAgY2FsbHN1YiByZWNhbGN1bGF0ZV9oZWFkX2Zvcl9lbGVtZW50c193aXRoX2J5dGVfbGVuZ3RoX2hlYWQKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gX3B1eWFfbGliLmFyYzQucmVjYWxjdWxhdGVfaGVhZF9mb3JfZWxlbWVudHNfd2l0aF9ieXRlX2xlbmd0aF9oZWFkKGFycmF5X2hlYWRfYW5kX3RhaWw6IGJ5dGVzLCBsZW5ndGg6IHVpbnQ2NCwgc3RhcnRfYXRfaW5kZXg6IHVpbnQ2NCkgLT4gYnl0ZXM6CnJlY2FsY3VsYXRlX2hlYWRfZm9yX2VsZW1lbnRzX3dpdGhfYnl0ZV9sZW5ndGhfaGVhZDoKICAgIHByb3RvIDMgMQogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMgogICAgKgogICAgZHVwCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAyCiAgICAqCiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGZyYW1lX2RpZyAtMwogICAgc3dhcAogICAgZXh0cmFjdF91aW50MTYKICAgIGZyYW1lX2RpZyAtMQogICAgc2VsZWN0CgpyZWNhbGN1bGF0ZV9oZWFkX2Zvcl9lbGVtZW50c193aXRoX2J5dGVfbGVuZ3RoX2hlYWRfZm9yX2hlYWRlckAxOgogICAgZnJhbWVfZGlnIDEKICAgIGZyYW1lX2RpZyAwCiAgICA8CiAgICBieiByZWNhbGN1bGF0ZV9oZWFkX2Zvcl9lbGVtZW50c193aXRoX2J5dGVfbGVuZ3RoX2hlYWRfYWZ0ZXJfZm9yQDQKICAgIGZyYW1lX2RpZyAyCiAgICBkdXAKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAxCiAgICBkdXAKICAgIGNvdmVyIDQKICAgIHVuY292ZXIgMgogICAgcmVwbGFjZTMKICAgIGR1cAogICAgZnJhbWVfYnVyeSAtMwogICAgZGlnIDEKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMgogICAgKwogICAgKwogICAgZnJhbWVfYnVyeSAyCiAgICBpbnQgMgogICAgKwogICAgZnJhbWVfYnVyeSAxCiAgICBiIHJlY2FsY3VsYXRlX2hlYWRfZm9yX2VsZW1lbnRzX3dpdGhfYnl0ZV9sZW5ndGhfaGVhZF9mb3JfaGVhZGVyQDEKCnJlY2FsY3VsYXRlX2hlYWRfZm9yX2VsZW1lbnRzX3dpdGhfYnl0ZV9sZW5ndGhfaGVhZF9hZnRlcl9mb3JANDoKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0RHluYW1pY0FycmF5LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "Arc4DynamicArray", + "methods": [ + { + "name": "arc4_dynamic_array", + "args": [ + { + "type": "string", + "name": "name" + } + ], + "returns": { + "type": "string" + }, + "desc": "Dynamic Arrays have variable size and capacity.\nThey are similar to native Python lists because they can also append, extend, and pop." + }, + { + "name": "arc4_dynamic_bytes", + "args": [], + "returns": { + "type": "byte[]" + }, + "desc": "arc4.DynamicBytes are essentially an arc4.DynamicArray[arc4.Bytes] and some convenience methods." + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +}""" +APP_SPEC = algokit_utils.ApplicationSpecification.from_json(_APP_SPEC_JSON) +_TReturn = typing.TypeVar("_TReturn") + + +class _ArgsBase(ABC, typing.Generic[_TReturn]): + @staticmethod + @abstractmethod + def method() -> str: + ... + + +_TArgs = typing.TypeVar("_TArgs", bound=_ArgsBase[typing.Any]) + + +@dataclasses.dataclass(kw_only=True) +class _TArgsHolder(typing.Generic[_TArgs]): + args: _TArgs + + +def _filter_none(value: dict | typing.Any) -> dict | typing.Any: + if isinstance(value, dict): + return {k: _filter_none(v) for k, v in value.items() if v is not None} + return value + + +def _as_dict(data: typing.Any, *, convert_all: bool = True) -> dict[str, typing.Any]: + if data is None: + return {} + if not dataclasses.is_dataclass(data): + raise TypeError(f"{data} must be a dataclass") + if convert_all: + result = dataclasses.asdict(data) # type: ignore[call-overload] + else: + result = {f.name: getattr(data, f.name) for f in dataclasses.fields(data)} + return _filter_none(result) + + +def _convert_transaction_parameters( + transaction_parameters: algokit_utils.TransactionParameters | None, +) -> algokit_utils.TransactionParametersDict: + return typing.cast(algokit_utils.TransactionParametersDict, _as_dict(transaction_parameters)) + + +def _convert_call_transaction_parameters( + transaction_parameters: algokit_utils.TransactionParameters | None, +) -> algokit_utils.OnCompleteCallParametersDict: + return typing.cast(algokit_utils.OnCompleteCallParametersDict, _as_dict(transaction_parameters)) + + +def _convert_create_transaction_parameters( + transaction_parameters: algokit_utils.TransactionParameters | None, + on_complete: algokit_utils.OnCompleteActionName, +) -> algokit_utils.CreateCallParametersDict: + result = typing.cast(algokit_utils.CreateCallParametersDict, _as_dict(transaction_parameters)) + on_complete_enum = on_complete.replace("_", " ").title().replace(" ", "") + "OC" + result["on_complete"] = getattr(algosdk.transaction.OnComplete, on_complete_enum) + return result + + +def _convert_deploy_args( + deploy_args: algokit_utils.DeployCallArgs | None, +) -> algokit_utils.ABICreateCallArgsDict | None: + if deploy_args is None: + return None + + deploy_args_dict = typing.cast(algokit_utils.ABICreateCallArgsDict, _as_dict(deploy_args)) + if isinstance(deploy_args, _TArgsHolder): + deploy_args_dict["args"] = _as_dict(deploy_args.args) + deploy_args_dict["method"] = deploy_args.args.method() + + return deploy_args_dict + + +@dataclasses.dataclass(kw_only=True) +class Arc4DynamicArrayArgs(_ArgsBase[str]): + """Dynamic Arrays have variable size and capacity. + They are similar to native Python lists because they can also append, extend, and pop.""" + + name: str + + @staticmethod + def method() -> str: + return "arc4_dynamic_array(string)string" + + +@dataclasses.dataclass(kw_only=True) +class Arc4DynamicBytesArgs(_ArgsBase[bytes | bytearray]): + """arc4.DynamicBytes are essentially an arc4.DynamicArray[arc4.Bytes] and some convenience methods.""" + + @staticmethod + def method() -> str: + return "arc4_dynamic_bytes()byte[]" + + +@dataclasses.dataclass(kw_only=True) +class SimulateOptions: + allow_more_logs: bool = dataclasses.field(default=False) + allow_empty_signatures: bool = dataclasses.field(default=False) + extra_opcode_budget: int = dataclasses.field(default=0) + exec_trace_config: models.SimulateTraceConfig | None = dataclasses.field(default=None) + + +class Composer: + + def __init__(self, app_client: algokit_utils.ApplicationClient, atc: AtomicTransactionComposer): + self.app_client = app_client + self.atc = atc + + def build(self) -> AtomicTransactionComposer: + return self.atc + + def simulate(self, options: SimulateOptions | None = None) -> SimulateAtomicTransactionResponse: + request = models.SimulateRequest( + allow_more_logs=options.allow_more_logs, + allow_empty_signatures=options.allow_empty_signatures, + extra_opcode_budget=options.extra_opcode_budget, + exec_trace_config=options.exec_trace_config, + txn_groups=[] + ) if options else None + result = self.atc.simulate(self.app_client.algod_client, request) + return result + + def execute(self) -> AtomicTransactionResponse: + return self.app_client.execute_atc(self.atc) + + def arc4_dynamic_array( + self, + *, + name: str, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Dynamic Arrays have variable size and capacity. + They are similar to native Python lists because they can also append, extend, and pop. + + Adds a call to `arc4_dynamic_array(string)string` ABI method + + :param str name: The `name` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = Arc4DynamicArrayArgs( + name=name, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def arc4_dynamic_bytes( + self, + *, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """arc4.DynamicBytes are essentially an arc4.DynamicArray[arc4.Bytes] and some convenience methods. + + Adds a call to `arc4_dynamic_bytes()byte[]` ABI method + + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = Arc4DynamicBytesArgs() + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def create_bare( + self, + *, + on_complete: typing.Literal["no_op"] = "no_op", + transaction_parameters: algokit_utils.CreateTransactionParameters | None = None, + ) -> "Composer": + """Adds a call to create an application using the no_op bare method + + :param typing.Literal[no_op] on_complete: On completion type to use + :param algokit_utils.CreateTransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + self.app_client.compose_create( + self.atc, + call_abi_method=False, + transaction_parameters=_convert_create_transaction_parameters(transaction_parameters, on_complete), + ) + return self + + def clear_state( + self, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + app_args: list[bytes] | None = None, + ) -> "Composer": + """Adds a call to the application with on completion set to ClearState + + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :param list[bytes] | None app_args: (optional) Application args to pass""" + + self.app_client.compose_clear_state(self.atc, _convert_transaction_parameters(transaction_parameters), app_args) + return self + + +class Arc4DynamicArrayClient: + """A class for interacting with the Arc4DynamicArray app providing high productivity and + strongly typed methods to deploy and call the app""" + + @typing.overload + def __init__( + self, + algod_client: algosdk.v2client.algod.AlgodClient, + *, + app_id: int = 0, + signer: TransactionSigner | algokit_utils.Account | None = None, + sender: str | None = None, + suggested_params: algosdk.transaction.SuggestedParams | None = None, + template_values: algokit_utils.TemplateValueMapping | None = None, + app_name: str | None = None, + ) -> None: + ... + + @typing.overload + def __init__( + self, + algod_client: algosdk.v2client.algod.AlgodClient, + *, + creator: str | algokit_utils.Account, + indexer_client: algosdk.v2client.indexer.IndexerClient | None = None, + existing_deployments: algokit_utils.AppLookup | None = None, + signer: TransactionSigner | algokit_utils.Account | None = None, + sender: str | None = None, + suggested_params: algosdk.transaction.SuggestedParams | None = None, + template_values: algokit_utils.TemplateValueMapping | None = None, + app_name: str | None = None, + ) -> None: + ... + + def __init__( + self, + algod_client: algosdk.v2client.algod.AlgodClient, + *, + creator: str | algokit_utils.Account | None = None, + indexer_client: algosdk.v2client.indexer.IndexerClient | None = None, + existing_deployments: algokit_utils.AppLookup | None = None, + app_id: int = 0, + signer: TransactionSigner | algokit_utils.Account | None = None, + sender: str | None = None, + suggested_params: algosdk.transaction.SuggestedParams | None = None, + template_values: algokit_utils.TemplateValueMapping | None = None, + app_name: str | None = None, + ) -> None: + """ + Arc4DynamicArrayClient can be created with an app_id to interact with an existing application, alternatively + it can be created with a creator and indexer_client specified to find existing applications by name and creator. + + :param AlgodClient algod_client: AlgoSDK algod client + :param int app_id: The app_id of an existing application, to instead find the application by creator and name + use the creator and indexer_client parameters + :param str | Account creator: The address or Account of the app creator to resolve the app_id + :param IndexerClient indexer_client: AlgoSDK indexer client, only required if deploying or finding app_id by + creator and app name + :param AppLookup existing_deployments: + :param TransactionSigner | Account signer: Account or signer to use to sign transactions, if not specified and + creator was passed as an Account will use that. + :param str sender: Address to use as the sender for all transactions, will use the address associated with the + signer if not specified. + :param TemplateValueMapping template_values: Values to use for TMPL_* template variables, dictionary keys should + *NOT* include the TMPL_ prefix + :param str | None app_name: Name of application to use when deploying, defaults to name defined on the + Application Specification + """ + + self.app_spec = APP_SPEC + + # calling full __init__ signature, so ignoring mypy warning about overloads + self.app_client = algokit_utils.ApplicationClient( # type: ignore[call-overload, misc] + algod_client=algod_client, + app_spec=self.app_spec, + app_id=app_id, + creator=creator, + indexer_client=indexer_client, + existing_deployments=existing_deployments, + signer=signer, + sender=sender, + suggested_params=suggested_params, + template_values=template_values, + app_name=app_name, + ) + + @property + def algod_client(self) -> algosdk.v2client.algod.AlgodClient: + return self.app_client.algod_client + + @property + def app_id(self) -> int: + return self.app_client.app_id + + @app_id.setter + def app_id(self, value: int) -> None: + self.app_client.app_id = value + + @property + def app_address(self) -> str: + return self.app_client.app_address + + @property + def sender(self) -> str | None: + return self.app_client.sender + + @sender.setter + def sender(self, value: str) -> None: + self.app_client.sender = value + + @property + def signer(self) -> TransactionSigner | None: + return self.app_client.signer + + @signer.setter + def signer(self, value: TransactionSigner) -> None: + self.app_client.signer = value + + @property + def suggested_params(self) -> algosdk.transaction.SuggestedParams | None: + return self.app_client.suggested_params + + @suggested_params.setter + def suggested_params(self, value: algosdk.transaction.SuggestedParams | None) -> None: + self.app_client.suggested_params = value + + def arc4_dynamic_array( + self, + *, + name: str, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[str]: + """Dynamic Arrays have variable size and capacity. + They are similar to native Python lists because they can also append, extend, and pop. + + Calls `arc4_dynamic_array(string)string` ABI method + + :param str name: The `name` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[str]: The result of the transaction""" + + args = Arc4DynamicArrayArgs( + name=name, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def arc4_dynamic_bytes( + self, + *, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[bytes | bytearray]: + """arc4.DynamicBytes are essentially an arc4.DynamicArray[arc4.Bytes] and some convenience methods. + + Calls `arc4_dynamic_bytes()byte[]` ABI method + + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[bytes | bytearray]: The result of the transaction""" + + args = Arc4DynamicBytesArgs() + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def create_bare( + self, + *, + on_complete: typing.Literal["no_op"] = "no_op", + transaction_parameters: algokit_utils.CreateTransactionParameters | None = None, + ) -> algokit_utils.TransactionResponse: + """Creates an application using the no_op bare method + + :param typing.Literal[no_op] on_complete: On completion type to use + :param algokit_utils.CreateTransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.TransactionResponse: The result of the transaction""" + + result = self.app_client.create( + call_abi_method=False, + transaction_parameters=_convert_create_transaction_parameters(transaction_parameters, on_complete), + ) + return result + + def clear_state( + self, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + app_args: list[bytes] | None = None, + ) -> algokit_utils.TransactionResponse: + """Calls the application with on completion set to ClearState + + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :param list[bytes] | None app_args: (optional) Application args to pass + :returns algokit_utils.TransactionResponse: The result of the transaction""" + + return self.app_client.clear_state(_convert_transaction_parameters(transaction_parameters), app_args) + + def deploy( + self, + version: str | None = None, + *, + signer: TransactionSigner | None = None, + sender: str | None = None, + allow_update: bool | None = None, + allow_delete: bool | None = None, + on_update: algokit_utils.OnUpdate = algokit_utils.OnUpdate.Fail, + on_schema_break: algokit_utils.OnSchemaBreak = algokit_utils.OnSchemaBreak.Fail, + template_values: algokit_utils.TemplateValueMapping | None = None, + create_args: algokit_utils.DeployCallArgs | None = None, + update_args: algokit_utils.DeployCallArgs | None = None, + delete_args: algokit_utils.DeployCallArgs | None = None, + ) -> algokit_utils.DeployResponse: + """Deploy an application and update client to reference it. + + Idempotently deploy (create, update/delete if changed) an app against the given name via the given creator + account, including deploy-time template placeholder substitutions. + To understand the architecture decisions behind this functionality please see + + + ```{note} + If there is a breaking state schema change to an existing app (and `on_schema_break` is set to + 'ReplaceApp' the existing app will be deleted and re-created. + ``` + + ```{note} + If there is an update (different TEAL code) to an existing app (and `on_update` is set to 'ReplaceApp') + the existing app will be deleted and re-created. + ``` + + :param str version: version to use when creating or updating app, if None version will be auto incremented + :param algosdk.atomic_transaction_composer.TransactionSigner signer: signer to use when deploying app + , if None uses self.signer + :param str sender: sender address to use when deploying app, if None uses self.sender + :param bool allow_delete: Used to set the `TMPL_DELETABLE` template variable to conditionally control if an app + can be deleted + :param bool allow_update: Used to set the `TMPL_UPDATABLE` template variable to conditionally control if an app + can be updated + :param OnUpdate on_update: Determines what action to take if an application update is required + :param OnSchemaBreak on_schema_break: Determines what action to take if an application schema requirements + has increased beyond the current allocation + :param dict[str, int|str|bytes] template_values: Values to use for `TMPL_*` template variables, dictionary keys + should *NOT* include the TMPL_ prefix + :param algokit_utils.DeployCallArgs | None create_args: Arguments used when creating an application + :param algokit_utils.DeployCallArgs | None update_args: Arguments used when updating an application + :param algokit_utils.DeployCallArgs | None delete_args: Arguments used when deleting an application + :return DeployResponse: details action taken and relevant transactions + :raises DeploymentError: If the deployment failed""" + + return self.app_client.deploy( + version, + signer=signer, + sender=sender, + allow_update=allow_update, + allow_delete=allow_delete, + on_update=on_update, + on_schema_break=on_schema_break, + template_values=template_values, + create_args=_convert_deploy_args(create_args), + update_args=_convert_deploy_args(update_args), + delete_args=_convert_deploy_args(delete_args), + ) + + def compose(self, atc: AtomicTransactionComposer | None = None) -> Composer: + return Composer(self.app_client, atc or AtomicTransactionComposer()) diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py index d092cd3..fa693aa 100644 --- a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_types_client.py @@ -38,6 +38,11 @@ "no_op": "CALL" } }, + "arc4_byte(byte)byte": { + "call_config": { + "no_op": "CALL" + } + }, "arc4_address_properties(address)uint64": { "call_config": { "no_op": "CALL" @@ -50,7 +55,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAOQogICAgbWV0aG9kICJhcmM0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF91aW50X24odWludDgsdWludDE2LHVpbnQzMix1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJhcmM0X2JpZ3VpbnRfbih1aW50MTI4LHVpbnQyNTYsdWludDUxMil1aW50NTEyIgogICAgbWV0aG9kICJhcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzKXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3JldHVybihhZGRyZXNzKWFkZHJlc3MiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnQ2NF9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9iaWd1aW50X25fcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcHJvcGVydGllc19yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANgogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF91aW50NjRfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGNhbGxzdWIgYXJjNF91aW50NjQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludF9uX3JvdXRlQDM6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBjYWxsc3ViIGFyYzRfdWludF9uCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2JpZ3VpbnRfbl9yb3V0ZUA0OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgY2FsbHN1YiBhcmM0X2JpZ3VpbnRfbgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19yZXR1cm5fcm91dGVANjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF9hZGRyZXNzX3JldHVybgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMzoKICAgIGludCAwCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50NjQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF91aW50NjQ6CiAgICBwcm90byAyIDEKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICArCiAgICBpdG9iCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXJjNF91aW50X24oYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3VpbnRfbjoKICAgIHByb3RvIDQgMQogICAgZnJhbWVfZGlnIC00CiAgICBsZW4KICAgIGludCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgaW50IDIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgNAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludCA4CiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTQKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMwogICAgYnRvaQogICAgKwogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICArCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2JpZ3VpbnRfbihhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlczoKYXJjNF9iaWd1aW50X246CiAgICBwcm90byAzIDEKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBpbnQgMTYKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnQgMzIKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnQgNjQKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBiKwogICAgZnJhbWVfZGlnIC0xCiAgICBiKwogICAgZHVwCiAgICBsZW4KICAgIGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50IDY0CiAgICBiemVybwogICAgYnwKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzOiBieXRlcykgLT4gdWludDY0OgphcmM0X2FkZHJlc3NfcHJvcGVydGllczoKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzczogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2FkZHJlc3NfcmV0dXJuOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1Ygo=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTAKICAgIG1ldGhvZCAiYXJjNF91aW50NjQodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgImFyYzRfdWludF9uKHVpbnQ4LHVpbnQxNix1aW50MzIsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAiYXJjNF9iaWd1aW50X24odWludDEyOCx1aW50MjU2LHVpbnQ1MTIpdWludDUxMiIKICAgIG1ldGhvZCAiYXJjNF9ieXRlKGJ5dGUpYnl0ZSIKICAgIG1ldGhvZCAiYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXMoYWRkcmVzcyl1aW50NjQiCiAgICBtZXRob2QgImFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzcylhZGRyZXNzIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF91aW50NjRfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnRfbl9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYmlndWludF9uX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9ieXRlX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9hZGRyZXNzX3Byb3BlcnRpZXNfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcmV0dXJuX3JvdXRlQDcKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdWludDY0X3JvdXRlQDI6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBjYWxsc3ViIGFyYzRfdWludDY0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3VpbnRfbl9yb3V0ZUAzOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgY2FsbHN1YiBhcmM0X3VpbnRfbgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9iaWd1aW50X25fcm91dGVANDoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGNhbGxzdWIgYXJjNF9iaWd1aW50X24KICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYnl0ZV9yb3V0ZUA1OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgY2FsbHN1YiBhcmM0X2J5dGUKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfYWRkcmVzc19wcm9wZXJ0aWVzX3JvdXRlQDY6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBjYWxsc3ViIGFyYzRfYWRkcmVzc19wcm9wZXJ0aWVzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X2FkZHJlc3NfcmV0dXJuX3JvdXRlQDc6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBjYWxsc3ViIGFyYzRfYWRkcmVzc19yZXR1cm4KICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMDoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE0CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE0OgogICAgaW50IDAKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3VpbnQ2NDoKICAgIHByb3RvIDIgMQogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X3VpbnRfbihhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiBieXRlcykgLT4gYnl0ZXM6CmFyYzRfdWludF9uOgogICAgcHJvdG8gNCAxCiAgICBmcmFtZV9kaWcgLTQKICAgIGxlbgogICAgaW50IDEKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBpbnQgMgogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludCA0CiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50IDgKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtNAogICAgYnRvaQogICAgZnJhbWVfZGlnIC0zCiAgICBidG9pCiAgICArCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ0b2kKICAgICsKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgKwogICAgaXRvYgogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYmlndWludF9uKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2JpZ3VpbnRfbjoKICAgIHByb3RvIDMgMQogICAgZnJhbWVfZGlnIC0zCiAgICBsZW4KICAgIGludCAxNgogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludCAzMgogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludCA2NAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGIrCiAgICBmcmFtZV9kaWcgLTEKICAgIGIrCiAgICBkdXAKICAgIGxlbgogICAgaW50IDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnQgNjQKICAgIGJ6ZXJvCiAgICBifAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYnl0ZShhOiBieXRlcykgLT4gYnl0ZXM6CmFyYzRfYnl0ZToKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICBpbnQgMQogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA3IDEKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUeXBlcy5hcmM0X2FkZHJlc3NfcHJvcGVydGllcyhhZGRyZXNzOiBieXRlcykgLT4gdWludDY0OgphcmM0X2FkZHJlc3NfcHJvcGVydGllczoKICAgIHByb3RvIDEgMQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR5cGVzLmFyYzRfYWRkcmVzc19yZXR1cm4oYWRkcmVzczogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X2FkZHJlc3NfcmV0dXJuOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHlwZXMuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { @@ -139,6 +144,19 @@ }, "desc": "Integers with larger bit size are supported up to 512 bits.\nUltimately, they are all represented with native BigUInt." }, + { + "name": "arc4_byte", + "args": [ + { + "type": "byte", + "name": "a" + } + ], + "returns": { + "type": "byte" + }, + "desc": "An arc4.Byte is essentially an alias for an 8-bit integer." + }, { "name": "arc4_address_properties", "args": [ @@ -285,6 +303,17 @@ def method() -> str: return "arc4_biguint_n(uint128,uint256,uint512)uint512" +@dataclasses.dataclass(kw_only=True) +class Arc4ByteArgs(_ArgsBase[int]): + """An arc4.Byte is essentially an alias for an 8-bit integer.""" + + a: int + + @staticmethod + def method() -> str: + return "arc4_byte(byte)byte" + + @dataclasses.dataclass(kw_only=True) class Arc4AddressPropertiesArgs(_ArgsBase[int]): address: str @@ -430,6 +459,31 @@ def arc4_biguint_n( ) return self + def arc4_byte( + self, + *, + a: int, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """An arc4.Byte is essentially an alias for an 8-bit integer. + + Adds a call to `arc4_byte(byte)byte` ABI method + + :param int a: The `a` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = Arc4ByteArgs( + a=a, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + def arc4_address_properties( self, *, @@ -728,6 +782,30 @@ def arc4_biguint_n( ) return result + def arc4_byte( + self, + *, + a: int, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[int]: + """An arc4.Byte is essentially an alias for an 8-bit integer. + + Calls `arc4_byte(byte)byte` ABI method + + :param int a: The `a` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[int]: The result of the transaction""" + + args = Arc4ByteArgs( + a=a, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + def arc4_address_properties( self, *, diff --git a/projects/python-contract-examples/tests/arc4_types_integration_test.py b/projects/python-contract-examples/tests/arc4_types_integration_test.py index 3070a82..ab972a2 100644 --- a/projects/python-contract-examples/tests/arc4_types_integration_test.py +++ b/projects/python-contract-examples/tests/arc4_types_integration_test.py @@ -7,6 +7,7 @@ from algokit_utils.config import config from algosdk.v2client.algod import AlgodClient +from smart_contracts.artifacts.arc4_types.arc4_dynamic_array_client import Arc4DynamicArrayClient, SimulateOptions from smart_contracts.artifacts.arc4_types.arc4_static_array_client import ( Arc4StaticArrayClient, ) @@ -85,6 +86,36 @@ def arc4_statc_array_app_client( return client +@pytest.fixture(scope="session") +def arc4_dynamic_array_app_client( + algod_client: AlgodClient, creator: AddressAndSigner, algorand: AlgorandClient +) -> Arc4DynamicArrayClient: + """Deploy the arc4 static array App and create an app client the creator will use to interact with the contract""" + + config.configure( + debug=True, + # trace_all=True, + ) + + client = Arc4DynamicArrayClient( + algod_client, + sender=creator.address, + signer=creator.signer, + ) + + client.create_bare() + + algorand.send.payment( + PayParams( + sender=creator.address, + receiver=client.app_address, + amount=1000000, # 1 Algo + ) + ) + + return client + + @pytest.fixture(scope="session") def arc4_struct_app_client( algod_client: AlgodClient, creator: AddressAndSigner, algorand: AlgorandClient @@ -177,6 +208,16 @@ def test_arc4_biguint_n( assert result.return_value == 2**65 + 2**129 + 2**257 +def test_arc4_byte( + arc4_types_app_client: Arc4TypesClient, +) -> None: + """Test the arc4_byte method""" + + result = arc4_types_app_client.arc4_byte(a=5) + + assert result.return_value == 6 + + def test_arc4_address_properties( arc4_types_app_client: Arc4TypesClient, creator: AddressAndSigner, @@ -211,6 +252,24 @@ def test_arc4_static_array(arc4_statc_array_app_client: Arc4StaticArrayClient) - arc4_statc_array_app_client.arc4_static_array() +def test_arc4_dynamic_array(arc4_dynamic_array_app_client: Arc4DynamicArrayClient) -> None: + """Test the arc4_dynamic_array method""" + + # Call the arc4_static_array method with simulate to avoid opcode budget constraints. + result = arc4_dynamic_array_app_client.compose().arc4_dynamic_array(name="John").simulate(SimulateOptions(extra_opcode_budget=700)) + + assert result.abi_results[0].return_value == "Hello world, John" + + +def test_arc4_dynamic_bytes(arc4_dynamic_array_app_client: Arc4DynamicArrayClient) -> None: + """Test the arc4_dynamic_bytes method""" + + # Call the arc4_static_array method. + result = arc4_dynamic_array_app_client.arc4_dynamic_bytes() + + assert result.return_value == [0, 255, 255] + + def test_arc4_struct_add_todo(arc4_struct_app_client: Arc4StructClient) -> None: """Test the add_todo method""" From 2b3ff149dc6fa7b44a0bb11ac25e8d8aa9539533 Mon Sep 17 00:00:00 2001 From: CiottiGiorgio Date: Mon, 4 Nov 2024 17:56:14 +0100 Subject: [PATCH 4/5] added tuples examples. --- .../smart_contracts/arc4_types/contract.py | 14 + .../arc4_types/Arc4Tuple.approval.teal | 104 ++++ .../artifacts/arc4_types/Arc4Tuple.arc32.json | 56 ++ .../artifacts/arc4_types/Arc4Tuple.clear.teal | 5 + .../artifacts/arc4_types/arc4_tuple_client.py | 499 ++++++++++++++++++ .../tests/arc4_types_integration_test.py | 41 ++ 6 files changed, 719 insertions(+) create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.approval.teal create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.arc32.json create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.clear.teal create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_tuple_client.py diff --git a/projects/python-contract-examples/smart_contracts/arc4_types/contract.py b/projects/python-contract-examples/smart_contracts/arc4_types/contract.py index 3d3e19b..a0cd972 100644 --- a/projects/python-contract-examples/smart_contracts/arc4_types/contract.py +++ b/projects/python-contract-examples/smart_contracts/arc4_types/contract.py @@ -209,3 +209,17 @@ def return_todo(self, task: arc4.String) -> Todo: assert exist return todo_to_return + + +class Arc4Tuple(ARC4Contract): + + @abimethod() + def arc4_tuple(self, a: arc4.Tuple[arc4.UInt8, arc4.String, arc4.UInt64, arc4.DynamicArray[arc4.UInt32]]) -> arc4.String: + """An arc4.Tuple is a heterogeneous collection of arc4 types.""" + + total = a[0].native + a[2].native + + for x in a[3]: + total += x.native + + return a[1] diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.approval.teal b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.approval.teal new file mode 100644 index 0000000..025d4bd --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.approval.teal @@ -0,0 +1,104 @@ +#pragma version 10 + +smart_contracts.arc4_types.contract.Arc4Tuple.approval_program: + callsub __puya_arc4_router__ + return + + +// smart_contracts.arc4_types.contract.Arc4Tuple.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + proto 0 1 + txn NumAppArgs + bz __puya_arc4_router___bare_routing@5 + method "arc4_tuple((uint8,string,uint64,uint32[]))string" + txna ApplicationArgs 0 + match __puya_arc4_router___arc4_tuple_route@2 + int 0 + retsub + +__puya_arc4_router___arc4_tuple_route@2: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + callsub arc4_tuple + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___bare_routing@5: + txn OnCompletion + bnz __puya_arc4_router___after_if_else@9 + txn ApplicationID + ! + assert // is creating + int 1 + retsub + +__puya_arc4_router___after_if_else@9: + int 0 + retsub + + +// smart_contracts.arc4_types.contract.Arc4Tuple.arc4_tuple(a: bytes) -> bytes: +arc4_tuple: + proto 1 1 + frame_dig -1 + extract 0 1 // on error: Index access is out of bounds + btoi + frame_dig -1 + extract 3 8 // on error: Index access is out of bounds + btoi + + + frame_dig -1 + int 11 + extract_uint16 + dup + frame_dig -1 + len + frame_dig -1 + cover 2 + substring3 + dup + int 0 + extract_uint16 + int 0 + +arc4_tuple_for_header@1: + frame_dig 4 + frame_dig 3 + < + bz arc4_tuple_after_for@4 + frame_dig 2 + extract 2 0 + frame_dig 4 + dup + cover 2 + int 4 + * + int 4 + extract3 // on error: Index access is out of bounds + btoi + frame_dig 0 + + + frame_bury 0 + int 1 + + + frame_bury 4 + b arc4_tuple_for_header@1 + +arc4_tuple_after_for@4: + frame_dig -1 + int 1 + extract_uint16 + frame_dig -1 + swap + frame_dig 1 + substring3 + frame_bury 0 + retsub diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.arc32.json b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.arc32.json new file mode 100644 index 0000000..c8e910f --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.arc32.json @@ -0,0 +1,56 @@ +{ + "hints": { + "arc4_tuple((uint8,string,uint64,uint32[]))string": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHVwbGUuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUdXBsZS5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANQogICAgbWV0aG9kICJhcmM0X3R1cGxlKCh1aW50OCxzdHJpbmcsdWludDY0LHVpbnQzMltdKSlzdHJpbmciCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3R1cGxlX3JvdXRlQDIKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdHVwbGVfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF90dXBsZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDU6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA5CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR1cGxlLmFyYzRfdHVwbGUoYTogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3R1cGxlOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDMgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ0b2kKICAgICsKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDExCiAgICBleHRyYWN0X3VpbnQxNgogICAgZHVwCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgZnJhbWVfZGlnIC0xCiAgICBjb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDAKCmFyYzRfdHVwbGVfZm9yX2hlYWRlckAxOgogICAgZnJhbWVfZGlnIDQKICAgIGZyYW1lX2RpZyAzCiAgICA8CiAgICBieiBhcmM0X3R1cGxlX2FmdGVyX2ZvckA0CiAgICBmcmFtZV9kaWcgMgogICAgZXh0cmFjdCAyIDAKICAgIGZyYW1lX2RpZyA0CiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludCA0CiAgICAqCiAgICBpbnQgNAogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBidG9pCiAgICBmcmFtZV9kaWcgMAogICAgKwogICAgZnJhbWVfYnVyeSAwCiAgICBpbnQgMQogICAgKwogICAgZnJhbWVfYnVyeSA0CiAgICBiIGFyYzRfdHVwbGVfZm9yX2hlYWRlckAxCgphcmM0X3R1cGxlX2FmdGVyX2ZvckA0OgogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMQogICAgZXh0cmFjdF91aW50MTYKICAgIGZyYW1lX2RpZyAtMQogICAgc3dhcAogICAgZnJhbWVfZGlnIDEKICAgIHN1YnN0cmluZzMKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHVwbGUuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "Arc4Tuple", + "methods": [ + { + "name": "arc4_tuple", + "args": [ + { + "type": "(uint8,string,uint64,uint32[])", + "name": "a" + } + ], + "readonly": false, + "returns": { + "type": "string" + }, + "desc": "An arc4.Tuple is a heterogeneous collection of arc4 types." + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.clear.teal b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.clear.teal new file mode 100644 index 0000000..3150069 --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/Arc4Tuple.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +smart_contracts.arc4_types.contract.Arc4Tuple.clear_state_program: + int 1 + return diff --git a/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_tuple_client.py b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_tuple_client.py new file mode 100644 index 0000000..e78a989 --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/arc4_types/arc4_tuple_client.py @@ -0,0 +1,499 @@ +# flake8: noqa +# fmt: off +# mypy: disable-error-code="no-any-return, no-untyped-call, misc, type-arg" +# This file was automatically generated by algokit-client-generator. +# DO NOT MODIFY IT BY HAND. +# requires: algokit-utils@^1.2.0 +import base64 +import dataclasses +import decimal +import typing +from abc import ABC, abstractmethod + +import algokit_utils +import algosdk +from algosdk.v2client import models +from algosdk.atomic_transaction_composer import ( + AtomicTransactionComposer, + AtomicTransactionResponse, + SimulateAtomicTransactionResponse, + TransactionSigner, + TransactionWithSigner +) + +_APP_SPEC_JSON = r"""{ + "hints": { + "arc4_tuple((uint8,string,uint64,uint32[]))string": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHVwbGUuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5hcmM0X3R5cGVzLmNvbnRyYWN0LkFyYzRUdXBsZS5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANQogICAgbWV0aG9kICJhcmM0X3R1cGxlKCh1aW50OCxzdHJpbmcsdWludDY0LHVpbnQzMltdKSlzdHJpbmciCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcmM0X3R1cGxlX3JvdXRlQDIKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FyYzRfdHVwbGVfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGNhbGxzdWIgYXJjNF90dXBsZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDU6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA5CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmFyYzRfdHlwZXMuY29udHJhY3QuQXJjNFR1cGxlLmFyYzRfdHVwbGUoYTogYnl0ZXMpIC0+IGJ5dGVzOgphcmM0X3R1cGxlOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDMgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ0b2kKICAgICsKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDExCiAgICBleHRyYWN0X3VpbnQxNgogICAgZHVwCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgZnJhbWVfZGlnIC0xCiAgICBjb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDAKCmFyYzRfdHVwbGVfZm9yX2hlYWRlckAxOgogICAgZnJhbWVfZGlnIDQKICAgIGZyYW1lX2RpZyAzCiAgICA8CiAgICBieiBhcmM0X3R1cGxlX2FmdGVyX2ZvckA0CiAgICBmcmFtZV9kaWcgMgogICAgZXh0cmFjdCAyIDAKICAgIGZyYW1lX2RpZyA0CiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludCA0CiAgICAqCiAgICBpbnQgNAogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBidG9pCiAgICBmcmFtZV9kaWcgMAogICAgKwogICAgZnJhbWVfYnVyeSAwCiAgICBpbnQgMQogICAgKwogICAgZnJhbWVfYnVyeSA0CiAgICBiIGFyYzRfdHVwbGVfZm9yX2hlYWRlckAxCgphcmM0X3R1cGxlX2FmdGVyX2ZvckA0OgogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMQogICAgZXh0cmFjdF91aW50MTYKICAgIGZyYW1lX2RpZyAtMQogICAgc3dhcAogICAgZnJhbWVfZGlnIDEKICAgIHN1YnN0cmluZzMKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMuYXJjNF90eXBlcy5jb250cmFjdC5BcmM0VHVwbGUuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "Arc4Tuple", + "methods": [ + { + "name": "arc4_tuple", + "args": [ + { + "type": "(uint8,string,uint64,uint32[])", + "name": "a" + } + ], + "returns": { + "type": "string" + }, + "desc": "An arc4.Tuple is a heterogeneous collection of arc4 types." + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +}""" +APP_SPEC = algokit_utils.ApplicationSpecification.from_json(_APP_SPEC_JSON) +_TReturn = typing.TypeVar("_TReturn") + + +class _ArgsBase(ABC, typing.Generic[_TReturn]): + @staticmethod + @abstractmethod + def method() -> str: + ... + + +_TArgs = typing.TypeVar("_TArgs", bound=_ArgsBase[typing.Any]) + + +@dataclasses.dataclass(kw_only=True) +class _TArgsHolder(typing.Generic[_TArgs]): + args: _TArgs + + +def _filter_none(value: dict | typing.Any) -> dict | typing.Any: + if isinstance(value, dict): + return {k: _filter_none(v) for k, v in value.items() if v is not None} + return value + + +def _as_dict(data: typing.Any, *, convert_all: bool = True) -> dict[str, typing.Any]: + if data is None: + return {} + if not dataclasses.is_dataclass(data): + raise TypeError(f"{data} must be a dataclass") + if convert_all: + result = dataclasses.asdict(data) # type: ignore[call-overload] + else: + result = {f.name: getattr(data, f.name) for f in dataclasses.fields(data)} + return _filter_none(result) + + +def _convert_transaction_parameters( + transaction_parameters: algokit_utils.TransactionParameters | None, +) -> algokit_utils.TransactionParametersDict: + return typing.cast(algokit_utils.TransactionParametersDict, _as_dict(transaction_parameters)) + + +def _convert_call_transaction_parameters( + transaction_parameters: algokit_utils.TransactionParameters | None, +) -> algokit_utils.OnCompleteCallParametersDict: + return typing.cast(algokit_utils.OnCompleteCallParametersDict, _as_dict(transaction_parameters)) + + +def _convert_create_transaction_parameters( + transaction_parameters: algokit_utils.TransactionParameters | None, + on_complete: algokit_utils.OnCompleteActionName, +) -> algokit_utils.CreateCallParametersDict: + result = typing.cast(algokit_utils.CreateCallParametersDict, _as_dict(transaction_parameters)) + on_complete_enum = on_complete.replace("_", " ").title().replace(" ", "") + "OC" + result["on_complete"] = getattr(algosdk.transaction.OnComplete, on_complete_enum) + return result + + +def _convert_deploy_args( + deploy_args: algokit_utils.DeployCallArgs | None, +) -> algokit_utils.ABICreateCallArgsDict | None: + if deploy_args is None: + return None + + deploy_args_dict = typing.cast(algokit_utils.ABICreateCallArgsDict, _as_dict(deploy_args)) + if isinstance(deploy_args, _TArgsHolder): + deploy_args_dict["args"] = _as_dict(deploy_args.args) + deploy_args_dict["method"] = deploy_args.args.method() + + return deploy_args_dict + + +@dataclasses.dataclass(kw_only=True) +class Arc4TupleArgs(_ArgsBase[str]): + """An arc4.Tuple is a heterogeneous collection of arc4 types.""" + + a: tuple[int, str, int, list[int]] + + @staticmethod + def method() -> str: + return "arc4_tuple((uint8,string,uint64,uint32[]))string" + + +@dataclasses.dataclass(kw_only=True) +class SimulateOptions: + allow_more_logs: bool = dataclasses.field(default=False) + allow_empty_signatures: bool = dataclasses.field(default=False) + extra_opcode_budget: int = dataclasses.field(default=0) + exec_trace_config: models.SimulateTraceConfig | None = dataclasses.field(default=None) + + +class Composer: + + def __init__(self, app_client: algokit_utils.ApplicationClient, atc: AtomicTransactionComposer): + self.app_client = app_client + self.atc = atc + + def build(self) -> AtomicTransactionComposer: + return self.atc + + def simulate(self, options: SimulateOptions | None = None) -> SimulateAtomicTransactionResponse: + request = models.SimulateRequest( + allow_more_logs=options.allow_more_logs, + allow_empty_signatures=options.allow_empty_signatures, + extra_opcode_budget=options.extra_opcode_budget, + exec_trace_config=options.exec_trace_config, + txn_groups=[] + ) if options else None + result = self.atc.simulate(self.app_client.algod_client, request) + return result + + def execute(self) -> AtomicTransactionResponse: + return self.app_client.execute_atc(self.atc) + + def arc4_tuple( + self, + *, + a: tuple[int, str, int, list[int]], + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """An arc4.Tuple is a heterogeneous collection of arc4 types. + + Adds a call to `arc4_tuple((uint8,string,uint64,uint32[]))string` ABI method + + :param tuple[int, str, int, list[int]] a: The `a` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = Arc4TupleArgs( + a=a, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def create_bare( + self, + *, + on_complete: typing.Literal["no_op"] = "no_op", + transaction_parameters: algokit_utils.CreateTransactionParameters | None = None, + ) -> "Composer": + """Adds a call to create an application using the no_op bare method + + :param typing.Literal[no_op] on_complete: On completion type to use + :param algokit_utils.CreateTransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + self.app_client.compose_create( + self.atc, + call_abi_method=False, + transaction_parameters=_convert_create_transaction_parameters(transaction_parameters, on_complete), + ) + return self + + def clear_state( + self, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + app_args: list[bytes] | None = None, + ) -> "Composer": + """Adds a call to the application with on completion set to ClearState + + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :param list[bytes] | None app_args: (optional) Application args to pass""" + + self.app_client.compose_clear_state(self.atc, _convert_transaction_parameters(transaction_parameters), app_args) + return self + + +class Arc4TupleClient: + """A class for interacting with the Arc4Tuple app providing high productivity and + strongly typed methods to deploy and call the app""" + + @typing.overload + def __init__( + self, + algod_client: algosdk.v2client.algod.AlgodClient, + *, + app_id: int = 0, + signer: TransactionSigner | algokit_utils.Account | None = None, + sender: str | None = None, + suggested_params: algosdk.transaction.SuggestedParams | None = None, + template_values: algokit_utils.TemplateValueMapping | None = None, + app_name: str | None = None, + ) -> None: + ... + + @typing.overload + def __init__( + self, + algod_client: algosdk.v2client.algod.AlgodClient, + *, + creator: str | algokit_utils.Account, + indexer_client: algosdk.v2client.indexer.IndexerClient | None = None, + existing_deployments: algokit_utils.AppLookup | None = None, + signer: TransactionSigner | algokit_utils.Account | None = None, + sender: str | None = None, + suggested_params: algosdk.transaction.SuggestedParams | None = None, + template_values: algokit_utils.TemplateValueMapping | None = None, + app_name: str | None = None, + ) -> None: + ... + + def __init__( + self, + algod_client: algosdk.v2client.algod.AlgodClient, + *, + creator: str | algokit_utils.Account | None = None, + indexer_client: algosdk.v2client.indexer.IndexerClient | None = None, + existing_deployments: algokit_utils.AppLookup | None = None, + app_id: int = 0, + signer: TransactionSigner | algokit_utils.Account | None = None, + sender: str | None = None, + suggested_params: algosdk.transaction.SuggestedParams | None = None, + template_values: algokit_utils.TemplateValueMapping | None = None, + app_name: str | None = None, + ) -> None: + """ + Arc4TupleClient can be created with an app_id to interact with an existing application, alternatively + it can be created with a creator and indexer_client specified to find existing applications by name and creator. + + :param AlgodClient algod_client: AlgoSDK algod client + :param int app_id: The app_id of an existing application, to instead find the application by creator and name + use the creator and indexer_client parameters + :param str | Account creator: The address or Account of the app creator to resolve the app_id + :param IndexerClient indexer_client: AlgoSDK indexer client, only required if deploying or finding app_id by + creator and app name + :param AppLookup existing_deployments: + :param TransactionSigner | Account signer: Account or signer to use to sign transactions, if not specified and + creator was passed as an Account will use that. + :param str sender: Address to use as the sender for all transactions, will use the address associated with the + signer if not specified. + :param TemplateValueMapping template_values: Values to use for TMPL_* template variables, dictionary keys should + *NOT* include the TMPL_ prefix + :param str | None app_name: Name of application to use when deploying, defaults to name defined on the + Application Specification + """ + + self.app_spec = APP_SPEC + + # calling full __init__ signature, so ignoring mypy warning about overloads + self.app_client = algokit_utils.ApplicationClient( # type: ignore[call-overload, misc] + algod_client=algod_client, + app_spec=self.app_spec, + app_id=app_id, + creator=creator, + indexer_client=indexer_client, + existing_deployments=existing_deployments, + signer=signer, + sender=sender, + suggested_params=suggested_params, + template_values=template_values, + app_name=app_name, + ) + + @property + def algod_client(self) -> algosdk.v2client.algod.AlgodClient: + return self.app_client.algod_client + + @property + def app_id(self) -> int: + return self.app_client.app_id + + @app_id.setter + def app_id(self, value: int) -> None: + self.app_client.app_id = value + + @property + def app_address(self) -> str: + return self.app_client.app_address + + @property + def sender(self) -> str | None: + return self.app_client.sender + + @sender.setter + def sender(self, value: str) -> None: + self.app_client.sender = value + + @property + def signer(self) -> TransactionSigner | None: + return self.app_client.signer + + @signer.setter + def signer(self, value: TransactionSigner) -> None: + self.app_client.signer = value + + @property + def suggested_params(self) -> algosdk.transaction.SuggestedParams | None: + return self.app_client.suggested_params + + @suggested_params.setter + def suggested_params(self, value: algosdk.transaction.SuggestedParams | None) -> None: + self.app_client.suggested_params = value + + def arc4_tuple( + self, + *, + a: tuple[int, str, int, list[int]], + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[str]: + """An arc4.Tuple is a heterogeneous collection of arc4 types. + + Calls `arc4_tuple((uint8,string,uint64,uint32[]))string` ABI method + + :param tuple[int, str, int, list[int]] a: The `a` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[str]: The result of the transaction""" + + args = Arc4TupleArgs( + a=a, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def create_bare( + self, + *, + on_complete: typing.Literal["no_op"] = "no_op", + transaction_parameters: algokit_utils.CreateTransactionParameters | None = None, + ) -> algokit_utils.TransactionResponse: + """Creates an application using the no_op bare method + + :param typing.Literal[no_op] on_complete: On completion type to use + :param algokit_utils.CreateTransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.TransactionResponse: The result of the transaction""" + + result = self.app_client.create( + call_abi_method=False, + transaction_parameters=_convert_create_transaction_parameters(transaction_parameters, on_complete), + ) + return result + + def clear_state( + self, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + app_args: list[bytes] | None = None, + ) -> algokit_utils.TransactionResponse: + """Calls the application with on completion set to ClearState + + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :param list[bytes] | None app_args: (optional) Application args to pass + :returns algokit_utils.TransactionResponse: The result of the transaction""" + + return self.app_client.clear_state(_convert_transaction_parameters(transaction_parameters), app_args) + + def deploy( + self, + version: str | None = None, + *, + signer: TransactionSigner | None = None, + sender: str | None = None, + allow_update: bool | None = None, + allow_delete: bool | None = None, + on_update: algokit_utils.OnUpdate = algokit_utils.OnUpdate.Fail, + on_schema_break: algokit_utils.OnSchemaBreak = algokit_utils.OnSchemaBreak.Fail, + template_values: algokit_utils.TemplateValueMapping | None = None, + create_args: algokit_utils.DeployCallArgs | None = None, + update_args: algokit_utils.DeployCallArgs | None = None, + delete_args: algokit_utils.DeployCallArgs | None = None, + ) -> algokit_utils.DeployResponse: + """Deploy an application and update client to reference it. + + Idempotently deploy (create, update/delete if changed) an app against the given name via the given creator + account, including deploy-time template placeholder substitutions. + To understand the architecture decisions behind this functionality please see + + + ```{note} + If there is a breaking state schema change to an existing app (and `on_schema_break` is set to + 'ReplaceApp' the existing app will be deleted and re-created. + ``` + + ```{note} + If there is an update (different TEAL code) to an existing app (and `on_update` is set to 'ReplaceApp') + the existing app will be deleted and re-created. + ``` + + :param str version: version to use when creating or updating app, if None version will be auto incremented + :param algosdk.atomic_transaction_composer.TransactionSigner signer: signer to use when deploying app + , if None uses self.signer + :param str sender: sender address to use when deploying app, if None uses self.sender + :param bool allow_delete: Used to set the `TMPL_DELETABLE` template variable to conditionally control if an app + can be deleted + :param bool allow_update: Used to set the `TMPL_UPDATABLE` template variable to conditionally control if an app + can be updated + :param OnUpdate on_update: Determines what action to take if an application update is required + :param OnSchemaBreak on_schema_break: Determines what action to take if an application schema requirements + has increased beyond the current allocation + :param dict[str, int|str|bytes] template_values: Values to use for `TMPL_*` template variables, dictionary keys + should *NOT* include the TMPL_ prefix + :param algokit_utils.DeployCallArgs | None create_args: Arguments used when creating an application + :param algokit_utils.DeployCallArgs | None update_args: Arguments used when updating an application + :param algokit_utils.DeployCallArgs | None delete_args: Arguments used when deleting an application + :return DeployResponse: details action taken and relevant transactions + :raises DeploymentError: If the deployment failed""" + + return self.app_client.deploy( + version, + signer=signer, + sender=sender, + allow_update=allow_update, + allow_delete=allow_delete, + on_update=on_update, + on_schema_break=on_schema_break, + template_values=template_values, + create_args=_convert_deploy_args(create_args), + update_args=_convert_deploy_args(update_args), + delete_args=_convert_deploy_args(delete_args), + ) + + def compose(self, atc: AtomicTransactionComposer | None = None) -> Composer: + return Composer(self.app_client, atc or AtomicTransactionComposer()) diff --git a/projects/python-contract-examples/tests/arc4_types_integration_test.py b/projects/python-contract-examples/tests/arc4_types_integration_test.py index ab972a2..1e5681a 100644 --- a/projects/python-contract-examples/tests/arc4_types_integration_test.py +++ b/projects/python-contract-examples/tests/arc4_types_integration_test.py @@ -12,6 +12,7 @@ Arc4StaticArrayClient, ) from smart_contracts.artifacts.arc4_types.arc4_struct_client import Arc4StructClient +from smart_contracts.artifacts.arc4_types.arc4_tuple_client import Arc4TupleClient from smart_contracts.artifacts.arc4_types.arc4_types_client import Arc4TypesClient @@ -116,6 +117,36 @@ def arc4_dynamic_array_app_client( return client +@pytest.fixture(scope="session") +def arc4_tuple_app_client( + algod_client: AlgodClient, creator: AddressAndSigner, algorand: AlgorandClient +) -> Arc4TupleClient: + """Deploy the arc4 static array App and create an app client the creator will use to interact with the contract""" + + config.configure( + debug=True, + # trace_all=True, + ) + + client = Arc4TupleClient( + algod_client, + sender=creator.address, + signer=creator.signer, + ) + + client.create_bare() + + algorand.send.payment( + PayParams( + sender=creator.address, + receiver=client.app_address, + amount=1000000, # 1 Algo + ) + ) + + return client + + @pytest.fixture(scope="session") def arc4_struct_app_client( algod_client: AlgodClient, creator: AddressAndSigner, algorand: AlgorandClient @@ -303,3 +334,13 @@ def test_arc4_struct_complete_and_return_todo( # Check the result assert result.return_value.task == "walk my dogs" assert result.return_value.completed is True + + +def test_arc4_tuple( + arc4_tuple_app_client: Arc4TupleClient, +) -> None: + """Test the arc4_tuple method""" + + result = arc4_tuple_app_client.arc4_tuple(a=(4, "This is a good string.", 100, [1, 2, 3])) + + assert result.return_value == "This is a good string." From 0c4c588e3cbf373a560470e256d44418c57cd248 Mon Sep 17 00:00:00 2001 From: CiottiGiorgio Date: Tue, 5 Nov 2024 10:21:31 +0100 Subject: [PATCH 5/5] fix linting. --- .../smart_contracts/arc4_types/contract.py | 21 ++++++++++++----- .../arc4_types/deploy_config.py | 6 ----- .../tests/arc4_types_integration_test.py | 23 +++++++++++++++---- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/projects/python-contract-examples/smart_contracts/arc4_types/contract.py b/projects/python-contract-examples/smart_contracts/arc4_types/contract.py index a0cd972..8b049ca 100644 --- a/projects/python-contract-examples/smart_contracts/arc4_types/contract.py +++ b/projects/python-contract-examples/smart_contracts/arc4_types/contract.py @@ -1,7 +1,7 @@ # pyright: reportMissingModuleSource=false import typing as t -from algopy import ARC4Contract, GlobalState, UInt64, arc4, urange, String, Bytes +from algopy import ARC4Contract, GlobalState, String, UInt64, arc4, urange from algopy.arc4 import abimethod @@ -38,7 +38,9 @@ def arc4_uint_n( return arc4.UInt64(total) @abimethod() - def arc4_biguint_n(self, a: arc4.UInt128, b: arc4.UInt256, c: arc4.UInt512) -> arc4.UInt512: + def arc4_biguint_n( + self, a: arc4.UInt128, b: arc4.UInt256, c: arc4.UInt512 + ) -> arc4.UInt512: """ Integers with larger bit size are supported up to 512 bits. Ultimately, they are all represented with native BigUInt. @@ -60,7 +62,7 @@ def arc4_byte(self, a: arc4.Byte) -> arc4.Byte: @abimethod() def arc4_address_properties(self, address: arc4.Address) -> UInt64: - underlying_bytes = ( + underlying_bytes = ( # noqa: F841 address.bytes ) # This will return the underlying bytes of the address. @@ -69,7 +71,7 @@ def arc4_address_properties(self, address: arc4.Address) -> UInt64: ) # This will return the account type of the given address. bal = account.balance # returns the balance of the account - total_asset = ( + total_asset = ( # noqa: F841 account.total_assets ) # returns the total assets held in the account @@ -140,7 +142,9 @@ def arc4_dynamic_array(self, name: arc4.String) -> arc4.String: """ dynamic_string_array = arc4.DynamicArray[arc4.String](arc4.String("Hello")) - extension = arc4.DynamicArray[arc4.String](arc4.String(" world"), arc4.String(", ")) + extension = arc4.DynamicArray[arc4.String]( + arc4.String(" world"), arc4.String(", ") + ) dynamic_string_array.extend(extension) dynamic_string_array.append(name) @@ -214,7 +218,12 @@ def return_todo(self, task: arc4.String) -> Todo: class Arc4Tuple(ARC4Contract): @abimethod() - def arc4_tuple(self, a: arc4.Tuple[arc4.UInt8, arc4.String, arc4.UInt64, arc4.DynamicArray[arc4.UInt32]]) -> arc4.String: + def arc4_tuple( + self, + a: arc4.Tuple[ + arc4.UInt8, arc4.String, arc4.UInt64, arc4.DynamicArray[arc4.UInt32] + ], + ) -> arc4.String: """An arc4.Tuple is a heterogeneous collection of arc4 types.""" total = a[0].native + a[2].native diff --git a/projects/python-contract-examples/smart_contracts/arc4_types/deploy_config.py b/projects/python-contract-examples/smart_contracts/arc4_types/deploy_config.py index d5f6bdf..14805d6 100644 --- a/projects/python-contract-examples/smart_contracts/arc4_types/deploy_config.py +++ b/projects/python-contract-examples/smart_contracts/arc4_types/deploy_config.py @@ -28,9 +28,3 @@ def deploy( on_schema_break=algokit_utils.OnSchemaBreak.AppendApp, on_update=algokit_utils.OnUpdate.AppendApp, ) - name = "world" - response = app_client.hello(name=name) - logger.info( - f"Called hello on {app_spec.contract.name} ({app_client.app_id}) " - f"with name={name}, received: {response.return_value}" - ) diff --git a/projects/python-contract-examples/tests/arc4_types_integration_test.py b/projects/python-contract-examples/tests/arc4_types_integration_test.py index 1e5681a..4d4f03f 100644 --- a/projects/python-contract-examples/tests/arc4_types_integration_test.py +++ b/projects/python-contract-examples/tests/arc4_types_integration_test.py @@ -7,7 +7,10 @@ from algokit_utils.config import config from algosdk.v2client.algod import AlgodClient -from smart_contracts.artifacts.arc4_types.arc4_dynamic_array_client import Arc4DynamicArrayClient, SimulateOptions +from smart_contracts.artifacts.arc4_types.arc4_dynamic_array_client import ( + Arc4DynamicArrayClient, + SimulateOptions, +) from smart_contracts.artifacts.arc4_types.arc4_static_array_client import ( Arc4StaticArrayClient, ) @@ -283,16 +286,24 @@ def test_arc4_static_array(arc4_statc_array_app_client: Arc4StaticArrayClient) - arc4_statc_array_app_client.arc4_static_array() -def test_arc4_dynamic_array(arc4_dynamic_array_app_client: Arc4DynamicArrayClient) -> None: +def test_arc4_dynamic_array( + arc4_dynamic_array_app_client: Arc4DynamicArrayClient, +) -> None: """Test the arc4_dynamic_array method""" # Call the arc4_static_array method with simulate to avoid opcode budget constraints. - result = arc4_dynamic_array_app_client.compose().arc4_dynamic_array(name="John").simulate(SimulateOptions(extra_opcode_budget=700)) + result = ( + arc4_dynamic_array_app_client.compose() + .arc4_dynamic_array(name="John") + .simulate(SimulateOptions(extra_opcode_budget=700)) + ) assert result.abi_results[0].return_value == "Hello world, John" -def test_arc4_dynamic_bytes(arc4_dynamic_array_app_client: Arc4DynamicArrayClient) -> None: +def test_arc4_dynamic_bytes( + arc4_dynamic_array_app_client: Arc4DynamicArrayClient, +) -> None: """Test the arc4_dynamic_bytes method""" # Call the arc4_static_array method. @@ -341,6 +352,8 @@ def test_arc4_tuple( ) -> None: """Test the arc4_tuple method""" - result = arc4_tuple_app_client.arc4_tuple(a=(4, "This is a good string.", 100, [1, 2, 3])) + result = arc4_tuple_app_client.arc4_tuple( + a=(4, "This is a good string.", 100, [1, 2, 3]) + ) assert result.return_value == "This is a good string."