-
Notifications
You must be signed in to change notification settings - Fork 132
ABI Strings #278
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ABI Strings #278
Changes from all commits
efbe1e5
7db17ca
4055424
12a36a6
af7967d
3e7fdfd
41ab811
1c22d14
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| from .array_static import StaticArray, StaticArrayTypeSpec | ||
| from .uint import ByteTypeSpec | ||
| from ..expr import Expr | ||
|
|
||
| ADDRESS_LENGTH = 32 | ||
|
|
||
|
|
||
| class AddressTypeSpec(StaticArrayTypeSpec): | ||
| def __init__(self) -> None: | ||
| super().__init__(ByteTypeSpec(), ADDRESS_LENGTH) | ||
|
|
||
| def new_instance(self) -> "Address": | ||
| return Address() | ||
|
|
||
| def __str__(self) -> str: | ||
| return "address" | ||
|
|
||
|
|
||
| AddressTypeSpec.__module__ = "pyteal" | ||
|
|
||
|
|
||
| class Address(StaticArray): | ||
| def __init__(self) -> None: | ||
| super().__init__(AddressTypeSpec(), ADDRESS_LENGTH) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't really work, since Probably you should modify |
||
|
|
||
| def type_spec(self) -> AddressTypeSpec: | ||
| return AddressTypeSpec() | ||
|
|
||
| def get(self) -> Expr: | ||
| return self.stored_value.load() | ||
|
|
||
|
|
||
| Address.__module__ = "pyteal" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| from ... import * | ||
|
|
||
| options = CompileOptions(version=5) | ||
|
|
||
|
|
||
| def test_AddressTypeSpec_str(): | ||
| assert str(abi.AddressTypeSpec()) == "address" | ||
|
|
||
|
|
||
| def test_AddressTypeSpec_is_dynamic(): | ||
| assert (abi.AddressTypeSpec()).is_dynamic() is False | ||
|
|
||
|
|
||
| def test_AddressTypeSpec_byte_length_static(): | ||
| assert (abi.AddressTypeSpec()).byte_length_static() == abi.ADDRESS_LENGTH | ||
|
|
||
|
|
||
| def test_AddressTypeSpec_new_instance(): | ||
| assert isinstance(abi.AddressTypeSpec().new_instance(), abi.Address) | ||
|
|
||
|
|
||
| def test_AddressTypeSpec_eq(): | ||
| assert abi.AddressTypeSpec() == abi.AddressTypeSpec() | ||
|
|
||
| for otherType in ( | ||
| abi.ByteTypeSpec, | ||
barnjamin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| abi.StaticArrayTypeSpec(abi.ByteTypeSpec(), 31), | ||
barnjamin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| abi.DynamicArrayTypeSpec(abi.ByteTypeSpec()), | ||
| ): | ||
| assert abi.AddressTypeSpec() != otherType | ||
|
|
||
|
|
||
| def test_Address_encode(): | ||
| value = abi.Address() | ||
| expr = value.encode() | ||
| assert expr.type_of() == TealType.bytes | ||
| assert expr.has_return() is False | ||
jasonpaulos marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| expected = TealSimpleBlock([TealOp(expr, Op.load, value.stored_value.slot)]) | ||
| actual, _ = expr.__teal__(options) | ||
| assert actual == expected | ||
|
|
||
|
|
||
| def test_Address_decode(): | ||
| from os import urandom | ||
|
|
||
| value = abi.Address() | ||
| for value_to_set in [urandom(abi.ADDRESS_LENGTH) for x in range(10)]: | ||
barnjamin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| expr = value.decode(Bytes(value_to_set)) | ||
|
|
||
| assert expr.type_of() == TealType.none | ||
| assert expr.has_return() is False | ||
|
|
||
| expected = TealSimpleBlock( | ||
| [ | ||
| TealOp(None, Op.byte, f"0x{value_to_set.hex()}"), | ||
| TealOp(None, Op.store, value.stored_value.slot), | ||
| ] | ||
| ) | ||
| actual, _ = expr.__teal__(options) | ||
| actual.addIncoming() | ||
| actual = TealBlock.NormalizeBlocks(actual) | ||
|
|
||
| with TealComponent.Context.ignoreExprEquality(): | ||
| assert actual == expected | ||
|
|
||
|
|
||
| def test_Address_get(): | ||
| value = abi.Address() | ||
| expr = value.get() | ||
| assert expr.type_of() == TealType.bytes | ||
| assert expr.has_return() is False | ||
|
|
||
| expected = TealSimpleBlock([TealOp(expr, Op.load, value.stored_value.slot)]) | ||
| actual, _ = expr.__teal__(options) | ||
| assert actual == expected | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| from .array_dynamic import DynamicArray, DynamicArrayTypeSpec | ||
| from .uint import ByteTypeSpec, Uint16TypeSpec | ||
| from .util import substringForDecoding | ||
|
|
||
| from ..int import Int | ||
| from ..expr import Expr | ||
|
|
||
|
|
||
| class StringTypeSpec(DynamicArrayTypeSpec): | ||
| def __init__(self) -> None: | ||
| super().__init__(ByteTypeSpec()) | ||
|
|
||
| def new_instance(self) -> "String": | ||
| return String() | ||
|
|
||
| def __str__(self) -> str: | ||
| return "string" | ||
|
|
||
|
|
||
| StringTypeSpec.__module__ = "pyteal" | ||
|
|
||
|
|
||
| class String(DynamicArray): | ||
| def __init__(self) -> None: | ||
| super().__init__(StringTypeSpec()) | ||
|
|
||
| def type_spec(self) -> StringTypeSpec: | ||
| return StringTypeSpec() | ||
|
|
||
| def get(self) -> Expr: | ||
| return substringForDecoding( | ||
| self.stored_value.load(), | ||
| startIndex=Int(Uint16TypeSpec().byte_length_static()), | ||
| ) | ||
barnjamin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| String.__module__ = "pyteal" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| from ... import * | ||
|
|
||
| options = CompileOptions(version=5) | ||
|
|
||
|
|
||
| def test_StringTypeSpec_str(): | ||
| assert str(abi.StringTypeSpec()) == "string" | ||
|
|
||
|
|
||
| def test_StringTypeSpec_is_dynamic(): | ||
| assert (abi.StringTypeSpec()).is_dynamic() | ||
tzaffi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| def test_StringTypeSpec_new_instance(): | ||
| assert isinstance(abi.StringTypeSpec().new_instance(), abi.String) | ||
|
|
||
|
|
||
| def test_StringTypeSpec_eq(): | ||
| assert abi.StringTypeSpec() == abi.StringTypeSpec() | ||
|
|
||
| for otherType in ( | ||
| abi.ByteTypeSpec, | ||
| abi.StaticArrayTypeSpec(abi.ByteTypeSpec(), 1), | ||
| abi.DynamicArrayTypeSpec(abi.Uint8TypeSpec()), | ||
barnjamin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ): | ||
| assert abi.StringTypeSpec() != otherType | ||
|
|
||
|
|
||
| def test_String_encode(): | ||
| value = abi.String() | ||
| expr = value.encode() | ||
| assert expr.type_of() == TealType.bytes | ||
| assert expr.has_return() is False | ||
|
|
||
| expected = TealSimpleBlock([TealOp(expr, Op.load, value.stored_value.slot)]) | ||
| actual, _ = expr.__teal__(options) | ||
| assert actual == expected | ||
|
|
||
|
|
||
| def test_String_decode(): | ||
| import random | ||
| from os import urandom | ||
|
|
||
| value = abi.String() | ||
| for value_to_set in [urandom(random.randint(0, 50)) for x in range(10)]: | ||
barnjamin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| expr = value.decode(Bytes(value_to_set)) | ||
|
|
||
| assert expr.type_of() == TealType.none | ||
| assert expr.has_return() is False | ||
|
|
||
| expected = TealSimpleBlock( | ||
| [ | ||
| TealOp(None, Op.byte, f"0x{value_to_set.hex()}"), | ||
| TealOp(None, Op.store, value.stored_value.slot), | ||
| ] | ||
| ) | ||
| actual, _ = expr.__teal__(options) | ||
| actual.addIncoming() | ||
| actual = TealBlock.NormalizeBlocks(actual) | ||
|
|
||
| with TealComponent.Context.ignoreExprEquality(): | ||
| assert actual == expected | ||
|
|
||
|
|
||
| def test_String_get(): | ||
| value = abi.String() | ||
| expr = value.get() | ||
| assert expr.type_of() == TealType.bytes | ||
| assert expr.has_return() is False | ||
|
|
||
| expected = TealSimpleBlock( | ||
| [TealOp(expr, Op.load, value.stored_value.slot), TealOp(None, Op.extract, 2, 0)] | ||
| ) | ||
| actual, _ = expr.__teal__(options) | ||
jasonpaulos marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| actual.addIncoming() | ||
| actual = TealBlock.NormalizeBlocks(actual) | ||
|
|
||
| with TealComponent.Context.ignoreExprEquality(): | ||
| assert actual == expected | ||
Uh oh!
There was an error while loading. Please reload this page.