From 119cc5773c3b02e8195f199a35b24753b282b82c Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Wed, 16 Oct 2019 14:50:52 -0400 Subject: [PATCH 01/35] .gitignore migrations/0x_ganache_snapshot --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 934fdf50d0..d99444d636 100644 --- a/.gitignore +++ b/.gitignore @@ -171,3 +171,6 @@ python-packages/json_schemas/src/zero_ex/json_schemas/schemas packages/*/docs/README.md .DS_Store + +# the snapshot that gets built for migrations sure does have a ton of files +packages/migrations/0x_ganache_snapshot* From ed7c6bc9f9c8cf8ef6ce4a46bd25612c50655ba5 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Wed, 16 Oct 2019 14:51:20 -0400 Subject: [PATCH 02/35] .gitignore new-ish Python contract wrappers These should have been added back when we started generating these wrappers. --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index d99444d636..14898c770c 100644 --- a/.gitignore +++ b/.gitignore @@ -130,6 +130,7 @@ contracts/erc1155/generated-wrappers/ contracts/extensions/generated-wrappers/ contracts/exchange-forwarder/generated-wrappers/ contracts/dev-utils/generated-wrappers/ +python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dev_utils/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_token/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/asset_proxy_owner/__init__.py @@ -138,6 +139,8 @@ python-packages/contract_wrappers/src/zero_ex/contract_wrappers/coordinator_regi python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dummy_erc20_token/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dummy_erc721_token/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dutch_auction/__init__.py +python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_mintable/__init__.py +python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_token/__init__.py @@ -148,6 +151,7 @@ python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_validator/__in python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_wallet/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/multi_asset_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_validator/__init__.py +python-packages/contract_wrappers/src/zero_ex/contract_wrappers/static_call_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/weth9/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/zrx_token/__init__.py From 4206e6df5ced57ecd8671b1bfdfbd0a92c062223 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Wed, 16 Oct 2019 15:11:26 -0400 Subject: [PATCH 03/35] rm superfluous contract artifact in Python package All of the contract artifacts were removed from the Python package recently, because now they're copied from the monorepo/packages area as an automated build step. Somehow this one artifact slipped through the cracks. --- .../artifacts/EthBalanceChecker.json | 23 ------------------- 1 file changed, 23 deletions(-) delete mode 100644 python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/EthBalanceChecker.json diff --git a/python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/EthBalanceChecker.json b/python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/EthBalanceChecker.json deleted file mode 100644 index a0708e3ee8..0000000000 --- a/python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/EthBalanceChecker.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "schemaVersion": "2.0.0", - "contractName": "EthBalanceChecker", - "compilerOutput": { - "abi": [ - { - "constant": true, - "inputs": [{ "name": "addresses", "type": "address[]" }], - "name": "getEthBalances", - "outputs": [{ "name": "", "type": "uint256[]" }], - "payable": false, - "stateMutability": "view", - "type": "function" - } - ], - "evm": { - "bytecode": { - "object": "0x608060405234801561001057600080fd5b506101e5806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a0901e5114610030575b600080fd5b6100d36004803603602081101561004657600080fd5b81019060208101813564010000000081111561006157600080fd5b82018360208201111561007357600080fd5b8035906020019184602083028401116401000000008311171561009557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610123945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561010f5781810151838201526020016100f7565b505050509050019250505060405180910390f35b6060808251604051908082528060200260200182016040528015610151578160200160208202803883390190505b50905060005b835181146101a95783818151811061016b57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff163182828151811061019657fe5b6020908102919091010152600101610157565b509291505056fea265627a7a72305820c934dc478ccdc0f8a6d0fb6135610c21efcb23a2fd5075c6d2c4891b449b70f964736f6c63430005090032" - } - } - }, - "networks": {} -} From 363363aee28642b3cbdef18b77c886ebb60032c8 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 18 Oct 2019 16:03:24 -0400 Subject: [PATCH 04/35] Eliminate circular dependency This was preventing the Exchange wrapper from ever importing its validator! --- .../contract_wrappers/exchange/types.py | 139 ----------------- .../contract_wrappers/exchange/validator.py | 2 +- .../contract_wrappers/order_conversions.py | 144 ++++++++++++++++++ python-packages/json_schemas/setup.py | 1 - .../src/zero_ex/json_schemas/__init__.py | 51 ++++--- .../src/zero_ex/order_utils/__init__.py | 2 +- .../src/zero_ex/sra_client/__init__.py | 3 +- 7 files changed, 175 insertions(+), 167 deletions(-) create mode 100644 python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/types.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/types.py index 3bdb3e4e75..21ce43df03 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/types.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/types.py @@ -11,12 +11,6 @@ converting Exchange structs between JSON and Python objects. """ -from copy import copy -from typing import cast, Dict - -from eth_utils import remove_0x_prefix - -from zero_ex.json_schemas import assert_valid from . import ( Tuple0xbb41e5b3, @@ -65,136 +59,3 @@ class OrderInfo(Tuple0xb1e4a1ae): """ -def order_to_jsdict( - order: Order, - exchange_address="0x0000000000000000000000000000000000000000", - signature: str = None, -) -> dict: - """Convert a Web3-compatible order struct to a JSON-schema-compatible dict. - - More specifically, do explicit decoding for the `bytes`:code: fields, and - convert numerics to strings. - - >>> import pprint - >>> pprint.pprint(order_to_jsdict( - ... { - ... 'makerAddress': "0x0000000000000000000000000000000000000000", - ... 'takerAddress': "0x0000000000000000000000000000000000000000", - ... 'feeRecipientAddress': - ... "0x0000000000000000000000000000000000000000", - ... 'senderAddress': "0x0000000000000000000000000000000000000000", - ... 'makerAssetAmount': 1, - ... 'takerAssetAmount': 1, - ... 'makerFee': 0, - ... 'takerFee': 0, - ... 'expirationTimeSeconds': 1, - ... 'salt': 1, - ... 'makerAssetData': (0).to_bytes(1, byteorder='big') * 20, - ... 'takerAssetData': (0).to_bytes(1, byteorder='big') * 20, - ... }, - ... )) - {'exchangeAddress': '0x0000000000000000000000000000000000000000', - 'expirationTimeSeconds': '1', - 'feeRecipientAddress': '0x0000000000000000000000000000000000000000', - 'makerAddress': '0x0000000000000000000000000000000000000000', - 'makerAssetAmount': '1', - 'makerAssetData': '0x0000000000000000000000000000000000000000', - 'makerFee': '0', - 'salt': '1', - 'senderAddress': '0x0000000000000000000000000000000000000000', - 'takerAddress': '0x0000000000000000000000000000000000000000', - 'takerAssetAmount': '1', - 'takerAssetData': '0x0000000000000000000000000000000000000000', - 'takerFee': '0'} - """ - jsdict = cast(Dict, copy(order)) - - # encode bytes fields - jsdict["makerAssetData"] = "0x" + order["makerAssetData"].hex() - jsdict["takerAssetData"] = "0x" + order["takerAssetData"].hex() - - jsdict["exchangeAddress"] = exchange_address - - jsdict["expirationTimeSeconds"] = str(order["expirationTimeSeconds"]) - - jsdict["makerAssetAmount"] = str(order["makerAssetAmount"]) - jsdict["takerAssetAmount"] = str(order["takerAssetAmount"]) - - jsdict["makerFee"] = str(order["makerFee"]) - jsdict["takerFee"] = str(order["takerFee"]) - - jsdict["salt"] = str(order["salt"]) - - if signature is not None: - jsdict["signature"] = signature - - assert_valid(jsdict, "/orderSchema") - - return jsdict - - -def jsdict_to_order(jsdict: dict) -> Order: - r"""Convert a JSON-schema-compatible dict order to a Web3-compatible struct. - - More specifically, do explicit encoding of the `bytes`:code: fields, and - parse integers from strings. - - >>> import pprint - >>> pprint.pprint(jsdict_to_order( - ... { - ... 'makerAddress': "0x0000000000000000000000000000000000000000", - ... 'takerAddress': "0x0000000000000000000000000000000000000000", - ... 'feeRecipientAddress': "0x0000000000000000000000000000000000000000", - ... 'senderAddress': "0x0000000000000000000000000000000000000000", - ... 'makerAssetAmount': "1000000000000000000", - ... 'takerAssetAmount': "1000000000000000000", - ... 'makerFee': "0", - ... 'takerFee': "0", - ... 'expirationTimeSeconds': "12345", - ... 'salt': "12345", - ... 'makerAssetData': "0x0000000000000000000000000000000000000000", - ... 'takerAssetData': "0x0000000000000000000000000000000000000000", - ... 'exchangeAddress': "0x0000000000000000000000000000000000000000", - ... }, - ... )) - {'expirationTimeSeconds': 12345, - 'feeRecipientAddress': '0x0000000000000000000000000000000000000000', - 'makerAddress': '0x0000000000000000000000000000000000000000', - 'makerAssetAmount': 1000000000000000000, - 'makerAssetData': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' - b'\x00\x00\x00\x00\x00\x00\x00\x00', - 'makerFee': 0, - 'salt': 12345, - 'senderAddress': '0x0000000000000000000000000000000000000000', - 'takerAddress': '0x0000000000000000000000000000000000000000', - 'takerAssetAmount': 1000000000000000000, - 'takerAssetData': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' - b'\x00\x00\x00\x00\x00\x00\x00\x00', - 'takerFee': 0} - """ # noqa: E501 (line too long) - assert_valid(jsdict, "/orderSchema") - - order = cast(Order, copy(jsdict)) - - order["makerAssetData"] = bytes.fromhex( - remove_0x_prefix(jsdict["makerAssetData"]) - ) - order["takerAssetData"] = bytes.fromhex( - remove_0x_prefix(jsdict["takerAssetData"]) - ) - - order["makerAssetAmount"] = int(jsdict["makerAssetAmount"]) - order["takerAssetAmount"] = int(jsdict["takerAssetAmount"]) - - order["makerFee"] = int(jsdict["makerFee"]) - order["takerFee"] = int(jsdict["takerFee"]) - - order["expirationTimeSeconds"] = int(jsdict["expirationTimeSeconds"]) - - order["salt"] = int(jsdict["salt"]) - - del order["exchangeAddress"] # type: ignore - # silence mypy pending release of - # https://github.com/python/mypy/issues/3550 - - return order diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py index 2479ee8179..12726336b5 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py @@ -5,9 +5,9 @@ from web3.providers.base import BaseProvider from zero_ex import json_schemas +from zero_ex.contract_wrappers.order_conversions import order_to_jsdict from ..bases import Validator -from .types import order_to_jsdict class ExchangeValidator(Validator): diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py new file mode 100644 index 0000000000..c1ade7b9a1 --- /dev/null +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py @@ -0,0 +1,144 @@ +"""Utilities to convert between JSON and Python-native objects.""" + +from copy import copy +from typing import cast, Dict + +from eth_utils import remove_0x_prefix + +from zero_ex.json_schemas import assert_valid +from zero_ex.contract_wrappers.exchange.types import Order + + +def order_to_jsdict( + order: Order, + exchange_address="0x0000000000000000000000000000000000000000", + signature: str = None, +) -> dict: + """Convert a Web3-compatible order struct to a JSON-schema-compatible dict. + + More specifically, do explicit decoding for the `bytes`:code: fields, and + convert numerics to strings. + + >>> import pprint + >>> pprint.pprint(order_to_jsdict( + ... { + ... 'makerAddress': "0x0000000000000000000000000000000000000000", + ... 'takerAddress': "0x0000000000000000000000000000000000000000", + ... 'feeRecipientAddress': + ... "0x0000000000000000000000000000000000000000", + ... 'senderAddress': "0x0000000000000000000000000000000000000000", + ... 'makerAssetAmount': 1, + ... 'takerAssetAmount': 1, + ... 'makerFee': 0, + ... 'takerFee': 0, + ... 'expirationTimeSeconds': 1, + ... 'salt': 1, + ... 'makerAssetData': (0).to_bytes(1, byteorder='big') * 20, + ... 'takerAssetData': (0).to_bytes(1, byteorder='big') * 20, + ... }, + ... )) + {'exchangeAddress': '0x0000000000000000000000000000000000000000', + 'expirationTimeSeconds': '1', + 'feeRecipientAddress': '0x0000000000000000000000000000000000000000', + 'makerAddress': '0x0000000000000000000000000000000000000000', + 'makerAssetAmount': '1', + 'makerAssetData': '0x0000000000000000000000000000000000000000', + 'makerFee': '0', + 'salt': '1', + 'senderAddress': '0x0000000000000000000000000000000000000000', + 'takerAddress': '0x0000000000000000000000000000000000000000', + 'takerAssetAmount': '1', + 'takerAssetData': '0x0000000000000000000000000000000000000000', + 'takerFee': '0'} + """ + jsdict = cast(Dict, copy(order)) + + # encode bytes fields + jsdict["makerAssetData"] = "0x" + order["makerAssetData"].hex() + jsdict["takerAssetData"] = "0x" + order["takerAssetData"].hex() + + jsdict["exchangeAddress"] = exchange_address + + jsdict["expirationTimeSeconds"] = str(order["expirationTimeSeconds"]) + + jsdict["makerAssetAmount"] = str(order["makerAssetAmount"]) + jsdict["takerAssetAmount"] = str(order["takerAssetAmount"]) + + jsdict["makerFee"] = str(order["makerFee"]) + jsdict["takerFee"] = str(order["takerFee"]) + + jsdict["salt"] = str(order["salt"]) + + if signature is not None: + jsdict["signature"] = signature + + assert_valid(jsdict, "/orderSchema") + + return jsdict + + +def jsdict_to_order(jsdict: dict) -> Order: + r"""Convert a JSON-schema-compatible dict order to a Web3-compatible struct. + + More specifically, do explicit encoding of the `bytes`:code: fields, and + parse integers from strings. + + >>> import pprint + >>> pprint.pprint(jsdict_to_order( + ... { + ... 'makerAddress': "0x0000000000000000000000000000000000000000", + ... 'takerAddress': "0x0000000000000000000000000000000000000000", + ... 'feeRecipientAddress': "0x0000000000000000000000000000000000000000", + ... 'senderAddress': "0x0000000000000000000000000000000000000000", + ... 'makerAssetAmount': "1000000000000000000", + ... 'takerAssetAmount': "1000000000000000000", + ... 'makerFee': "0", + ... 'takerFee': "0", + ... 'expirationTimeSeconds': "12345", + ... 'salt': "12345", + ... 'makerAssetData': "0x0000000000000000000000000000000000000000", + ... 'takerAssetData': "0x0000000000000000000000000000000000000000", + ... 'exchangeAddress': "0x0000000000000000000000000000000000000000", + ... }, + ... )) + {'expirationTimeSeconds': 12345, + 'feeRecipientAddress': '0x0000000000000000000000000000000000000000', + 'makerAddress': '0x0000000000000000000000000000000000000000', + 'makerAssetAmount': 1000000000000000000, + 'makerAssetData': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00', + 'makerFee': 0, + 'salt': 12345, + 'senderAddress': '0x0000000000000000000000000000000000000000', + 'takerAddress': '0x0000000000000000000000000000000000000000', + 'takerAssetAmount': 1000000000000000000, + 'takerAssetData': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00', + 'takerFee': 0} + """ # noqa: E501 (line too long) + assert_valid(jsdict, "/orderSchema") + + order = cast(Order, copy(jsdict)) + + order["makerAssetData"] = bytes.fromhex( + remove_0x_prefix(jsdict["makerAssetData"]) + ) + order["takerAssetData"] = bytes.fromhex( + remove_0x_prefix(jsdict["takerAssetData"]) + ) + + order["makerAssetAmount"] = int(jsdict["makerAssetAmount"]) + order["takerAssetAmount"] = int(jsdict["takerAssetAmount"]) + + order["makerFee"] = int(jsdict["makerFee"]) + order["takerFee"] = int(jsdict["takerFee"]) + + order["expirationTimeSeconds"] = int(jsdict["expirationTimeSeconds"]) + + order["salt"] = int(jsdict["salt"]) + + del order["exchangeAddress"] # type: ignore + # silence mypy pending release of + # https://github.com/python/mypy/issues/3550 + + return order diff --git a/python-packages/json_schemas/setup.py b/python-packages/json_schemas/setup.py index 650e2d8469..efa9056833 100755 --- a/python-packages/json_schemas/setup.py +++ b/python-packages/json_schemas/setup.py @@ -162,7 +162,6 @@ def run(self): extras_require={ "dev": [ "0x-contract-addresses", - "0x-contract-wrappers", "bandit", "black", "coverage", diff --git a/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py b/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py index e74717d6ea..01f6ccb4bd 100644 --- a/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py +++ b/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py @@ -61,35 +61,38 @@ def assert_valid(data: Mapping, schema_id: str) -> None: >>> from zero_ex.json_schemas import assert_valid >>> from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId - >>> from zero_ex.contract_wrappers.exchange.types import ( - ... Order, order_to_jsdict - ... ) >>> from zero_ex.order_utils import asset_data_utils >>> from eth_utils import remove_0x_prefix >>> import random >>> from datetime import datetime, timedelta - >>> example_order = Order( - ... makerAddress='0x5409ed021d9299bf6814279a6a1411a7e866a631', - ... takerAddress='0x0000000000000000000000000000000000000000', - ... senderAddress='0x0000000000000000000000000000000000000000', - ... exchangeAddress='0x4f833a24e1f95d70f028921e27040ca56e09ab0b', - ... feeRecipientAddress='0x0000000000000000000000000000000000000000', - ... makerAssetData=asset_data_utils.encode_erc20( - ... NETWORK_TO_ADDRESSES[NetworkId.MAINNET].zrx_token - ... ), - ... takerAssetData=asset_data_utils.encode_erc20( - ... NETWORK_TO_ADDRESSES[NetworkId.MAINNET].ether_token - ... ), - ... salt=random.randint(1, 100000000000000000), - ... makerFee=0, - ... takerFee=0, - ... makerAssetAmount=1000000000000000000, - ... takerAssetAmount=500000000000000000000, - ... expirationTimeSeconds=round( - ... (datetime.utcnow() + timedelta(days=1)).timestamp() - ... ) + >>> assert_valid( + ... {'makerAddress': '0x5409ed021d9299bf6814279a6a1411a7e866a631', + ... 'takerAddress': '0x0000000000000000000000000000000000000000', + ... 'senderAddress': '0x0000000000000000000000000000000000000000', + ... 'exchangeAddress': '0x4f833a24e1f95d70f028921e27040ca56e09ab0b', + ... 'feeRecipientAddress': ( + ... '0x0000000000000000000000000000000000000000' + ... ), + ... 'makerAssetData': ( + ... NETWORK_TO_ADDRESSES[NetworkId.MAINNET].zrx_token + ... ), + ... 'takerAssetData': ( + ... NETWORK_TO_ADDRESSES[NetworkId.MAINNET].ether_token + ... ), + ... 'salt': random.randint(1, 100000000000000000), + ... 'makerFee': 0, + ... 'makerFeeAssetData': '0x' + '00'*20, + ... 'takerFee': 0, + ... 'takerFeeAssetData': '0x' + '00'*20, + ... 'makerAssetAmount': 1000000000000000000, + ... 'takerAssetAmount': 500000000000000000000, + ... 'expirationTimeSeconds': round( + ... (datetime.utcnow() + timedelta(days=1)).timestamp() + ... ), + ... 'chainId': 50 + ... }, + ... "/orderSchema" ... ) - >>> assert_valid(order_to_jsdict(example_order), "/orderSchema") """ _, schema = _LOCAL_RESOLVER.resolve(schema_id) jsonschema.validate(data, schema, resolver=_LOCAL_RESOLVER) diff --git a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py index 62306ce057..0494f41044 100644 --- a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py +++ b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py @@ -31,7 +31,7 @@ from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId import zero_ex.contract_artifacts -from zero_ex.contract_wrappers.exchange.types import Order, order_to_jsdict +from zero_ex.contract_wrappers.order_conversions import order_to_jsdict from zero_ex.dev_utils.type_assertions import ( assert_is_address, assert_is_hex_string, diff --git a/python-packages/sra_client/src/zero_ex/sra_client/__init__.py b/python-packages/sra_client/src/zero_ex/sra_client/__init__.py index a1ccdd1ff8..31aeb30f57 100644 --- a/python-packages/sra_client/src/zero_ex/sra_client/__init__.py +++ b/python-packages/sra_client/src/zero_ex/sra_client/__init__.py @@ -105,7 +105,8 @@ Post an order for our Maker to trade ZRX for WETH: ->>> from zero_ex.contract_wrappers.exchange.types import Order, order_to_jsdict +>>> from zero_ex.contract_wrappers.exchange.types import Order +>>> from zero_ex.contract_wrappers.order_conversions import order_to_jsdict >>> from zero_ex.order_utils import ( ... asset_data_utils, ... sign_hash) From 7b5bf319f021e556c283ae8d2066bc32aee19068 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 22 Oct 2019 18:45:18 -0400 Subject: [PATCH 05/35] Improve output of monorepo-level parallel script - Capture stderr (and have it included in stdout) so that it doesn't leak onto the console for commands that didn't actually fail. - Include all error output in the Exception object (eliminate print statement). --- python-packages/parallel | 11 +++++++---- python-packages/parallel_without_sra_client | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/python-packages/parallel b/python-packages/parallel index c127d3cf5f..0f374bb950 100755 --- a/python-packages/parallel +++ b/python-packages/parallel @@ -22,7 +22,7 @@ $ ./parallel pip uninstall $(basename $(pwd)) from concurrent.futures import ProcessPoolExecutor, wait from os import chdir -from subprocess import CalledProcessError, check_output +from subprocess import CalledProcessError, check_output, STDOUT from sys import argv PACKAGES = [ @@ -38,11 +38,14 @@ PACKAGES = [ def run_cmd_on_package(package: str): """cd to the package dir, ./setup.py lint, cd ..""" chdir(package) + command = f"{' '.join(argv[1:])}" try: - check_output(f"{' '.join(argv[1:])}".split()) + check_output(command.split(), stderr=STDOUT) except CalledProcessError as error: - print(f"standard output from command:\n{error.output.decode('utf-8')}") - raise RuntimeError(f"Above exception raised in {package}, ") from error + raise RuntimeError( + f"Failure return code received from command `{command}` in package" + + f" {package}, which produced the following output:\n" + + f"{error.output.decode('utf-8')}") from error finally: chdir("..") diff --git a/python-packages/parallel_without_sra_client b/python-packages/parallel_without_sra_client index b0744824bc..206415b758 100755 --- a/python-packages/parallel_without_sra_client +++ b/python-packages/parallel_without_sra_client @@ -22,7 +22,7 @@ $ ./parallel pip uninstall $(basename $(pwd)) from concurrent.futures import ProcessPoolExecutor, wait from os import chdir -from subprocess import CalledProcessError, check_output +from subprocess import CalledProcessError, check_output, STDOUT from sys import argv PACKAGES = [ @@ -37,11 +37,14 @@ PACKAGES = [ def run_cmd_on_package(package: str): """cd to the package dir, ./setup.py lint, cd ..""" chdir(package) + command = f"{' '.join(argv[1:])}" try: - check_output(f"{' '.join(argv[1:])}".split()) + check_output(command.split(), stderr=STDOUT) except CalledProcessError as error: - print(f"standard output from command:\n{error.output.decode('utf-8')}") - raise RuntimeError(f"Above exception raised in {package}, ") from error + raise RuntimeError( + f"Failure return code received from command `{command}` in package" + + f" {package}, which produced the following output:\n" + + f"{error.output.decode('utf-8')}") from error finally: chdir("..") From 923edcd9e19e494390eeaf2306954b37e77bb1cf Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 22 Oct 2019 23:47:41 -0400 Subject: [PATCH 06/35] Silence new versions of linters Newer versions care about this stuff. Old versions didn't, and we don't either. --- python-packages/contract_addresses/setup.py | 6 +++++- python-packages/contract_addresses/src/zero_ex/__init__.py | 2 +- python-packages/contract_artifacts/setup.py | 6 +++++- python-packages/contract_artifacts/src/zero_ex/__init__.py | 2 +- python-packages/contract_wrappers/setup.py | 6 +++++- python-packages/contract_wrappers/src/zero_ex/__init__.py | 2 +- .../src/zero_ex/contract_wrappers/tx_params.py | 5 ++++- python-packages/json_schemas/setup.py | 6 +++++- python-packages/json_schemas/src/zero_ex/__init__.py | 2 +- python-packages/middlewares/setup.py | 6 +++++- python-packages/middlewares/src/zero_ex/__init__.py | 2 +- python-packages/order_utils/setup.py | 6 +++++- python-packages/order_utils/src/zero_ex/__init__.py | 2 +- python-packages/sra_client/setup.py | 5 +++++ python-packages/sra_client/src/zero_ex/__init__.py | 2 +- 15 files changed, 46 insertions(+), 14 deletions(-) diff --git a/python-packages/contract_addresses/setup.py b/python-packages/contract_addresses/setup.py index 1e1d811f6e..a84ee3551c 100755 --- a/python-packages/contract_addresses/setup.py +++ b/python-packages/contract_addresses/setup.py @@ -2,10 +2,14 @@ """setuptools module for contract_addresses package.""" +# pylint: disable=import-outside-toplevel +# we import things outside of top-level because 3rd party libs may not yet be +# installed when you invoke this script + import subprocess # nosec from shutil import rmtree from os import environ, path -from sys import argv +from sys import argv, exit # pylint: disable=redefined-builtin from distutils.command.clean import clean import distutils.command.build_py diff --git a/python-packages/contract_addresses/src/zero_ex/__init__.py b/python-packages/contract_addresses/src/zero_ex/__init__.py index e90d833db6..3fe1300cfb 100644 --- a/python-packages/contract_addresses/src/zero_ex/__init__.py +++ b/python-packages/contract_addresses/src/zero_ex/__init__.py @@ -1,2 +1,2 @@ """0x Python API.""" -__import__("pkg_resources").declare_namespace(__name__) +__import__("pkg_resources").declare_namespace(__name__) # type: ignore diff --git a/python-packages/contract_artifacts/setup.py b/python-packages/contract_artifacts/setup.py index 101fb2fc41..60cd883979 100755 --- a/python-packages/contract_artifacts/setup.py +++ b/python-packages/contract_artifacts/setup.py @@ -2,10 +2,14 @@ """setuptools module for contract_artifacts package.""" +# pylint: disable=import-outside-toplevel +# we import things outside of top-level because 3rd party libs may not yet be +# installed when you invoke this script + import subprocess # nosec from shutil import copytree, rmtree from os import environ, path -from sys import argv +from sys import argv, exit # pylint: disable=redefined-builtin from distutils.command.clean import clean import distutils.command.build_py diff --git a/python-packages/contract_artifacts/src/zero_ex/__init__.py b/python-packages/contract_artifacts/src/zero_ex/__init__.py index e90d833db6..3fe1300cfb 100644 --- a/python-packages/contract_artifacts/src/zero_ex/__init__.py +++ b/python-packages/contract_artifacts/src/zero_ex/__init__.py @@ -1,2 +1,2 @@ """0x Python API.""" -__import__("pkg_resources").declare_namespace(__name__) +__import__("pkg_resources").declare_namespace(__name__) # type: ignore diff --git a/python-packages/contract_wrappers/setup.py b/python-packages/contract_wrappers/setup.py index 58ad0aba81..a3c32fa126 100755 --- a/python-packages/contract_wrappers/setup.py +++ b/python-packages/contract_wrappers/setup.py @@ -2,11 +2,15 @@ """setuptools module for contract_wrappers package.""" +# pylint: disable=import-outside-toplevel +# we import things outside of top-level because 3rd party libs may not yet be +# installed when you invoke this script + import subprocess # nosec from shutil import rmtree from os import environ, path, remove from pathlib import Path -from sys import argv +from sys import argv, exit # pylint: disable=redefined-builtin from distutils.command.clean import clean import distutils.command.build_py diff --git a/python-packages/contract_wrappers/src/zero_ex/__init__.py b/python-packages/contract_wrappers/src/zero_ex/__init__.py index e90d833db6..3fe1300cfb 100644 --- a/python-packages/contract_wrappers/src/zero_ex/__init__.py +++ b/python-packages/contract_wrappers/src/zero_ex/__init__.py @@ -1,2 +1,2 @@ """0x Python API.""" -__import__("pkg_resources").declare_namespace(__name__) +__import__("pkg_resources").declare_namespace(__name__) # type: ignore diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/tx_params.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/tx_params.py index 4b864898ec..226a1f908e 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/tx_params.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/tx_params.py @@ -23,7 +23,7 @@ class TxParams: gas: Optional[int] = attr.ib( default=None, converter=attr.converters.optional(int) ) - gasPrice: Optional[int] = attr.ib( + gas_price: Optional[int] = attr.ib( default=None, converter=attr.converters.optional(int) ) nonce: Optional[int] = attr.ib( @@ -36,4 +36,7 @@ def as_dict(self): if "from_" in res: res["from"] = res["from_"] del res["from_"] + if "gas_price" in res: + res["gasPrice"] = res["gas_price"] + del res["gas_price"] return res diff --git a/python-packages/json_schemas/setup.py b/python-packages/json_schemas/setup.py index efa9056833..34b92c924c 100755 --- a/python-packages/json_schemas/setup.py +++ b/python-packages/json_schemas/setup.py @@ -2,12 +2,16 @@ """setuptools module for json_schemas package.""" +# pylint: disable=import-outside-toplevel +# we import things outside of top-level because 3rd party libs may not yet be +# installed when you invoke this script + import distutils.command.build_py from distutils.command.clean import clean import subprocess # nosec from shutil import copytree, rmtree from os import environ, path -from sys import argv +from sys import argv, exit # pylint: disable=redefined-builtin from setuptools import find_packages, setup from setuptools.command.test import test as TestCommand diff --git a/python-packages/json_schemas/src/zero_ex/__init__.py b/python-packages/json_schemas/src/zero_ex/__init__.py index e90d833db6..3fe1300cfb 100644 --- a/python-packages/json_schemas/src/zero_ex/__init__.py +++ b/python-packages/json_schemas/src/zero_ex/__init__.py @@ -1,2 +1,2 @@ """0x Python API.""" -__import__("pkg_resources").declare_namespace(__name__) +__import__("pkg_resources").declare_namespace(__name__) # type: ignore diff --git a/python-packages/middlewares/setup.py b/python-packages/middlewares/setup.py index 3a02febcf0..53b78a8023 100755 --- a/python-packages/middlewares/setup.py +++ b/python-packages/middlewares/setup.py @@ -2,10 +2,14 @@ """setuptools module for middlewares package.""" +# pylint: disable=import-outside-toplevel +# we import things outside of top-level because 3rd party libs may not yet be +# installed when you invoke this script + import subprocess # nosec from shutil import rmtree from os import environ, path -from sys import argv +from sys import argv, exit # pylint: disable=redefined-builtin from distutils.command.clean import clean import distutils.command.build_py diff --git a/python-packages/middlewares/src/zero_ex/__init__.py b/python-packages/middlewares/src/zero_ex/__init__.py index e90d833db6..3fe1300cfb 100644 --- a/python-packages/middlewares/src/zero_ex/__init__.py +++ b/python-packages/middlewares/src/zero_ex/__init__.py @@ -1,2 +1,2 @@ """0x Python API.""" -__import__("pkg_resources").declare_namespace(__name__) +__import__("pkg_resources").declare_namespace(__name__) # type: ignore diff --git a/python-packages/order_utils/setup.py b/python-packages/order_utils/setup.py index e7a4b2e2fd..2732639521 100755 --- a/python-packages/order_utils/setup.py +++ b/python-packages/order_utils/setup.py @@ -2,11 +2,15 @@ """setuptools module for order_utils package.""" +# pylint: disable=import-outside-toplevel +# we import things outside of top-level because 3rd party libs may not yet be +# installed when you invoke this script + import subprocess # nosec from shutil import rmtree from os import environ, path from pathlib import Path -from sys import argv +from sys import argv, exit # pylint: disable=redefined-builtin from distutils.command.clean import clean import distutils.command.build_py diff --git a/python-packages/order_utils/src/zero_ex/__init__.py b/python-packages/order_utils/src/zero_ex/__init__.py index e90d833db6..3fe1300cfb 100644 --- a/python-packages/order_utils/src/zero_ex/__init__.py +++ b/python-packages/order_utils/src/zero_ex/__init__.py @@ -1,2 +1,2 @@ """0x Python API.""" -__import__("pkg_resources").declare_namespace(__name__) +__import__("pkg_resources").declare_namespace(__name__) # type: ignore diff --git a/python-packages/sra_client/setup.py b/python-packages/sra_client/setup.py index a79d148c47..ec784d4b4c 100755 --- a/python-packages/sra_client/setup.py +++ b/python-packages/sra_client/setup.py @@ -3,10 +3,15 @@ """setuptools module for sra_client package.""" +# pylint: disable=import-outside-toplevel +# we import things outside of top-level because 3rd party libs may not yet be +# installed when you invoke this script + import subprocess # nosec import distutils.command.build_py from distutils.command.clean import clean from shutil import rmtree +from sys import exit # pylint: disable=redefined-builtin from urllib.request import urlopen from urllib.error import URLError diff --git a/python-packages/sra_client/src/zero_ex/__init__.py b/python-packages/sra_client/src/zero_ex/__init__.py index e90d833db6..3fe1300cfb 100644 --- a/python-packages/sra_client/src/zero_ex/__init__.py +++ b/python-packages/sra_client/src/zero_ex/__init__.py @@ -1,2 +1,2 @@ """0x Python API.""" -__import__("pkg_resources").declare_namespace(__name__) +__import__("pkg_resources").declare_namespace(__name__) # type: ignore From 1c1fc50316352edc2d2092fdccc3539e668c5c0d Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 28 Oct 2019 07:55:22 -0400 Subject: [PATCH 07/35] Support Rich Reverts via Web3.py middleware --- .../templates/Python/contract.handlebars | 27 +- .../output/python/abi_gen_dummy/__init__.py | 27 +- .../output/python/lib_dummy/__init__.py | 27 +- .../output/python/test_lib_dummy/__init__.py | 27 +- .../zero_ex/contract_wrappers/exceptions.py | 80 ++++ .../contract_wrappers/exchange/exceptions.py | 341 ++++++++++++++++++ .../contract_wrappers/exchange/middleware.py | 36 ++ 7 files changed, 553 insertions(+), 12 deletions(-) create mode 100644 python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exceptions.py create mode 100644 python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/exceptions.py create mode 100644 python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/middleware.py diff --git a/packages/abi-gen/templates/Python/contract.handlebars b/packages/abi-gen/templates/Python/contract.handlebars index 6aec525d3f..38afd29ef0 100644 --- a/packages/abi-gen/templates/Python/contract.handlebars +++ b/packages/abi-gen/templates/Python/contract.handlebars @@ -40,6 +40,12 @@ except ImportError: """No-op input validator.""" +try: + from .middleware import MIDDLEWARE # type: ignore +except ImportError: + pass + + {{tupleDefinitions ABIString}} {{#each methods}} @@ -69,14 +75,29 @@ class {{contractName}}: :param contract_address: where the contract has been deployed :param validator: for validation of method inputs. """ + # pylint: disable=too-many-statements + self.contract_address = contract_address if not validator: validator = {{contractName}}Validator(provider, contract_address) - self._web3_eth = Web3( # type: ignore # pylint: disable=no-member - provider - ).eth + web3 = Web3(provider) + + # if any middleware was imported, inject it + try: + MIDDLEWARE + except NameError: + pass + else: + for middleware in MIDDLEWARE: + web3.middleware_onion.inject( # type: ignore + middleware['function'], layer=middleware['layer'], + ) + + self._web3_eth = ( + web3.eth # type: ignore # pylint: disable=no-member + ) {{#if methods}} functions = self._web3_eth.contract(address=to_checksum_address(contract_address), abi={{contractName}}.abi()).functions diff --git a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py index e215b5f7cc..49bcb59cc8 100644 --- a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py @@ -40,6 +40,12 @@ class AbiGenDummyValidator( # type: ignore """No-op input validator.""" +try: + from .middleware import MIDDLEWARE # type: ignore +except ImportError: + pass + + class Tuple0x246f9407(TypedDict): """Python representation of a tuple or struct. @@ -1953,14 +1959,29 @@ def __init__( :param contract_address: where the contract has been deployed :param validator: for validation of method inputs. """ + # pylint: disable=too-many-statements + self.contract_address = contract_address if not validator: validator = AbiGenDummyValidator(provider, contract_address) - self._web3_eth = Web3( # type: ignore # pylint: disable=no-member - provider - ).eth + web3 = Web3(provider) + + # if any middleware was imported, inject it + try: + MIDDLEWARE + except NameError: + pass + else: + for middleware in MIDDLEWARE: + web3.middleware_onion.inject( # type: ignore + middleware["function"], layer=middleware["layer"] + ) + + self._web3_eth = ( + web3.eth # type: ignore # pylint: disable=no-member + ) functions = self._web3_eth.contract( address=to_checksum_address(contract_address), diff --git a/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py index 1181817fdc..e5ec5d76cd 100644 --- a/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py @@ -40,6 +40,12 @@ class LibDummyValidator( # type: ignore """No-op input validator.""" +try: + from .middleware import MIDDLEWARE # type: ignore +except ImportError: + pass + + # pylint: disable=too-many-public-methods,too-many-instance-attributes class LibDummy: """Wrapper class for LibDummy Solidity contract.""" @@ -56,14 +62,29 @@ def __init__( :param contract_address: where the contract has been deployed :param validator: for validation of method inputs. """ + # pylint: disable=too-many-statements + self.contract_address = contract_address if not validator: validator = LibDummyValidator(provider, contract_address) - self._web3_eth = Web3( # type: ignore # pylint: disable=no-member - provider - ).eth + web3 = Web3(provider) + + # if any middleware was imported, inject it + try: + MIDDLEWARE + except NameError: + pass + else: + for middleware in MIDDLEWARE: + web3.middleware_onion.inject( # type: ignore + middleware["function"], layer=middleware["layer"] + ) + + self._web3_eth = ( + web3.eth # type: ignore # pylint: disable=no-member + ) @staticmethod def abi(): diff --git a/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py index ebdd8c6c6a..7af4d6b224 100644 --- a/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py @@ -40,6 +40,12 @@ class TestLibDummyValidator( # type: ignore """No-op input validator.""" +try: + from .middleware import MIDDLEWARE # type: ignore +except ImportError: + pass + + class PublicAddConstantMethod(ContractMethod): """Various interfaces to the publicAddConstant method.""" @@ -176,14 +182,29 @@ def __init__( :param contract_address: where the contract has been deployed :param validator: for validation of method inputs. """ + # pylint: disable=too-many-statements + self.contract_address = contract_address if not validator: validator = TestLibDummyValidator(provider, contract_address) - self._web3_eth = Web3( # type: ignore # pylint: disable=no-member - provider - ).eth + web3 = Web3(provider) + + # if any middleware was imported, inject it + try: + MIDDLEWARE + except NameError: + pass + else: + for middleware in MIDDLEWARE: + web3.middleware_onion.inject( # type: ignore + middleware["function"], layer=middleware["layer"] + ) + + self._web3_eth = ( + web3.eth # type: ignore # pylint: disable=no-member + ) functions = self._web3_eth.contract( address=to_checksum_address(contract_address), diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exceptions.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exceptions.py new file mode 100644 index 0000000000..32cf19f25c --- /dev/null +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exceptions.py @@ -0,0 +1,80 @@ +"""Exception classes common to all wrappers.""" + +from inspect import isclass +from typing import List + +from eth_abi import decode_abi + + +class RichRevert(Exception): + """Raised when a contract method returns a rich revert error.""" + + def __init__( + self, abi_signature: str, param_names: List[str], return_data: str + ): + """Populate instance variables with decoded return data values.""" + arg_start_index = abi_signature.index("(") + 1 + arg_end_index = abi_signature.index(")") + arguments = decode_abi( + abi_signature[arg_start_index:arg_end_index].split(","), + bytes.fromhex(return_data[10:]), + ) + for (param_name, argument) in zip(param_names, arguments): + setattr(self, param_name, argument) + super().__init__(vars(self)) + + +class NoExceptionForSelector(Exception): + """Indicates that no exception could be found for the given selector.""" + + +def exception_class_from_rich_revert_selector( + selector: str, exceptions_module +) -> RichRevert: + """Return the appropriate exception class. + + :param selector: A string of the format '0xffffffff' which indicates the + 4-byte ABI function selector of a rich revert error type, which is + expected to be found as a class attribute on some class in + `exceptions_module`:code:. + :param exceptions_module: The Python module in which to look for a class + with a `selector`:code: attribute matching the value of the + `selector`:code: argument. + """ + # noqa: D202 (No blank lines allowed after function docstring + def _get_rich_revert_exception_classes(): + def _exception_name_is_class_with_selector(name: str): + if not isclass(getattr(exceptions_module, name)): + return False + + try: + getattr(exceptions_module, name).selector + except AttributeError: + return False + + return True + + def _convert_class_name_to_class(name: str): + return getattr(exceptions_module, name) + + return list( + map( + _convert_class_name_to_class, + filter( + _exception_name_is_class_with_selector, + dir(exceptions_module), + ), + ) + ) + + rich_reverts = _get_rich_revert_exception_classes() + + try: + return next( + filter( + lambda rich_revert: rich_revert.selector == selector, + rich_reverts, + ) + ) + except StopIteration: + raise NoExceptionForSelector(selector) diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/exceptions.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/exceptions.py new file mode 100644 index 0000000000..ab60b845ac --- /dev/null +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/exceptions.py @@ -0,0 +1,341 @@ +"""Exchange-specific exception classes.""" + +from enum import auto, Enum + +from zero_ex.contract_wrappers.exceptions import RichRevert + +# pylint: disable=missing-docstring + + +class AssetProxyDispatchErrorCodes(Enum): # noqa: D101 (missing docstring) + INVALID_ASSET_DATA_LENGTH = 0 + UNKNOWN_ASSET_PROXY = auto() + + +class BatchMatchOrdersErrorCodes(Enum): # noqa: D101 (missing docstring) + ZERO_LEFT_ORDERS = 0 + ZERO_RIGHT_ORDERS = auto() + INVALID_LENGTH_LEFT_SIGNATURES = auto() + INVALID_LENGTH_RIGHT_SIGNATURES = auto() + + +class ExchangeContextErrorCodes(Enum): # noqa: D101 (missing docstring) + INVALID_MAKER = 0 + INVALID_TAKER = auto() + INVALID_SENDER = auto() + + +class FillErrorCodes(Enum): # noqa: D101 (missing docstring) + INVALID_TAKER_AMOUNT = 0 + TAKER_OVERPAY = auto() + OVERFILL = auto() + INVALID_FILL_PRICE = auto() + + +class SignatureErrorCodes(Enum): # noqa: D101 (missing docstring) + BAD_ORDER_SIGNATURE = 0 + BAD_TRANSACTION_SIGNATURE = auto() + INVALID_LENGTH = auto() + UNSUPPORTED = auto() + ILLEGAL = auto() + INAPPROPRIATE_SIGNATURE_TYPE = auto() + INVALID_SIGNER = auto() + + +class TransactionErrorCodes(Enum): # noqa: D101 (missing docstring) + ALREADY_EXECUTED = 0 + EXPIRED = auto() + + +class IncompleteFillErrorCode(Enum): # noqa: D101 (missing docstring) + INCOMPLETE_MARKET_BUY_ORDERS = 0 + INCOMPLETE_MARKET_SELL_ORDERS = auto() + INCOMPLETE_FILL_ORDER = auto() + + +class SignatureError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "SignatureError(uint8,bytes32,address,bytes)", + ["errorCode", "hash", "signerAddress", "signature"], + return_data, + ) + + errorCode: SignatureErrorCodes + hash: bytes + signerAddress: str + signature: bytes + + selector = "0x7e5a2318" + + +class SignatureValidatorNotApprovedError( + RichRevert +): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "SignatureValidatorNotApprovedError(address,address)", + ["signerAddress", "validatorAddress"], + return_data, + ) + + signerAddress: str + validatorAddress: str + + selector = "0xa15c0d06" + + +class EIP1271SignatureError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "EIP1271SignatureError(address,bytes,bytes,bytes)", + ["verifyingContractAddress", "data", "signature", "errorData"], + return_data, + ) + + verifyingContractAddress: str + data: bytes + signature: bytes + errorData: bytes + + selector = "0x5bd0428d" + + +class SignatureWalletError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "SignatureWalletError(bytes32,address,bytes,bytes)", + ["hash", "walletAddress", "signature", "errorData"], + return_data, + ) + + hash: bytes + walletAddress: str + signature: bytes + errorData: bytes + + selector = "0x1b8388f7" + + +class OrderStatusError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "OrderStatusError(bytes32,uint8)", + ["orderHash", "orderStatus"], + return_data, + ) + + orderHash: bytes + orderStatus: int + + selector = "0xfdb6ca8d" + + +class ExchangeInvalidContextError( + RichRevert +): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "ExchangeInvalidContextError(uint8,bytes32,address)", + ["errorCode", "orderHash", "contextAddress"], + return_data, + ) + + errorCode: ExchangeContextErrorCodes + orderHash: bytes + contextAddress: str + + selector = "0xe53c76c8" + + +class FillError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "FillError(uint8,bytes32)", ["errorCode", "orderHash"], return_data + ) + + errorCode: FillErrorCodes + orderHash: bytes + + selector = "0xe94a7ed0" + + +class OrderEpochError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "OrderEpochError(address,address,uint256)", + ["makerAddress", "orderSenderAddress", "currentEpoch"], + return_data, + ) + + makerAddress: str + orderSenderAddress: str + currentEpoch: int + + selector = "0x4ad31275" + + +class AssetProxyExistsError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "AssetProxyExistsError(bytes4,address)", + ["assetProxyId", "assetProxyAddress"], + return_data, + ) + + assetProxyId: bytes + assetProxyAddress: str + + selector = "0x11c7b720" + + +class AssetProxyDispatchError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "AssetProxyDispatchError(uint8,bytes32,bytes)", + ["errorCode", "orderHash", "assetData"], + return_data, + ) + + errorCode: AssetProxyDispatchErrorCodes + orderHash: bytes + assetData: bytes + + selector = "0x488219a6" + + +class AssetProxyTransferError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "AssetProxyTransferError(bytes32,bytes,bytes)", + ["orderHash", "assetData", "errorData"], + return_data, + ) + + orderHash: bytes + assetData: bytes + errorData: bytes + + selector = "0x4678472b" + + +class NegativeSpreadError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "NegativeSpreadError(bytes32,bytes32)", + ["leftOrderHash", "rightOrderHash"], + return_data, + ) + + leftOrderHash: bytes + rightOrderHash: bytes + + selector = "0xb6555d6f" + + +class TransactionError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "TransactionError(uint8,bytes32)", + ["errorCode", "transactionHash"], + return_data, + ) + + errorCode: TransactionErrorCodes + transactionHash: bytes + + selector = "0xf5985184" + + +class TransactionExecutionError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "TransactionExecutionError(bytes32,bytes)", + ["transactionHash", "errorData"], + return_data, + ) + + transactionHash: bytes + errorData: bytes + + selector = "0x20d11f61" + + +class TransactionGasPriceError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "TransactionGasPriceError(bytes32,uint256,uint256)", + ["transactionHash", "actualGasPrice", "requiredGasPrice"], + return_data, + ) + + transactionHash: bytes + actualGasPrice: int + requiredGasPrice: int + + selector = "0xa26dac09" + + +class TransactionInvalidContextError( + RichRevert +): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "TransactionInvalidContextError(bytes32,address)", + ["transactionHash", "currentContextAddress"], + return_data, + ) + + transactionHash: bytes + currentContextAddress: str + + selector = "0xdec4aedf" + + +class IncompleteFillError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "IncompleteFillError(uint8,uint256,uint256)", + ["errorCode", "expectedAssetAmount", "actualAssetAmount"], + return_data, + ) + + errorCode: IncompleteFillErrorCode + expectedAssetAmount: int + actualAssetAmount: int + + selector = "0x18e4b141" + + +class BatchMatchOrdersError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "BatchMatchOrdersError(uint8)", ["errorCode"], return_data + ) + + errorCode: BatchMatchOrdersErrorCodes + + selector = "0xd4092f4f" + + +class PayProtocolFeeError(RichRevert): # noqa: D101 (missing docstring) + def __init__(self, return_data): # noqa: D107 (missing docstring) + super().__init__( + "PayProtocolFeeError(bytes32,uint256,address,address,bytes)", + [ + "orderHash", + "protocolFee", + "makerAddress", + "takerAddress", + "errorData", + ], + return_data, + ) + + orderHash: bytes + protocolFee: int + makerAddress: str + takerAddress: str + errorData: bytes + + selector = "0x87cb1e75" diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/middleware.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/middleware.py new file mode 100644 index 0000000000..4b509fdd8c --- /dev/null +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/middleware.py @@ -0,0 +1,36 @@ +"""Web3.py-compatible middleware to be injected upon contract instantiation.""" + +from zero_ex.contract_wrappers.exceptions import ( + exception_class_from_rich_revert_selector, + NoExceptionForSelector, +) + +from . import exceptions + + +def rich_revert_handler(make_request, _): + """Return a middlware to raise exceptions for rich revert return data.""" + # noqa: D202 (No blank lines allowed after function docstring + def middleware(method, params): + response = make_request(method, params) + try: + raise exception_class_from_rich_revert_selector( + response["result"][0:10], exceptions + )(response["result"]) + except NoExceptionForSelector: + # response prefix didn't indicate a known error + pass + except TypeError: + # eg "unhashable type: 'slice'". if response["result"] isn't + # sliceable (eg if it's a dict), then it definitely isn't a rich + # revert. + pass + except KeyError: + # response doesn't have a "result" key + pass + return response + + return middleware + + +MIDDLEWARE = [{"layer": 0, "function": rich_revert_handler}] From 66ce2c0c4a8688d5083fa70c663124031205c6d5 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 28 Oct 2019 07:59:44 -0400 Subject: [PATCH 08/35] Fix bug in generated wrappers' bytes handling `bytes.fromhex(bytes.decode('utf-8')` is just plain wrong. It would work for some cases, but is not working when trying to fill orders with the latest Exchange contract. --- .../templates/Python/partials/method_class.handlebars | 7 ------- .../test-cli/output/python/abi_gen_dummy/__init__.py | 3 --- 2 files changed, 10 deletions(-) diff --git a/packages/abi-gen/templates/Python/partials/method_class.handlebars b/packages/abi-gen/templates/Python/partials/method_class.handlebars index 1817eac591..6bbbb07684 100644 --- a/packages/abi-gen/templates/Python/partials/method_class.handlebars +++ b/packages/abi-gen/templates/Python/partials/method_class.handlebars @@ -21,13 +21,6 @@ class {{toPythonClassname this.languageSpecificName}}Method(ContractMethod): {{else if (equal type 'uint256')}} # safeguard against fractional inputs {{toPythonIdentifier this.name}} = int({{toPythonIdentifier this.name}}) - {{else if (equal type 'bytes')}} - {{toPythonIdentifier this.name}} = bytes.fromhex({{toPythonIdentifier this.name}}.decode("utf-8")) - {{else if (equal type 'bytes[]')}} - {{toPythonIdentifier this.name}} = [ - bytes.fromhex({{toPythonIdentifier this.name}}_element.decode("utf-8")) - for {{toPythonIdentifier this.name}}_element in {{toPythonIdentifier this.name}} - ] {{/if}} {{/each}} return ({{> params }}) diff --git a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py index 49bcb59cc8..98bb551cde 100644 --- a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py @@ -239,7 +239,6 @@ def validate_and_normalize_inputs(self, a: List[bytes]): parameter_name="a", argument_value=a, ) - a = [bytes.fromhex(a_element.decode("utf-8")) for a_element in a] return a def call( @@ -426,7 +425,6 @@ def validate_and_normalize_inputs( parameter_name="index_1", argument_value=index_1, ) - index_1 = bytes.fromhex(index_1.decode("utf-8")) self.validator.assert_valid( method_name="multiInputMultiOutput", parameter_name="index_2", @@ -624,7 +622,6 @@ def validate_and_normalize_inputs(self, a: bytes): self.validator.assert_valid( method_name="acceptsBytes", parameter_name="a", argument_value=a ) - a = bytes.fromhex(a.decode("utf-8")) return a def call(self, a: bytes, tx_params: Optional[TxParams] = None) -> None: From 606ec2110a3a7975942dcae3a069aeb01217c15e Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 28 Oct 2019 08:08:46 -0400 Subject: [PATCH 09/35] Migrate to Exchange v3 --- .../contract_wrappers/src/index.rst | 12 ++- .../src/zero_ex/contract_wrappers/__init__.py | 67 ++++++++++--- .../contract_wrappers/exchange/types.py | 36 +++++-- .../contract_wrappers/exchange/validator.py | 12 ++- .../contract_wrappers/order_conversions.py | 33 ++++++- .../test/test_exchange_wrapper.py | 33 +++++-- .../json_schemas/test/test_json_schemas.py | 3 + .../test/test_local_message_signer.py | 11 ++- .../src/zero_ex/order_utils/__init__.py | 95 ++++++++++--------- .../test/test_generate_order_hash_hex.py | 7 +- .../order_utils/test/test_signature_utils.py | 57 +++++++---- 11 files changed, 261 insertions(+), 105 deletions(-) diff --git a/python-packages/contract_wrappers/src/index.rst b/python-packages/contract_wrappers/src/index.rst index 2cb98cea20..f3c97a34e5 100644 --- a/python-packages/contract_wrappers/src/index.rst +++ b/python-packages/contract_wrappers/src/index.rst @@ -180,18 +180,20 @@ zero_ex.contract_wrappers.exchange.types .. autoclass:: zero_ex.contract_wrappers.exchange.types.MatchedFillResults +.. autoclass:: zero_ex.contract_wrappers.exchange.types.ZeroExTransaction + zero_ex.contract_wrappers.exchange: Generated Tuples ==================================================== -.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0x260219a2 +.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0x6ca34a6f This is the generated class representing `the Order struct `_. -.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0xbb41e5b3 +.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0x735c43e3 This is the generated class representing `the FillResults struct `_. -.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0x054ca44e +.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0x4c5ca29b This is the generated class representing `the MatchedFillResults struct `_. @@ -199,6 +201,10 @@ zero_ex.contract_wrappers.exchange: Generated Tuples This is the generated class representing `the OrderInfo struct `_. +.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0xdabc15fe + + This is the generated class representing `the ZeroExTransaction struct `_. + Indices and tables ================== diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py index 3ffd80b6bc..98be012a96 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py @@ -135,16 +135,21 @@ ... takerAssetAmount=to_wei(0.1, 'ether'), ... expirationTimeSeconds=round( ... (datetime.utcnow() + timedelta(days=1)).timestamp() -... ) +... ), +... makerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), +... takerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), +... chain_id=Web3(ganache).eth.chainId, ... ) For this order to be valid, our Maker must sign a hash of it: >>> from zero_ex.order_utils import generate_order_hash_hex ->>> order_hash_hex = generate_order_hash_hex(order, exchange_address) +>>> order_hash_hex = generate_order_hash_hex( +... order, exchange_address, Web3(ganache).eth.chainId +... ) ->>> from zero_ex.order_utils import sign_hash_to_bytes ->>> maker_signature = sign_hash_to_bytes( +>>> from zero_ex.order_utils import sign_hash +>>> maker_signature = sign_hash( ... ganache, Web3.toChecksumAddress(maker_address), order_hash_hex ... ) @@ -156,16 +161,37 @@ Filling an order ---------------- -Now our Taker will fill the order. The `takerAssetAmount`:code: parameter -specifies the amount of tokens (in this case WETH) that the taker wants to -fill. This example fills the order completely, but partial fills are possible -too. +Now we'll have our Taker fill the order. >>> from zero_ex.contract_wrappers.exchange import Exchange >>> exchange = Exchange( ... provider=ganache, ... contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange, ... ) + +But before filling an order, one may wish to check that it's actually fillable: + +>>> from zero_ex.contract_wrappers.exchange.types import OrderStatus +>>> OrderStatus(exchange.get_order_info.call(order)[0]) + + +The `takerAssetAmount`:code: parameter specifies the amount of tokens (in this +case WETH) that the taker wants to fill. This example fills the order +completely, but partial fills are possible too. + +One may wish to first call the method in a read-only way, to ensure that it +will not revert, and to validate that the return data is as expected: + +>>> exchange.fill_order.call( +... order=order, +... taker_asset_fill_amount=order["takerAssetAmount"], +... signature=maker_signature, +... tx_params=TxParams(from_=taker_address) +... ) +(100000000000000000, 100000000000000000, 0, 0, 0) + +Finally, submit the transaction: + >>> tx_hash = exchange.fill_order.send_transaction( ... order=order, ... taker_asset_fill_amount=order["takerAssetAmount"], @@ -184,12 +210,15 @@ 'makerAddress': '0x...', 'makerAssetData': b..., 'makerAssetFilledAmount': 100000000000000000, + 'makerFeeAssetData': b..., 'makerFeePaid': 0, 'orderHash': b..., + 'protocolFeePaid': ..., 'senderAddress': '0x...', 'takerAddress': '0x...', 'takerAssetData': b..., 'takerAssetFilledAmount': 100000000000000000, + 'takerFeeAssetData': b..., 'takerFeePaid': 0} >>> exchange.get_fill_event(tx_hash)[0].args.takerAssetFilledAmount 100000000000000000 @@ -206,7 +235,9 @@ ... senderAddress='0x0000000000000000000000000000000000000000', ... feeRecipientAddress='0x0000000000000000000000000000000000000000', ... makerAssetData=asset_data_utils.encode_erc20(weth_address), +... makerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), ... takerAssetData=asset_data_utils.encode_erc20(weth_address), +... takerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), ... salt=random.randint(1, 100000000000000000), ... makerFee=0, ... takerFee=0, @@ -248,7 +279,9 @@ ... senderAddress='0x0000000000000000000000000000000000000000', ... feeRecipientAddress='0x0000000000000000000000000000000000000000', ... makerAssetData=asset_data_utils.encode_erc20(zrx_address), +... makerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), ... takerAssetData=asset_data_utils.encode_erc20(weth_address), +... takerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), ... salt=random.randint(1, 100000000000000000), ... makerFee=0, ... takerFee=0, @@ -258,10 +291,12 @@ ... (datetime.utcnow() + timedelta(days=1)).timestamp() ... ) ... ) ->>> signature_1 = sign_hash_to_bytes( +>>> signature_1 = sign_hash( ... ganache, ... Web3.toChecksumAddress(maker_address), -... generate_order_hash_hex(order_1, exchange.contract_address) +... generate_order_hash_hex( +... order_1, exchange.contract_address, Web3(ganache).eth.chainId +... ), ... ) >>> order_2 = Order( ... makerAddress=maker_address, @@ -269,7 +304,9 @@ ... senderAddress='0x0000000000000000000000000000000000000000', ... feeRecipientAddress='0x0000000000000000000000000000000000000000', ... makerAssetData=asset_data_utils.encode_erc20(zrx_address), +... makerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), ... takerAssetData=asset_data_utils.encode_erc20(weth_address), +... takerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), ... salt=random.randint(1, 100000000000000000), ... makerFee=0, ... takerFee=0, @@ -279,10 +316,12 @@ ... (datetime.utcnow() + timedelta(days=1)).timestamp() ... ) ... ) ->>> signature_2 = sign_hash_to_bytes( +>>> signature_2 = sign_hash( ... ganache, ... Web3.toChecksumAddress(maker_address), -... generate_order_hash_hex(order_2, exchange.contract_address) +... generate_order_hash_hex( +... order_2, exchange.contract_address, Web3(ganache).eth.chainId +... ), ... ) Fill order_1 and order_2 together: @@ -308,7 +347,9 @@ ... senderAddress='0x0000000000000000000000000000000000000000', ... feeRecipientAddress='0x0000000000000000000000000000000000000000', ... makerAssetData=asset_data_utils.encode_erc20(weth_address), +... makerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), ... takerAssetData=asset_data_utils.encode_erc20(weth_address), +... takerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), ... salt=random.randint(1, 100000000000000000), ... makerFee=0, ... takerFee=0, @@ -320,7 +361,7 @@ ... ), ... tx_params=TxParams(from_=maker_address), ... ) -73... +74... """ from .tx_params import TxParams diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/types.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/types.py index 21ce43df03..500732d6bd 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/types.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/types.py @@ -11,11 +11,13 @@ converting Exchange structs between JSON and Python objects. """ +from enum import auto, Enum from . import ( - Tuple0xbb41e5b3, - Tuple0x260219a2, - Tuple0x054ca44e, + Tuple0x735c43e3, + Tuple0x6ca34a6f, + Tuple0x4c5ca29b, + Tuple0xdabc15fe, Tuple0xb1e4a1ae, ) @@ -27,27 +29,35 @@ # of each of these classes. -class FillResults(Tuple0xbb41e5b3): +class FillResults(Tuple0x735c43e3): """The `FillResults`:code: Solidity struct. Also known as - `zero_ex.contract_wrappers.exchange.Tuple0xbb41e5b3`:py:class:. + `zero_ex.contract_wrappers.exchange.Tuple0x735c43e3`:py:class:. """ -class Order(Tuple0x260219a2): +class Order(Tuple0x6ca34a6f): """The `Order`:code: Solidity struct. Also known as - `zero_ex.contract_wrappers.exchange.Tuple0x260219a2`:py:class:. + `zero_ex.contract_wrappers.exchange.Tuple0x6ca34a6f`:py:class:. """ -class MatchedFillResults(Tuple0x054ca44e): +class MatchedFillResults(Tuple0x4c5ca29b): """The `MatchedFillResults`:code: Solidity struct. Also known as - `zero_ex.contract_wrappers.exchange.Tuple0x054ca44e`:py:class:. + `zero_ex.contract_wrappers.exchange.Tuple0x4c5ca29b`:py:class:. + """ + + +class ZeroExTransaction(Tuple0xdabc15fe): + """The `ZeroExTransaction`:code: Solidity struct. + + Also known as + `zero_ex.contract_wrappers.exchange.Tuple0xdabc15fe`:py:class:. """ @@ -59,3 +69,11 @@ class OrderInfo(Tuple0xb1e4a1ae): """ +class OrderStatus(Enum): # noqa: D101 # pylint: disable=missing-docstring + INVALID = 0 + INVALID_MAKER_ASSET_AMOUNT = auto() + INVALID_TAKER_ASSET_AMOUNT = auto() + FILLABLE = auto() + EXPIRED = auto() + FULLY_FILLED = auto() + CANCELLED = auto() diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py index 12726336b5..5f56340ffd 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py @@ -2,6 +2,7 @@ from typing import Any +from web3 import Web3 from web3.providers.base import BaseProvider from zero_ex import json_schemas @@ -17,6 +18,9 @@ def __init__(self, provider: BaseProvider, contract_address: str): """Initialize the class.""" super().__init__(provider, contract_address) self.contract_address = contract_address + self.chain_id = Web3( # type: ignore # pylint: disable=no-member + provider + ).eth.chainId def assert_valid( self, method_name: str, parameter_name: str, argument_value: Any @@ -30,13 +34,17 @@ def assert_valid( """ if parameter_name == "order": json_schemas.assert_valid( - order_to_jsdict(argument_value, self.contract_address), + order_to_jsdict( + argument_value, self.chain_id, self.contract_address + ), "/orderSchema", ) if parameter_name == "orders": for order in argument_value: json_schemas.assert_valid( - order_to_jsdict(order, self.contract_address), + order_to_jsdict( + order, self.chain_id, self.contract_address + ), "/orderSchema", ) diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py index c1ade7b9a1..42fe5457ca 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py @@ -11,6 +11,7 @@ def order_to_jsdict( order: Order, + chain_id: int, exchange_address="0x0000000000000000000000000000000000000000", signature: str = None, ) -> dict: @@ -35,27 +36,35 @@ def order_to_jsdict( ... 'salt': 1, ... 'makerAssetData': (0).to_bytes(1, byteorder='big') * 20, ... 'takerAssetData': (0).to_bytes(1, byteorder='big') * 20, + ... 'makerFeeAssetData': (0).to_bytes(1, byteorder='big') * 20, + ... 'takerFeeAssetData': (0).to_bytes(1, byteorder='big') * 20, ... }, + ... chain_id=50 ... )) - {'exchangeAddress': '0x0000000000000000000000000000000000000000', + {'chainId': 50, + 'exchangeAddress': '0x0000000000000000000000000000000000000000', 'expirationTimeSeconds': '1', 'feeRecipientAddress': '0x0000000000000000000000000000000000000000', 'makerAddress': '0x0000000000000000000000000000000000000000', 'makerAssetAmount': '1', 'makerAssetData': '0x0000000000000000000000000000000000000000', 'makerFee': '0', + 'makerFeeAssetData': '0x0000000000000000000000000000000000000000', 'salt': '1', 'senderAddress': '0x0000000000000000000000000000000000000000', 'takerAddress': '0x0000000000000000000000000000000000000000', 'takerAssetAmount': '1', 'takerAssetData': '0x0000000000000000000000000000000000000000', - 'takerFee': '0'} + 'takerFee': '0', + 'takerFeeAssetData': '0x0000000000000000000000000000000000000000'} """ jsdict = cast(Dict, copy(order)) # encode bytes fields jsdict["makerAssetData"] = "0x" + order["makerAssetData"].hex() + jsdict["makerFeeAssetData"] = "0x" + order["makerFeeAssetData"].hex() jsdict["takerAssetData"] = "0x" + order["takerAssetData"].hex() + jsdict["takerFeeAssetData"] = "0x" + order["takerFeeAssetData"].hex() jsdict["exchangeAddress"] = exchange_address @@ -69,6 +78,8 @@ def order_to_jsdict( jsdict["salt"] = str(order["salt"]) + jsdict["chainId"] = chain_id + if signature is not None: jsdict["signature"] = signature @@ -98,23 +109,31 @@ def jsdict_to_order(jsdict: dict) -> Order: ... 'salt': "12345", ... 'makerAssetData': "0x0000000000000000000000000000000000000000", ... 'takerAssetData': "0x0000000000000000000000000000000000000000", + ... 'makerFeeAssetData': "0x0000000000000000000000000000000000000000", + ... 'takerFeeAssetData': "0x0000000000000000000000000000000000000000", ... 'exchangeAddress': "0x0000000000000000000000000000000000000000", + ... 'chainId': 50 ... }, ... )) - {'expirationTimeSeconds': 12345, + {'chainId': 50, + 'expirationTimeSeconds': 12345, 'feeRecipientAddress': '0x0000000000000000000000000000000000000000', 'makerAddress': '0x0000000000000000000000000000000000000000', 'makerAssetAmount': 1000000000000000000, 'makerAssetData': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00', 'makerFee': 0, + 'makerFeeAssetData': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00', 'salt': 12345, 'senderAddress': '0x0000000000000000000000000000000000000000', 'takerAddress': '0x0000000000000000000000000000000000000000', 'takerAssetAmount': 1000000000000000000, 'takerAssetData': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00', - 'takerFee': 0} + 'takerFee': 0, + 'takerFeeAssetData': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00'} """ # noqa: E501 (line too long) assert_valid(jsdict, "/orderSchema") @@ -123,9 +142,15 @@ def jsdict_to_order(jsdict: dict) -> Order: order["makerAssetData"] = bytes.fromhex( remove_0x_prefix(jsdict["makerAssetData"]) ) + order["makerFeeAssetData"] = bytes.fromhex( + remove_0x_prefix(jsdict["makerFeeAssetData"]) + ) order["takerAssetData"] = bytes.fromhex( remove_0x_prefix(jsdict["takerAssetData"]) ) + order["takerFeeAssetData"] = bytes.fromhex( + remove_0x_prefix(jsdict["takerFeeAssetData"]) + ) order["makerAssetAmount"] = int(jsdict["makerAssetAmount"]) order["takerAssetAmount"] = int(jsdict["takerAssetAmount"]) diff --git a/python-packages/contract_wrappers/test/test_exchange_wrapper.py b/python-packages/contract_wrappers/test/test_exchange_wrapper.py index 8290756a9a..582d35f005 100644 --- a/python-packages/contract_wrappers/test/test_exchange_wrapper.py +++ b/python-packages/contract_wrappers/test/test_exchange_wrapper.py @@ -10,7 +10,11 @@ from zero_ex.contract_wrappers.exchange import Exchange from zero_ex.contract_wrappers.exchange.types import Order from zero_ex.json_schemas import assert_valid -from zero_ex.order_utils import generate_order_hash_hex, sign_hash_to_bytes +from zero_ex.order_utils import ( + asset_data_utils, + generate_order_hash_hex, + sign_hash, +) @pytest.fixture(scope="module") @@ -43,6 +47,8 @@ def create_test_order( salt=random.randint(1, 1000000000), makerAssetData=maker_asset_data, takerAssetData=taker_asset_data, + makerFeeAssetData=asset_data_utils.encode_erc20("0x" + "00" * 20), + takerFeeAssetData=asset_data_utils.encode_erc20("0x" + "00" * 20), ) return order @@ -67,16 +73,29 @@ def test_exchange_wrapper__fill_order( exchange_wrapper, # pylint: disable=redefined-outer-name ganache_provider, weth_asset_data, + zrx_asset_data, ): """Test filling an order.""" taker = accounts[0] maker = accounts[1] exchange_address = exchange_wrapper.contract_address - order = create_test_order(maker, 1, weth_asset_data, 1, weth_asset_data) + order = create_test_order(maker, 1, weth_asset_data, 1, zrx_asset_data) order_hash = generate_order_hash_hex( - order=order, exchange_address=exchange_address + order=order, exchange_address=exchange_address, chain_id=1337 ) - order_signature = sign_hash_to_bytes(ganache_provider, maker, order_hash) + order_signature = sign_hash(ganache_provider, maker, order_hash) + + fill_results = exchange_wrapper.fill_order.call( + order=order, + taker_asset_fill_amount=order["takerAssetAmount"], + signature=order_signature, + tx_params=TxParams(from_=taker), + ) + assert fill_results[0] == 1 + assert fill_results[1] == 1 + assert fill_results[2] == 0 + assert fill_results[3] == 0 + assert fill_results[4] == 0 tx_hash = exchange_wrapper.fill_order.send_transaction( order=order, @@ -107,11 +126,13 @@ def test_exchange_wrapper__batch_fill_orders( orders.append(order_1) orders.append(order_2) order_hashes = [ - generate_order_hash_hex(order=order, exchange_address=exchange_address) + generate_order_hash_hex( + order=order, exchange_address=exchange_address, chain_id=1337 + ) for order in orders ] order_signatures = [ - sign_hash_to_bytes(ganache_provider, maker, order_hash) + sign_hash(ganache_provider, maker, order_hash) for order_hash in order_hashes ] taker_amounts = [order["takerAssetAmount"] for order in orders] diff --git a/python-packages/json_schemas/test/test_json_schemas.py b/python-packages/json_schemas/test/test_json_schemas.py index cfd2787ee6..bba37f333a 100644 --- a/python-packages/json_schemas/test/test_json_schemas.py +++ b/python-packages/json_schemas/test/test_json_schemas.py @@ -15,11 +15,14 @@ "takerAssetData": NULL_ADDRESS, "salt": "0", "makerFee": "0", + "makerFeeAssetData": NULL_ADDRESS, "takerFee": "0", + "takerFeeAssetData": NULL_ADDRESS, "makerAssetAmount": "0", "takerAssetAmount": "0", "expirationTimeSeconds": "0", "exchangeAddress": NULL_ADDRESS, + "chainId": 50, } diff --git a/python-packages/middlewares/test/test_local_message_signer.py b/python-packages/middlewares/test/test_local_message_signer.py index ef1b36f595..6fbe0ba819 100644 --- a/python-packages/middlewares/test/test_local_message_signer.py +++ b/python-packages/middlewares/test/test_local_message_signer.py @@ -17,8 +17,8 @@ def test_local_message_signer__sign_order(): """Test signing order with the local_message_signer middleware""" expected_signature = ( - "0x1cd17d75b891accf16030c572a64cf9e7955de63bcafa5b084439cec630ade2d7" - "c00f47a2f4d5b6a4508267bf4b8527100bd97cf1af9984c0a58e42d25b13f4f0a03" + "0x1c8bdfbb3ce3ed0f38c5a358a7f49ad5f21ea9857224c2fe98c458f2fa25551d4" + "d6db0157d9dfe9f9fadb8dedabb7786352843357f4ec8d0fbcbeeb619b1091f5803" ) address = "0x5409ED021D9299bf6814279A6A1411A7e866A631" exchange = NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange @@ -36,7 +36,9 @@ def test_local_message_signer__sign_order(): "senderAddress": "0x0000000000000000000000000000000000000000", "feeRecipientAddress": "0x0000000000000000000000000000000000000000", "makerAssetData": (b"\x00") * 20, + "makerFeeAssetData": (b"\x00") * 20, "takerAssetData": (b"\x00") * 20, + "takerFeeAssetData": (b"\x00") * 20, "salt": 0, "makerFee": 0, "takerFee": 0, @@ -44,8 +46,7 @@ def test_local_message_signer__sign_order(): "takerAssetAmount": 0, "expirationTimeSeconds": 0, } - order_hash = generate_order_hash_hex(order, exchange) + order_hash = generate_order_hash_hex(order, exchange, chain_id=1337) signature = sign_hash(ganache, to_checksum_address(address), order_hash) assert signature == expected_signature - is_valid = is_valid_signature(ganache, order_hash, signature, address)[0] - assert is_valid is True + assert is_valid_signature(ganache, order_hash, signature, address) diff --git a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py index 0494f41044..174e21dcba 100644 --- a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py +++ b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py @@ -31,6 +31,8 @@ from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId import zero_ex.contract_artifacts +from zero_ex.contract_wrappers.exchange import Exchange +from zero_ex.contract_wrappers.exchange.types import Order from zero_ex.contract_wrappers.order_conversions import order_to_jsdict from zero_ex.dev_utils.type_assertions import ( assert_is_address, @@ -48,13 +50,18 @@ class _Constants: eip191_header = b"\x19\x01" eip712_domain_separator_schema_hash = keccak( - b"EIP712Domain(string name,string version,address verifyingContract)" + b"EIP712Domain(" + + b"string name," + + b"string version," + + b"uint256 chainId," + + b"address verifyingContract" + + b")" ) eip712_domain_struct_header = ( eip712_domain_separator_schema_hash + keccak(b"0x Protocol") - + keccak(b"2") + + keccak(b"3.0.0") ) eip712_order_schema_hash = keccak( @@ -70,7 +77,9 @@ class _Constants: + b"uint256 expirationTimeSeconds," + b"uint256 salt," + b"bytes makerAssetData," - + b"bytes takerAssetData" + + b"bytes takerAssetData," + + b"bytes makerFeeAssetData," + + b"bytes takerFeeAssetData" + b")" ) @@ -87,7 +96,9 @@ class SignatureType(Enum): N_SIGNATURE_TYPES = auto() -def generate_order_hash_hex(order: Order, exchange_address: str) -> str: +def generate_order_hash_hex( + order: Order, exchange_address: str, chain_id: int +) -> str: """Calculate the hash of the given order as a hexadecimal string. :param order: The order to be hashed. Must conform to `the 0x order JSON schema `_. @@ -95,27 +106,35 @@ def generate_order_hash_hex(order: Order, exchange_address: str) -> str: contract has been deployed. :returns: A string, of ASCII hex digits, representing the order hash. + Inputs and expected result below were copied from + @0x/order-utils/test/order_hash_test.ts + >>> generate_order_hash_hex( ... Order( ... makerAddress="0x0000000000000000000000000000000000000000", ... takerAddress="0x0000000000000000000000000000000000000000", ... feeRecipientAddress="0x0000000000000000000000000000000000000000", ... senderAddress="0x0000000000000000000000000000000000000000", - ... makerAssetAmount="1000000000000000000", - ... takerAssetAmount="1000000000000000000", + ... makerAssetAmount="0", + ... takerAssetAmount="0", ... makerFee="0", ... takerFee="0", - ... expirationTimeSeconds="12345", - ... salt="12345", + ... expirationTimeSeconds="0", + ... salt="0", ... makerAssetData=((0).to_bytes(1, byteorder='big') * 20), ... takerAssetData=((0).to_bytes(1, byteorder='big') * 20), + ... makerFeeAssetData=((0).to_bytes(1, byteorder='big') * 20), + ... takerFeeAssetData=((0).to_bytes(1, byteorder='big') * 20), ... ), - ... exchange_address="0x0000000000000000000000000000000000000000", + ... exchange_address="0x1dc4c1cefef38a777b15aa20260a54e584b16c48", + ... chain_id=50 ... ) - '55eaa6ec02f3224d30873577e9ddd069a288c16d6fb407210eecbc501fa76692' + '331cb7e07a757bae130702da6646c26531798c92bcfaf671817268fd2c188531' """ # noqa: E501 (line too long) assert_is_address(exchange_address, "exchange_address") - assert_valid(order_to_jsdict(order, exchange_address), "/orderSchema") + assert_valid( + order_to_jsdict(order, chain_id, exchange_address), "/orderSchema" + ) def pad_20_bytes_to_32(twenty_bytes: bytes): return bytes(12) + twenty_bytes @@ -125,6 +144,7 @@ def int_to_32_big_endian_bytes(i: int): eip712_domain_struct_hash = keccak( _Constants.eip712_domain_struct_header + + int_to_32_big_endian_bytes(int(chain_id)) + pad_20_bytes_to_32(to_bytes(hexstr=exchange_address)) ) @@ -142,6 +162,8 @@ def int_to_32_big_endian_bytes(i: int): + int_to_32_big_endian_bytes(int(order["salt"])) + keccak(to_bytes(hexstr=order["makerAssetData"].hex())) + keccak(to_bytes(hexstr=order["takerAssetData"].hex())) + + keccak(to_bytes(hexstr=order["makerFeeAssetData"].hex())) + + keccak(to_bytes(hexstr=order["takerFeeAssetData"].hex())) ) return keccak( @@ -153,7 +175,7 @@ def int_to_32_big_endian_bytes(i: int): def is_valid_signature( provider: BaseProvider, data: str, signature: str, signer_address: str -) -> Tuple[bool, str]: +) -> bool: """Check the validity of the supplied signature. Check if the supplied `signature`:code: corresponds to signing `data`:code: @@ -173,42 +195,25 @@ def is_valid_signature( ... '0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403', ... '0x5409ed021d9299bf6814279a6a1411a7e866a631', ... ) - (True, '') + True """ # noqa: E501 (line too long) assert_is_provider(provider, "provider") assert_is_hex_string(data, "data") assert_is_hex_string(signature, "signature") assert_is_address(signer_address, "signer_address") - web3_instance = Web3(provider) - # false positive from pylint: disable=no-member - contract_address = NETWORK_TO_ADDRESSES[ - NetworkId(int(web3_instance.net.version)) - ].exchange - # false positive from pylint: disable=no-member - contract: Contract = web3_instance.eth.contract( - address=to_checksum_address(contract_address), - abi=zero_ex.contract_artifacts.abi_by_name("Exchange"), + return Exchange( + provider, + NETWORK_TO_ADDRESSES[ + NetworkId( + int(Web3(provider).net.version) # pylint: disable=no-member + ) + ].exchange, + ).is_valid_hash_signature.call( + bytes.fromhex(remove_0x_prefix(data)), + to_checksum_address(signer_address), + bytes.fromhex(remove_0x_prefix(signature)), ) - try: - return ( - contract.functions.isValidSignature( - data, to_checksum_address(signer_address), signature - ).call(), - "", - ) - except web3.exceptions.BadFunctionCallOutput as exception: - known_revert_reasons = [ - "LENGTH_GREATER_THAN_0_REQUIRED", - "SIGNATURE_ILLEGAL", - "SIGNATURE_UNSUPPORTED", - "LENGTH_0_REQUIRED", - "LENGTH_65_REQUIRED", - ] - for known_revert_reason in known_revert_reasons: - if known_revert_reason in str(exception): - return (False, known_revert_reason) - return (False, f"Unknown: {exception}") class ECSignature(TypedDict): @@ -319,7 +324,7 @@ def sign_hash( ).hex() ) - (valid, _) = is_valid_signature( + valid = is_valid_signature( provider, hash_hex, signature_as_vrst_hex, signer_address ) @@ -334,7 +339,7 @@ def sign_hash( 1, byteorder="big" ).hex() ) - (valid, _) = is_valid_signature( + valid = is_valid_signature( provider, hash_hex, signature_as_vrst_hex, signer_address ) @@ -342,8 +347,8 @@ def sign_hash( return signature_as_vrst_hex raise RuntimeError( - "Signature returned from web3 provider is in an unknown format." - + " Attempted to parse as RSV and as VRS." + "Signature returned from web3 provider is in an unknown format. " + + "Signature was: {signature}" ) diff --git a/python-packages/order_utils/test/test_generate_order_hash_hex.py b/python-packages/order_utils/test/test_generate_order_hash_hex.py index 21b8dda2db..cb6dca35c7 100644 --- a/python-packages/order_utils/test/test_generate_order_hash_hex.py +++ b/python-packages/order_utils/test/test_generate_order_hash_hex.py @@ -6,7 +6,7 @@ def test_get_order_hash_hex__empty_order(): """Test the hashing of an uninitialized order.""" expected_hash_hex = ( - "faa49b35faeb9197e9c3ba7a52075e6dad19739549f153b77dfcf59408a4b422" + "331cb7e07a757bae130702da6646c26531798c92bcfaf671817268fd2c188531" ) actual_hash_hex = generate_order_hash_hex( { @@ -18,6 +18,8 @@ def test_get_order_hash_hex__empty_order(): ), "makerAssetData": (b"\x00") * 20, "takerAssetData": (b"\x00") * 20, + "makerFeeAssetData": (b"\x00") * 20, + "takerFeeAssetData": (b"\x00") * 20, "salt": 0, "makerFee": 0, "takerFee": 0, @@ -25,6 +27,7 @@ def test_get_order_hash_hex__empty_order(): "takerAssetAmount": 0, "expirationTimeSeconds": 0, }, - "0x0000000000000000000000000000000000000000", + "0x1dc4c1cefef38a777b15aa20260a54e584b16c48", + 50, ) assert actual_hash_hex == expected_hash_hex diff --git a/python-packages/order_utils/test/test_signature_utils.py b/python-packages/order_utils/test/test_signature_utils.py index a542f8eba3..7bcd090169 100644 --- a/python-packages/order_utils/test/test_signature_utils.py +++ b/python-packages/order_utils/test/test_signature_utils.py @@ -3,6 +3,10 @@ import pytest from web3 import Web3 +from zero_ex.contract_wrappers.exchange.exceptions import ( + SignatureError, + SignatureErrorCodes, +) from zero_ex.order_utils import is_valid_signature, sign_hash_to_bytes @@ -117,28 +121,49 @@ def test_is_valid_signature__unsupported_sig_types(): To induce this error, the last byte of the signature is tweaked from 03 to ff.""" - (is_valid, reason) = is_valid_signature( - Web3.HTTPProvider("http://127.0.0.1:8545"), - "0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0", - "0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc334" - + "0349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254ff", - "0x5409ed021d9299bf6814279a6a1411a7e866a631", - ) - assert is_valid is False - assert reason == "SIGNATURE_UNSUPPORTED" + try: + is_valid_signature( + Web3.HTTPProvider("http://127.0.0.1:8545"), + "0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222" + + "b0", + "0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b" + + "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace" + + "225401", + "0x5409ed021d9299bf6814279a6a1411a7e866a631", + ) + except SignatureError as signature_error: + assert ( + signature_error.errorCode + == SignatureErrorCodes.INVALID_LENGTH.value + ) + else: + pytest.fail("Expected exception") -def test_sign_hash_to_bytes__golden_path(): +def test_sign_hash_to_bytes_and_validate__golden_path(): """Test the happy path through sign_hash_to_bytes().""" provider = Web3.HTTPProvider("http://127.0.0.1:8545") - signature = sign_hash_to_bytes( - provider, - Web3( # pylint: disable=no-member - provider - ).geth.personal.listAccounts()[0], - "0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004", + + signing_address = Web3( # pylint: disable=no-member + provider + ).geth.personal.listAccounts()[0] + + order_hash_hex = ( + "0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004" ) + + signature = sign_hash_to_bytes(provider, signing_address, order_hash_hex) + assert ( signature == b"1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03" # noqa: E501 (line too long) ) + + is_valid = is_valid_signature( + Web3.HTTPProvider("http://127.0.0.1:8545"), + order_hash_hex, + signature.decode("utf-8"), + signing_address, + ) + + assert is_valid is True From 76e8f1782e92af45cc536ecb02ce3f267ab191a6 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 28 Oct 2019 08:09:08 -0400 Subject: [PATCH 10/35] Fix typo in DevUtils documentation --- python-packages/contract_wrappers/src/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python-packages/contract_wrappers/src/index.rst b/python-packages/contract_wrappers/src/index.rst index f3c97a34e5..12ec319378 100644 --- a/python-packages/contract_wrappers/src/index.rst +++ b/python-packages/contract_wrappers/src/index.rst @@ -34,7 +34,7 @@ zero_ex.contract_wrappers.coordinator_registry zero_ex.contract_wrappers.dev_utils -======================================= +=================================== .. automodule:: zero_ex.contract_wrappers.dev_utils :members: From d70289070e5ef714b94a8cde2ff31abe676644cd Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 28 Oct 2019 08:11:45 -0400 Subject: [PATCH 11/35] Include new contracts in docs --- .../contract_wrappers/src/index.rst | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/python-packages/contract_wrappers/src/index.rst b/python-packages/contract_wrappers/src/index.rst index 12ec319378..7a20f701e2 100644 --- a/python-packages/contract_wrappers/src/index.rst +++ b/python-packages/contract_wrappers/src/index.rst @@ -49,6 +49,22 @@ zero_ex.contract_wrappers.dutch_auction :special-members: +zero_ex.contract_wrappers.erc1155_mintable +========================================== + +.. automodule:: zero_ex.contract_wrappers.erc1155_mintable + :members: + :special-members: + + +zero_ex.contract_wrappers.erc1155_proxy +======================================= + +.. automodule:: zero_ex.contract_wrappers.erc1155_proxy + :members: + :special-members: + + zero_ex.contract_wrappers.erc20_proxy ===================================== @@ -145,6 +161,14 @@ zero_ex.contract_wrappers.order_validator :special-members: +zero_ex.contract_wrappers.static_call_proxy +=========================================== + +.. automodule:: zero_ex.contract_wrappers.static_call_proxy + :members: + :special-members: + + zero_ex.contract_wrappers.weth9 =============================== From a04cec5bffbba3824dff43aa4edaafff46998c11 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 28 Oct 2019 08:12:07 -0400 Subject: [PATCH 12/35] Re-enable Python checks in CI --- .circleci/config.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 421c1d9a9d..87fc939706 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -192,7 +192,10 @@ jobs: working_directory: ~/repo docker: - image: nikolaik/python-nodejs:python3.7-nodejs8 - - image: 0xorg/ganache-cli:2.2.2 + - image: 0xorg/ganache-cli:4.4.0-beta.1 + environment: + VERSION: 4.4.0-beta.1 + SNAPSHOT_NAME: 0x_ganache_snapshot-v3-beta - image: 0xorg/launch-kit-backend:74bcc39 environment: RPC_URL: http://localhost:8545 @@ -426,12 +429,11 @@ workflows: - test-exchange-ganache-3.0 - test-rest - static-tests - # - test-python: - # requires: - # - build - # - test-rest - # - static-tests-python: - # requires: - # - test-python + - test-python: + requires: + - build + - static-tests-python: + requires: + - build # skip python tox run for now, as we don't yet have multiple test environments to support. # - test-rest-python From 4b02dcc6ec1fb5259eb461fa663d56f8467fecf4 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 18 Oct 2019 20:57:33 -0400 Subject: [PATCH 13/35] Accept strings for bytes --- packages/abi-gen/src/utils.ts | 2 +- .../output/python/abi_gen_dummy/__init__.py | 62 ++++++++++--------- .../src/zero_ex/contract_wrappers/__init__.py | 4 +- .../contract_wrappers/order_conversions.py | 23 +++++-- .../src/zero_ex/order_utils/__init__.py | 19 ++++-- 5 files changed, 67 insertions(+), 43 deletions(-) diff --git a/packages/abi-gen/src/utils.ts b/packages/abi-gen/src/utils.ts index bb5a2d7812..8828ce009b 100644 --- a/packages/abi-gen/src/utils.ts +++ b/packages/abi-gen/src/utils.ts @@ -115,7 +115,7 @@ export const utils = { { regex: '^address$', pyType: 'str' }, { regex: '^bool$', pyType: 'bool' }, { regex: '^u?int\\d*$', pyType: 'int' }, - { regex: '^bytes\\d*$', pyType: 'bytes' }, + { regex: '^bytes\\d*$', pyType: 'Union[bytes, str]' }, ]; for (const regexAndTxType of solTypeRegexToPyType) { const { regex, pyType } = regexAndTxType; diff --git a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py index 98bb551cde..11fdfe76e6 100644 --- a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py @@ -100,11 +100,11 @@ class Tuple0xcf8ad995(TypedDict): accomplished via `str.encode("utf_8")`:code: """ - someBytes: bytes + someBytes: Union[bytes, str] anInteger: int - aDynamicArrayOfBytes: List[bytes] + aDynamicArrayOfBytes: List[Union[bytes, str]] aString: str @@ -148,7 +148,7 @@ class Tuple0xf95128ef(TypedDict): foo: int - bar: bytes + bar: Union[bytes, str] car: str @@ -171,9 +171,9 @@ class Tuple0xa057bf41(TypedDict): input: Tuple0xf95128ef - lorem: bytes + lorem: Union[bytes, str] - ipsum: bytes + ipsum: Union[bytes, str] dolor: str @@ -232,7 +232,7 @@ def __init__( super().__init__(provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, a: List[bytes]): + def validate_and_normalize_inputs(self, a: List[Union[bytes, str]]): """Validate the inputs to the acceptsAnArrayOfBytes method.""" self.validator.assert_valid( method_name="acceptsAnArrayOfBytes", @@ -242,7 +242,7 @@ def validate_and_normalize_inputs(self, a: List[bytes]): return a def call( - self, a: List[bytes], tx_params: Optional[TxParams] = None + self, a: List[Union[bytes, str]], tx_params: Optional[TxParams] = None ) -> None: """Execute underlying contract method via eth_call. @@ -257,7 +257,7 @@ def call( return self.underlying_method(a).call(tx_params.as_dict()) def send_transaction( - self, a: List[bytes], tx_params: Optional[TxParams] = None + self, a: List[Union[bytes, str]], tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. @@ -272,7 +272,7 @@ def send_transaction( return self.underlying_method(a).transact(tx_params.as_dict()) def estimate_gas( - self, a: List[bytes], tx_params: Optional[TxParams] = None + self, a: List[Union[bytes, str]], tx_params: Optional[TxParams] = None ) -> int: """Estimate gas consumption of method call.""" (a) = self.validate_and_normalize_inputs(a) @@ -410,7 +410,7 @@ def __init__( self.underlying_method = contract_function def validate_and_normalize_inputs( - self, index_0: int, index_1: bytes, index_2: str + self, index_0: int, index_1: Union[bytes, str], index_2: str ): """Validate the inputs to the multiInputMultiOutput method.""" self.validator.assert_valid( @@ -435,10 +435,10 @@ def validate_and_normalize_inputs( def call( self, index_0: int, - index_1: bytes, + index_1: Union[bytes, str], index_2: str, tx_params: Optional[TxParams] = None, - ) -> Tuple[bytes, bytes, str]: + ) -> Tuple[Union[bytes, str], Union[bytes, str], str]: """Execute underlying contract method via eth_call. Tests decoding when the input and output are complex and have more than @@ -458,7 +458,7 @@ def call( def send_transaction( self, index_0: int, - index_1: bytes, + index_1: Union[bytes, str], index_2: str, tx_params: Optional[TxParams] = None, ) -> Union[HexBytes, bytes]: @@ -481,7 +481,7 @@ def send_transaction( def estimate_gas( self, index_0: int, - index_1: bytes, + index_1: Union[bytes, str], index_2: str, tx_params: Optional[TxParams] = None, ) -> int: @@ -510,7 +510,11 @@ def __init__( self.underlying_method = contract_function def validate_and_normalize_inputs( - self, _hash: bytes, v: int, r: bytes, s: bytes + self, + _hash: Union[bytes, str], + v: int, + r: Union[bytes, str], + s: Union[bytes, str], ): """Validate the inputs to the ecrecoverFn method.""" self.validator.assert_valid( @@ -531,10 +535,10 @@ def validate_and_normalize_inputs( def call( self, - _hash: bytes, + _hash: Union[bytes, str], v: int, - r: bytes, - s: bytes, + r: Union[bytes, str], + s: Union[bytes, str], tx_params: Optional[TxParams] = None, ) -> str: """Execute underlying contract method via eth_call. @@ -559,10 +563,10 @@ def call( def send_transaction( self, - _hash: bytes, + _hash: Union[bytes, str], v: int, - r: bytes, - s: bytes, + r: Union[bytes, str], + s: Union[bytes, str], tx_params: Optional[TxParams] = None, ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. @@ -589,10 +593,10 @@ def send_transaction( def estimate_gas( self, - _hash: bytes, + _hash: Union[bytes, str], v: int, - r: bytes, - s: bytes, + r: Union[bytes, str], + s: Union[bytes, str], tx_params: Optional[TxParams] = None, ) -> int: """Estimate gas consumption of method call.""" @@ -617,14 +621,16 @@ def __init__( super().__init__(provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, a: bytes): + def validate_and_normalize_inputs(self, a: Union[bytes, str]): """Validate the inputs to the acceptsBytes method.""" self.validator.assert_valid( method_name="acceptsBytes", parameter_name="a", argument_value=a ) return a - def call(self, a: bytes, tx_params: Optional[TxParams] = None) -> None: + def call( + self, a: Union[bytes, str], tx_params: Optional[TxParams] = None + ) -> None: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters @@ -635,7 +641,7 @@ def call(self, a: bytes, tx_params: Optional[TxParams] = None) -> None: return self.underlying_method(a).call(tx_params.as_dict()) def send_transaction( - self, a: bytes, tx_params: Optional[TxParams] = None + self, a: Union[bytes, str], tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. @@ -647,7 +653,7 @@ def send_transaction( return self.underlying_method(a).transact(tx_params.as_dict()) def estimate_gas( - self, a: bytes, tx_params: Optional[TxParams] = None + self, a: Union[bytes, str], tx_params: Optional[TxParams] = None ) -> int: """Estimate gas consumption of method call.""" (a) = self.validate_and_normalize_inputs(a) diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py index 98be012a96..a80c089c1c 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py @@ -136,8 +136,8 @@ ... expirationTimeSeconds=round( ... (datetime.utcnow() + timedelta(days=1)).timestamp() ... ), -... makerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), -... takerFeeAssetData=asset_data_utils.encode_erc20('0x' + '00'*20), +... makerFeeAssetData='0x', +... takerFeeAssetData='0x', ... chain_id=Web3(ganache).eth.chainId, ... ) diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py index 42fe5457ca..138e125eeb 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_conversions.py @@ -1,7 +1,7 @@ """Utilities to convert between JSON and Python-native objects.""" from copy import copy -from typing import cast, Dict +from typing import cast, Dict, Union from eth_utils import remove_0x_prefix @@ -60,11 +60,22 @@ def order_to_jsdict( """ jsdict = cast(Dict, copy(order)) - # encode bytes fields - jsdict["makerAssetData"] = "0x" + order["makerAssetData"].hex() - jsdict["makerFeeAssetData"] = "0x" + order["makerFeeAssetData"].hex() - jsdict["takerAssetData"] = "0x" + order["takerAssetData"].hex() - jsdict["takerFeeAssetData"] = "0x" + order["takerFeeAssetData"].hex() + def encode_bytes(bytes_or_str: Union[bytes, str]) -> bytes: + def ensure_hex_prefix(hex_str: str): + if hex_str[0:2] != "0x": + hex_str = "0x" + hex_str + return hex_str + + return ensure_hex_prefix( + cast(bytes, bytes_or_str).hex() + if isinstance(bytes_or_str, bytes) + else bytes_or_str + ) + + jsdict["makerAssetData"] = encode_bytes(order["makerAssetData"]) + jsdict["takerAssetData"] = encode_bytes(order["takerAssetData"]) + jsdict["makerFeeAssetData"] = encode_bytes(order["makerFeeAssetData"]) + jsdict["takerFeeAssetData"] = encode_bytes(order["takerFeeAssetData"]) jsdict["exchangeAddress"] = exchange_address diff --git a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py index 174e21dcba..b09e0431de 100644 --- a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py +++ b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py @@ -18,9 +18,9 @@ from enum import auto, Enum import json -from typing import Tuple -from pkg_resources import resource_string +from typing import cast, Tuple, Union +from pkg_resources import resource_string from mypy_extensions import TypedDict from eth_utils import keccak, remove_0x_prefix, to_bytes, to_checksum_address @@ -148,6 +148,13 @@ def int_to_32_big_endian_bytes(i: int): + pad_20_bytes_to_32(to_bytes(hexstr=exchange_address)) ) + def ensure_bytes(str_or_bytes: Union[str, bytes]) -> bytes: + return ( + to_bytes(hexstr=cast(bytes, str_or_bytes)) + if isinstance(str_or_bytes, str) + else str_or_bytes + ) + eip712_order_struct_hash = keccak( _Constants.eip712_order_schema_hash + pad_20_bytes_to_32(to_bytes(hexstr=order["makerAddress"])) @@ -160,10 +167,10 @@ def int_to_32_big_endian_bytes(i: int): + int_to_32_big_endian_bytes(int(order["takerFee"])) + int_to_32_big_endian_bytes(int(order["expirationTimeSeconds"])) + int_to_32_big_endian_bytes(int(order["salt"])) - + keccak(to_bytes(hexstr=order["makerAssetData"].hex())) - + keccak(to_bytes(hexstr=order["takerAssetData"].hex())) - + keccak(to_bytes(hexstr=order["makerFeeAssetData"].hex())) - + keccak(to_bytes(hexstr=order["takerFeeAssetData"].hex())) + + keccak(ensure_bytes(order["makerAssetData"])) + + keccak(ensure_bytes(order["takerAssetData"])) + + keccak(ensure_bytes(order["makerFeeAssetData"])) + + keccak(ensure_bytes(order["takerFeeAssetData"])) ) return keccak( From 3a8d2a6cf8aedf7e645a8f459eb3a33de82e33d4 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Wed, 23 Oct 2019 12:12:52 -0400 Subject: [PATCH 14/35] Fix CircleCI build artifacts for gen'd python I swear the previous way was working before, but it wasn't working now, so this fixes it. --- .circleci/config.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 87fc939706..96e6213f50 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -226,6 +226,12 @@ jobs: cd python-packages ./parallel_without_sra_client coverage run setup.py test ./build_docs + - run: + command: | + # copy generated wrappers into contract_wrappers/build, + # JUST so CircleCI will persist them as build artifacts. + cd python-packages/contract_wrappers/src/zero_ex + for i in contract_wrappers/[^__]*/; do mkdir -p ../../build/$i; cp $i/__init__.py ../../build/$i; done - save_cache: key: coverage-python-contract-addresses-{{ .Environment.CIRCLE_SHA1 }} paths: @@ -250,8 +256,6 @@ jobs: key: coverage-python-sra-client-{{ .Environment.CIRCLE_SHA1 }} paths: - ~/repo/python-packages/sra_client/.coverage - - store_artifacts: - path: ~/repo/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/*/__init__.py - store_artifacts: path: ~/repo/python-packages/contract_addresses/build - store_artifacts: From 348a7184fc1a55bb73e98cc0252060644ac92a31 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Wed, 23 Oct 2019 16:53:23 -0400 Subject: [PATCH 15/35] Accept a provider OR a Web3 object In various places. This allows the caller to install middleware (which in web3.py is installed on a Web3 object, not on a provider) before executing any RPC calls, which is important for the case where one wants to produce signatures locally before submitting to a remote node. --- .../templates/Python/contract.handlebars | 34 ++- .../Python/partials/method_class.handlebars | 4 +- .../output/python/abi_gen_dummy/__init__.py | 262 +++++++++++------- .../output/python/lib_dummy/__init__.py | 34 ++- .../output/python/test_lib_dummy/__init__.py | 54 +++- .../src/zero_ex/contract_wrappers/__init__.py | 6 +- .../src/zero_ex/contract_wrappers/bases.py | 25 +- .../contract_wrappers/exchange/validator.py | 28 +- .../test/test_base_contract_method.py | 2 +- .../test/test_exchange_wrapper.py | 19 +- .../test/test_local_message_signer.py | 18 +- .../src/zero_ex/order_utils/__init__.py | 36 ++- .../order_utils/stubs/web3/__init__.pyi | 2 + 13 files changed, 357 insertions(+), 167 deletions(-) diff --git a/packages/abi-gen/templates/Python/contract.handlebars b/packages/abi-gen/templates/Python/contract.handlebars index 38afd29ef0..dbabff2b55 100644 --- a/packages/abi-gen/templates/Python/contract.handlebars +++ b/packages/abi-gen/templates/Python/contract.handlebars @@ -65,13 +65,14 @@ class {{contractName}}: def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, validator: {{contractName}}Validator = None, ): """Get an instance of wrapper for smart contract. - :param provider: instance of :class:`web3.providers.base.BaseProvider` + :param web3_or_provider: Either an instance of `web3.Web3`:code: or + `web3.providers.base.BaseProvider`:code: :param contract_address: where the contract has been deployed :param validator: for validation of method inputs. """ @@ -80,9 +81,18 @@ class {{contractName}}: self.contract_address = contract_address if not validator: - validator = {{contractName}}Validator(provider, contract_address) - - web3 = Web3(provider) + validator = {{contractName}}Validator(web3_or_provider, contract_address) + + web3 = None + if isinstance(web3_or_provider, BaseProvider): + web3 = Web3(web3_or_provider) + elif isinstance(web3_or_provider, Web3): + web3 = web3_or_provider + if web3 is None: + raise TypeError( + "Expected parameter 'web3_or_provider' to be an instance of either" + + " Web3 or BaseProvider" + ) # if any middleware was imported, inject it try: @@ -90,10 +100,14 @@ class {{contractName}}: except NameError: pass else: - for middleware in MIDDLEWARE: - web3.middleware_onion.inject( # type: ignore - middleware['function'], layer=middleware['layer'], - ) + try: + for middleware in MIDDLEWARE: + web3.middleware_onion.inject( # type: ignore + middleware['function'], layer=middleware['layer'], + ) + except ValueError as value_error: + if value_error.args == ("You can't add the same un-named instance twice",): + pass self._web3_eth = ( web3.eth # type: ignore # pylint: disable=no-member @@ -103,7 +117,7 @@ class {{contractName}}: functions = self._web3_eth.contract(address=to_checksum_address(contract_address), abi={{contractName}}.abi()).functions {{#each methods}} - self.{{toPythonIdentifier this.languageSpecificName}} = {{toPythonClassname this.languageSpecificName}}Method(provider, contract_address, functions.{{this.name}}, validator) + self.{{toPythonIdentifier this.languageSpecificName}} = {{toPythonClassname this.languageSpecificName}}Method(web3_or_provider, contract_address, functions.{{this.name}}, validator) {{/each}} {{/if}} diff --git a/packages/abi-gen/templates/Python/partials/method_class.handlebars b/packages/abi-gen/templates/Python/partials/method_class.handlebars index 6bbbb07684..2586142662 100644 --- a/packages/abi-gen/templates/Python/partials/method_class.handlebars +++ b/packages/abi-gen/templates/Python/partials/method_class.handlebars @@ -2,9 +2,9 @@ class {{toPythonClassname this.languageSpecificName}}Method(ContractMethod): """Various interfaces to the {{this.name}} method.""" - def __init__(self, provider: BaseProvider, contract_address: str, contract_function: ContractFunction, validator: Validator=None): + def __init__(self, web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator=None): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function {{#if inputs}} diff --git a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py index 11fdfe76e6..d2536618cb 100644 --- a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py @@ -183,13 +183,13 @@ class SimpleRequireMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> None: @@ -223,13 +223,13 @@ class AcceptsAnArrayOfBytesMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, a: List[Union[bytes, str]]): @@ -285,13 +285,13 @@ class SimpleInputSimpleOutputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, index_0: int): @@ -345,13 +345,13 @@ class WithdrawMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, wad: int): @@ -400,13 +400,13 @@ class MultiInputMultiOutputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs( @@ -500,13 +500,13 @@ class EcrecoverFnMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs( @@ -612,13 +612,13 @@ class AcceptsBytesMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, a: Union[bytes, str]): @@ -666,13 +666,13 @@ class NoInputSimpleOutputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> int: @@ -710,13 +710,13 @@ class RevertWithConstantMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> None: @@ -750,13 +750,13 @@ class SimpleRevertMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> None: @@ -792,13 +792,13 @@ class MethodUsingNestedStructWithInnerStructNotUsedElsewhereMethod( def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> Tuple0x1b9da225: @@ -832,13 +832,13 @@ class NestedStructOutputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> Tuple0xc9bdd2d5: @@ -872,13 +872,13 @@ class RequireWithConstantMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> None: @@ -912,13 +912,13 @@ class WithAddressInputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs( @@ -1020,13 +1020,13 @@ class StructInputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, s: Tuple0xcf8ad995): @@ -1074,13 +1074,13 @@ class NonPureMethodMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call( @@ -1115,13 +1115,13 @@ class ComplexInputComplexOutputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, complex_input: Tuple0xf95128ef): @@ -1185,13 +1185,13 @@ class NoInputNoOutputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> None: @@ -1229,13 +1229,13 @@ class SimplePureFunctionWithInputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, x: int): @@ -1285,13 +1285,13 @@ class NonPureMethodThatReturnsNothingMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call( @@ -1326,13 +1326,13 @@ class SimplePureFunctionMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> int: @@ -1366,13 +1366,13 @@ class NestedStructInputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, n: Tuple0xc9bdd2d5): @@ -1422,13 +1422,13 @@ class MethodReturningMultipleValuesMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> Tuple[int, str]: @@ -1462,13 +1462,13 @@ class MethodReturningArrayOfStructsMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call( @@ -1504,13 +1504,13 @@ class EmitSimpleEventMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call( @@ -1545,13 +1545,13 @@ class StructOutputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> Tuple0xcf8ad995: @@ -1589,13 +1589,13 @@ class PureFunctionWithConstantMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def call(self, tx_params: Optional[TxParams] = None) -> int: @@ -1629,13 +1629,13 @@ class SimpleInputNoOutputMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, index_0: int): @@ -1689,13 +1689,13 @@ class OverloadedMethod2Method(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, a: str): @@ -1743,13 +1743,13 @@ class OverloadedMethod1Method(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, a: int): @@ -1952,13 +1952,14 @@ class AbiGenDummy: def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, validator: AbiGenDummyValidator = None, ): """Get an instance of wrapper for smart contract. - :param provider: instance of :class:`web3.providers.base.BaseProvider` + :param web3_or_provider: Either an instance of `web3.Web3`:code: or + `web3.providers.base.BaseProvider`:code: :param contract_address: where the contract has been deployed :param validator: for validation of method inputs. """ @@ -1967,9 +1968,20 @@ def __init__( self.contract_address = contract_address if not validator: - validator = AbiGenDummyValidator(provider, contract_address) + validator = AbiGenDummyValidator( + web3_or_provider, contract_address + ) - web3 = Web3(provider) + web3 = None + if isinstance(web3_or_provider, BaseProvider): + web3 = Web3(web3_or_provider) + elif isinstance(web3_or_provider, Web3): + web3 = web3_or_provider + if web3 is None: + raise TypeError( + "Expected parameter 'web3_or_provider' to be an instance of either" + + " Web3 or BaseProvider" + ) # if any middleware was imported, inject it try: @@ -1977,10 +1989,16 @@ def __init__( except NameError: pass else: - for middleware in MIDDLEWARE: - web3.middleware_onion.inject( # type: ignore - middleware["function"], layer=middleware["layer"] - ) + try: + for middleware in MIDDLEWARE: + web3.middleware_onion.inject( # type: ignore + middleware["function"], layer=middleware["layer"] + ) + except ValueError as value_error: + if value_error.args == ( + "You can't add the same un-named instance twice", + ): + pass self._web3_eth = ( web3.eth # type: ignore # pylint: disable=no-member @@ -1992,162 +2010,210 @@ def __init__( ).functions self.simple_require = SimpleRequireMethod( - provider, contract_address, functions.simpleRequire, validator + web3_or_provider, + contract_address, + functions.simpleRequire, + validator, ) self.accepts_an_array_of_bytes = AcceptsAnArrayOfBytesMethod( - provider, + web3_or_provider, contract_address, functions.acceptsAnArrayOfBytes, validator, ) self.simple_input_simple_output = SimpleInputSimpleOutputMethod( - provider, + web3_or_provider, contract_address, functions.simpleInputSimpleOutput, validator, ) self.withdraw = WithdrawMethod( - provider, contract_address, functions.withdraw, validator + web3_or_provider, contract_address, functions.withdraw, validator ) self.multi_input_multi_output = MultiInputMultiOutputMethod( - provider, + web3_or_provider, contract_address, functions.multiInputMultiOutput, validator, ) self.ecrecover_fn = EcrecoverFnMethod( - provider, contract_address, functions.ecrecoverFn, validator + web3_or_provider, + contract_address, + functions.ecrecoverFn, + validator, ) self.accepts_bytes = AcceptsBytesMethod( - provider, contract_address, functions.acceptsBytes, validator + web3_or_provider, + contract_address, + functions.acceptsBytes, + validator, ) self.no_input_simple_output = NoInputSimpleOutputMethod( - provider, + web3_or_provider, contract_address, functions.noInputSimpleOutput, validator, ) self.revert_with_constant = RevertWithConstantMethod( - provider, contract_address, functions.revertWithConstant, validator + web3_or_provider, + contract_address, + functions.revertWithConstant, + validator, ) self.simple_revert = SimpleRevertMethod( - provider, contract_address, functions.simpleRevert, validator + web3_or_provider, + contract_address, + functions.simpleRevert, + validator, ) self.method_using_nested_struct_with_inner_struct_not_used_elsewhere = MethodUsingNestedStructWithInnerStructNotUsedElsewhereMethod( - provider, + web3_or_provider, contract_address, functions.methodUsingNestedStructWithInnerStructNotUsedElsewhere, validator, ) self.nested_struct_output = NestedStructOutputMethod( - provider, contract_address, functions.nestedStructOutput, validator + web3_or_provider, + contract_address, + functions.nestedStructOutput, + validator, ) self.require_with_constant = RequireWithConstantMethod( - provider, + web3_or_provider, contract_address, functions.requireWithConstant, validator, ) self.with_address_input = WithAddressInputMethod( - provider, contract_address, functions.withAddressInput, validator + web3_or_provider, + contract_address, + functions.withAddressInput, + validator, ) self.struct_input = StructInputMethod( - provider, contract_address, functions.structInput, validator + web3_or_provider, + contract_address, + functions.structInput, + validator, ) self.non_pure_method = NonPureMethodMethod( - provider, contract_address, functions.nonPureMethod, validator + web3_or_provider, + contract_address, + functions.nonPureMethod, + validator, ) self.complex_input_complex_output = ComplexInputComplexOutputMethod( - provider, + web3_or_provider, contract_address, functions.complexInputComplexOutput, validator, ) self.no_input_no_output = NoInputNoOutputMethod( - provider, contract_address, functions.noInputNoOutput, validator + web3_or_provider, + contract_address, + functions.noInputNoOutput, + validator, ) self.simple_pure_function_with_input = SimplePureFunctionWithInputMethod( - provider, + web3_or_provider, contract_address, functions.simplePureFunctionWithInput, validator, ) self.non_pure_method_that_returns_nothing = NonPureMethodThatReturnsNothingMethod( - provider, + web3_or_provider, contract_address, functions.nonPureMethodThatReturnsNothing, validator, ) self.simple_pure_function = SimplePureFunctionMethod( - provider, contract_address, functions.simplePureFunction, validator + web3_or_provider, + contract_address, + functions.simplePureFunction, + validator, ) self.nested_struct_input = NestedStructInputMethod( - provider, contract_address, functions.nestedStructInput, validator + web3_or_provider, + contract_address, + functions.nestedStructInput, + validator, ) self.method_returning_multiple_values = MethodReturningMultipleValuesMethod( - provider, + web3_or_provider, contract_address, functions.methodReturningMultipleValues, validator, ) self.method_returning_array_of_structs = MethodReturningArrayOfStructsMethod( - provider, + web3_or_provider, contract_address, functions.methodReturningArrayOfStructs, validator, ) self.emit_simple_event = EmitSimpleEventMethod( - provider, contract_address, functions.emitSimpleEvent, validator + web3_or_provider, + contract_address, + functions.emitSimpleEvent, + validator, ) self.struct_output = StructOutputMethod( - provider, contract_address, functions.structOutput, validator + web3_or_provider, + contract_address, + functions.structOutput, + validator, ) self.pure_function_with_constant = PureFunctionWithConstantMethod( - provider, + web3_or_provider, contract_address, functions.pureFunctionWithConstant, validator, ) self.simple_input_no_output = SimpleInputNoOutputMethod( - provider, + web3_or_provider, contract_address, functions.simpleInputNoOutput, validator, ) self.overloaded_method2 = OverloadedMethod2Method( - provider, contract_address, functions.overloadedMethod, validator + web3_or_provider, + contract_address, + functions.overloadedMethod, + validator, ) self.overloaded_method1 = OverloadedMethod1Method( - provider, contract_address, functions.overloadedMethod, validator + web3_or_provider, + contract_address, + functions.overloadedMethod, + validator, ) def get_withdrawal_event( diff --git a/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py index e5ec5d76cd..8a7e70e454 100644 --- a/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py @@ -52,13 +52,14 @@ class LibDummy: def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, validator: LibDummyValidator = None, ): """Get an instance of wrapper for smart contract. - :param provider: instance of :class:`web3.providers.base.BaseProvider` + :param web3_or_provider: Either an instance of `web3.Web3`:code: or + `web3.providers.base.BaseProvider`:code: :param contract_address: where the contract has been deployed :param validator: for validation of method inputs. """ @@ -67,9 +68,18 @@ def __init__( self.contract_address = contract_address if not validator: - validator = LibDummyValidator(provider, contract_address) - - web3 = Web3(provider) + validator = LibDummyValidator(web3_or_provider, contract_address) + + web3 = None + if isinstance(web3_or_provider, BaseProvider): + web3 = Web3(web3_or_provider) + elif isinstance(web3_or_provider, Web3): + web3 = web3_or_provider + if web3 is None: + raise TypeError( + "Expected parameter 'web3_or_provider' to be an instance of either" + + " Web3 or BaseProvider" + ) # if any middleware was imported, inject it try: @@ -77,10 +87,16 @@ def __init__( except NameError: pass else: - for middleware in MIDDLEWARE: - web3.middleware_onion.inject( # type: ignore - middleware["function"], layer=middleware["layer"] - ) + try: + for middleware in MIDDLEWARE: + web3.middleware_onion.inject( # type: ignore + middleware["function"], layer=middleware["layer"] + ) + except ValueError as value_error: + if value_error.args == ( + "You can't add the same un-named instance twice", + ): + pass self._web3_eth = ( web3.eth # type: ignore # pylint: disable=no-member diff --git a/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py index 7af4d6b224..ee16b23642 100644 --- a/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py @@ -51,13 +51,13 @@ class PublicAddConstantMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, x: int): @@ -107,13 +107,13 @@ class PublicAddOneMethod(ContractMethod): def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator = None, ): """Persist instance data.""" - super().__init__(provider, contract_address, validator) + super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function def validate_and_normalize_inputs(self, x: int): @@ -172,13 +172,14 @@ class TestLibDummy: def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, validator: TestLibDummyValidator = None, ): """Get an instance of wrapper for smart contract. - :param provider: instance of :class:`web3.providers.base.BaseProvider` + :param web3_or_provider: Either an instance of `web3.Web3`:code: or + `web3.providers.base.BaseProvider`:code: :param contract_address: where the contract has been deployed :param validator: for validation of method inputs. """ @@ -187,9 +188,20 @@ def __init__( self.contract_address = contract_address if not validator: - validator = TestLibDummyValidator(provider, contract_address) - - web3 = Web3(provider) + validator = TestLibDummyValidator( + web3_or_provider, contract_address + ) + + web3 = None + if isinstance(web3_or_provider, BaseProvider): + web3 = Web3(web3_or_provider) + elif isinstance(web3_or_provider, Web3): + web3 = web3_or_provider + if web3 is None: + raise TypeError( + "Expected parameter 'web3_or_provider' to be an instance of either" + + " Web3 or BaseProvider" + ) # if any middleware was imported, inject it try: @@ -197,10 +209,16 @@ def __init__( except NameError: pass else: - for middleware in MIDDLEWARE: - web3.middleware_onion.inject( # type: ignore - middleware["function"], layer=middleware["layer"] - ) + try: + for middleware in MIDDLEWARE: + web3.middleware_onion.inject( # type: ignore + middleware["function"], layer=middleware["layer"] + ) + except ValueError as value_error: + if value_error.args == ( + "You can't add the same un-named instance twice", + ): + pass self._web3_eth = ( web3.eth # type: ignore # pylint: disable=no-member @@ -212,11 +230,17 @@ def __init__( ).functions self.public_add_constant = PublicAddConstantMethod( - provider, contract_address, functions.publicAddConstant, validator + web3_or_provider, + contract_address, + functions.publicAddConstant, + validator, ) self.public_add_one = PublicAddOneMethod( - provider, contract_address, functions.publicAddOne, validator + web3_or_provider, + contract_address, + functions.publicAddOne, + validator, ) @staticmethod diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py index a80c089c1c..558588f179 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py @@ -92,11 +92,11 @@ >>> from zero_ex.contract_wrappers.erc20_token import ERC20Token >>> zrx_token = ERC20Token( -... provider=ganache, +... web3_or_provider=ganache, ... contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].zrx_token, ... ) >>> weth_token = ERC20Token( -... provider=ganache, +... web3_or_provider=ganache, ... contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].ether_token, ... ) @@ -165,7 +165,7 @@ >>> from zero_ex.contract_wrappers.exchange import Exchange >>> exchange = Exchange( -... provider=ganache, +... web3_or_provider=ganache, ... contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange, ... ) diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/bases.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/bases.py index 39280f4efe..a3fe5c6ff3 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/bases.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/bases.py @@ -1,6 +1,6 @@ """Base wrapper class for accessing ethereum smart contracts.""" -from typing import Any +from typing import Any, Union from eth_utils import is_address, to_checksum_address from web3 import Web3 @@ -12,7 +12,11 @@ class Validator: """Base class for validating inputs to methods.""" - def __init__(self, provider: BaseProvider, contract_address: str): + def __init__( + self, + web3_or_provider: Union[Web3, BaseProvider], + contract_address: str, + ): """Initialize the instance.""" def assert_valid( @@ -32,7 +36,7 @@ class ContractMethod: def __init__( self, - provider: BaseProvider, + web3_or_provider: Union[Web3, BaseProvider], contract_address: str, validator: Validator = None, ): @@ -42,9 +46,20 @@ def __init__( :param contract_address: Where the contract has been deployed to. :param validator: Used to validate method inputs. """ - self._web3_eth = Web3(provider).eth # pylint: disable=no-member + web3 = None + if isinstance(web3_or_provider, BaseProvider): + web3 = Web3(web3_or_provider) + elif isinstance(web3_or_provider, Web3): + web3 = web3_or_provider + if web3 is None: + raise TypeError( + "Expected parameter 'web3_or_provider' to be an instance of either" + + " Web3 or BaseProvider" + ) + + self._web3_eth = web3.eth # pylint: disable=no-member if validator is None: - validator = Validator(provider, contract_address) + validator = Validator(web3_or_provider, contract_address) self.validator = validator @staticmethod diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py index 5f56340ffd..a7264ab3d4 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py @@ -1,6 +1,6 @@ """Validate inputs to the Exchange contract.""" -from typing import Any +from typing import Any, Union from web3 import Web3 from web3.providers.base import BaseProvider @@ -14,13 +14,29 @@ class ExchangeValidator(Validator): """Validate inputs to Exchange methods.""" - def __init__(self, provider: BaseProvider, contract_address: str): + def __init__( + self, + web3_or_provider: Union[Web3, BaseProvider], + contract_address: str, + ): """Initialize the class.""" - super().__init__(provider, contract_address) + super().__init__(web3_or_provider, contract_address) + + web3 = None + if isinstance(web3_or_provider, BaseProvider): + web3 = Web3(web3_or_provider) + elif isinstance(web3_or_provider, Web3): + web3 = web3_or_provider + if web3 is None: + raise TypeError( + "Expected parameter 'web3_or_provider' to be an instance of either" + + " Web3 or BaseProvider" + ) + self.contract_address = contract_address - self.chain_id = Web3( # type: ignore # pylint: disable=no-member - provider - ).eth.chainId + self.chain_id = ( + web3.eth.chainId # type: ignore # pylint: disable=no-member + ) def assert_valid( self, method_name: str, parameter_name: str, argument_value: Any diff --git a/python-packages/contract_wrappers/test/test_base_contract_method.py b/python-packages/contract_wrappers/test/test_base_contract_method.py index 6b558b9fad..fd6e4d1731 100644 --- a/python-packages/contract_wrappers/test/test_base_contract_method.py +++ b/python-packages/contract_wrappers/test/test_base_contract_method.py @@ -10,6 +10,6 @@ def contract_wrapper(ganache_provider): """Get a ContractMethod instance for testing.""" return ContractMethod( - provider=ganache_provider, + web3_or_provider=ganache_provider, contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].ether_token, ) diff --git a/python-packages/contract_wrappers/test/test_exchange_wrapper.py b/python-packages/contract_wrappers/test/test_exchange_wrapper.py index 582d35f005..1da326d793 100644 --- a/python-packages/contract_wrappers/test/test_exchange_wrapper.py +++ b/python-packages/contract_wrappers/test/test_exchange_wrapper.py @@ -21,7 +21,7 @@ def exchange_wrapper(ganache_provider): """Get an Exchange wrapper instance.""" return Exchange( - provider=ganache_provider, + web3_or_provider=ganache_provider, contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange, ) @@ -149,3 +149,20 @@ def test_exchange_wrapper__batch_fill_orders( assert_fill_log( fill_events[index].args, maker, taker, order, order_hashes[index] ) + + +def test_two_instantiations_with_web3_objects(web3_instance): + """Test that instantiating two Exchange objects doesn't raise. + + When instantiating an Exchange object with a web3 client (rather than a + provider) there was a bug encountered where web3.py was giving an error + when trying to install the rich-revert-handling middleware on the web3 + client, an error saying "can't install this same middleware instance + again." Test that that bug isn't occurring. + """ + exchange = Exchange( # pylint: disable=unused-variable + web3_instance, NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange + ) + exchange2 = Exchange( # pylint: disable=unused-variable + web3_instance, NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange + ) diff --git a/python-packages/middlewares/test/test_local_message_signer.py b/python-packages/middlewares/test/test_local_message_signer.py index 6fbe0ba819..c49f667f0d 100644 --- a/python-packages/middlewares/test/test_local_message_signer.py +++ b/python-packages/middlewares/test/test_local_message_signer.py @@ -7,11 +7,7 @@ from zero_ex.middlewares.local_message_signer import ( construct_local_message_signer, ) -from zero_ex.order_utils import ( - generate_order_hash_hex, - is_valid_signature, - sign_hash, -) +from zero_ex.order_utils import generate_order_hash_hex, sign_hash def test_local_message_signer__sign_order(): @@ -46,7 +42,11 @@ def test_local_message_signer__sign_order(): "takerAssetAmount": 0, "expirationTimeSeconds": 0, } - order_hash = generate_order_hash_hex(order, exchange, chain_id=1337) - signature = sign_hash(ganache, to_checksum_address(address), order_hash) - assert signature == expected_signature - assert is_valid_signature(ganache, order_hash, signature, address) + assert ( + sign_hash( + web3_instance, + to_checksum_address(address), + generate_order_hash_hex(order, exchange, chain_id=1337), + ) + == expected_signature + ) diff --git a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py index b09e0431de..f14dd3570d 100644 --- a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py +++ b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py @@ -284,11 +284,14 @@ def _convert_ec_signature_to_vrs_hex(signature: ECSignature) -> str: def sign_hash( - provider: BaseProvider, signer_address: str, hash_hex: str + web3_or_provider: Union[Web3, BaseProvider], + signer_address: str, + hash_hex: str, ) -> str: """Sign a message with the given hash, and return the signature. - :param provider: A Web3 provider. + :param web3_or_provider: Either an instance of `web3.Web3`:code: or + `web3.providers.base.BaseProvider`:code: :param signer_address: The address of the signing account. :param hash_hex: A hex string representing the hash, like that returned from `generate_order_hash_hex()`:code:. @@ -302,11 +305,20 @@ def sign_hash( ... ) '0x1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03' """ # noqa: E501 (line too long) - assert_is_provider(provider, "provider") + web3_instance = None + if isinstance(web3_or_provider, BaseProvider): + web3_instance = Web3(web3_or_provider) + elif isinstance(web3_or_provider, Web3): + web3_instance = web3_or_provider + else: + raise TypeError( + "Expected parameter 'web3_or_provider' to be an instance of either" + + " Web3 or BaseProvider" + ) + assert_is_address(signer_address, "signer_address") assert_is_hex_string(hash_hex, "hash_hex") - web3_instance = Web3(provider) # false positive from pylint: disable=no-member signature = web3_instance.eth.sign( # type: ignore signer_address, hexstr=hash_hex.replace("0x", "") @@ -332,7 +344,10 @@ def sign_hash( ) valid = is_valid_signature( - provider, hash_hex, signature_as_vrst_hex, signer_address + web3_instance.provider, + hash_hex, + signature_as_vrst_hex, + signer_address, ) if valid is True: @@ -347,7 +362,10 @@ def sign_hash( ).hex() ) valid = is_valid_signature( - provider, hash_hex, signature_as_vrst_hex, signer_address + web3_instance.provider, + hash_hex, + signature_as_vrst_hex, + signer_address, ) if valid is True: @@ -360,7 +378,9 @@ def sign_hash( def sign_hash_to_bytes( - provider: BaseProvider, signer_address: str, hash_hex: str + web3_or_provider: Union[Web3, BaseProvider], + signer_address: str, + hash_hex: str, ) -> bytes: """Sign a message with the given hash, and return the signature. @@ -373,5 +393,5 @@ def sign_hash_to_bytes( '1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03' """ # noqa: E501 (line too long) return remove_0x_prefix( - sign_hash(provider, signer_address, hash_hex) + sign_hash(web3_or_provider, signer_address, hash_hex) ).encode(encoding="utf_8") diff --git a/python-packages/order_utils/stubs/web3/__init__.pyi b/python-packages/order_utils/stubs/web3/__init__.pyi index a1dd77adb4..a23a5141a8 100644 --- a/python-packages/order_utils/stubs/web3/__init__.pyi +++ b/python-packages/order_utils/stubs/web3/__init__.pyi @@ -34,4 +34,6 @@ class Web3: ... ... + provider: BaseProvider + ... From b2fbbe785cfe723c2474ea3291e26669aae70bcd Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 25 Oct 2019 15:59:19 -0400 Subject: [PATCH 16/35] wrapper base: don't assume there are accounts --- .../src/zero_ex/contract_wrappers/bases.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/bases.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/bases.py index a3fe5c6ff3..75878c77e0 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/bases.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/bases.py @@ -74,8 +74,13 @@ def normalize_tx_params(self, tx_params) -> TxParams: if not tx_params: tx_params = TxParams() if not tx_params.from_: - tx_params.from_ = ( - self._web3_eth.defaultAccount or self._web3_eth.accounts[0] + tx_params.from_ = self._web3_eth.defaultAccount or ( + self._web3_eth.accounts[0] + if len(self._web3_eth.accounts) > 0 + else None + ) + if tx_params.from_: + tx_params.from_ = self.validate_and_checksum_address( + tx_params.from_ ) - tx_params.from_ = self.validate_and_checksum_address(tx_params.from_) return tx_params From ea7760983d5f1b9d4e683d580b8e8704e2910d98 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Sun, 27 Oct 2019 13:27:53 -0400 Subject: [PATCH 17/35] Eliminate some inline linter directives --- .../abi-gen/templates/Python/contract.handlebars | 6 ++---- .../output/python/abi_gen_dummy/__init__.py | 6 ++---- .../test-cli/output/python/lib_dummy/__init__.py | 6 ++---- .../output/python/test_lib_dummy/__init__.py | 6 ++---- .../zero_ex/contract_wrappers/exchange/validator.py | 4 +--- .../contract_wrappers/stubs/web3/__init__.pyi | 13 ++++++++++++- 6 files changed, 21 insertions(+), 20 deletions(-) diff --git a/packages/abi-gen/templates/Python/contract.handlebars b/packages/abi-gen/templates/Python/contract.handlebars index dbabff2b55..5fa8dcfa51 100644 --- a/packages/abi-gen/templates/Python/contract.handlebars +++ b/packages/abi-gen/templates/Python/contract.handlebars @@ -102,16 +102,14 @@ class {{contractName}}: else: try: for middleware in MIDDLEWARE: - web3.middleware_onion.inject( # type: ignore + web3.middleware_onion.inject( middleware['function'], layer=middleware['layer'], ) except ValueError as value_error: if value_error.args == ("You can't add the same un-named instance twice",): pass - self._web3_eth = ( - web3.eth # type: ignore # pylint: disable=no-member - ) + self._web3_eth = web3.eth {{#if methods}} functions = self._web3_eth.contract(address=to_checksum_address(contract_address), abi={{contractName}}.abi()).functions diff --git a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py index d2536618cb..3982f02477 100644 --- a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py @@ -1991,7 +1991,7 @@ def __init__( else: try: for middleware in MIDDLEWARE: - web3.middleware_onion.inject( # type: ignore + web3.middleware_onion.inject( middleware["function"], layer=middleware["layer"] ) except ValueError as value_error: @@ -2000,9 +2000,7 @@ def __init__( ): pass - self._web3_eth = ( - web3.eth # type: ignore # pylint: disable=no-member - ) + self._web3_eth = web3.eth functions = self._web3_eth.contract( address=to_checksum_address(contract_address), diff --git a/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py index 8a7e70e454..11d4a39bef 100644 --- a/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py @@ -89,7 +89,7 @@ def __init__( else: try: for middleware in MIDDLEWARE: - web3.middleware_onion.inject( # type: ignore + web3.middleware_onion.inject( middleware["function"], layer=middleware["layer"] ) except ValueError as value_error: @@ -98,9 +98,7 @@ def __init__( ): pass - self._web3_eth = ( - web3.eth # type: ignore # pylint: disable=no-member - ) + self._web3_eth = web3.eth @staticmethod def abi(): diff --git a/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py index ee16b23642..321893ee3a 100644 --- a/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py @@ -211,7 +211,7 @@ def __init__( else: try: for middleware in MIDDLEWARE: - web3.middleware_onion.inject( # type: ignore + web3.middleware_onion.inject( middleware["function"], layer=middleware["layer"] ) except ValueError as value_error: @@ -220,9 +220,7 @@ def __init__( ): pass - self._web3_eth = ( - web3.eth # type: ignore # pylint: disable=no-member - ) + self._web3_eth = web3.eth functions = self._web3_eth.contract( address=to_checksum_address(contract_address), diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py index a7264ab3d4..bf9ec40a3b 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/validator.py @@ -34,9 +34,7 @@ def __init__( ) self.contract_address = contract_address - self.chain_id = ( - web3.eth.chainId # type: ignore # pylint: disable=no-member - ) + self.chain_id = web3.eth.chainId def assert_valid( self, method_name: str, parameter_name: str, argument_value: Any diff --git a/python-packages/contract_wrappers/stubs/web3/__init__.pyi b/python-packages/contract_wrappers/stubs/web3/__init__.pyi index ab531c1e73..1dfa4bb5f5 100644 --- a/python-packages/contract_wrappers/stubs/web3/__init__.pyi +++ b/python-packages/contract_wrappers/stubs/web3/__init__.pyi @@ -26,16 +26,24 @@ class Web3: class middleware_stack: @staticmethod def get(key: str) -> Callable: ... + + def inject( + self, middleware_func: object, layer: object + ) -> None: ... + ... + middleware_onion: middleware_stack + class net: version: str ... - class eth: + class Eth: defaultAccount: str accounts: List[str] + chainId: int ... class account: @@ -53,4 +61,7 @@ class Web3: @staticmethod def isAddress(address: str) -> bool: ... ... + + eth: Eth + ... From 6eb5ca00e5163cac421a99c46de66b1da658c5e6 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 28 Oct 2019 19:46:53 -0400 Subject: [PATCH 18/35] make CHANGELOGs be REVERSE chronological --- python-packages/contract_artifacts/CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python-packages/contract_artifacts/CHANGELOG.md b/python-packages/contract_artifacts/CHANGELOG.md index 3a4a5cca80..16afedf6e6 100644 --- a/python-packages/contract_artifacts/CHANGELOG.md +++ b/python-packages/contract_artifacts/CHANGELOG.md @@ -1,9 +1,9 @@ # Changelog -## 2.0.0 - 2019-01-09 - -- Initial release. - ## 2.0.1 - 2019-04-30 - Expanded documentation. + +## 2.0.0 - 2019-01-09 + +- Initial release. From bc354e341b3a1c7c06f819fc06eb2413569edada Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 28 Oct 2019 20:06:02 -0400 Subject: [PATCH 19/35] Update CHANGELOG entries and bump version numbers --- packages/abi-gen/CHANGELOG.json | 21 +++++++++++++++++++ .../contract_artifacts/CHANGELOG.md | 4 ++++ python-packages/contract_artifacts/setup.py | 2 +- .../contract_wrappers/CHANGELOG.md | 9 ++++++++ python-packages/contract_wrappers/setup.py | 2 +- python-packages/json_schemas/CHANGELOG.md | 4 ++++ python-packages/json_schemas/setup.py | 2 +- python-packages/middlewares/CHANGELOG.md | 2 +- python-packages/order_utils/CHANGELOG.md | 6 ++++++ python-packages/order_utils/setup.py | 2 +- 10 files changed, 49 insertions(+), 5 deletions(-) diff --git a/packages/abi-gen/CHANGELOG.json b/packages/abi-gen/CHANGELOG.json index 73b8d81211..079e1f902b 100644 --- a/packages/abi-gen/CHANGELOG.json +++ b/packages/abi-gen/CHANGELOG.json @@ -1,4 +1,25 @@ [ + { + "version": "4.5.0-beta.0", + "changes": [ + { + "note": "In Python wrappers, accept string arguments to bytes parameters", + "pr": 2284 + }, + { + "note": "In Python wrappers, support module-local, Web3.py-compatible middleware", + "pr": 2284 + }, + { + "note": "In Python wrappers, allow contracts to be instantiated with EITHER a Web3.py BaseProvider OR a Web3 client object", + "pr": 2284 + }, + { + "note": "In Python wrappers, fix bug with casting some bytes objects using bytes.fromhex()", + "pr": 2284 + } + ] + }, { "version": "4.4.0-beta.0", "changes": [ diff --git a/python-packages/contract_artifacts/CHANGELOG.md b/python-packages/contract_artifacts/CHANGELOG.md index 16afedf6e6..0a67e1b4fe 100644 --- a/python-packages/contract_artifacts/CHANGELOG.md +++ b/python-packages/contract_artifacts/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.0.0 - TBD + +- Updated with artifacts for version 3 of the protocol. + ## 2.0.1 - 2019-04-30 - Expanded documentation. diff --git a/python-packages/contract_artifacts/setup.py b/python-packages/contract_artifacts/setup.py index 60cd883979..d4ea9b5577 100755 --- a/python-packages/contract_artifacts/setup.py +++ b/python-packages/contract_artifacts/setup.py @@ -152,7 +152,7 @@ def run_tests(self): setup( name="0x-contract-artifacts", - version="2.0.1", + version="3.0.0", description="0x smart contract compilation artifacts", long_description=README_MD, long_description_content_type="text/markdown", diff --git a/python-packages/contract_wrappers/CHANGELOG.md b/python-packages/contract_wrappers/CHANGELOG.md index 69ed9b8caa..24161a8b93 100644 --- a/python-packages/contract_wrappers/CHANGELOG.md +++ b/python-packages/contract_wrappers/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 2.0.0 - TBD + +- Updated for version 3 of the protocol. +- Allow wrappers to be instantiated with EITHER a Web3.py `BaseProvider` OR an already-instantiated `Web3` client object. +- Accept `str`ing arguments to `bytes` contract method parameters. +- Expanded documentation examples. +- Moved methods `jsdict_to_order()` and `order_to_jsdict()` from `zero_ex.contract_wrappers.exchange.types` to `zero_ex.contract_wrappers.order_conversions`. +- Changed field name `zero_ex.contract_wrappers.tx_params.TxParams.gasPrice` to `.gas_price`. + ## 1.1.0 - 2019-08-14 - Added wrapper for DevUtils contract. diff --git a/python-packages/contract_wrappers/setup.py b/python-packages/contract_wrappers/setup.py index a3c32fa126..301fb6f514 100755 --- a/python-packages/contract_wrappers/setup.py +++ b/python-packages/contract_wrappers/setup.py @@ -196,7 +196,7 @@ def run(self): setup( name="0x-contract-wrappers", - version="1.1.0", + version="2.0.0", description="Python wrappers for 0x smart contracts", long_description=README_MD, long_description_content_type="text/markdown", diff --git a/python-packages/json_schemas/CHANGELOG.md b/python-packages/json_schemas/CHANGELOG.md index 88d9babcd2..b06c98ec8c 100644 --- a/python-packages/json_schemas/CHANGELOG.md +++ b/python-packages/json_schemas/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.1.1 - TBD + +- Removed dev dependency on package `0x-contract-wrappers` + ## 1.1.0 - 2019-08-09 - Added `verifyingContractAddress` to `/zeroExTransactionSchema`. diff --git a/python-packages/json_schemas/setup.py b/python-packages/json_schemas/setup.py index 34b92c924c..f943260847 100755 --- a/python-packages/json_schemas/setup.py +++ b/python-packages/json_schemas/setup.py @@ -143,7 +143,7 @@ def run(self): setup( name="0x-json-schemas", - version="1.1.0", + version="1.1.1", description="JSON schemas for 0x applications", long_description=README_MD, long_description_content_type="text/markdown", diff --git a/python-packages/middlewares/CHANGELOG.md b/python-packages/middlewares/CHANGELOG.md index 1639a8f546..c1ebd2f6ed 100644 --- a/python-packages/middlewares/CHANGELOG.md +++ b/python-packages/middlewares/CHANGELOG.md @@ -1,5 +1,5 @@ # Changelog -## 1.0.0 - 2019-04-30 +## 1.0.0 - TBD - Initial release. diff --git a/python-packages/order_utils/CHANGELOG.md b/python-packages/order_utils/CHANGELOG.md index 8a329b289f..afa979ae92 100644 --- a/python-packages/order_utils/CHANGELOG.md +++ b/python-packages/order_utils/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 4.0.0 - TBD + +- Upgraded to protocol version 3. +- `is_valid_signature()` now returns just a boolean. (Formerly, it returned a tuple consisting of the boolean and a reason string.) +- Allow `sign_hash()` to be called with EITHER a Web3.py `BaseProvider` OR an already-instantiated `Web3` client object. + ## 3.0.1 - 2019-08-09 - Fixed dependencies: changed `deprecated` from being an extras_require["dev"] dependency to being an install_requires dependency, since it's required not just for doc generation but also just to import the package. diff --git a/python-packages/order_utils/setup.py b/python-packages/order_utils/setup.py index 2732639521..f54c1defde 100755 --- a/python-packages/order_utils/setup.py +++ b/python-packages/order_utils/setup.py @@ -156,7 +156,7 @@ def run(self): setup( name="0x-order-utils", - version="3.0.1", + version="4.0.0", description="Order utilities for 0x applications", long_description=README_MD, long_description_content_type="text/markdown", From 0ef343534b0d841710b36781cf454e767793f66b Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 29 Oct 2019 11:08:40 -0400 Subject: [PATCH 20/35] @0x/contract-addresses: Put addr's in JSON, not TS This allows easier consumption by other languages. (Specifically, it eliminates the overhead of keeping the Python addresses package in sync with the TypeScript one.) --- .gitignore | 3 +- packages/contract-addresses/addresses.json | 117 ++++++++++++ packages/contract-addresses/src/index.ts | 125 +----------- packages/contract-addresses/tsconfig.json | 7 +- python-packages/contract_addresses/setup.py | 41 +++- .../contract_addresses/src/index.rst | 2 +- .../zero_ex/contract_addresses/__init__.py | 179 +++++++++--------- .../src/zero_ex/contract_wrappers/__init__.py | 16 +- .../contract_wrappers/test/conftest.py | 10 +- .../test/test_base_contract_method.py | 4 +- .../test/test_erc20_wrapper.py | 4 +- .../test/test_exchange_wrapper.py | 8 +- .../src/zero_ex/json_schemas/__init__.py | 6 +- .../test/test_local_message_signer.py | 4 +- .../src/zero_ex/order_utils/__init__.py | 6 +- python-packages/pre_install | 1 + .../src/zero_ex/sra_client/__init__.py | 6 +- 17 files changed, 294 insertions(+), 245 deletions(-) create mode 100644 packages/contract-addresses/addresses.json diff --git a/.gitignore b/.gitignore index 14898c770c..7313764d8c 100644 --- a/.gitignore +++ b/.gitignore @@ -168,8 +168,9 @@ __pycache__ python-packages/*/src/*.egg-info python-packages/*/.coverage -# python keeps package-local copies of json schemas +# python keeps package-local copies of json schemas and contract addresses python-packages/json_schemas/src/zero_ex/json_schemas/schemas +python-packages/contract_addresses/src/zero_ex/contract_addresses/addresses.json # Doc README copy packages/*/docs/README.md diff --git a/packages/contract-addresses/addresses.json b/packages/contract-addresses/addresses.json new file mode 100644 index 0000000000..9eeb90f921 --- /dev/null +++ b/packages/contract-addresses/addresses.json @@ -0,0 +1,117 @@ +{ + "1": { + "exchangeV2": "0x080bf510fcbf18b91105470639e9561022937712", + "exchange": "0x0000000000000000000000000000000000000000", + "erc20Proxy": "0x95e6f48254609a6ee006f7d493c8e5fb97094cef", + "erc721Proxy": "0xefc70a1b18c432bdc64b596838b4d138f6bc6cad", + "forwarder": "0x0000000000000000000000000000000000000000", + "orderValidator": "0x0000000000000000000000000000000000000000", + "zrxToken": "0xe41d2489571d322189246dafa5ebde1f4699f498", + "etherToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "assetProxyOwner": "0xdffe798c7172dd6deb32baee68af322e8f495ce0", + "zeroExGovernor": "0x0000000000000000000000000000000000000000", + "dutchAuction": "0x0000000000000000000000000000000000000000", + "coordinatorRegistry": "0x45797531b873fd5e519477a070a955764c1a5b07", + "coordinator": "0x0000000000000000000000000000000000000000", + "multiAssetProxy": "0xef701d5389ae74503d633396c4d654eabedc9d78", + "staticCallProxy": "0x3517b88c19508c08650616019062b898ab65ed29", + "erc1155Proxy": "0x7eefbd48fd63d441ec7435d024ec7c5131019add", + "zrxVault": "0x0000000000000000000000000000000000000000", + "staking": "0x0000000000000000000000000000000000000000", + "stakingProxy": "0x0000000000000000000000000000000000000000", + "devUtils": "0x0000000000000000000000000000000000000000", + "erc20BridgeProxy": "0x0000000000000000000000000000000000000000" + }, + "3": { + "erc20Proxy": "0xb1408f4c245a23c31b98d2c626777d4c0d766caa", + "erc721Proxy": "0xe654aac058bfbf9f83fcaee7793311dd82f6ddb4", + "zrxToken": "0xff67881f8d12f372d91baae9752eb3631ff0ed00", + "etherToken": "0xc778417e063141139fce010982780140aa0cd5ab", + "exchangeV2": "0xbff9493f92a3df4b0429b6d00743b3cfb4c85831", + "exchange": "0xc56388332ddfc98701fefed94535100c6166956c", + "assetProxyOwner": "0x0000000000000000000000000000000000000000", + "zeroExGovernor": "0xdcf20f7b447d51f2b3e5499b7f6cbbf7295a5d26", + "forwarder": "0xe66ae6162b3e9067d6ce9e5b9799cca1ba0d09f8", + "orderValidator": "0x0000000000000000000000000000000000000000", + "dutchAuction": "0x0000000000000000000000000000000000000000", + "coordinatorRegistry": "0x403cc23e88c17c4652fb904784d1af640a6722d9", + "coordinator": "0xad8464022213a618c96a1178a927a5ed15ad6949", + "multiAssetProxy": "0xab8fbd189c569ccdee3a4d929bb7f557be4028f6", + "staticCallProxy": "0xe1b97e47aa3796276033a5341e884d2ba46b6ac1", + "erc1155Proxy": "0x19bb6caa3bc34d39e5a23cedfa3e6c7e7f3c931d", + "devUtils": "0x9a8590eebcfc53f0cc7ab5ebb8c079e9e7d4e0f5", + "zrxVault": "0xffd161026865ad8b4ab28a76840474935eec4dfa", + "staking": "0x3f46b98061a3e1e1f41dff296ec19402c298f8a9", + "stakingProxy": "0xfaabcee42ab6b9c649794ac6c133711071897ee9", + "erc20BridgeProxy": "0x599b340b5045436a99b1f0c718d30f5a0c8519dd" + }, + "4": { + "exchangeV2": "0xbff9493f92a3df4b0429b6d00743b3cfb4c85831", + "exchange": "0x3afe8aa355e086d898447732cfa5d931cfb2a792", + "erc20Proxy": "0x2f5ae4f6106e89b4147651688a92256885c5f410", + "erc721Proxy": "0x7656d773e11ff7383a14dcf09a9c50990481cd10", + "zrxToken": "0x8080c7e4b81ecf23aa6f877cfbfd9b0c228c6ffa", + "etherToken": "0xc778417e063141139fce010982780140aa0cd5ab", + "assetProxyOwner": "0x0000000000000000000000000000000000000000", + "zeroExGovernor": "0x5d751aa855a1aee5fe44cf5350ed25b5727b66ae", + "forwarder": "0xf36eabdfe986b35b62c8fd5a98a7f2aebb79b291", + "orderValidator": "0x0000000000000000000000000000000000000000", + "dutchAuction": "0x0000000000000000000000000000000000000000", + "coordinatorRegistry": "0x1084b6a398e47907bae43fec3ff4b677db6e4fee", + "coordinator": "0x9ae7a6e4e4d58c36b7aa573fc06ce46dd3cb0d44", + "multiAssetProxy": "0xb34cde0ad3a83d04abebc0b66e75196f22216621", + "staticCallProxy": "0xe1b97e47aa3796276033a5341e884d2ba46b6ac1", + "erc1155Proxy": "0x19bb6caa3bc34d39e5a23cedfa3e6c7e7f3c931d", + "devUtils": "0xfcbb258112485f18dd68f4b1016e48c23542fdc5", + "zrxVault": "0xa5bf6ac73bc40790fc6ffc9dbbbce76c9176e224", + "staking": "0x344d4f661a82afdd84d31456c291822d90d5dc3a", + "stakingProxy": "0xc6ad5277ea225ac05e271eb14a7ebb480cd9dd9f", + "erc20BridgeProxy": "0x31b8653642110f17bdb1f719901d7e7d49b08141" + }, + "42": { + "erc20Proxy": "0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e", + "erc721Proxy": "0x2a9127c745688a165106c11cd4d647d2220af821", + "zrxToken": "0x2002d3812f58e35f0ea1ffbf80a75a38c32175fa", + "etherToken": "0xd0a1e359811322d97991e03f863a0c30c2cf029c", + "exchangeV2": "0x30589010550762d2f0d06f650d8e8b6ade6dbf4b", + "exchange": "0xca8b1626b3b7a0da722ca9f264c4630c7d34d3b8", + "assetProxyOwner": "0x0000000000000000000000000000000000000000", + "zeroExGovernor": "0x3654e5363cd75c8974c76208137df9691e820e97", + "forwarder": "0xd6330f9d2073e1889a295dd1dd2e28d42dec4bff", + "orderValidator": "0x0000000000000000000000000000000000000000", + "dutchAuction": "0x0000000000000000000000000000000000000000", + "coordinatorRegistry": "0x09fb99968c016a3ff537bf58fb3d9fe55a7975d5", + "coordinator": "0x10e0b1c2e6065ec7f290c7e3731264f9a2bf2b2d", + "multiAssetProxy": "0xf6313a772c222f51c28f2304c0703b8cf5428fd8", + "staticCallProxy": "0x48e94bdb9033640d45ea7c721e25f380f8bffa43", + "erc1155Proxy": "0x64517fa2b480ba3678a2a3c0cf08ef7fd4fad36f", + "devUtils": "0x58c4fbdf9222f10ad2bef8f4d374f209135e71a5", + "zrxVault": "0xf36eabdfe986b35b62c8fd5a98a7f2aebb79b291", + "staking": "0x89150f5eed50b3528f79bfb539f29d727f92821c", + "stakingProxy": "0xbab9145f1d57cd4bb0c9aa2d1ece0a5b6e734d34", + "erc20BridgeProxy": "0xfb2dd2a1366de37f7241c83d47da58fd503e2c64" + }, + "50": { + "erc20Proxy": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48", + "erc721Proxy": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401", + "erc1155Proxy": "0x6a4a62e5a7ed13c361b176a5f62c2ee620ac0df8", + "zrxToken": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c", + "etherToken": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082", + "exchangeV2": "0x48bacb9266a570d521063ef5dd96e61686dbe788", + "exchange": "0x48bacb9266a570d521063ef5dd96e61686dbe788", + "zeroExGovernor": "0x0000000000000000000000000000000000000000", + "assetProxyOwner": "0x0000000000000000000000000000000000000000", + "forwarder": "0x0000000000000000000000000000000000000000", + "orderValidator": "0x0000000000000000000000000000000000000000", + "dutchAuction": "0x0000000000000000000000000000000000000000", + "coordinatorRegistry": "0x1941ff73d1154774d87521d2d0aaad5d19c8df60", + "coordinator": "0x0000000000000000000000000000000000000000", + "multiAssetProxy": "0xcfc18cec799fbd1793b5c43e773c98d4d61cc2db", + "staticCallProxy": "0x6dfff22588be9b3ef8cf0ad6dc9b84796f9fb45f", + "devUtils": "0x38ef19fdf8e8415f18c307ed71967e19aac28ba1", + "zrxVault": "0x0000000000000000000000000000000000000000", + "staking": "0x0000000000000000000000000000000000000000", + "stakingProxy": "0x0000000000000000000000000000000000000000", + "erc20BridgeProxy": "0x0000000000000000000000000000000000000000" + } +} diff --git a/packages/contract-addresses/src/index.ts b/packages/contract-addresses/src/index.ts index 1687c0d311..f2c12e6458 100644 --- a/packages/contract-addresses/src/index.ts +++ b/packages/contract-addresses/src/index.ts @@ -1,5 +1,7 @@ import * as _ from 'lodash'; +import addresses from '../addresses.json'; + export interface ContractAddresses { erc20Proxy: string; erc721Proxy: string; @@ -32,127 +34,6 @@ export enum NetworkId { Ganache = 50, } -const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; - -const networkToAddresses: { [networkId: number]: ContractAddresses } = { - 1: { - exchangeV2: '0x080bf510fcbf18b91105470639e9561022937712', - exchange: NULL_ADDRESS, - erc20Proxy: '0x95e6f48254609a6ee006f7d493c8e5fb97094cef', - erc721Proxy: '0xefc70a1b18c432bdc64b596838b4d138f6bc6cad', - forwarder: NULL_ADDRESS, - orderValidator: NULL_ADDRESS, - zrxToken: '0xe41d2489571d322189246dafa5ebde1f4699f498', - etherToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - assetProxyOwner: '0xdffe798c7172dd6deb32baee68af322e8f495ce0', - zeroExGovernor: NULL_ADDRESS, - dutchAuction: NULL_ADDRESS, - coordinatorRegistry: '0x45797531b873fd5e519477a070a955764c1a5b07', - coordinator: NULL_ADDRESS, - multiAssetProxy: '0xef701d5389ae74503d633396c4d654eabedc9d78', - staticCallProxy: '0x3517b88c19508c08650616019062b898ab65ed29', - erc1155Proxy: '0x7eefbd48fd63d441ec7435d024ec7c5131019add', - zrxVault: NULL_ADDRESS, - staking: NULL_ADDRESS, - stakingProxy: NULL_ADDRESS, - devUtils: NULL_ADDRESS, - erc20BridgeProxy: NULL_ADDRESS, - }, - 3: { - erc20Proxy: '0xb1408f4c245a23c31b98d2c626777d4c0d766caa', - erc721Proxy: '0xe654aac058bfbf9f83fcaee7793311dd82f6ddb4', - zrxToken: '0xff67881f8d12f372d91baae9752eb3631ff0ed00', - etherToken: '0xc778417e063141139fce010982780140aa0cd5ab', - exchangeV2: '0xbff9493f92a3df4b0429b6d00743b3cfb4c85831', - exchange: '0xc56388332ddfc98701fefed94535100c6166956c', - assetProxyOwner: NULL_ADDRESS, - zeroExGovernor: '0xdcf20f7b447d51f2b3e5499b7f6cbbf7295a5d26', - forwarder: '0xe66ae6162b3e9067d6ce9e5b9799cca1ba0d09f8', - orderValidator: NULL_ADDRESS, - dutchAuction: NULL_ADDRESS, - coordinatorRegistry: '0x403cc23e88c17c4652fb904784d1af640a6722d9', - coordinator: '0xad8464022213a618c96a1178a927a5ed15ad6949', - multiAssetProxy: '0xab8fbd189c569ccdee3a4d929bb7f557be4028f6', - staticCallProxy: '0xe1b97e47aa3796276033a5341e884d2ba46b6ac1', - erc1155Proxy: '0x19bb6caa3bc34d39e5a23cedfa3e6c7e7f3c931d', - devUtils: '0x9a8590eebcfc53f0cc7ab5ebb8c079e9e7d4e0f5', - zrxVault: '0xffd161026865ad8b4ab28a76840474935eec4dfa', - staking: '0x3f46b98061a3e1e1f41dff296ec19402c298f8a9', - stakingProxy: '0xfaabcee42ab6b9c649794ac6c133711071897ee9', - erc20BridgeProxy: '0x599b340b5045436a99b1f0c718d30f5a0c8519dd', - }, - 4: { - exchangeV2: '0xbff9493f92a3df4b0429b6d00743b3cfb4c85831', - exchange: '0x3afe8aa355e086d898447732cfa5d931cfb2a792', - erc20Proxy: '0x2f5ae4f6106e89b4147651688a92256885c5f410', - erc721Proxy: '0x7656d773e11ff7383a14dcf09a9c50990481cd10', - zrxToken: '0x8080c7e4b81ecf23aa6f877cfbfd9b0c228c6ffa', - etherToken: '0xc778417e063141139fce010982780140aa0cd5ab', - assetProxyOwner: NULL_ADDRESS, - zeroExGovernor: '0x5d751aa855a1aee5fe44cf5350ed25b5727b66ae', - forwarder: '0xf36eabdfe986b35b62c8fd5a98a7f2aebb79b291', - orderValidator: NULL_ADDRESS, - dutchAuction: NULL_ADDRESS, - coordinatorRegistry: '0x1084b6a398e47907bae43fec3ff4b677db6e4fee', - coordinator: '0x9ae7a6e4e4d58c36b7aa573fc06ce46dd3cb0d44', - multiAssetProxy: '0xb34cde0ad3a83d04abebc0b66e75196f22216621', - staticCallProxy: '0xe1b97e47aa3796276033a5341e884d2ba46b6ac1', - erc1155Proxy: '0x19bb6caa3bc34d39e5a23cedfa3e6c7e7f3c931d', - devUtils: '0xfcbb258112485f18dd68f4b1016e48c23542fdc5', - zrxVault: '0xa5bf6ac73bc40790fc6ffc9dbbbce76c9176e224', - staking: '0x344d4f661a82afdd84d31456c291822d90d5dc3a', - stakingProxy: '0xc6ad5277ea225ac05e271eb14a7ebb480cd9dd9f', - erc20BridgeProxy: '0x31b8653642110f17bdb1f719901d7e7d49b08141', - }, - 42: { - erc20Proxy: '0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e', - erc721Proxy: '0x2a9127c745688a165106c11cd4d647d2220af821', - zrxToken: '0x2002d3812f58e35f0ea1ffbf80a75a38c32175fa', - etherToken: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', - exchangeV2: '0x30589010550762d2f0d06f650d8e8b6ade6dbf4b', - exchange: '0xca8b1626b3b7a0da722ca9f264c4630c7d34d3b8', - assetProxyOwner: NULL_ADDRESS, - zeroExGovernor: '0x3654e5363cd75c8974c76208137df9691e820e97', - forwarder: '0xd6330f9d2073e1889a295dd1dd2e28d42dec4bff', - orderValidator: NULL_ADDRESS, - dutchAuction: NULL_ADDRESS, - coordinatorRegistry: '0x09fb99968c016a3ff537bf58fb3d9fe55a7975d5', - coordinator: '0x10e0b1c2e6065ec7f290c7e3731264f9a2bf2b2d', - multiAssetProxy: '0xf6313a772c222f51c28f2304c0703b8cf5428fd8', - staticCallProxy: '0x48e94bdb9033640d45ea7c721e25f380f8bffa43', - erc1155Proxy: '0x64517fa2b480ba3678a2a3c0cf08ef7fd4fad36f', - devUtils: '0x58c4fbdf9222f10ad2bef8f4d374f209135e71a5', - zrxVault: '0xf36eabdfe986b35b62c8fd5a98a7f2aebb79b291', - staking: '0x89150f5eed50b3528f79bfb539f29d727f92821c', - stakingProxy: '0xbab9145f1d57cd4bb0c9aa2d1ece0a5b6e734d34', - erc20BridgeProxy: '0xfb2dd2a1366de37f7241c83d47da58fd503e2c64', - }, - // NetworkId 50 represents our Ganache snapshot generated from migrations. - 50: { - erc20Proxy: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48', - erc721Proxy: '0x1d7022f5b17d2f8b695918fb48fa1089c9f85401', - erc1155Proxy: '0x6a4a62e5a7ed13c361b176a5f62c2ee620ac0df8', - zrxToken: '0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c', - etherToken: '0x0b1ba0af832d7c05fd64161e0db78e85978e8082', - exchangeV2: '0x48bacb9266a570d521063ef5dd96e61686dbe788', - exchange: '0x48bacb9266a570d521063ef5dd96e61686dbe788', - zeroExGovernor: NULL_ADDRESS, - assetProxyOwner: NULL_ADDRESS, - forwarder: NULL_ADDRESS, - orderValidator: NULL_ADDRESS, - dutchAuction: NULL_ADDRESS, - coordinatorRegistry: '0x1941ff73d1154774d87521d2d0aaad5d19c8df60', - coordinator: NULL_ADDRESS, - multiAssetProxy: '0xcfc18cec799fbd1793b5c43e773c98d4d61cc2db', - staticCallProxy: '0x6dfff22588be9b3ef8cf0ad6dc9b84796f9fb45f', - devUtils: '0x38ef19fdf8e8415f18c307ed71967e19aac28ba1', - zrxVault: NULL_ADDRESS, - staking: NULL_ADDRESS, - stakingProxy: NULL_ADDRESS, - erc20BridgeProxy: NULL_ADDRESS, - }, -}; - /** * Used to get addresses of contracts that have been deployed to either the * Ethereum mainnet or a supported testnet. Throws if there are no known @@ -162,6 +43,8 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { * given networkId. */ export function getContractAddressesForNetworkOrThrow(networkId: NetworkId): ContractAddresses { + const networkToAddresses: { [networkId: number]: ContractAddresses } = addresses; + if (networkToAddresses[networkId] === undefined) { throw new Error(`Unknown network id (${networkId}). No known 0x contracts have been deployed on this network.`); } diff --git a/packages/contract-addresses/tsconfig.json b/packages/contract-addresses/tsconfig.json index 233008d61c..3d191a3c01 100644 --- a/packages/contract-addresses/tsconfig.json +++ b/packages/contract-addresses/tsconfig.json @@ -2,7 +2,10 @@ "extends": "../../tsconfig", "compilerOptions": { "outDir": "lib", - "rootDir": "." + "rootDir": ".", + "resolveJsonModule": true, + "esModuleInterop": true }, - "include": ["./src/**/*"] + "include": ["./src/**/*"], + "files": ["./addresses.json"] } diff --git a/python-packages/contract_addresses/setup.py b/python-packages/contract_addresses/setup.py index a84ee3551c..e5916386a0 100755 --- a/python-packages/contract_addresses/setup.py +++ b/python-packages/contract_addresses/setup.py @@ -7,8 +7,8 @@ # installed when you invoke this script import subprocess # nosec -from shutil import rmtree -from os import environ, path +from shutil import copyfile, rmtree +from os import environ, path, remove from sys import argv, exit # pylint: disable=redefined-builtin from distutils.command.clean import clean @@ -17,6 +17,38 @@ from setuptools.command.test import test as TestCommand +class PreInstallCommand(distutils.command.build_py.build_py): + """Custom setuptools command class for pulling in addresses.json.""" + + description = ( + "Pull in addresses.json from ../../packages/contract-addresses" + ) + + def run(self): + """Copy over addresses.json.""" + pkgdir = path.dirname(path.realpath(argv[0])) + + destination_path = path.join( + pkgdir, "src", "zero_ex", "contract_addresses" + ) + + try: + remove(path.join(destination_path, "addresses.json")) + except FileNotFoundError: + pass + copyfile( + path.join( + pkgdir, + "..", + "..", + "packages", + "contract-addresses", + "addresses.json", + ), + path.join(destination_path, "addresses.json"), + ) + + class LintCommand(distutils.command.build_py.build_py): """Custom setuptools command class for running linters.""" @@ -135,6 +167,7 @@ def run_tests(self): author_email="feuGeneA@users.noreply.github.com", cmdclass={ "clean": CleanCommandExtension, + "pre_install": PreInstallCommand, "lint": LintCommand, "test": TestCommandExtension, "test_publish": TestPublishCommand, @@ -160,7 +193,9 @@ def run_tests(self): ] }, python_requires=">=3.6, <4", - package_data={"zero_ex.contract_addresses": ["py.typed"]}, + package_data={ + "zero_ex.contract_addresses": ["py.typed", "addresses.json"] + }, package_dir={"": "src"}, license="Apache 2.0", keywords=( diff --git a/python-packages/contract_addresses/src/index.rst b/python-packages/contract_addresses/src/index.rst index 5dd096b16a..62a2f4bf0e 100644 --- a/python-packages/contract_addresses/src/index.rst +++ b/python-packages/contract_addresses/src/index.rst @@ -19,7 +19,7 @@ Python zero_ex.contract_addresses :members: :show-inheritance: -.. autodata:: zero_ex.contract_addresses.NETWORK_TO_ADDRESSES +.. autodata:: zero_ex.contract_addresses.network_to_addresses :annotation: : Dict[NetworkId, ContractAddresses] Indices and tables diff --git a/python-packages/contract_addresses/src/zero_ex/contract_addresses/__init__.py b/python-packages/contract_addresses/src/zero_ex/contract_addresses/__init__.py index 1a252bfbd2..7e267485d0 100644 --- a/python-packages/contract_addresses/src/zero_ex/contract_addresses/__init__.py +++ b/python-packages/contract_addresses/src/zero_ex/contract_addresses/__init__.py @@ -10,8 +10,11 @@ """ from enum import Enum +import json from typing import Dict, NamedTuple +from pkg_resources import resource_string + class ContractAddresses(NamedTuple): """An abstract record listing all the contracts that have addresses.""" @@ -20,10 +23,7 @@ class ContractAddresses(NamedTuple): """Address of the ERC20Proxy contract.""" erc721_proxy: str - """Address of the ERC20Proxy contract.""" - - erc1155_proxy: str - """Address of the ERC1155Proxy contract.""" + """Address of the ERC721Proxy contract.""" zrx_token: str """Address of the ZRX token contract.""" @@ -31,27 +31,57 @@ class ContractAddresses(NamedTuple): ether_token: str """Address of the WETH token contract.""" + exchange_v2: str + """Address of the v2 Exchange contract.""" + exchange: str - """Address of the Exchange contract.""" + """Address of the v3 Exchange contract.""" asset_proxy_owner: str """Address of the AssetProxyOwner contract.""" + zero_ex_governor: str + """Address of the ZeroExGovernor contract.""" + forwarder: str """Address of the Forwarder contract.""" order_validator: str """Address of the OrderValidator contract.""" + dutch_auction: str + """Address of the DutchAuction contract.""" + coordinator_registry: str """Address of the CoordinatorRegistry contract.""" coordinator: str """Address of the Coordinator contract.""" + multi_asset_proxy: str + """Address of the MultiAssetProxy contract.""" + + static_call_proxy: str + """Address of the StaticCallProxy contract.""" + + erc1155_proxy: str + """Address of the ERC1155Proxy contract.""" + dev_utils: str """Address of the DevUtils contract.""" + zrx_vault: str + """Address of the ZRXVault contract.""" + + staking: str + """Address of the Staking contract.""" + + staking_proxy: str + """Address of the StakingProxy contract.""" + + erc20_bridge_proxy: str + """Address of the ERC20BridgeProxy contract.""" + class NetworkId(Enum): """Network names correlated to their network identification numbers. @@ -70,83 +100,62 @@ class NetworkId(Enum): GANACHE = 50 -NETWORK_TO_ADDRESSES: Dict[NetworkId, ContractAddresses] = { - NetworkId.MAINNET: ContractAddresses( # nosec - erc20_proxy="0x95e6f48254609a6ee006f7d493c8e5fb97094cef", - erc721_proxy="0xefc70a1b18c432bdc64b596838b4d138f6bc6cad", - zrx_token="0xe41d2489571d322189246dafa5ebde1f4699f498", - ether_token="0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - exchange="0x080bf510fcbf18b91105470639e9561022937712", - asset_proxy_owner="0xdffe798c7172dd6deb32baee68af322e8f495ce0", - forwarder="0x76481caa104b5f6bccb540dae4cefaf1c398ebea", - order_validator="0xa09329c6003c9a5402102e226417738ee22cf1f2", - coordinator_registry="0x45797531b873fd5e519477a070a955764c1a5b07", - coordinator="0xa14857e8930acd9a882d33ec20559beb5479c8a6", - erc1155_proxy="0x7eefbd48fd63d441ec7435d024ec7c5131019add", - dev_utils="0x92d9a4d50190ae04e03914db2ee650124af844e6", - ), - NetworkId.ROPSTEN: ContractAddresses( # nosec - erc20_proxy="0xb1408f4c245a23c31b98d2c626777d4c0d766caa", - erc721_proxy="0xe654aac058bfbf9f83fcaee7793311dd82f6ddb4", - zrx_token="0xff67881f8d12f372d91baae9752eb3631ff0ed00", - ether_token="0xc778417e063141139fce010982780140aa0cd5ab", - exchange="0xbff9493f92a3df4b0429b6d00743b3cfb4c85831", - asset_proxy_owner="0xf5fa5b5fed2727a0e44ac67f6772e97977aa358b", - forwarder="0x1ebdc9758e85c1c6a85af06cc96cf89000a31913", - order_validator="0x90431a90516ab49af23a0530e04e8c7836e7122f", - coordinator_registry="0x403cc23e88c17c4652fb904784d1af640a6722d9", - coordinator="0x2ba02e03ee0029311e0f43715307870a3e701b53", - erc1155_proxy="0x19bb6caa3bc34d39e5a23cedfa3e6c7e7f3c931d", - dev_utils="0x3e0b46bad8e374e4a110c12b832cb120dbe4a479", - ), - NetworkId.RINKEBY: ContractAddresses( # nosec - exchange="0xbff9493f92a3df4b0429b6d00743b3cfb4c85831", - erc20_proxy="0x2f5ae4f6106e89b4147651688a92256885c5f410", - erc721_proxy="0x7656d773e11ff7383a14dcf09a9c50990481cd10", - zrx_token="0x8080c7e4b81ecf23aa6f877cfbfd9b0c228c6ffa", - ether_token="0xc778417e063141139fce010982780140aa0cd5ab", - asset_proxy_owner="0xe1703da878afcebff5b7624a826902af475b9c03", - forwarder="0x1ebdc9758e85c1c6a85af06cc96cf89000a31913", - order_validator="0x0c5173a51e26b29d6126c686756fb9fbef71f762", - coordinator_registry="0x1084b6a398e47907bae43fec3ff4b677db6e4fee", - coordinator="0x2ba02e03ee0029311e0f43715307870a3e701b53", - erc1155_proxy="0x19bb6caa3bc34d39e5a23cedfa3e6c7e7f3c931d", - dev_utils="0x2d4a9abda7b8b3605c8dbd34e3550a7467c78287'", - ), - NetworkId.KOVAN: ContractAddresses( # nosec - erc20_proxy="0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e", - erc721_proxy="0x2a9127c745688a165106c11cd4d647d2220af821", - zrx_token="0x2002d3812f58e35f0ea1ffbf80a75a38c32175fa", - ether_token="0xd0a1e359811322d97991e03f863a0c30c2cf029c", - exchange="0x30589010550762d2f0d06f650d8e8b6ade6dbf4b", - asset_proxy_owner="0x2c824d2882baa668e0d5202b1e7f2922278703f8", - forwarder="0x1ebdc9758e85c1c6a85af06cc96cf89000a31913", - order_validator="0xb389da3d204b412df2f75c6afb3d0a7ce0bc283d", - coordinator_registry="0x09fb99968c016a3ff537bf58fb3d9fe55a7975d5", - coordinator="0x2ba02e03ee0029311e0f43715307870a3e701b53", - erc1155_proxy="0x64517fa2b480ba3678a2a3c0cf08ef7fd4fad36f", - dev_utils="0x1e3616bc5144362f95d72de41874395567697e93", - ), - NetworkId.GANACHE: ContractAddresses( # nosec - exchange="0x48bacb9266a570d521063ef5dd96e61686dbe788", - erc20_proxy="0x1dc4c1cefef38a777b15aa20260a54e584b16c48", - erc721_proxy="0x1d7022f5b17d2f8b695918fb48fa1089c9f85401", - erc1155_proxy="0x6a4a62e5a7ed13c361b176a5f62c2ee620ac0df8", - zrx_token="0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c", - ether_token="0x0b1ba0af832d7c05fd64161e0db78e85978e8082", - asset_proxy_owner="0x8d42e38980ce74736c21c059b2240df09958d3c8", - forwarder="0xaa86dda78e9434aca114b6676fc742a18d15a1cc", - order_validator="0x4d3d5c850dd5bd9d6f4adda3dd039a3c8054ca29", - coordinator_registry="0x1941ff73d1154774d87521d2d0aaad5d19c8df60", - coordinator="0x0d8b0dd11f5d34ed41d556def5f841900d5b1c6b", - dev_utils="0x38ef19fdf8e8415f18c307ed71967e19aac28ba1", - ), -} -"""A mapping from instances of NetworkId to instances of ContractAddresses. - -Addresses under NetworkId.Ganache are from our Ganache snapshot generated from -npm package @0x/migrations. - ->>> NETWORK_TO_ADDRESSES[NetworkId.MAINNET].exchange -0x4f833a24e1f95d70f028921e27040ca56e09ab0b -""" +class _AddressCache: + """A cache to facilitate lazy & singular loading of contract addresses.""" + + # pylint: disable=too-few-public-methods + + # class data, not instance: + _network_to_addresses: Dict[str, ContractAddresses] = {} + + @classmethod + def network_to_addresses(cls, network_id: NetworkId): + """Return the addresses for the given network ID. + + First tries to get data from the class level storage + `_network_to_addresses`. If it's not there, loads it from disk, stores + it in the class data (for the next caller), and then returns it. + """ + try: + return cls._network_to_addresses[str(network_id.value)] + except KeyError: + cls._network_to_addresses = json.loads( + resource_string("zero_ex.contract_addresses", "addresses.json") + ) + return cls._network_to_addresses[str(network_id.value)] + + +def network_to_addresses(network_id: NetworkId) -> ContractAddresses: + """Map a NetworkId to an instance of ContractAddresses. + + Addresses under NetworkId.Ganache are from our Ganache snapshot generated + from npm package @0x/migrations. + + >>> network_to_addresses(NetworkId.MAINNET).exchange + '0x...' + """ + addresses = _AddressCache.network_to_addresses(network_id) + + return ContractAddresses( + erc20_proxy=addresses["erc20Proxy"], + erc721_proxy=addresses["erc721Proxy"], + zrx_token=addresses["zrxToken"], + ether_token=addresses["etherToken"], + exchange_v2=addresses["exchangeV2"], + exchange=addresses["exchange"], + asset_proxy_owner=addresses["assetProxyOwner"], + zero_ex_governor=addresses["zeroExGovernor"], + forwarder=addresses["forwarder"], + order_validator=addresses["orderValidator"], + dutch_auction=addresses["dutchAuction"], + coordinator_registry=addresses["coordinatorRegistry"], + coordinator=addresses["coordinator"], + multi_asset_proxy=addresses["multiAssetProxy"], + static_call_proxy=addresses["staticCallProxy"], + erc1155_proxy=addresses["erc1155Proxy"], + dev_utils=addresses["devUtils"], + zrx_vault=addresses["zrxVault"], + staking=addresses["staking"], + staking_proxy=addresses["stakingProxy"], + erc20_bridge_proxy=addresses["erc20BridgeProxy"], + ) diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py index 558588f179..538607c6fa 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py @@ -52,10 +52,10 @@ pre-deployed deployed in the `0xorg/ganache-cli`:code: docker image. Let's capture the addresses we'll use throughout the examples below: ->>> from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId ->>> weth_address = NETWORK_TO_ADDRESSES[NetworkId.GANACHE].ether_token ->>> zrx_address = NETWORK_TO_ADDRESSES[NetworkId.GANACHE].zrx_token ->>> exchange_address = NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange +>>> from zero_ex.contract_addresses import network_to_addresses, NetworkId +>>> weth_address = network_to_addresses(NetworkId.GANACHE).ether_token +>>> zrx_address = network_to_addresses(NetworkId.GANACHE).zrx_token +>>> exchange_address = network_to_addresses(NetworkId.GANACHE).exchange Wrapping ETH ------------ @@ -93,14 +93,14 @@ >>> from zero_ex.contract_wrappers.erc20_token import ERC20Token >>> zrx_token = ERC20Token( ... web3_or_provider=ganache, -... contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].zrx_token, +... contract_address=network_to_addresses(NetworkId.GANACHE).zrx_token, ... ) >>> weth_token = ERC20Token( ... web3_or_provider=ganache, -... contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].ether_token, +... contract_address=network_to_addresses(NetworkId.GANACHE).ether_token, ... ) ->>> erc20_proxy_addr = NETWORK_TO_ADDRESSES[NetworkId.GANACHE].erc20_proxy +>>> erc20_proxy_addr = network_to_addresses(NetworkId.GANACHE).erc20_proxy >>> tx = zrx_token.approve.send_transaction( ... erc20_proxy_addr, @@ -166,7 +166,7 @@ >>> from zero_ex.contract_wrappers.exchange import Exchange >>> exchange = Exchange( ... web3_or_provider=ganache, -... contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange, +... contract_address=network_to_addresses(NetworkId.GANACHE).exchange, ... ) But before filling an order, one may wish to check that it's actually fillable: diff --git a/python-packages/contract_wrappers/test/conftest.py b/python-packages/contract_wrappers/test/conftest.py index 9c0fb47097..040593a373 100644 --- a/python-packages/contract_wrappers/test/conftest.py +++ b/python-packages/contract_wrappers/test/conftest.py @@ -5,7 +5,7 @@ from web3 import Web3 from zero_ex.order_utils import asset_data_utils -from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId +from zero_ex.contract_addresses import network_to_addresses, NetworkId from zero_ex.contract_artifacts import abi_by_name @@ -36,14 +36,14 @@ def accounts(web3_eth): # pylint: disable=redefined-outer-name @pytest.fixture(scope="module") def erc20_proxy_address(): """Get the 0x ERC20 Proxy address.""" - return NETWORK_TO_ADDRESSES[NetworkId.GANACHE].erc20_proxy + return network_to_addresses(NetworkId.GANACHE).erc20_proxy @pytest.fixture(scope="module") def weth_asset_data(): # pylint: disable=redefined-outer-name """Get 0x asset data for Wrapped Ether (WETH) token.""" return asset_data_utils.encode_erc20( - NETWORK_TO_ADDRESSES[NetworkId.GANACHE].ether_token + network_to_addresses(NetworkId.GANACHE).ether_token ) @@ -52,7 +52,7 @@ def weth_instance(web3_eth): # pylint: disable=redefined-outer-name """Get an instance of the WrapperEther contract.""" return web3_eth.contract( address=to_checksum_address( - NETWORK_TO_ADDRESSES[NetworkId.GANACHE].ether_token + network_to_addresses(NetworkId.GANACHE).ether_token ), abi=abi_by_name("WETH9"), ) @@ -61,7 +61,7 @@ def weth_instance(web3_eth): # pylint: disable=redefined-outer-name @pytest.fixture(scope="module") def zrx_address(): """Get address of ZRX token for Ganache network.""" - return NETWORK_TO_ADDRESSES[NetworkId.GANACHE].zrx_token + return network_to_addresses(NetworkId.GANACHE).zrx_token @pytest.fixture(scope="module") diff --git a/python-packages/contract_wrappers/test/test_base_contract_method.py b/python-packages/contract_wrappers/test/test_base_contract_method.py index fd6e4d1731..e437f55aec 100644 --- a/python-packages/contract_wrappers/test/test_base_contract_method.py +++ b/python-packages/contract_wrappers/test/test_base_contract_method.py @@ -2,7 +2,7 @@ import pytest -from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId +from zero_ex.contract_addresses import network_to_addresses, NetworkId from zero_ex.contract_wrappers.bases import ContractMethod @@ -11,5 +11,5 @@ def contract_wrapper(ganache_provider): """Get a ContractMethod instance for testing.""" return ContractMethod( web3_or_provider=ganache_provider, - contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].ether_token, + contract_address=network_to_addresses(NetworkId.GANACHE).ether_token, ) diff --git a/python-packages/contract_wrappers/test/test_erc20_wrapper.py b/python-packages/contract_wrappers/test/test_erc20_wrapper.py index da80356ed0..8e13528e50 100644 --- a/python-packages/contract_wrappers/test/test_erc20_wrapper.py +++ b/python-packages/contract_wrappers/test/test_erc20_wrapper.py @@ -4,7 +4,7 @@ import pytest -from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId +from zero_ex.contract_addresses import network_to_addresses, NetworkId from zero_ex.contract_wrappers import TxParams from zero_ex.contract_wrappers.erc20_token import ERC20Token @@ -16,7 +16,7 @@ def erc20_wrapper(ganache_provider): """Get an instance of ERC20Token wrapper class for testing.""" return ERC20Token( - ganache_provider, NETWORK_TO_ADDRESSES[NetworkId.GANACHE].ether_token + ganache_provider, network_to_addresses(NetworkId.GANACHE).ether_token ) diff --git a/python-packages/contract_wrappers/test/test_exchange_wrapper.py b/python-packages/contract_wrappers/test/test_exchange_wrapper.py index 1da326d793..c299eeac9d 100644 --- a/python-packages/contract_wrappers/test/test_exchange_wrapper.py +++ b/python-packages/contract_wrappers/test/test_exchange_wrapper.py @@ -5,7 +5,7 @@ import pytest from eth_utils import remove_0x_prefix -from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId +from zero_ex.contract_addresses import network_to_addresses, NetworkId from zero_ex.contract_wrappers import TxParams from zero_ex.contract_wrappers.exchange import Exchange from zero_ex.contract_wrappers.exchange.types import Order @@ -22,7 +22,7 @@ def exchange_wrapper(ganache_provider): """Get an Exchange wrapper instance.""" return Exchange( web3_or_provider=ganache_provider, - contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange, + contract_address=network_to_addresses(NetworkId.GANACHE).exchange, ) @@ -161,8 +161,8 @@ def test_two_instantiations_with_web3_objects(web3_instance): again." Test that that bug isn't occurring. """ exchange = Exchange( # pylint: disable=unused-variable - web3_instance, NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange + web3_instance, network_to_addresses(NetworkId.GANACHE).exchange ) exchange2 = Exchange( # pylint: disable=unused-variable - web3_instance, NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange + web3_instance, network_to_addresses(NetworkId.GANACHE).exchange ) diff --git a/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py b/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py index 01f6ccb4bd..9314f4d194 100644 --- a/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py +++ b/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py @@ -60,7 +60,7 @@ def assert_valid(data: Mapping, schema_id: str) -> None: Raises an exception if validation fails. >>> from zero_ex.json_schemas import assert_valid - >>> from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId + >>> from zero_ex.contract_addresses import network_to_addresses, NetworkId >>> from zero_ex.order_utils import asset_data_utils >>> from eth_utils import remove_0x_prefix >>> import random @@ -74,10 +74,10 @@ def assert_valid(data: Mapping, schema_id: str) -> None: ... '0x0000000000000000000000000000000000000000' ... ), ... 'makerAssetData': ( - ... NETWORK_TO_ADDRESSES[NetworkId.MAINNET].zrx_token + ... network_to_addresses(NetworkId.MAINNET).zrx_token ... ), ... 'takerAssetData': ( - ... NETWORK_TO_ADDRESSES[NetworkId.MAINNET].ether_token + ... network_to_addresses(NetworkId.MAINNET).ether_token ... ), ... 'salt': random.randint(1, 100000000000000000), ... 'makerFee': 0, diff --git a/python-packages/middlewares/test/test_local_message_signer.py b/python-packages/middlewares/test/test_local_message_signer.py index c49f667f0d..2eb87997a8 100644 --- a/python-packages/middlewares/test/test_local_message_signer.py +++ b/python-packages/middlewares/test/test_local_message_signer.py @@ -3,7 +3,7 @@ from eth_utils import to_checksum_address from web3 import Web3, HTTPProvider -from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId +from zero_ex.contract_addresses import network_to_addresses, NetworkId from zero_ex.middlewares.local_message_signer import ( construct_local_message_signer, ) @@ -17,7 +17,7 @@ def test_local_message_signer__sign_order(): "d6db0157d9dfe9f9fadb8dedabb7786352843357f4ec8d0fbcbeeb619b1091f5803" ) address = "0x5409ED021D9299bf6814279A6A1411A7e866A631" - exchange = NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange + exchange = network_to_addresses(NetworkId.GANACHE).exchange private_key = ( "f2f48ee19680706196e2e339e5da3491186e0c4c5030670656b0e0164837257d" ) diff --git a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py index f14dd3570d..7cc7ef277e 100644 --- a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py +++ b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py @@ -29,7 +29,7 @@ from web3.providers.base import BaseProvider from web3.contract import Contract -from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES, NetworkId +from zero_ex.contract_addresses import network_to_addresses, NetworkId import zero_ex.contract_artifacts from zero_ex.contract_wrappers.exchange import Exchange from zero_ex.contract_wrappers.exchange.types import Order @@ -211,11 +211,11 @@ def is_valid_signature( return Exchange( provider, - NETWORK_TO_ADDRESSES[ + network_to_addresses( NetworkId( int(Web3(provider).net.version) # pylint: disable=no-member ) - ].exchange, + ).exchange, ).is_valid_hash_signature.call( bytes.fromhex(remove_0x_prefix(data)), to_checksum_address(signer_address), diff --git a/python-packages/pre_install b/python-packages/pre_install index 42e561ca88..24ed40a633 100755 --- a/python-packages/pre_install +++ b/python-packages/pre_install @@ -12,6 +12,7 @@ from sys import argv PACKAGES = [ "contract_wrappers", + "contract_addresses", "contract_artifacts", "json_schemas", ] diff --git a/python-packages/sra_client/src/zero_ex/sra_client/__init__.py b/python-packages/sra_client/src/zero_ex/sra_client/__init__.py index 31aeb30f57..c9af8d5c25 100644 --- a/python-packages/sra_client/src/zero_ex/sra_client/__init__.py +++ b/python-packages/sra_client/src/zero_ex/sra_client/__init__.py @@ -83,8 +83,8 @@ Before such an order can be valid, though, the maker must give the 0x contracts permission to trade their ZRX tokens: ->>> from zero_ex.contract_addresses import NETWORK_TO_ADDRESSES ->>> contract_addresses = NETWORK_TO_ADDRESSES[network_id] +>>> from zero_ex.contract_addresses import network_to_addresses +>>> contract_addresses = network_to_addresses(network_id) >>> >>> from zero_ex.contract_artifacts import abi_by_name >>> zrx_token_contract = Web3(eth_node).eth.contract( @@ -321,7 +321,7 @@ >>> from zero_ex.order_utils import Order >>> exchange = Exchange( ... provider=eth_node, -... contract_address=NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange +... contract_address=network_to_addresses(NetworkId.GANACHE).exchange ... ) (Due to `an Issue with the Launch Kit Backend From 5873b5653a78f6022564258a9ce9b44624242714 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 18 Oct 2019 20:30:48 -0400 Subject: [PATCH 21/35] sra_client.py: incl. docker in `./setup.py clean` --- python-packages/sra_client/setup.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python-packages/sra_client/setup.py b/python-packages/sra_client/setup.py index ec784d4b4c..b06ae38bf3 100755 --- a/python-packages/sra_client/setup.py +++ b/python-packages/sra_client/setup.py @@ -46,6 +46,12 @@ def run(self): rmtree("0x_sra_client.egg-info", ignore_errors=True) rmtree("build", ignore_errors=True) rmtree("dist", ignore_errors=True) + subprocess.check_call( # nosec + ("docker-compose -f test/relayer/docker-compose.yml down").split() + ) + subprocess.check_call( # nosec + ("docker-compose -f test/relayer/docker-compose.yml rm").split() + ) class TestCommandExtension(TestCommand): From 8941145f2d34eaf5e4b9415ee8b7e5ba74e4c69f Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 21 Oct 2019 19:57:09 -0400 Subject: [PATCH 22/35] sra_client.py: Migrate to protocol v3 Removed script that existed only to exclude runs of sra_client builds (parallel_without_sra_client). Now `parallel` is used by CI, re-including sra_client in CI checks. --- .circleci/config.yml | 24 ++++- python-packages/parallel_without_sra_client | 57 ----------- python-packages/sra_client/setup.py | 7 +- .../src/zero_ex/sra_client/__init__.py | 63 ++++++++---- .../src/zero_ex/sra_client/api/default_api.py | 96 +++++++++---------- .../test/relayer/docker-compose.yml | 36 ++++++- 6 files changed, 147 insertions(+), 136 deletions(-) delete mode 100755 python-packages/parallel_without_sra_client diff --git a/.circleci/config.yml b/.circleci/config.yml index 96e6213f50..61e62d9eab 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -196,13 +196,29 @@ jobs: environment: VERSION: 4.4.0-beta.1 SNAPSHOT_NAME: 0x_ganache_snapshot-v3-beta - - image: 0xorg/launch-kit-backend:74bcc39 + - image: 0xorg/mesh:6.0.0-beta-0xv3 environment: - RPC_URL: http://localhost:8545 + ETHEREUM_RPC_URL: 'http://localhost:8545' + ETHEREUM_NETWORK_ID: '50' + ETHEREUM_CHAIN_ID: '1337' + USE_BOOTSTRAP_LIST: 'true' + VERBOSITY: 3 + PRIVATE_KEY_PATH: '' + BLOCK_POLLING_INTERVAL: '5s' + P2P_LISTEN_PORT: '60557' + command: | + sh -c "waitForGanache () { until printf 'POST /\r\nContent-Length: 26\r\n\r\n{\"method\":\"net_listening\"}' | nc localhost 8545 | grep true; do continue; done }; waitForGanache && ./mesh" + - image: 0xorg/launch-kit-backend:v3 + environment: + RPC_URL: 'http://localhost:8545' NETWORK_ID: 50 WHITELIST_ALL_TOKENS: True + FEE_RECIPIENT: '0x0000000000000000000000000000000000000001' + MAKER_FEE_UNIT_AMOUNT: 0 + TAKER_FEE_UNIT_AMOUNT: 0 + MESH_ENDPOINT: 'ws://localhost:60557' command: | - sh -c "until printf 'POST /\r\nContent-Length: 26\r\n\r\n{\"method\":\"net_listening\"}' | nc localhost 8545 | grep true; do continue; done; node_modules/.bin/forever ts/lib/index.js" + sh -c "waitForMesh () { sleep 5; }; waitForMesh && node_modules/.bin/forever ts/lib/index.js" steps: - checkout - restore_cache: @@ -224,7 +240,7 @@ jobs: - run: command: | cd python-packages - ./parallel_without_sra_client coverage run setup.py test + ./parallel coverage run setup.py test ./build_docs - run: command: | diff --git a/python-packages/parallel_without_sra_client b/python-packages/parallel_without_sra_client deleted file mode 100755 index 206415b758..0000000000 --- a/python-packages/parallel_without_sra_client +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python - -"""Run the given command in all packages in parallel. - -Handy for quick verification test runs, but annoying in that all of the output -is interleaved. - -$ ./parallel ./setup.py lint - -This will `cd` into each package, run `./setup.py lint`, then `cd ..`, all in -parallel, in a separate process for each package. The number of processes is -decided by ProcessPoolExecutor. Replace "lint" with any of "test", "clean", -"build_sphinx" (for docs), etc. - -Also consider: - -$ ./parallel pip install -e .[dev] # install all the packages in editable mode - -$ ./parallel pip uninstall $(basename $(pwd)) - ->>>""" - -from concurrent.futures import ProcessPoolExecutor, wait -from os import chdir -from subprocess import CalledProcessError, check_output, STDOUT -from sys import argv - -PACKAGES = [ - "contract_addresses", - "contract_artifacts", - "contract_wrappers", - "json_schemas", - "order_utils", - "middlewares", -] - -def run_cmd_on_package(package: str): - """cd to the package dir, ./setup.py lint, cd ..""" - chdir(package) - command = f"{' '.join(argv[1:])}" - try: - check_output(command.split(), stderr=STDOUT) - except CalledProcessError as error: - raise RuntimeError( - f"Failure return code received from command `{command}` in package" - + f" {package}, which produced the following output:\n" - + f"{error.output.decode('utf-8')}") from error - finally: - chdir("..") - -with ProcessPoolExecutor() as executor: - for future in executor.map(run_cmd_on_package, PACKAGES): - # iterate over map()'s return value, to resolve the futures. - # but we don't actually care what the return values are, so just `pass`. - # if any exceptions were raised by the underlying task, they'll be - # raised as the iteration encounters them. - pass diff --git a/python-packages/sra_client/setup.py b/python-packages/sra_client/setup.py index b06ae38bf3..b143467009 100755 --- a/python-packages/sra_client/setup.py +++ b/python-packages/sra_client/setup.py @@ -96,12 +96,15 @@ def run(self): ("docker-compose -f test/relayer/docker-compose.yml up -d").split() ) launch_kit_ready = False - print("Waiting for relayer to start accepting connections...", end="") + print( + "Waiting for Launch Kit Backend to start accepting connections...", + flush=True, + ) while not launch_kit_ready: try: launch_kit_ready = ( urlopen( # nosec - "http://localhost:3000/v2/asset_pairs" + "http://localhost:3000/v3/asset_pairs" ).getcode() == 200 ) diff --git a/python-packages/sra_client/src/zero_ex/sra_client/__init__.py b/python-packages/sra_client/src/zero_ex/sra_client/__init__.py index c9af8d5c25..dd15ab7ffb 100644 --- a/python-packages/sra_client/src/zero_ex/sra_client/__init__.py +++ b/python-packages/sra_client/src/zero_ex/sra_client/__init__.py @@ -19,7 +19,7 @@ pip install 0x-sra-client To interact with a 0x Relayer, you need the HTTP endpoint of the Relayer you'd -like to connect to (eg https://api.radarrelay.com/0x/v2). +like to connect to (eg https://api.radarrelay.com/0x/v3). For testing one can use the `0x-launch-kit-backend `_ to host @@ -121,9 +121,11 @@ ... makerAssetData=asset_data_utils.encode_erc20( ... contract_addresses.zrx_token ... ), +... makerFeeAssetData=asset_data_utils.encode_erc20('0x'+'00'*20), ... takerAssetData=asset_data_utils.encode_erc20( ... contract_addresses.ether_token ... ), +... takerFeeAssetData=asset_data_utils.encode_erc20('0x'+'00'*20), ... salt=random.randint(1, 100000000000000000), ... makerFee=0, ... takerFee=0, @@ -136,7 +138,7 @@ >>> from zero_ex.order_utils import generate_order_hash_hex >>> order_hash_hex = generate_order_hash_hex( -... order, contract_addresses.exchange +... order, contract_addresses.exchange, Web3(eth_node).eth.chainId ... ) >>> relayer.post_order_with_http_info( ... network_id=network_id.value, @@ -145,7 +147,8 @@ ... exchange_address=contract_addresses.exchange, ... signature=sign_hash( ... eth_node, Web3.toChecksumAddress(maker_address), order_hash_hex -... ) +... ), +... chain_id=Web3(eth_node).eth.chainId, ... ) ... )[1] 200 @@ -153,24 +156,35 @@ Get Order --------- +(But first sleep for a moment, to give the test relayer a chance to start up. + +>>> from time import sleep +>>> sleep(0.2) + +This is necessary for automated verification of these examples.) + Retrieve the order we just posted: >>> relayer.get_order("0x" + order_hash_hex) -{'meta_data': {}, - 'order': {'exchangeAddress': '0x...', +{'meta_data': {'orderHash': '0x...', + 'remainingFillableTakerAssetAmount': '2'}, + 'order': {'chainId': 50, + 'exchangeAddress': '0x...', 'expirationTimeSeconds': '...', 'feeRecipientAddress': '0x0000000000000000000000000000000000000000', 'makerAddress': '0x...', 'makerAssetAmount': '2', 'makerAssetData': '0xf47261b0000000000000000000000000...', 'makerFee': '0', + 'makerFeeAssetData': '0xf47261b0000000000000000000000000...', 'salt': '...', 'senderAddress': '0x0000000000000000000000000000000000000000', 'signature': '0x...', 'takerAddress': '0x0000000000000000000000000000000000000000', 'takerAssetAmount': '2', 'takerAssetData': '0xf47261b0000000000000000000000000...', - 'takerFee': '0'}} + 'takerFee': '0', + 'takerFeeAssetData': '0xf47261b0000000000000000000000000...'}} Get Orders ----------- @@ -179,21 +193,25 @@ of the one we just posted: >>> relayer.get_orders() -{'records': [{'meta_data': {}, - 'order': {'exchangeAddress': '0x...', +{'records': [{'meta_data': {'orderHash': '0x...', + 'remainingFillableTakerAssetAmount': '2'}, + 'order': {'chainId': 50, + 'exchangeAddress': '0x...', 'expirationTimeSeconds': '...', 'feeRecipientAddress': '0x0000000000000000000000000000000000000000', 'makerAddress': '0x...', 'makerAssetAmount': '2', 'makerAssetData': '0xf47261b000000000000000000000000...', 'makerFee': '0', + 'makerFeeAssetData': '0xf47261b000000000000000000000000...', 'salt': '...', 'senderAddress': '0x0000000000000000000000000000000000000000', 'signature': '0x...', 'takerAddress': '0x0000000000000000000000000000000000000000', 'takerAssetAmount': '2', 'takerAssetData': '0xf47261b0000000000000000000000000...', - 'takerFee': '0'}}]} + 'takerFee': '0', + 'takerFeeAssetData': '0xf47261b0000000000000000000000000...'}}...]} Get Asset Pairs --------------- @@ -234,43 +252,50 @@ ... ).hex(), ... ) >>> orderbook -{'asks': {'records': []}, - 'bids': {'records': [{'meta_data': {}, - 'order': {'exchangeAddress': '0x...', +{'asks': {'records': [...]}, + 'bids': {'records': [{'meta_data': {'orderHash': '0x...', + 'remainingFillableTakerAssetAmount': '2'}, + 'order': {'chainId': 50, + 'exchangeAddress': '0x...', 'expirationTimeSeconds': '...', 'feeRecipientAddress': '0x0000000000000000000000000000000000000000', 'makerAddress': '0x...', 'makerAssetAmount': '2', 'makerAssetData': '0xf47261b0000000000000000000000000...', 'makerFee': '0', + 'makerFeeAssetData': '0xf47261b0000000000000000000000000...', 'salt': '...', 'senderAddress': '0x0000000000000000000000000000000000000000', 'signature': '0x...', 'takerAddress': '0x0000000000000000000000000000000000000000', 'takerAssetAmount': '2', 'takerAssetData': '0xf47261b0000000000000000000000000...', - 'takerFee': '0'}}]}} + 'takerFee': '0', + 'takerFeeAssetData': '0xf47261b0000000000000000000000000...'}}...]}} Select an order from the orderbook ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->>> from zero_ex.contract_wrappers.exchange.types import jsdict_to_order +>>> from zero_ex.contract_wrappers.order_conversions import jsdict_to_order >>> order = jsdict_to_order(orderbook.bids.records[0].order) >>> from pprint import pprint >>> pprint(order) -{'expirationTimeSeconds': ..., +{'chainId': 50, + 'expirationTimeSeconds': ..., 'feeRecipientAddress': '0x0000000000000000000000000000000000000000', 'makerAddress': '0x...', 'makerAssetAmount': 2, 'makerAssetData': b... 'makerFee': 0, + 'makerFeeAssetData': b... 'salt': ..., 'senderAddress': '0x0000000000000000000000000000000000000000', 'signature': '0x...', 'takerAddress': '0x0000000000000000000000000000000000000000', 'takerAssetAmount': 2, - 'takerAssetData': b... - 'takerFee': 0} + 'takerAssetData': b..., + 'takerFee': 0, + 'takerFeeAssetData': b...} Filling or Cancelling an Order ------------------------------ @@ -320,7 +345,7 @@ >>> from zero_ex.contract_wrappers.exchange import Exchange >>> from zero_ex.order_utils import Order >>> exchange = Exchange( -... provider=eth_node, +... web3_or_provider=eth_node, ... contract_address=network_to_addresses(NetworkId.GANACHE).exchange ... ) @@ -332,7 +357,7 @@ >>> exchange.fill_order.send_transaction( ... order=order, ... taker_asset_fill_amount=order['makerAssetAmount']/2, # note the half fill -... signature=order['signature'].replace('0x', '').encode('utf-8'), +... signature=bytes.fromhex(order['signature'].replace('0x', '')), ... tx_params=TxParams(from_=taker_address) ... ) HexBytes('0x...') diff --git a/python-packages/sra_client/src/zero_ex/sra_client/api/default_api.py b/python-packages/sra_client/src/zero_ex/sra_client/api/default_api.py index e097f6c7c9..03e0316979 100644 --- a/python-packages/sra_client/src/zero_ex/sra_client/api/default_api.py +++ b/python-packages/sra_client/src/zero_ex/sra_client/api/default_api.py @@ -139,7 +139,7 @@ def get_asset_pairs_with_http_info(self, **kwargs): auth_settings = [] return self.api_client.call_api( - "/v2/asset_pairs", + "/v3/asset_pairs", "GET", path_params, query_params, @@ -250,7 +250,7 @@ def get_fee_recipients_with_http_info(self, **kwargs): auth_settings = [] return self.api_client.call_api( - "/v2/fee_recipients", + "/v3/fee_recipients", "GET", path_params, query_params, @@ -363,7 +363,7 @@ def get_order_with_http_info(self, order_hash, **kwargs): auth_settings = [] return self.api_client.call_api( - "/v2/order/{orderHash}", + "/v3/order/{orderHash}", "GET", path_params, query_params, @@ -497,7 +497,7 @@ def get_order_config_with_http_info(self, **kwargs): auth_settings = [] return self.api_client.call_api( - "/v2/order_config", + "/v3/order_config", "POST", path_params, query_params, @@ -680,7 +680,7 @@ def get_orderbook_with_http_info( auth_settings = [] return self.api_client.call_api( - "/v2/orderbook", + "/v3/orderbook", "GET", path_params, query_params, @@ -718,50 +718,48 @@ def get_orders(self, **kwargs): :param bool async_req: Whether request should be asynchronous. :param str maker_asset_proxy_id: The maker `asset proxy id - `__ + `__ (example: "0xf47261b0" for ERC20, "0x02571792" for ERC721). :param str taker_asset_proxy_id: The taker asset `asset proxy id - `__ + `__ (example: "0xf47261b0" for ERC20, "0x02571792" for ERC721). :param str maker_asset_address: The contract address for the maker asset. :param str taker_asset_address: The contract address for the taker asset. - :param str exchange_address: Same as exchangeAddress in the - `0x Protocol v2 Specification - `__ + :param str exchange_address: Contract address for the exchange + contract. :param str sender_address: Same as senderAddress in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str maker_asset_data: Same as makerAssetData in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str taker_asset_data: Same as takerAssetData in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str trader_asset_data: Same as traderAssetData in the [0x - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str maker_address: Same as makerAddress in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str taker_address: Same as takerAddress in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str trader_address: Same as traderAddress in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str fee_recipient_address: Same as feeRecipientAddress in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param int network_id: The id of the Ethereum network :param int page: The number of the page to request in the collection. :param int per_page: The number of records to return per page. @@ -795,50 +793,50 @@ def get_orders_with_http_info(self, **kwargs): :param bool async_req: Whether request should be asynchronous. :param str maker_asset_proxy_id: The maker `asset proxy id - `__ + `__ (example: "0xf47261b0" for ERC20, "0x02571792" for ERC721). :param str taker_asset_proxy_id: The taker asset `asset proxy id - `__ + `__ (example: "0xf47261b0" for ERC20, "0x02571792" for ERC721). :param str maker_asset_address: The contract address for the maker asset. :param str taker_asset_address: The contract address for the taker asset. :param str exchange_address: Same as exchangeAddress in the [0x - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str sender_address: Same as senderAddress in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str maker_asset_data: Same as makerAssetData in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str taker_asset_data: Same as takerAssetData in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str trader_asset_data: Same as traderAssetData in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str maker_address: Same as makerAddress in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str taker_address: Same as takerAddress in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str trader_address: Same as traderAddress in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param str fee_recipient_address: Same as feeRecipientAddress in the - `0x Protocol v2 Specification + `0x Protocol v3 Specification `__ + master/v3/v3-specification.md#order-message-format>`__ :param int network_id: The id of the Ethereum network :param int page: The number of the page to request in the collection. :param int per_page: The number of records to return per page. @@ -965,7 +963,7 @@ def get_orders_with_http_info(self, **kwargs): auth_settings = [] return self.api_client.call_api( - "/v2/orders", + "/v3/orders", "GET", path_params, query_params, @@ -1077,7 +1075,7 @@ def post_order_with_http_info(self, **kwargs): auth_settings = [] return self.api_client.call_api( - "/v2/order", + "/v3/order", "POST", path_params, query_params, diff --git a/python-packages/sra_client/test/relayer/docker-compose.yml b/python-packages/sra_client/test/relayer/docker-compose.yml index 6a67dcea71..e5b6657ab4 100644 --- a/python-packages/sra_client/test/relayer/docker-compose.yml +++ b/python-packages/sra_client/test/relayer/docker-compose.yml @@ -1,14 +1,36 @@ -# Run Launch Kit with Ganache as the backing node +# Run Launch Kit Backend with Ganache and Mesh instances backing it. version: '3' services: ganache: - image: "0xorg/ganache-cli:2.2.2" + image: "0xorg/ganache-cli:4.4.0-beta.1" ports: - "8545:8545" - launchkit: - image: "0xorg/launch-kit-backend:74bcc39" + environment: + - VERSION=4.4.0-beta.1 + - SNAPSHOT_NAME=0x_ganache_snapshot-v3-beta + mesh: + image: 0xorg/mesh:6.0.0-beta-0xv3 + depends_on: + - ganache + environment: + ETHEREUM_RPC_URL: 'http://localhost:8545' + ETHEREUM_NETWORK_ID: '50' + ETHEREUM_CHAIN_ID: '1337' + USE_BOOTSTRAP_LIST: 'true' + VERBOSITY: 3 + PRIVATE_KEY_PATH: '' + BLOCK_POLLING_INTERVAL: '5s' + P2P_LISTEN_PORT: '60557' + ports: + - '60557:60557' + network_mode: "host" # to connect to ganache + command: | + sh -c "waitForGanache () { until printf 'POST /\r\nContent-Length: 26\r\n\r\n{\"method\":\"net_listening\"}' | nc localhost 8545 | grep true; do continue; done }; waitForGanache && ./mesh" + launch-kit-backend: + image: "0xorg/launch-kit-backend:v3" depends_on: - ganache + - mesh ports: - "3000:3000" network_mode: "host" # to connect to ganache @@ -16,5 +38,9 @@ services: - NETWORK_ID=50 - RPC_URL=http://localhost:8545 - WHITELIST_ALL_TOKENS=True + - FEE_RECIPIENT=0x0000000000000000000000000000000000000001 + - MAKER_FEE_UNIT_AMOUNT=0 + - TAKER_FEE_UNIT_AMOUNT=0 + - MESH_ENDPOINT=ws://localhost:60557 command: | - sh -c "until printf 'POST /\r\nContent-Length: 26\r\n\r\n{\"method\":\"net_listening\"}' | nc localhost 8545 | grep true; do continue; done; node_modules/.bin/forever ts/lib/index.js" + sh -c "waitForMesh () { sleep 3; }; waitForMesh && sleep 5 && node_modules/.bin/forever ts/lib/index.js" From 1ec50980dd825bb4aa50984dc4018326817abc5f Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Sat, 2 Nov 2019 00:13:46 -0400 Subject: [PATCH 23/35] abi-gen/test: recompile contract fixtures for 3.0 It seems this hadn't been done since the merge with the 3.0 branch. --- .../fixtures/artifacts/AbiGenDummy.json | 738 ++--- .../test-cli/fixtures/artifacts/LibDummy.json | 12 +- .../fixtures/artifacts/TestLibDummy.json | 16 +- .../output/python/abi_gen_dummy/__init__.py | 1442 ++++----- .../output/python/test_lib_dummy/__init__.py | 2 +- .../output/typescript/abi_gen_dummy.ts | 2648 ++++++++--------- .../output/typescript/test_lib_dummy.ts | 2 +- 7 files changed, 2432 insertions(+), 2428 deletions(-) diff --git a/packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json b/packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json index d6f248d320..2023f5685e 100644 --- a/packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json +++ b/packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json @@ -4,100 +4,144 @@ "compilerOutput": { "abi": [ { - "constant": true, - "inputs": [], - "name": "simpleRequire", - "outputs": [], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": true, + "anonymous": false, "inputs": [ { - "internalType": "bytes[]", - "name": "a", - "type": "bytes[]" + "indexed": false, + "internalType": "bytes", + "name": "someBytes", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "string", + "name": "someString", + "type": "string" } ], - "name": "acceptsAnArrayOfBytes", - "outputs": [], - "payable": false, - "stateMutability": "pure", - "type": "function" + "name": "SimpleEvent", + "type": "event" }, { - "constant": true, + "anonymous": false, "inputs": [ { + "indexed": true, + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "", + "name": "_value", "type": "uint256" } ], - "name": "simpleInputSimpleOutput", - "outputs": [ + "name": "Withdrawal", + "type": "event" + }, + { + "constant": true, + "inputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "bytes[]", + "name": "a", + "type": "bytes[]" } ], + "name": "acceptsAnArrayOfBytes", + "outputs": [], "payable": false, "stateMutability": "pure", "type": "function" }, { - "constant": false, + "constant": true, "inputs": [ { - "internalType": "uint256", - "name": "wad", - "type": "uint256" + "internalType": "bytes", + "name": "a", + "type": "bytes" } ], - "name": "withdraw", + "name": "acceptsBytes", "outputs": [], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "pure", "type": "function" }, { "constant": true, "inputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - }, - { - "internalType": "string", - "name": "", - "type": "string" + "components": [ + { + "internalType": "uint256", + "name": "foo", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "bar", + "type": "bytes" + }, + { + "internalType": "string", + "name": "car", + "type": "string" + } + ], + "internalType": "struct AbiGenDummy.ComplexInput", + "name": "complexInput", + "type": "tuple" } ], - "name": "multiInputMultiOutput", + "name": "complexInputComplexOutput", "outputs": [ { - "internalType": "bytes", - "name": "", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - }, - { - "internalType": "string", + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "foo", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "bar", + "type": "bytes" + }, + { + "internalType": "string", + "name": "car", + "type": "string" + } + ], + "internalType": "struct AbiGenDummy.ComplexInput", + "name": "input", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "lorem", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "ipsum", + "type": "bytes" + }, + { + "internalType": "string", + "name": "dolor", + "type": "string" + } + ], + "internalType": "struct AbiGenDummy.ComplexOutput", "name": "", - "type": "string" + "type": "tuple" } ], "payable": false, @@ -140,17 +184,48 @@ "stateMutability": "pure", "type": "function" }, + { + "constant": false, + "inputs": [], + "name": "emitSimpleEvent", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": true, - "inputs": [ + "inputs": [], + "name": "methodReturningArrayOfStructs", + "outputs": [ { - "internalType": "bytes", - "name": "a", - "type": "bytes" + "components": [ + { + "internalType": "bytes", + "name": "someBytes", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "anInteger", + "type": "uint32" + }, + { + "internalType": "bytes[]", + "name": "aDynamicArrayOfBytes", + "type": "bytes[]" + }, + { + "internalType": "string", + "name": "aString", + "type": "string" + } + ], + "internalType": "struct AbiGenDummy.Struct[]", + "name": "", + "type": "tuple[]" } ], - "name": "acceptsBytes", - "outputs": [], "payable": false, "stateMutability": "pure", "type": "function" @@ -158,12 +233,17 @@ { "constant": true, "inputs": [], - "name": "noInputSimpleOutput", + "name": "methodReturningMultipleValues", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" } ], "payable": false, @@ -173,46 +253,118 @@ { "constant": true, "inputs": [], - "name": "revertWithConstant", - "outputs": [], + "name": "methodUsingNestedStructWithInnerStructNotUsedElsewhere", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "aField", + "type": "uint256" + } + ], + "internalType": "struct AbiGenDummy.StructNotDirectlyUsedAnywhere", + "name": "innerStruct", + "type": "tuple" + } + ], + "internalType": "struct AbiGenDummy.NestedStructWithInnerStructNotUsedElsewhere", + "name": "", + "type": "tuple" + } + ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, - "inputs": [], - "name": "simpleRevert", - "outputs": [], + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "name": "multiInputMultiOutput", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "string", + "name": "", + "type": "string" + } + ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, - "inputs": [], - "name": "methodUsingNestedStructWithInnerStructNotUsedElsewhere", - "outputs": [ + "inputs": [ { "components": [ { "components": [ { - "internalType": "uint256", - "name": "aField", - "type": "uint256" + "internalType": "bytes", + "name": "someBytes", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "anInteger", + "type": "uint32" + }, + { + "internalType": "bytes[]", + "name": "aDynamicArrayOfBytes", + "type": "bytes[]" + }, + { + "internalType": "string", + "name": "aString", + "type": "string" } ], - "internalType": "struct AbiGenDummy.StructNotDirectlyUsedAnywhere", + "internalType": "struct AbiGenDummy.Struct", "name": "innerStruct", "type": "tuple" + }, + { + "internalType": "string", + "name": "description", + "type": "string" } ], - "internalType": "struct AbiGenDummy.NestedStructWithInnerStructNotUsedElsewhere", - "name": "", + "internalType": "struct AbiGenDummy.NestedStruct", + "name": "n", "type": "tuple" } ], + "name": "nestedStructInput", + "outputs": [], "payable": false, "stateMutability": "pure", "type": "function" @@ -269,7 +421,7 @@ { "constant": true, "inputs": [], - "name": "requireWithConstant", + "name": "noInputNoOutput", "outputs": [], "payable": false, "stateMutability": "pure", @@ -277,78 +429,15 @@ }, { "constant": true, - "inputs": [ - { - "internalType": "address", - "name": "x", - "type": "address" - }, - { - "internalType": "uint256", - "name": "a", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "b", - "type": "uint256" - }, - { - "internalType": "address", - "name": "y", - "type": "address" - }, + "inputs": [], + "name": "noInputSimpleOutput", + "outputs": [ { "internalType": "uint256", - "name": "c", + "name": "", "type": "uint256" } ], - "name": "withAddressInput", - "outputs": [ - { - "internalType": "address", - "name": "z", - "type": "address" - } - ], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "components": [ - { - "internalType": "bytes", - "name": "someBytes", - "type": "bytes" - }, - { - "internalType": "uint32", - "name": "anInteger", - "type": "uint32" - }, - { - "internalType": "bytes[]", - "name": "aDynamicArrayOfBytes", - "type": "bytes[]" - }, - { - "internalType": "string", - "name": "aString", - "type": "string" - } - ], - "internalType": "struct AbiGenDummy.Struct", - "name": "s", - "type": "tuple" - } - ], - "name": "structInput", - "outputs": [], "payable": false, "stateMutability": "pure", "type": "function" @@ -368,79 +457,41 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "constant": false, + "inputs": [], + "name": "nonPureMethodThatReturnsNothing", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": true, "inputs": [ { - "components": [ - { - "internalType": "uint256", - "name": "foo", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "bar", - "type": "bytes" - }, - { - "internalType": "string", - "name": "car", - "type": "string" - } - ], - "internalType": "struct AbiGenDummy.ComplexInput", - "name": "complexInput", - "type": "tuple" + "internalType": "string", + "name": "a", + "type": "string" } ], - "name": "complexInputComplexOutput", - "outputs": [ + "name": "overloadedMethod", + "outputs": [], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ { - "components": [ - { - "components": [ - { - "internalType": "uint256", - "name": "foo", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "bar", - "type": "bytes" - }, - { - "internalType": "string", - "name": "car", - "type": "string" - } - ], - "internalType": "struct AbiGenDummy.ComplexInput", - "name": "input", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "lorem", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "ipsum", - "type": "bytes" - }, - { - "internalType": "string", - "name": "dolor", - "type": "string" - } - ], - "internalType": "struct AbiGenDummy.ComplexOutput", - "name": "", - "type": "tuple" + "internalType": "int256", + "name": "a", + "type": "int256" } ], + "name": "overloadedMethod", + "outputs": [], "payable": false, "stateMutability": "pure", "type": "function" @@ -448,7 +499,31 @@ { "constant": true, "inputs": [], - "name": "noInputNoOutput", + "name": "pureFunctionWithConstant", + "outputs": [ + { + "internalType": "uint256", + "name": "someConstant", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "requireWithConstant", + "outputs": [], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "revertWithConstant", "outputs": [], "payable": false, "stateMutability": "pure", @@ -459,15 +534,30 @@ "inputs": [ { "internalType": "uint256", - "name": "x", + "name": "", "type": "uint256" } ], - "name": "simplePureFunctionWithInput", + "name": "simpleInputNoOutput", + "outputs": [], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "simpleInputSimpleOutput", "outputs": [ { "internalType": "uint256", - "name": "sum", + "name": "", "type": "uint256" } ], @@ -475,15 +565,6 @@ "stateMutability": "pure", "type": "function" }, - { - "constant": false, - "inputs": [], - "name": "nonPureMethodThatReturnsNothing", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, { "constant": true, "inputs": [], @@ -503,47 +584,19 @@ "constant": true, "inputs": [ { - "components": [ - { - "components": [ - { - "internalType": "bytes", - "name": "someBytes", - "type": "bytes" - }, - { - "internalType": "uint32", - "name": "anInteger", - "type": "uint32" - }, - { - "internalType": "bytes[]", - "name": "aDynamicArrayOfBytes", - "type": "bytes[]" - }, - { - "internalType": "string", - "name": "aString", - "type": "string" - } - ], - "internalType": "struct AbiGenDummy.Struct", - "name": "innerStruct", - "type": "tuple" - }, - { - "internalType": "string", - "name": "description", - "type": "string" - } - ], - "internalType": "struct AbiGenDummy.NestedStruct", - "name": "n", - "type": "tuple" + "internalType": "uint256", + "name": "x", + "type": "uint256" + } + ], + "name": "simplePureFunctionWithInput", + "outputs": [ + { + "internalType": "uint256", + "name": "sum", + "type": "uint256" } ], - "name": "nestedStructInput", - "outputs": [], "payable": false, "stateMutability": "pure", "type": "function" @@ -551,19 +604,8 @@ { "constant": true, "inputs": [], - "name": "methodReturningMultipleValues", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "string", - "name": "", - "type": "string" - } - ], + "name": "simpleRequire", + "outputs": [], "payable": false, "stateMutability": "pure", "type": "function" @@ -571,8 +613,15 @@ { "constant": true, "inputs": [], - "name": "methodReturningArrayOfStructs", - "outputs": [ + "name": "simpleRevert", + "outputs": [], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ { "components": [ { @@ -596,22 +645,15 @@ "type": "string" } ], - "internalType": "struct AbiGenDummy.Struct[]", - "name": "", - "type": "tuple[]" + "internalType": "struct AbiGenDummy.Struct", + "name": "s", + "type": "tuple" } ], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "emitSimpleEvent", + "name": "structInput", "outputs": [], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "pure", "type": "function" }, { @@ -653,101 +695,59 @@ }, { "constant": true, - "inputs": [], - "name": "pureFunctionWithConstant", - "outputs": [ + "inputs": [ + { + "internalType": "address", + "name": "x", + "type": "address" + }, { "internalType": "uint256", - "name": "someConstant", + "name": "a", "type": "uint256" - } - ], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": true, - "inputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "b", "type": "uint256" - } - ], - "name": "simpleInputNoOutput", - "outputs": [], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": true, - "inputs": [ + }, { - "internalType": "string", - "name": "a", - "type": "string" + "internalType": "address", + "name": "y", + "type": "address" + }, + { + "internalType": "uint256", + "name": "c", + "type": "uint256" } ], - "name": "overloadedMethod", - "outputs": [], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": true, - "inputs": [ + "name": "withAddressInput", + "outputs": [ { - "internalType": "int256", - "name": "a", - "type": "int256" + "internalType": "address", + "name": "z", + "type": "address" } ], - "name": "overloadedMethod", - "outputs": [], "payable": false, "stateMutability": "pure", "type": "function" }, { - "anonymous": false, + "constant": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "indexed": false, "internalType": "uint256", - "name": "_value", + "name": "wad", "type": "uint256" } ], - "name": "Withdrawal", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes", - "name": "someBytes", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "string", - "name": "someString", - "type": "string" - } - ], - "name": "SimpleEvent", - "type": "event" + "name": "withdraw", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" } ], "devdoc": { @@ -795,15 +795,15 @@ "evm": { "bytecode": { "linkReferences": {}, - "object": "0x608060405234801561001057600080fd5b50611478806100206000396000f3fe608060405234801561001057600080fd5b50600436106101d95760003560e01c806376f15d5b11610104578063bb607362116100a2578063d88be12f11610071578063d88be12f1461039b578063ee8b86fb146103a3578063f408fb3114610279578063fa315f9d146103b6576101d9565b8063bb60736214610353578063bdab168814610369578063cd3c0b971461037e578063d6d7618c14610386576101d9565b80638ee52b4e116100de5780638ee52b4e146103225780639a3b618514610335578063a3c2f6b61461033d578063ae2dae1714610345576101d9565b806376f15d5b146102f25780637833bec0146102fa5780637a791e6e1461031a576101d9565b80634303a5421161017c57806359c28add1161014b57806359c28add146102b45780635ba3c7c0146102c957806363d69c88146102d1578063647341eb146102e4576101d9565b80634303a542146102875780634582eab21461028f57806345fdbdb714610297578063586f84b21461029f576101d9565b80632e1a7d4d116101b85780632e1a7d4d146102245780633687617d1461023757806336b32396146102595780633e9ef66a14610279576101d9565b806209e437146101de5780630527c28f146101e85780631310e444146101fb575b600080fd5b6101e66103c4565b005b6101e66101f6366004610c7f565b610401565b61020e610209366004610d34565b610404565b60405161021b919061139a565b60405180910390f35b6101e6610232366004610d34565b61040b565b61024a610245366004610eac565b61045c565b60405161021b93929190611103565b61026c610267366004610cbc565b6104fc565b60405161021b9190611045565b6101e66101f6366004610cff565b61020e6105de565b6101e66105e5565b6101e661064a565b6102a761067c565b60405161021b9190611325565b6102bc610684565b60405161021b9190611330565b6101e661068c565b61026c6102df366004610c2d565b6106f1565b6101e66101f6366004610e77565b61020e6106fa565b61030d610308366004610d4d565b610708565b60405161021b9190611239565b6101e66107c5565b61020e610330366004610d34565b6107ca565b6101e66107d0565b61020e6107db565b6101e66101f6366004610de7565b61035b6107e0565b60405161021b9291906113a3565b610371610819565b60405161021b9190611066565b6101e661081e565b61038e610855565b60405161021b9190611387565b61020e6109ae565b6101e66103b1366004610d34565b6101f6565b6101e66101f6366004610d34565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f690611202565b60405180910390fd5b565b50565b506107c790565b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6582604051610451919061139a565b60405180910390a250565b505060408051808201825260048082527f1234567800000000000000000000000000000000000000000000000000000000602080840191909152835180850185528281527f87654321000000000000000000000000000000000000000000000000000000008183015284518086019095529184527f616d657400000000000000000000000000000000000000000000000000000000908401529093909250565b600060606040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525090506000818760405160200161054d929190611023565b6040516020818303038152906040528051906020012090506001818787876040516000815260200160405260405161058894939291906110e5565b6020604051602081039080840390855afa1580156105aa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015198975050505050505050565b6107c75b90565b604080518082018252601481527f5245564552545f574954485f434f4e5354414e54000000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611145565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f6906111cb565b6105e26109b4565b6105e26109cc565b604080518082018252601581527f524551554952455f574954485f434f4e5354414e540000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611145565b50929392505050565b600080546001019081905590565b6107106109ec565b50604080516080810182529182528051808201825260048082527f123456780000000000000000000000000000000000000000000000000000000060208381019190915280850192909252825180840184528181527f87654321000000000000000000000000000000000000000000000000000000008184015284840152825180840190935282527f616d65740000000000000000000000000000000000000000000000000000000090820152606082015290565b6103ff565b60010190565b600080546001019055565b600190565b60408051808201909152600581527f68656c6c6f0000000000000000000000000000000000000000000000000000006020820152600191565b606090565b7f61a6029a4c7ddee5824d171331eecbd015d26a271310a223718b837facb5b77160405161084b9061115f565b60405180910390a1565b61085d610a1a565b6040805160028082526060828101909352816020015b60608152602001906001900390816108735790505090506040518060400160405280600581526020017f3078313233000000000000000000000000000000000000000000000000000000815250816000815181106108cd57fe5b60200260200101819052506040518060400160405280600581526020017f30783332310000000000000000000000000000000000000000000000000000008152508160018151811061091b57fe5b6020908102919091018101919091526040805160c0810182526005608082018181527f307831323300000000000000000000000000000000000000000000000000000060a0840152825281840152808201939093528051808201909152600381527f6162630000000000000000000000000000000000000000000000000000000000918101919091526060820152905090565b6104d290565b60405180602001604052806109c7610a48565b905290565b60405180604001604052806109df610a1a565b8152602001606081525090565b60405180608001604052806109ff610a5b565b81526020016060815260200160608152602001606081525090565b604051806080016040528060608152602001600063ffffffff16815260200160608152602001606081525090565b6040518060200160405280600081525090565b60405180606001604052806000815260200160608152602001606081525090565b600082601f830112610a8c578081fd5b813567ffffffffffffffff811115610aa2578182fd5b6020610ab181828402016113bc565b828152925080830184820160005b84811015610ae857610ad6888584358a0101610af3565b83529183019190830190600101610abf565b505050505092915050565b600082601f830112610b03578081fd5b813567ffffffffffffffff811115610b19578182fd5b610b4a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016113bc565b9150808252836020828501011115610b6157600080fd5b8060208401602084013760009082016020015292915050565b600060808284031215610b8b578081fd5b610b9560806113bc565b90506000823567ffffffffffffffff80821115610bb0578283fd5b610bbc86838701610af3565b84526020850135915063ffffffff82168214610bd6578283fd5b8160208501526040850135915080821115610bef578283fd5b610bfb86838701610a7c565b60408501526060850135915080821115610c13578283fd5b50610c2085828601610af3565b6060840152505092915050565b600080600080600060a08688031215610c4557600080fd5b8535610c5081611413565b945060208601359350604086013592506060860135610c6e81611413565b949793965091946080013592915050565b600060208284031215610c9157600080fd5b813567ffffffffffffffff811115610ca857600080fd5b610cb484828501610a7c565b949350505050565b60008060008060808587031215610cd257600080fd5b84359350602085013560ff81168114610cea57600080fd5b93969395505050506040820135916060013590565b600060208284031215610d1157600080fd5b813567ffffffffffffffff811115610d2857600080fd5b610cb484828501610af3565b600060208284031215610d4657600080fd5b5035919050565b600060208284031215610d5e578081fd5b813567ffffffffffffffff80821115610d75578283fd5b81840160608187031215610d87578384fd5b610d9160606113bc565b925080358352602081013582811115610da8578485fd5b610db487828401610af3565b602085015250604081013582811115610dcb578485fd5b610dd787828401610af3565b6040850152509195945050505050565b600060208284031215610df8578081fd5b813567ffffffffffffffff80821115610e0f578283fd5b81840160408187031215610e21578384fd5b610e2b60406113bc565b9250803582811115610e3b578485fd5b610e4787828401610b7a565b845250602081013582811115610e5b578485fd5b610e6787828401610af3565b6020850152509195945050505050565b600060208284031215610e8957600080fd5b813567ffffffffffffffff811115610ea057600080fd5b610cb484828501610b7a565b600080600060608486031215610ec0578081fd5b83359250602084013567ffffffffffffffff80821115610ede578283fd5b610eea87838801610af3565b93506040860135915080821115610eff578283fd5b50610f0c86828701610af3565b9150509250925092565b60008151808452610f2e8160208601602086016113e3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000815160808452610f756080850182610f16565b6020915063ffffffff82850151168286015260408401518582036040870152818151808452848401915084858202850101858401600094505b82851015610ffc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868303018452610fe8828251610f16565b600195909501949387019391508601610fae565b506060880151955088810360608a01526110168187610f16565b9998505050505050505050565b600083516110358184602088016113e3565b9190910191825250602001919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600060208083018184528085518083526040860191506040848202870101925083870160005b828110156110d8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526110c6858351610f60565b9450928501929085019060010161108c565b5092979650505050505050565b93845260ff9290921660208401526040830152606082015260800190565b6000606082526111166060830186610f16565b82810360208401526111288186610f16565b838103604085015261113a8186610f16565b979650505050505050565b6000602082526111586020830184610f16565b9392505050565b60408082526004908201527f123456780000000000000000000000000000000000000000000000000000000060608201526080602082018190526005908201527f6c6f72656d00000000000000000000000000000000000000000000000000000060a082015260c00190565b6020808252600d908201527f53494d504c455f52455645525400000000000000000000000000000000000000604082015260600190565b6020808252600e908201527f53494d504c455f52455155495245000000000000000000000000000000000000604082015260600190565b600060208252825160806020840152805160a08401526020810151606060c0850152611269610100850182610f16565b604083015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608582030160e08601526112a48183610f16565b9250505060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808584030160408601526112e28383610f16565b60408701519350818682030160608701526112fd8185610f16565b92505060608601519250808583030160808601525061131c8183610f16565b95945050505050565b905151815260200190565b60006020825282516040602084015261134c6060840182610f60565b602085015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084820301604085015261131c8183610f16565b6000602082526111586020830184610f60565b90815260200190565b600083825260406020830152610cb46040830184610f16565b60405181810167ffffffffffffffff811182821017156113db57600080fd5b604052919050565b60005b838110156113fe5781810151838201526020016113e6565b8381111561140d576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461040157600080fdfea365627a7a723158207f0854b76fc684de0be1f1a5db2d486bc187ff28d1e99d27ca0f61b452a1942f6c6578706572696d656e74616cf564736f6c634300050b0040", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1478 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x1D9 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x76F15D5B GT PUSH2 0x104 JUMPI DUP1 PUSH4 0xBB607362 GT PUSH2 0xA2 JUMPI DUP1 PUSH4 0xD88BE12F GT PUSH2 0x71 JUMPI DUP1 PUSH4 0xD88BE12F EQ PUSH2 0x39B JUMPI DUP1 PUSH4 0xEE8B86FB EQ PUSH2 0x3A3 JUMPI DUP1 PUSH4 0xF408FB31 EQ PUSH2 0x279 JUMPI DUP1 PUSH4 0xFA315F9D EQ PUSH2 0x3B6 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0xBB607362 EQ PUSH2 0x353 JUMPI DUP1 PUSH4 0xBDAB1688 EQ PUSH2 0x369 JUMPI DUP1 PUSH4 0xCD3C0B97 EQ PUSH2 0x37E JUMPI DUP1 PUSH4 0xD6D7618C EQ PUSH2 0x386 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x8EE52B4E GT PUSH2 0xDE JUMPI DUP1 PUSH4 0x8EE52B4E EQ PUSH2 0x322 JUMPI DUP1 PUSH4 0x9A3B6185 EQ PUSH2 0x335 JUMPI DUP1 PUSH4 0xA3C2F6B6 EQ PUSH2 0x33D JUMPI DUP1 PUSH4 0xAE2DAE17 EQ PUSH2 0x345 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x76F15D5B EQ PUSH2 0x2F2 JUMPI DUP1 PUSH4 0x7833BEC0 EQ PUSH2 0x2FA JUMPI DUP1 PUSH4 0x7A791E6E EQ PUSH2 0x31A JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x4303A542 GT PUSH2 0x17C JUMPI DUP1 PUSH4 0x59C28ADD GT PUSH2 0x14B JUMPI DUP1 PUSH4 0x59C28ADD EQ PUSH2 0x2B4 JUMPI DUP1 PUSH4 0x5BA3C7C0 EQ PUSH2 0x2C9 JUMPI DUP1 PUSH4 0x63D69C88 EQ PUSH2 0x2D1 JUMPI DUP1 PUSH4 0x647341EB EQ PUSH2 0x2E4 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x4303A542 EQ PUSH2 0x287 JUMPI DUP1 PUSH4 0x4582EAB2 EQ PUSH2 0x28F JUMPI DUP1 PUSH4 0x45FDBDB7 EQ PUSH2 0x297 JUMPI DUP1 PUSH4 0x586F84B2 EQ PUSH2 0x29F JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x2E1A7D4D GT PUSH2 0x1B8 JUMPI DUP1 PUSH4 0x2E1A7D4D EQ PUSH2 0x224 JUMPI DUP1 PUSH4 0x3687617D EQ PUSH2 0x237 JUMPI DUP1 PUSH4 0x36B32396 EQ PUSH2 0x259 JUMPI DUP1 PUSH4 0x3E9EF66A EQ PUSH2 0x279 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH3 0x9E437 EQ PUSH2 0x1DE JUMPI DUP1 PUSH4 0x527C28F EQ PUSH2 0x1E8 JUMPI DUP1 PUSH4 0x1310E444 EQ PUSH2 0x1FB JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1E6 PUSH2 0x3C4 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xC7F JUMP JUMPDEST PUSH2 0x401 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x209 CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH2 0x404 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x139A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x1E6 PUSH2 0x232 CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH2 0x40B JUMP JUMPDEST PUSH2 0x24A PUSH2 0x245 CALLDATASIZE PUSH1 0x4 PUSH2 0xEAC JUMP JUMPDEST PUSH2 0x45C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1103 JUMP JUMPDEST PUSH2 0x26C PUSH2 0x267 CALLDATASIZE PUSH1 0x4 PUSH2 0xCBC JUMP JUMPDEST PUSH2 0x4FC JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1045 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xCFF JUMP JUMPDEST PUSH2 0x20E PUSH2 0x5DE JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x5E5 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x64A JUMP JUMPDEST PUSH2 0x2A7 PUSH2 0x67C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1325 JUMP JUMPDEST PUSH2 0x2BC PUSH2 0x684 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1330 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x68C JUMP JUMPDEST PUSH2 0x26C PUSH2 0x2DF CALLDATASIZE PUSH1 0x4 PUSH2 0xC2D JUMP JUMPDEST PUSH2 0x6F1 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xE77 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x6FA JUMP JUMPDEST PUSH2 0x30D PUSH2 0x308 CALLDATASIZE PUSH1 0x4 PUSH2 0xD4D JUMP JUMPDEST PUSH2 0x708 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1239 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x7C5 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x330 CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH2 0x7CA JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x7D0 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x7DB JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xDE7 JUMP JUMPDEST PUSH2 0x35B PUSH2 0x7E0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP3 SWAP2 SWAP1 PUSH2 0x13A3 JUMP JUMPDEST PUSH2 0x371 PUSH2 0x819 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1066 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x81E JUMP JUMPDEST PUSH2 0x38E PUSH2 0x855 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1387 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x9AE JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x3B1 CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH2 0x1F6 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3F6 SWAP1 PUSH2 0x1202 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST JUMP JUMPDEST POP JUMP JUMPDEST POP PUSH2 0x7C7 SWAP1 JUMP JUMPDEST CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0x7FCF532C15F0A6DB0BD6D0E038BEA71D30D808C7D98CB3BF7268A95BF5081B65 DUP3 PUSH1 0x40 MLOAD PUSH2 0x451 SWAP2 SWAP1 PUSH2 0x139A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 POP JUMP JUMPDEST POP POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x4 DUP1 DUP3 MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP4 MLOAD DUP1 DUP6 ADD DUP6 MSTORE DUP3 DUP2 MSTORE PUSH32 0x8765432100000000000000000000000000000000000000000000000000000000 DUP2 DUP4 ADD MSTORE DUP5 MLOAD DUP1 DUP7 ADD SWAP1 SWAP6 MSTORE SWAP2 DUP5 MSTORE PUSH32 0x616D657400000000000000000000000000000000000000000000000000000000 SWAP1 DUP5 ADD MSTORE SWAP1 SWAP4 SWAP1 SWAP3 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x1C DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE POP SWAP1 POP PUSH1 0x0 DUP2 DUP8 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x54D SWAP3 SWAP2 SWAP1 PUSH2 0x1023 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 SWAP1 POP PUSH1 0x1 DUP2 DUP8 DUP8 DUP8 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x588 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x10E5 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x5AA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0x7C7 JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x14 DUP2 MSTORE PUSH32 0x5245564552545F574954485F434F4E5354414E54000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH2 0x3F6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x1145 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3F6 SWAP1 PUSH2 0x11CB JUMP JUMPDEST PUSH2 0x5E2 PUSH2 0x9B4 JUMP JUMPDEST PUSH2 0x5E2 PUSH2 0x9CC JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x15 DUP2 MSTORE PUSH32 0x524551554952455F574954485F434F4E5354414E540000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH2 0x3F6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x1145 JUMP JUMPDEST POP SWAP3 SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 DUP2 SWAP1 SSTORE SWAP1 JUMP JUMPDEST PUSH2 0x710 PUSH2 0x9EC JUMP JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x80 DUP2 ADD DUP3 MSTORE SWAP2 DUP3 MSTORE DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x4 DUP1 DUP3 MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP4 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP1 DUP6 ADD SWAP3 SWAP1 SWAP3 MSTORE DUP3 MLOAD DUP1 DUP5 ADD DUP5 MSTORE DUP2 DUP2 MSTORE PUSH32 0x8765432100000000000000000000000000000000000000000000000000000000 DUP2 DUP5 ADD MSTORE DUP5 DUP5 ADD MSTORE DUP3 MLOAD DUP1 DUP5 ADD SWAP1 SWAP4 MSTORE DUP3 MSTORE PUSH32 0x616D657400000000000000000000000000000000000000000000000000000000 SWAP1 DUP3 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE SWAP1 JUMP JUMPDEST PUSH2 0x3FF JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x1 SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x5 DUP2 MSTORE PUSH32 0x68656C6C6F000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x1 SWAP2 JUMP JUMPDEST PUSH1 0x60 SWAP1 JUMP JUMPDEST PUSH32 0x61A6029A4C7DDEE5824D171331EECBD015D26A271310A223718B837FACB5B771 PUSH1 0x40 MLOAD PUSH2 0x84B SWAP1 PUSH2 0x115F JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMP JUMPDEST PUSH2 0x85D PUSH2 0xA1A JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x2 DUP1 DUP3 MSTORE PUSH1 0x60 DUP3 DUP2 ADD SWAP1 SWAP4 MSTORE DUP2 PUSH1 0x20 ADD JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0x873 JUMPI SWAP1 POP POP SWAP1 POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x3078313233000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x8CD JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x3078333231000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 PUSH1 0x1 DUP2 MLOAD DUP2 LT PUSH2 0x91B JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 ADD DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 DUP1 MLOAD PUSH1 0xC0 DUP2 ADD DUP3 MSTORE PUSH1 0x5 PUSH1 0x80 DUP3 ADD DUP2 DUP2 MSTORE PUSH32 0x3078313233000000000000000000000000000000000000000000000000000000 PUSH1 0xA0 DUP5 ADD MSTORE DUP3 MSTORE DUP2 DUP5 ADD MSTORE DUP1 DUP3 ADD SWAP4 SWAP1 SWAP4 MSTORE DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x3 DUP2 MSTORE PUSH32 0x6162630000000000000000000000000000000000000000000000000000000000 SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP3 ADD MSTORE SWAP1 POP SWAP1 JUMP JUMPDEST PUSH2 0x4D2 SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9C7 PUSH2 0xA48 JUMP JUMPDEST SWAP1 MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9DF PUSH2 0xA1A JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x80 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9FF PUSH2 0xA5B JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x80 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH4 0xFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xA8C JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xAA2 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH1 0x20 PUSH2 0xAB1 DUP2 DUP3 DUP5 MUL ADD PUSH2 0x13BC JUMP JUMPDEST DUP3 DUP2 MSTORE SWAP3 POP DUP1 DUP4 ADD DUP5 DUP3 ADD PUSH1 0x0 JUMPDEST DUP5 DUP2 LT ISZERO PUSH2 0xAE8 JUMPI PUSH2 0xAD6 DUP9 DUP6 DUP5 CALLDATALOAD DUP11 ADD ADD PUSH2 0xAF3 JUMP JUMPDEST DUP4 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0xABF JUMP JUMPDEST POP POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xB03 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB19 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0xB4A PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP5 ADD AND ADD PUSH2 0x13BC JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xB61 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP5 ADD CALLDATACOPY PUSH1 0x0 SWAP1 DUP3 ADD PUSH1 0x20 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB8B JUMPI DUP1 DUP2 REVERT JUMPDEST PUSH2 0xB95 PUSH1 0x80 PUSH2 0x13BC JUMP JUMPDEST SWAP1 POP PUSH1 0x0 DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xBB0 JUMPI DUP3 DUP4 REVERT JUMPDEST PUSH2 0xBBC DUP7 DUP4 DUP8 ADD PUSH2 0xAF3 JUMP JUMPDEST DUP5 MSTORE PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH4 0xFFFFFFFF DUP3 AND DUP3 EQ PUSH2 0xBD6 JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD MSTORE PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xBEF JUMPI DUP3 DUP4 REVERT JUMPDEST PUSH2 0xBFB DUP7 DUP4 DUP8 ADD PUSH2 0xA7C JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE PUSH1 0x60 DUP6 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xC13 JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0xC20 DUP6 DUP3 DUP7 ADD PUSH2 0xAF3 JUMP JUMPDEST PUSH1 0x60 DUP5 ADD MSTORE POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xC45 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xC50 DUP2 PUSH2 0x1413 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD PUSH2 0xC6E DUP2 PUSH2 0x1413 JUMP JUMPDEST SWAP5 SWAP8 SWAP4 SWAP7 POP SWAP2 SWAP5 PUSH1 0x80 ADD CALLDATALOAD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xC91 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xCA8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xCB4 DUP5 DUP3 DUP6 ADD PUSH2 0xA7C JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xCD2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH1 0xFF DUP2 AND DUP2 EQ PUSH2 0xCEA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP7 SWAP4 SWAP6 POP POP POP POP PUSH1 0x40 DUP3 ADD CALLDATALOAD SWAP2 PUSH1 0x60 ADD CALLDATALOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xD28 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xCB4 DUP5 DUP3 DUP6 ADD PUSH2 0xAF3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD46 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD5E JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD75 JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x60 DUP2 DUP8 SUB SLT ISZERO PUSH2 0xD87 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0xD91 PUSH1 0x60 PUSH2 0x13BC JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP4 MSTORE PUSH1 0x20 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xDA8 JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xDB4 DUP8 DUP3 DUP5 ADD PUSH2 0xAF3 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MSTORE POP PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xDCB JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xDD7 DUP8 DUP3 DUP5 ADD PUSH2 0xAF3 JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDF8 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xE0F JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x40 DUP2 DUP8 SUB SLT ISZERO PUSH2 0xE21 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0xE2B PUSH1 0x40 PUSH2 0x13BC JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xE3B JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xE47 DUP8 DUP3 DUP5 ADD PUSH2 0xB7A JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xE5B JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xE67 DUP8 DUP3 DUP5 ADD PUSH2 0xAF3 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE89 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xEA0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xCB4 DUP5 DUP3 DUP6 ADD PUSH2 0xB7A JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xEC0 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP4 CALLDATALOAD SWAP3 POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xEDE JUMPI DUP3 DUP4 REVERT JUMPDEST PUSH2 0xEEA DUP8 DUP4 DUP9 ADD PUSH2 0xAF3 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xEFF JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0xF0C DUP7 DUP3 DUP8 ADD PUSH2 0xAF3 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0xF2E DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x13E3 JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD PUSH1 0x80 DUP5 MSTORE PUSH2 0xF75 PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x20 SWAP2 POP PUSH4 0xFFFFFFFF DUP3 DUP6 ADD MLOAD AND DUP3 DUP7 ADD MSTORE PUSH1 0x40 DUP5 ADD MLOAD DUP6 DUP3 SUB PUSH1 0x40 DUP8 ADD MSTORE DUP2 DUP2 MLOAD DUP1 DUP5 MSTORE DUP5 DUP5 ADD SWAP2 POP DUP5 DUP6 DUP3 MUL DUP6 ADD ADD DUP6 DUP5 ADD PUSH1 0x0 SWAP5 POP JUMPDEST DUP3 DUP6 LT ISZERO PUSH2 0xFFC JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP7 DUP4 SUB ADD DUP5 MSTORE PUSH2 0xFE8 DUP3 DUP3 MLOAD PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x1 SWAP6 SWAP1 SWAP6 ADD SWAP5 SWAP4 DUP8 ADD SWAP4 SWAP2 POP DUP7 ADD PUSH2 0xFAE JUMP JUMPDEST POP PUSH1 0x60 DUP9 ADD MLOAD SWAP6 POP DUP9 DUP2 SUB PUSH1 0x60 DUP11 ADD MSTORE PUSH2 0x1016 DUP2 DUP8 PUSH2 0xF16 JUMP JUMPDEST SWAP10 SWAP9 POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 MLOAD PUSH2 0x1035 DUP2 DUP5 PUSH1 0x20 DUP9 ADD PUSH2 0x13E3 JUMP JUMPDEST SWAP2 SWAP1 SWAP2 ADD SWAP2 DUP3 MSTORE POP PUSH1 0x20 ADD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 ADD DUP2 DUP5 MSTORE DUP1 DUP6 MLOAD DUP1 DUP4 MSTORE PUSH1 0x40 DUP7 ADD SWAP2 POP PUSH1 0x40 DUP5 DUP3 MUL DUP8 ADD ADD SWAP3 POP DUP4 DUP8 ADD PUSH1 0x0 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0x10D8 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 DUP9 DUP7 SUB ADD DUP5 MSTORE PUSH2 0x10C6 DUP6 DUP4 MLOAD PUSH2 0xF60 JUMP JUMPDEST SWAP5 POP SWAP3 DUP6 ADD SWAP3 SWAP1 DUP6 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x108C JUMP JUMPDEST POP SWAP3 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST SWAP4 DUP5 MSTORE PUSH1 0xFF SWAP3 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 MSTORE PUSH2 0x1116 PUSH1 0x60 DUP4 ADD DUP7 PUSH2 0xF16 JUMP JUMPDEST DUP3 DUP2 SUB PUSH1 0x20 DUP5 ADD MSTORE PUSH2 0x1128 DUP2 DUP7 PUSH2 0xF16 JUMP JUMPDEST DUP4 DUP2 SUB PUSH1 0x40 DUP6 ADD MSTORE PUSH2 0x113A DUP2 DUP7 PUSH2 0xF16 JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0x1158 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xF16 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 DUP3 MSTORE PUSH1 0x4 SWAP1 DUP3 ADD MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0x5 SWAP1 DUP3 ADD MSTORE PUSH32 0x6C6F72656D000000000000000000000000000000000000000000000000000000 PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0xD SWAP1 DUP3 ADD MSTORE PUSH32 0x53494D504C455F52455645525400000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0xE SWAP1 DUP3 ADD MSTORE PUSH32 0x53494D504C455F52455155495245000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE DUP3 MLOAD PUSH1 0x80 PUSH1 0x20 DUP5 ADD MSTORE DUP1 MLOAD PUSH1 0xA0 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0x60 PUSH1 0xC0 DUP6 ADD MSTORE PUSH2 0x1269 PUSH2 0x100 DUP6 ADD DUP3 PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MLOAD SWAP2 POP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 DUP6 DUP3 SUB ADD PUSH1 0xE0 DUP7 ADD MSTORE PUSH2 0x12A4 DUP2 DUP4 PUSH2 0xF16 JUMP JUMPDEST SWAP3 POP POP POP PUSH1 0x20 DUP5 ADD MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP1 DUP6 DUP5 SUB ADD PUSH1 0x40 DUP7 ADD MSTORE PUSH2 0x12E2 DUP4 DUP4 PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x40 DUP8 ADD MLOAD SWAP4 POP DUP2 DUP7 DUP3 SUB ADD PUSH1 0x60 DUP8 ADD MSTORE PUSH2 0x12FD DUP2 DUP6 PUSH2 0xF16 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP7 ADD MLOAD SWAP3 POP DUP1 DUP6 DUP4 SUB ADD PUSH1 0x80 DUP7 ADD MSTORE POP PUSH2 0x131C DUP2 DUP4 PUSH2 0xF16 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST SWAP1 MLOAD MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE DUP3 MLOAD PUSH1 0x40 PUSH1 0x20 DUP5 ADD MSTORE PUSH2 0x134C PUSH1 0x60 DUP5 ADD DUP3 PUSH2 0xF60 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MLOAD SWAP2 POP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP5 DUP3 SUB ADD PUSH1 0x40 DUP6 ADD MSTORE PUSH2 0x131C DUP2 DUP4 PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0x1158 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xF60 JUMP JUMPDEST SWAP1 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP4 DUP3 MSTORE PUSH1 0x40 PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0xCB4 PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x13DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x13FE JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x13E6 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x140D JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x401 JUMPI PUSH1 0x0 DUP1 REVERT INVALID LOG3 PUSH6 0x627A7A723158 KECCAK256 PUSH32 0x854B76FC684DE0BE1F1A5DB2D486BC187FF28D1E99D27CA0F61B452A1942F6C PUSH6 0x78706572696D PUSH6 0x6E74616CF564 PUSH20 0x6F6C634300050B00400000000000000000000000 ", + "object": "0x608060405234801561001057600080fd5b506114e6806100206000396000f3fe608060405234801561001057600080fd5b50600436106101d95760003560e01c806376f15d5b11610104578063bb607362116100a2578063d88be12f11610071578063d88be12f1461039b578063ee8b86fb146103a3578063f408fb3114610279578063fa315f9d146103b6576101d9565b8063bb60736214610353578063bdab168814610369578063cd3c0b971461037e578063d6d7618c14610386576101d9565b80638ee52b4e116100de5780638ee52b4e146103225780639a3b618514610335578063a3c2f6b61461033d578063ae2dae1714610345576101d9565b806376f15d5b146102f25780637833bec0146102fa5780637a791e6e1461031a576101d9565b80634303a5421161017c57806359c28add1161014b57806359c28add146102b45780635ba3c7c0146102c957806363d69c88146102d1578063647341eb146102e4576101d9565b80634303a542146102875780634582eab21461028f57806345fdbdb714610297578063586f84b21461029f576101d9565b80632e1a7d4d116101b85780632e1a7d4d146102245780633687617d1461023757806336b32396146102595780633e9ef66a14610279576101d9565b806209e437146101de5780630527c28f146101e85780631310e444146101fb575b600080fd5b6101e66103c4565b005b6101e66101f6366004610c7f565b610401565b61020e610209366004610d87565b610404565b60405161021b91906113e8565b60405180910390f35b6101e6610232366004610d87565b61040b565b61024a610245366004610efc565b61045c565b60405161021b93929190611151565b61026c610267366004610d0b565b6104fc565b60405161021b9190611094565b6101e66101f6366004610d4c565b61020e6105de565b6101e66105e5565b6101e661064a565b6102a761067c565b60405161021b9190611373565b6102bc610684565b60405161021b919061137e565b6101e661068c565b61026c6102df366004610c2e565b6106f1565b6101e66101f6366004610ec9565b61020e6106fa565b61030d610308366004610d9f565b610708565b60405161021b9190611287565b6101e66107c5565b61020e610330366004610d87565b6107ca565b6101e66107d0565b61020e6107db565b6101e66101f6366004610e39565b61035b6107e0565b60405161021b9291906113f1565b610371610819565b60405161021b91906110b5565b6101e661081e565b61038e610855565b60405161021b91906113d5565b61020e6109ae565b6101e66103b1366004610d87565b6101f6565b6101e66101f6366004610d87565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f690611250565b60405180910390fd5b565b50565b506107c790565b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b658260405161045191906113e8565b60405180910390a250565b505060408051808201825260048082527f1234567800000000000000000000000000000000000000000000000000000000602080840191909152835180850185528281527f87654321000000000000000000000000000000000000000000000000000000008183015284518086019095529184527f616d657400000000000000000000000000000000000000000000000000000000908401529093909250565b600060606040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525090506000818760405160200161054d929190611072565b604051602081830303815290604052805190602001209050600181878787604051600081526020016040526040516105889493929190611133565b6020604051602081039080840390855afa1580156105aa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015198975050505050505050565b6107c75b90565b604080518082018252601481527f5245564552545f574954485f434f4e5354414e54000000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611193565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f690611219565b6105e26109b4565b6105e26109cc565b604080518082018252601581527f524551554952455f574954485f434f4e5354414e540000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611193565b50929392505050565b600080546001019081905590565b6107106109ec565b50604080516080810182529182528051808201825260048082527f123456780000000000000000000000000000000000000000000000000000000060208381019190915280850192909252825180840184528181527f87654321000000000000000000000000000000000000000000000000000000008184015284840152825180840190935282527f616d65740000000000000000000000000000000000000000000000000000000090820152606082015290565b6103ff565b60010190565b600080546001019055565b600190565b60408051808201909152600581527f68656c6c6f0000000000000000000000000000000000000000000000000000006020820152600191565b606090565b7f61a6029a4c7ddee5824d171331eecbd015d26a271310a223718b837facb5b77160405161084b906111ad565b60405180910390a1565b61085d610a1a565b6040805160028082526060828101909352816020015b60608152602001906001900390816108735790505090506040518060400160405280600581526020017f3078313233000000000000000000000000000000000000000000000000000000815250816000815181106108cd57fe5b60200260200101819052506040518060400160405280600581526020017f30783332310000000000000000000000000000000000000000000000000000008152508160018151811061091b57fe5b6020908102919091018101919091526040805160c0810182526005608082018181527f307831323300000000000000000000000000000000000000000000000000000060a0840152825281840152808201939093528051808201909152600381527f6162630000000000000000000000000000000000000000000000000000000000918101919091526060820152905090565b6104d290565b60405180602001604052806109c7610a48565b905290565b60405180604001604052806109df610a1a565b8152602001606081525090565b60405180608001604052806109ff610a5b565b81526020016060815260200160608152602001606081525090565b604051806080016040528060608152602001600063ffffffff16815260200160608152602001606081525090565b6040518060200160405280600081525090565b60405180606001604052806000815260200160608152602001606081525090565b600082601f830112610a8c578081fd5b8135610a9f610a9a82611431565b61140a565b8181529150602080830190840160005b83811015610adc57610ac78760208435890101610ae6565b83526020928301929190910190600101610aaf565b5050505092915050565b600082601f830112610af6578081fd5b813567ffffffffffffffff811115610b0c578182fd5b610b3d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161140a565b9150808252836020828501011115610b5457600080fd5b8060208401602084013760009082016020015292915050565b600060808284031215610b7e578081fd5b610b88608061140a565b9050813567ffffffffffffffff80821115610ba257600080fd5b610bae85838601610ae6565b8352610bbd8560208601610c14565b60208401526040840135915080821115610bd657600080fd5b610be285838601610a7c565b60408401526060840135915080821115610bfb57600080fd5b50610c0884828501610ae6565b60608301525092915050565b803563ffffffff81168114610c2857600080fd5b92915050565b600080600080600060a08688031215610c45578081fd5b8535610c5081611481565b945060208601359350604086013592506060860135610c6e81611481565b949793965091946080013592915050565b60006020808385031215610c91578182fd5b823567ffffffffffffffff811115610ca7578283fd5b80840185601f820112610cb8578384fd5b80359150610cc8610a9a83611431565b82815283810190828501865b85811015610cfd57610ceb8a888435880101610ae6565b84529286019290860190600101610cd4565b509098975050505050505050565b60008060008060808587031215610d20578384fd5b84359350602085013560ff81168114610d37578384fd5b93969395505050506040820135916060013590565b600060208284031215610d5d578081fd5b813567ffffffffffffffff811115610d73578182fd5b610d7f84828501610ae6565b949350505050565b600060208284031215610d98578081fd5b5035919050565b600060208284031215610db0578081fd5b813567ffffffffffffffff80821115610dc7578283fd5b81840160608187031215610dd9578384fd5b610de3606061140a565b925080358352602081013582811115610dfa578485fd5b610e0687828401610ae6565b602085015250604081013582811115610e1d578485fd5b610e2987828401610ae6565b6040850152509195945050505050565b600060208284031215610e4a578081fd5b813567ffffffffffffffff80821115610e61578283fd5b81840160408187031215610e73578384fd5b610e7d604061140a565b9250803582811115610e8d578485fd5b610e9987828401610b6d565b845250602081013582811115610ead578485fd5b610eb987828401610ae6565b6020850152509195945050505050565b600060208284031215610eda578081fd5b813567ffffffffffffffff811115610ef0578182fd5b610d7f84828501610b6d565b600080600060608486031215610f10578081fd5b83359250602084013567ffffffffffffffff80821115610f2e578283fd5b610f3a87838801610ae6565b93506040860135915080821115610f4f578283fd5b50610f5c86828701610ae6565b9150509250925092565b60008151808452610f7e816020860160208601611451565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000815160808452610fc56080850182610f66565b6020915063ffffffff828501511682860152604084015185820360408701528181518084528484019150848582028501018584018794505b8285101561104b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868303018452611037828251610f66565b600195909501949387019391508601610ffd565b506060880151955088810360608a01526110658187610f66565b9998505050505050505050565b60008351611084818460208801611451565b9190910191825250602001919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611126577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452611114858351610fb0565b945092850192908501906001016110da565b5092979650505050505050565b93845260ff9290921660208401526040830152606082015260800190565b6000606082526111646060830186610f66565b82810360208401526111768186610f66565b83810360408501526111888186610f66565b979650505050505050565b6000602082526111a66020830184610f66565b9392505050565b60408082526004908201527f123456780000000000000000000000000000000000000000000000000000000060608201526080602082018190526005908201527f6c6f72656d00000000000000000000000000000000000000000000000000000060a082015260c00190565b6020808252600d908201527f53494d504c455f52455645525400000000000000000000000000000000000000604082015260600190565b6020808252600e908201527f53494d504c455f52455155495245000000000000000000000000000000000000604082015260600190565b600060208252825160806020840152805160a08401526020810151606060c08501526112b7610100850182610f66565b604083015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608582030160e08601526112f28183610f66565b9250505060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808584030160408601526113308383610f66565b604087015193508186820301606087015261134b8185610f66565b92505060608601519250808583030160808601525061136a8183610f66565b95945050505050565b905151815260200190565b60006020825282516040602084015261139a6060840182610fb0565b602085015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084820301604085015261136a8183610f66565b6000602082526111a66020830184610fb0565b90815260200190565b600083825260406020830152610d7f6040830184610f66565b60405181810167ffffffffffffffff8111828210171561142957600080fd5b604052919050565b600067ffffffffffffffff821115611447578081fd5b5060209081020190565b60005b8381101561146c578181015183820152602001611454565b8381111561147b576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461040157600080fdfea365627a7a723158204f5b227587475ada330d11bfb46020f41172555bd06234eaaad1a7d10a4c2a396c6578706572696d656e74616cf564736f6c634300050c0040", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14E6 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x1D9 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x76F15D5B GT PUSH2 0x104 JUMPI DUP1 PUSH4 0xBB607362 GT PUSH2 0xA2 JUMPI DUP1 PUSH4 0xD88BE12F GT PUSH2 0x71 JUMPI DUP1 PUSH4 0xD88BE12F EQ PUSH2 0x39B JUMPI DUP1 PUSH4 0xEE8B86FB EQ PUSH2 0x3A3 JUMPI DUP1 PUSH4 0xF408FB31 EQ PUSH2 0x279 JUMPI DUP1 PUSH4 0xFA315F9D EQ PUSH2 0x3B6 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0xBB607362 EQ PUSH2 0x353 JUMPI DUP1 PUSH4 0xBDAB1688 EQ PUSH2 0x369 JUMPI DUP1 PUSH4 0xCD3C0B97 EQ PUSH2 0x37E JUMPI DUP1 PUSH4 0xD6D7618C EQ PUSH2 0x386 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x8EE52B4E GT PUSH2 0xDE JUMPI DUP1 PUSH4 0x8EE52B4E EQ PUSH2 0x322 JUMPI DUP1 PUSH4 0x9A3B6185 EQ PUSH2 0x335 JUMPI DUP1 PUSH4 0xA3C2F6B6 EQ PUSH2 0x33D JUMPI DUP1 PUSH4 0xAE2DAE17 EQ PUSH2 0x345 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x76F15D5B EQ PUSH2 0x2F2 JUMPI DUP1 PUSH4 0x7833BEC0 EQ PUSH2 0x2FA JUMPI DUP1 PUSH4 0x7A791E6E EQ PUSH2 0x31A JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x4303A542 GT PUSH2 0x17C JUMPI DUP1 PUSH4 0x59C28ADD GT PUSH2 0x14B JUMPI DUP1 PUSH4 0x59C28ADD EQ PUSH2 0x2B4 JUMPI DUP1 PUSH4 0x5BA3C7C0 EQ PUSH2 0x2C9 JUMPI DUP1 PUSH4 0x63D69C88 EQ PUSH2 0x2D1 JUMPI DUP1 PUSH4 0x647341EB EQ PUSH2 0x2E4 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x4303A542 EQ PUSH2 0x287 JUMPI DUP1 PUSH4 0x4582EAB2 EQ PUSH2 0x28F JUMPI DUP1 PUSH4 0x45FDBDB7 EQ PUSH2 0x297 JUMPI DUP1 PUSH4 0x586F84B2 EQ PUSH2 0x29F JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x2E1A7D4D GT PUSH2 0x1B8 JUMPI DUP1 PUSH4 0x2E1A7D4D EQ PUSH2 0x224 JUMPI DUP1 PUSH4 0x3687617D EQ PUSH2 0x237 JUMPI DUP1 PUSH4 0x36B32396 EQ PUSH2 0x259 JUMPI DUP1 PUSH4 0x3E9EF66A EQ PUSH2 0x279 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH3 0x9E437 EQ PUSH2 0x1DE JUMPI DUP1 PUSH4 0x527C28F EQ PUSH2 0x1E8 JUMPI DUP1 PUSH4 0x1310E444 EQ PUSH2 0x1FB JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1E6 PUSH2 0x3C4 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xC7F JUMP JUMPDEST PUSH2 0x401 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x209 CALLDATASIZE PUSH1 0x4 PUSH2 0xD87 JUMP JUMPDEST PUSH2 0x404 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x13E8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x1E6 PUSH2 0x232 CALLDATASIZE PUSH1 0x4 PUSH2 0xD87 JUMP JUMPDEST PUSH2 0x40B JUMP JUMPDEST PUSH2 0x24A PUSH2 0x245 CALLDATASIZE PUSH1 0x4 PUSH2 0xEFC JUMP JUMPDEST PUSH2 0x45C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1151 JUMP JUMPDEST PUSH2 0x26C PUSH2 0x267 CALLDATASIZE PUSH1 0x4 PUSH2 0xD0B JUMP JUMPDEST PUSH2 0x4FC JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1094 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xD4C JUMP JUMPDEST PUSH2 0x20E PUSH2 0x5DE JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x5E5 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x64A JUMP JUMPDEST PUSH2 0x2A7 PUSH2 0x67C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1373 JUMP JUMPDEST PUSH2 0x2BC PUSH2 0x684 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x137E JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x68C JUMP JUMPDEST PUSH2 0x26C PUSH2 0x2DF CALLDATASIZE PUSH1 0x4 PUSH2 0xC2E JUMP JUMPDEST PUSH2 0x6F1 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xEC9 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x6FA JUMP JUMPDEST PUSH2 0x30D PUSH2 0x308 CALLDATASIZE PUSH1 0x4 PUSH2 0xD9F JUMP JUMPDEST PUSH2 0x708 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1287 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x7C5 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x330 CALLDATASIZE PUSH1 0x4 PUSH2 0xD87 JUMP JUMPDEST PUSH2 0x7CA JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x7D0 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x7DB JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xE39 JUMP JUMPDEST PUSH2 0x35B PUSH2 0x7E0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP3 SWAP2 SWAP1 PUSH2 0x13F1 JUMP JUMPDEST PUSH2 0x371 PUSH2 0x819 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x10B5 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x81E JUMP JUMPDEST PUSH2 0x38E PUSH2 0x855 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x13D5 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x9AE JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x3B1 CALLDATASIZE PUSH1 0x4 PUSH2 0xD87 JUMP JUMPDEST PUSH2 0x1F6 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xD87 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3F6 SWAP1 PUSH2 0x1250 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST JUMP JUMPDEST POP JUMP JUMPDEST POP PUSH2 0x7C7 SWAP1 JUMP JUMPDEST CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0x7FCF532C15F0A6DB0BD6D0E038BEA71D30D808C7D98CB3BF7268A95BF5081B65 DUP3 PUSH1 0x40 MLOAD PUSH2 0x451 SWAP2 SWAP1 PUSH2 0x13E8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 POP JUMP JUMPDEST POP POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x4 DUP1 DUP3 MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP4 MLOAD DUP1 DUP6 ADD DUP6 MSTORE DUP3 DUP2 MSTORE PUSH32 0x8765432100000000000000000000000000000000000000000000000000000000 DUP2 DUP4 ADD MSTORE DUP5 MLOAD DUP1 DUP7 ADD SWAP1 SWAP6 MSTORE SWAP2 DUP5 MSTORE PUSH32 0x616D657400000000000000000000000000000000000000000000000000000000 SWAP1 DUP5 ADD MSTORE SWAP1 SWAP4 SWAP1 SWAP3 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x1C DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE POP SWAP1 POP PUSH1 0x0 DUP2 DUP8 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x54D SWAP3 SWAP2 SWAP1 PUSH2 0x1072 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 SWAP1 POP PUSH1 0x1 DUP2 DUP8 DUP8 DUP8 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x588 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1133 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x5AA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0x7C7 JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x14 DUP2 MSTORE PUSH32 0x5245564552545F574954485F434F4E5354414E54000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH2 0x3F6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x1193 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3F6 SWAP1 PUSH2 0x1219 JUMP JUMPDEST PUSH2 0x5E2 PUSH2 0x9B4 JUMP JUMPDEST PUSH2 0x5E2 PUSH2 0x9CC JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x15 DUP2 MSTORE PUSH32 0x524551554952455F574954485F434F4E5354414E540000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH2 0x3F6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x1193 JUMP JUMPDEST POP SWAP3 SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 DUP2 SWAP1 SSTORE SWAP1 JUMP JUMPDEST PUSH2 0x710 PUSH2 0x9EC JUMP JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x80 DUP2 ADD DUP3 MSTORE SWAP2 DUP3 MSTORE DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x4 DUP1 DUP3 MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP4 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP1 DUP6 ADD SWAP3 SWAP1 SWAP3 MSTORE DUP3 MLOAD DUP1 DUP5 ADD DUP5 MSTORE DUP2 DUP2 MSTORE PUSH32 0x8765432100000000000000000000000000000000000000000000000000000000 DUP2 DUP5 ADD MSTORE DUP5 DUP5 ADD MSTORE DUP3 MLOAD DUP1 DUP5 ADD SWAP1 SWAP4 MSTORE DUP3 MSTORE PUSH32 0x616D657400000000000000000000000000000000000000000000000000000000 SWAP1 DUP3 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE SWAP1 JUMP JUMPDEST PUSH2 0x3FF JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x1 SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x5 DUP2 MSTORE PUSH32 0x68656C6C6F000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x1 SWAP2 JUMP JUMPDEST PUSH1 0x60 SWAP1 JUMP JUMPDEST PUSH32 0x61A6029A4C7DDEE5824D171331EECBD015D26A271310A223718B837FACB5B771 PUSH1 0x40 MLOAD PUSH2 0x84B SWAP1 PUSH2 0x11AD JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMP JUMPDEST PUSH2 0x85D PUSH2 0xA1A JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x2 DUP1 DUP3 MSTORE PUSH1 0x60 DUP3 DUP2 ADD SWAP1 SWAP4 MSTORE DUP2 PUSH1 0x20 ADD JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0x873 JUMPI SWAP1 POP POP SWAP1 POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x3078313233000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x8CD JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x3078333231000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 PUSH1 0x1 DUP2 MLOAD DUP2 LT PUSH2 0x91B JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 ADD DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 DUP1 MLOAD PUSH1 0xC0 DUP2 ADD DUP3 MSTORE PUSH1 0x5 PUSH1 0x80 DUP3 ADD DUP2 DUP2 MSTORE PUSH32 0x3078313233000000000000000000000000000000000000000000000000000000 PUSH1 0xA0 DUP5 ADD MSTORE DUP3 MSTORE DUP2 DUP5 ADD MSTORE DUP1 DUP3 ADD SWAP4 SWAP1 SWAP4 MSTORE DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x3 DUP2 MSTORE PUSH32 0x6162630000000000000000000000000000000000000000000000000000000000 SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP3 ADD MSTORE SWAP1 POP SWAP1 JUMP JUMPDEST PUSH2 0x4D2 SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9C7 PUSH2 0xA48 JUMP JUMPDEST SWAP1 MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9DF PUSH2 0xA1A JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x80 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9FF PUSH2 0xA5B JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x80 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH4 0xFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xA8C JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0xA9F PUSH2 0xA9A DUP3 PUSH2 0x1431 JUMP JUMPDEST PUSH2 0x140A JUMP JUMPDEST DUP2 DUP2 MSTORE SWAP2 POP PUSH1 0x20 DUP1 DUP4 ADD SWAP1 DUP5 ADD PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xADC JUMPI PUSH2 0xAC7 DUP8 PUSH1 0x20 DUP5 CALLDATALOAD DUP10 ADD ADD PUSH2 0xAE6 JUMP JUMPDEST DUP4 MSTORE PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0xAAF JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xAF6 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB0C JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0xB3D PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP5 ADD AND ADD PUSH2 0x140A JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xB54 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP5 ADD CALLDATACOPY PUSH1 0x0 SWAP1 DUP3 ADD PUSH1 0x20 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB7E JUMPI DUP1 DUP2 REVERT JUMPDEST PUSH2 0xB88 PUSH1 0x80 PUSH2 0x140A JUMP JUMPDEST SWAP1 POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xBA2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBAE DUP6 DUP4 DUP7 ADD PUSH2 0xAE6 JUMP JUMPDEST DUP4 MSTORE PUSH2 0xBBD DUP6 PUSH1 0x20 DUP7 ADD PUSH2 0xC14 JUMP JUMPDEST PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP5 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xBD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBE2 DUP6 DUP4 DUP7 ADD PUSH2 0xA7C JUMP JUMPDEST PUSH1 0x40 DUP5 ADD MSTORE PUSH1 0x60 DUP5 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xBFB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xC08 DUP5 DUP3 DUP6 ADD PUSH2 0xAE6 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP1 CALLDATALOAD PUSH4 0xFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0xC28 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xC45 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xC50 DUP2 PUSH2 0x1481 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD PUSH2 0xC6E DUP2 PUSH2 0x1481 JUMP JUMPDEST SWAP5 SWAP8 SWAP4 SWAP7 POP SWAP2 SWAP5 PUSH1 0x80 ADD CALLDATALOAD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xC91 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xCA7 JUMPI DUP3 DUP4 REVERT JUMPDEST DUP1 DUP5 ADD DUP6 PUSH1 0x1F DUP3 ADD SLT PUSH2 0xCB8 JUMPI DUP4 DUP5 REVERT JUMPDEST DUP1 CALLDATALOAD SWAP2 POP PUSH2 0xCC8 PUSH2 0xA9A DUP4 PUSH2 0x1431 JUMP JUMPDEST DUP3 DUP2 MSTORE DUP4 DUP2 ADD SWAP1 DUP3 DUP6 ADD DUP7 JUMPDEST DUP6 DUP2 LT ISZERO PUSH2 0xCFD JUMPI PUSH2 0xCEB DUP11 DUP9 DUP5 CALLDATALOAD DUP9 ADD ADD PUSH2 0xAE6 JUMP JUMPDEST DUP5 MSTORE SWAP3 DUP7 ADD SWAP3 SWAP1 DUP7 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0xCD4 JUMP JUMPDEST POP SWAP1 SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xD20 JUMPI DUP4 DUP5 REVERT JUMPDEST DUP5 CALLDATALOAD SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH1 0xFF DUP2 AND DUP2 EQ PUSH2 0xD37 JUMPI DUP4 DUP5 REVERT JUMPDEST SWAP4 SWAP7 SWAP4 SWAP6 POP POP POP POP PUSH1 0x40 DUP3 ADD CALLDATALOAD SWAP2 PUSH1 0x60 ADD CALLDATALOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD5D JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xD73 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0xD7F DUP5 DUP3 DUP6 ADD PUSH2 0xAE6 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD98 JUMPI DUP1 DUP2 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDB0 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xDC7 JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x60 DUP2 DUP8 SUB SLT ISZERO PUSH2 0xDD9 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0xDE3 PUSH1 0x60 PUSH2 0x140A JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP4 MSTORE PUSH1 0x20 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xDFA JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xE06 DUP8 DUP3 DUP5 ADD PUSH2 0xAE6 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MSTORE POP PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xE1D JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xE29 DUP8 DUP3 DUP5 ADD PUSH2 0xAE6 JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE4A JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xE61 JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x40 DUP2 DUP8 SUB SLT ISZERO PUSH2 0xE73 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0xE7D PUSH1 0x40 PUSH2 0x140A JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xE8D JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xE99 DUP8 DUP3 DUP5 ADD PUSH2 0xB6D JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xEAD JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xEB9 DUP8 DUP3 DUP5 ADD PUSH2 0xAE6 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xEDA JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xEF0 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0xD7F DUP5 DUP3 DUP6 ADD PUSH2 0xB6D JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xF10 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP4 CALLDATALOAD SWAP3 POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xF2E JUMPI DUP3 DUP4 REVERT JUMPDEST PUSH2 0xF3A DUP8 DUP4 DUP9 ADD PUSH2 0xAE6 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xF4F JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0xF5C DUP7 DUP3 DUP8 ADD PUSH2 0xAE6 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0xF7E DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1451 JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD PUSH1 0x80 DUP5 MSTORE PUSH2 0xFC5 PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x20 SWAP2 POP PUSH4 0xFFFFFFFF DUP3 DUP6 ADD MLOAD AND DUP3 DUP7 ADD MSTORE PUSH1 0x40 DUP5 ADD MLOAD DUP6 DUP3 SUB PUSH1 0x40 DUP8 ADD MSTORE DUP2 DUP2 MLOAD DUP1 DUP5 MSTORE DUP5 DUP5 ADD SWAP2 POP DUP5 DUP6 DUP3 MUL DUP6 ADD ADD DUP6 DUP5 ADD DUP8 SWAP5 POP JUMPDEST DUP3 DUP6 LT ISZERO PUSH2 0x104B JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP7 DUP4 SUB ADD DUP5 MSTORE PUSH2 0x1037 DUP3 DUP3 MLOAD PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x1 SWAP6 SWAP1 SWAP6 ADD SWAP5 SWAP4 DUP8 ADD SWAP4 SWAP2 POP DUP7 ADD PUSH2 0xFFD JUMP JUMPDEST POP PUSH1 0x60 DUP9 ADD MLOAD SWAP6 POP DUP9 DUP2 SUB PUSH1 0x60 DUP11 ADD MSTORE PUSH2 0x1065 DUP2 DUP8 PUSH2 0xF66 JUMP JUMPDEST SWAP10 SWAP9 POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 MLOAD PUSH2 0x1084 DUP2 DUP5 PUSH1 0x20 DUP9 ADD PUSH2 0x1451 JUMP JUMPDEST SWAP2 SWAP1 SWAP2 ADD SWAP2 DUP3 MSTORE POP PUSH1 0x20 ADD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 ADD DUP2 DUP5 MSTORE DUP1 DUP6 MLOAD DUP1 DUP4 MSTORE PUSH1 0x40 DUP7 ADD SWAP2 POP PUSH1 0x40 DUP5 DUP3 MUL DUP8 ADD ADD SWAP3 POP DUP4 DUP8 ADD DUP6 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0x1126 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 DUP9 DUP7 SUB ADD DUP5 MSTORE PUSH2 0x1114 DUP6 DUP4 MLOAD PUSH2 0xFB0 JUMP JUMPDEST SWAP5 POP SWAP3 DUP6 ADD SWAP3 SWAP1 DUP6 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x10DA JUMP JUMPDEST POP SWAP3 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST SWAP4 DUP5 MSTORE PUSH1 0xFF SWAP3 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 MSTORE PUSH2 0x1164 PUSH1 0x60 DUP4 ADD DUP7 PUSH2 0xF66 JUMP JUMPDEST DUP3 DUP2 SUB PUSH1 0x20 DUP5 ADD MSTORE PUSH2 0x1176 DUP2 DUP7 PUSH2 0xF66 JUMP JUMPDEST DUP4 DUP2 SUB PUSH1 0x40 DUP6 ADD MSTORE PUSH2 0x1188 DUP2 DUP7 PUSH2 0xF66 JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0x11A6 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xF66 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 DUP3 MSTORE PUSH1 0x4 SWAP1 DUP3 ADD MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0x5 SWAP1 DUP3 ADD MSTORE PUSH32 0x6C6F72656D000000000000000000000000000000000000000000000000000000 PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0xD SWAP1 DUP3 ADD MSTORE PUSH32 0x53494D504C455F52455645525400000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0xE SWAP1 DUP3 ADD MSTORE PUSH32 0x53494D504C455F52455155495245000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE DUP3 MLOAD PUSH1 0x80 PUSH1 0x20 DUP5 ADD MSTORE DUP1 MLOAD PUSH1 0xA0 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0x60 PUSH1 0xC0 DUP6 ADD MSTORE PUSH2 0x12B7 PUSH2 0x100 DUP6 ADD DUP3 PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MLOAD SWAP2 POP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 DUP6 DUP3 SUB ADD PUSH1 0xE0 DUP7 ADD MSTORE PUSH2 0x12F2 DUP2 DUP4 PUSH2 0xF66 JUMP JUMPDEST SWAP3 POP POP POP PUSH1 0x20 DUP5 ADD MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP1 DUP6 DUP5 SUB ADD PUSH1 0x40 DUP7 ADD MSTORE PUSH2 0x1330 DUP4 DUP4 PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x40 DUP8 ADD MLOAD SWAP4 POP DUP2 DUP7 DUP3 SUB ADD PUSH1 0x60 DUP8 ADD MSTORE PUSH2 0x134B DUP2 DUP6 PUSH2 0xF66 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP7 ADD MLOAD SWAP3 POP DUP1 DUP6 DUP4 SUB ADD PUSH1 0x80 DUP7 ADD MSTORE POP PUSH2 0x136A DUP2 DUP4 PUSH2 0xF66 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST SWAP1 MLOAD MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE DUP3 MLOAD PUSH1 0x40 PUSH1 0x20 DUP5 ADD MSTORE PUSH2 0x139A PUSH1 0x60 DUP5 ADD DUP3 PUSH2 0xFB0 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MLOAD SWAP2 POP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP5 DUP3 SUB ADD PUSH1 0x40 DUP6 ADD MSTORE PUSH2 0x136A DUP2 DUP4 PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0x11A6 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xFB0 JUMP JUMPDEST SWAP1 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP4 DUP3 MSTORE PUSH1 0x40 PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0xD7F PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x1429 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1447 JUMPI DUP1 DUP2 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x146C JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1454 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x147B JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x401 JUMPI PUSH1 0x0 DUP1 REVERT INVALID LOG3 PUSH6 0x627A7A723158 KECCAK256 0x4f JUMPDEST 0x22 PUSH22 0x87475ADA330D11BFB46020F41172555BD06234EAAAD1 0xa7 0xd1 EXP 0x4c 0x2a CODECOPY PUSH13 0x6578706572696D656E74616CF5 PUSH5 0x736F6C6343 STOP SDIV 0xc STOP BLOCKHASH ", "sourceMap": "641:6754:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;641:6754:0;;;;;;;" }, "deployedBytecode": { "linkReferences": {}, - "object": "0x608060405234801561001057600080fd5b50600436106101d95760003560e01c806376f15d5b11610104578063bb607362116100a2578063d88be12f11610071578063d88be12f1461039b578063ee8b86fb146103a3578063f408fb3114610279578063fa315f9d146103b6576101d9565b8063bb60736214610353578063bdab168814610369578063cd3c0b971461037e578063d6d7618c14610386576101d9565b80638ee52b4e116100de5780638ee52b4e146103225780639a3b618514610335578063a3c2f6b61461033d578063ae2dae1714610345576101d9565b806376f15d5b146102f25780637833bec0146102fa5780637a791e6e1461031a576101d9565b80634303a5421161017c57806359c28add1161014b57806359c28add146102b45780635ba3c7c0146102c957806363d69c88146102d1578063647341eb146102e4576101d9565b80634303a542146102875780634582eab21461028f57806345fdbdb714610297578063586f84b21461029f576101d9565b80632e1a7d4d116101b85780632e1a7d4d146102245780633687617d1461023757806336b32396146102595780633e9ef66a14610279576101d9565b806209e437146101de5780630527c28f146101e85780631310e444146101fb575b600080fd5b6101e66103c4565b005b6101e66101f6366004610c7f565b610401565b61020e610209366004610d34565b610404565b60405161021b919061139a565b60405180910390f35b6101e6610232366004610d34565b61040b565b61024a610245366004610eac565b61045c565b60405161021b93929190611103565b61026c610267366004610cbc565b6104fc565b60405161021b9190611045565b6101e66101f6366004610cff565b61020e6105de565b6101e66105e5565b6101e661064a565b6102a761067c565b60405161021b9190611325565b6102bc610684565b60405161021b9190611330565b6101e661068c565b61026c6102df366004610c2d565b6106f1565b6101e66101f6366004610e77565b61020e6106fa565b61030d610308366004610d4d565b610708565b60405161021b9190611239565b6101e66107c5565b61020e610330366004610d34565b6107ca565b6101e66107d0565b61020e6107db565b6101e66101f6366004610de7565b61035b6107e0565b60405161021b9291906113a3565b610371610819565b60405161021b9190611066565b6101e661081e565b61038e610855565b60405161021b9190611387565b61020e6109ae565b6101e66103b1366004610d34565b6101f6565b6101e66101f6366004610d34565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f690611202565b60405180910390fd5b565b50565b506107c790565b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6582604051610451919061139a565b60405180910390a250565b505060408051808201825260048082527f1234567800000000000000000000000000000000000000000000000000000000602080840191909152835180850185528281527f87654321000000000000000000000000000000000000000000000000000000008183015284518086019095529184527f616d657400000000000000000000000000000000000000000000000000000000908401529093909250565b600060606040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525090506000818760405160200161054d929190611023565b6040516020818303038152906040528051906020012090506001818787876040516000815260200160405260405161058894939291906110e5565b6020604051602081039080840390855afa1580156105aa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015198975050505050505050565b6107c75b90565b604080518082018252601481527f5245564552545f574954485f434f4e5354414e54000000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611145565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f6906111cb565b6105e26109b4565b6105e26109cc565b604080518082018252601581527f524551554952455f574954485f434f4e5354414e540000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611145565b50929392505050565b600080546001019081905590565b6107106109ec565b50604080516080810182529182528051808201825260048082527f123456780000000000000000000000000000000000000000000000000000000060208381019190915280850192909252825180840184528181527f87654321000000000000000000000000000000000000000000000000000000008184015284840152825180840190935282527f616d65740000000000000000000000000000000000000000000000000000000090820152606082015290565b6103ff565b60010190565b600080546001019055565b600190565b60408051808201909152600581527f68656c6c6f0000000000000000000000000000000000000000000000000000006020820152600191565b606090565b7f61a6029a4c7ddee5824d171331eecbd015d26a271310a223718b837facb5b77160405161084b9061115f565b60405180910390a1565b61085d610a1a565b6040805160028082526060828101909352816020015b60608152602001906001900390816108735790505090506040518060400160405280600581526020017f3078313233000000000000000000000000000000000000000000000000000000815250816000815181106108cd57fe5b60200260200101819052506040518060400160405280600581526020017f30783332310000000000000000000000000000000000000000000000000000008152508160018151811061091b57fe5b6020908102919091018101919091526040805160c0810182526005608082018181527f307831323300000000000000000000000000000000000000000000000000000060a0840152825281840152808201939093528051808201909152600381527f6162630000000000000000000000000000000000000000000000000000000000918101919091526060820152905090565b6104d290565b60405180602001604052806109c7610a48565b905290565b60405180604001604052806109df610a1a565b8152602001606081525090565b60405180608001604052806109ff610a5b565b81526020016060815260200160608152602001606081525090565b604051806080016040528060608152602001600063ffffffff16815260200160608152602001606081525090565b6040518060200160405280600081525090565b60405180606001604052806000815260200160608152602001606081525090565b600082601f830112610a8c578081fd5b813567ffffffffffffffff811115610aa2578182fd5b6020610ab181828402016113bc565b828152925080830184820160005b84811015610ae857610ad6888584358a0101610af3565b83529183019190830190600101610abf565b505050505092915050565b600082601f830112610b03578081fd5b813567ffffffffffffffff811115610b19578182fd5b610b4a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016113bc565b9150808252836020828501011115610b6157600080fd5b8060208401602084013760009082016020015292915050565b600060808284031215610b8b578081fd5b610b9560806113bc565b90506000823567ffffffffffffffff80821115610bb0578283fd5b610bbc86838701610af3565b84526020850135915063ffffffff82168214610bd6578283fd5b8160208501526040850135915080821115610bef578283fd5b610bfb86838701610a7c565b60408501526060850135915080821115610c13578283fd5b50610c2085828601610af3565b6060840152505092915050565b600080600080600060a08688031215610c4557600080fd5b8535610c5081611413565b945060208601359350604086013592506060860135610c6e81611413565b949793965091946080013592915050565b600060208284031215610c9157600080fd5b813567ffffffffffffffff811115610ca857600080fd5b610cb484828501610a7c565b949350505050565b60008060008060808587031215610cd257600080fd5b84359350602085013560ff81168114610cea57600080fd5b93969395505050506040820135916060013590565b600060208284031215610d1157600080fd5b813567ffffffffffffffff811115610d2857600080fd5b610cb484828501610af3565b600060208284031215610d4657600080fd5b5035919050565b600060208284031215610d5e578081fd5b813567ffffffffffffffff80821115610d75578283fd5b81840160608187031215610d87578384fd5b610d9160606113bc565b925080358352602081013582811115610da8578485fd5b610db487828401610af3565b602085015250604081013582811115610dcb578485fd5b610dd787828401610af3565b6040850152509195945050505050565b600060208284031215610df8578081fd5b813567ffffffffffffffff80821115610e0f578283fd5b81840160408187031215610e21578384fd5b610e2b60406113bc565b9250803582811115610e3b578485fd5b610e4787828401610b7a565b845250602081013582811115610e5b578485fd5b610e6787828401610af3565b6020850152509195945050505050565b600060208284031215610e8957600080fd5b813567ffffffffffffffff811115610ea057600080fd5b610cb484828501610b7a565b600080600060608486031215610ec0578081fd5b83359250602084013567ffffffffffffffff80821115610ede578283fd5b610eea87838801610af3565b93506040860135915080821115610eff578283fd5b50610f0c86828701610af3565b9150509250925092565b60008151808452610f2e8160208601602086016113e3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000815160808452610f756080850182610f16565b6020915063ffffffff82850151168286015260408401518582036040870152818151808452848401915084858202850101858401600094505b82851015610ffc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868303018452610fe8828251610f16565b600195909501949387019391508601610fae565b506060880151955088810360608a01526110168187610f16565b9998505050505050505050565b600083516110358184602088016113e3565b9190910191825250602001919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600060208083018184528085518083526040860191506040848202870101925083870160005b828110156110d8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526110c6858351610f60565b9450928501929085019060010161108c565b5092979650505050505050565b93845260ff9290921660208401526040830152606082015260800190565b6000606082526111166060830186610f16565b82810360208401526111288186610f16565b838103604085015261113a8186610f16565b979650505050505050565b6000602082526111586020830184610f16565b9392505050565b60408082526004908201527f123456780000000000000000000000000000000000000000000000000000000060608201526080602082018190526005908201527f6c6f72656d00000000000000000000000000000000000000000000000000000060a082015260c00190565b6020808252600d908201527f53494d504c455f52455645525400000000000000000000000000000000000000604082015260600190565b6020808252600e908201527f53494d504c455f52455155495245000000000000000000000000000000000000604082015260600190565b600060208252825160806020840152805160a08401526020810151606060c0850152611269610100850182610f16565b604083015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608582030160e08601526112a48183610f16565b9250505060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808584030160408601526112e28383610f16565b60408701519350818682030160608701526112fd8185610f16565b92505060608601519250808583030160808601525061131c8183610f16565b95945050505050565b905151815260200190565b60006020825282516040602084015261134c6060840182610f60565b602085015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084820301604085015261131c8183610f16565b6000602082526111586020830184610f60565b90815260200190565b600083825260406020830152610cb46040830184610f16565b60405181810167ffffffffffffffff811182821017156113db57600080fd5b604052919050565b60005b838110156113fe5781810151838201526020016113e6565b8381111561140d576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461040157600080fdfea365627a7a723158207f0854b76fc684de0be1f1a5db2d486bc187ff28d1e99d27ca0f61b452a1942f6c6578706572696d656e74616cf564736f6c634300050b0040", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x1D9 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x76F15D5B GT PUSH2 0x104 JUMPI DUP1 PUSH4 0xBB607362 GT PUSH2 0xA2 JUMPI DUP1 PUSH4 0xD88BE12F GT PUSH2 0x71 JUMPI DUP1 PUSH4 0xD88BE12F EQ PUSH2 0x39B JUMPI DUP1 PUSH4 0xEE8B86FB EQ PUSH2 0x3A3 JUMPI DUP1 PUSH4 0xF408FB31 EQ PUSH2 0x279 JUMPI DUP1 PUSH4 0xFA315F9D EQ PUSH2 0x3B6 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0xBB607362 EQ PUSH2 0x353 JUMPI DUP1 PUSH4 0xBDAB1688 EQ PUSH2 0x369 JUMPI DUP1 PUSH4 0xCD3C0B97 EQ PUSH2 0x37E JUMPI DUP1 PUSH4 0xD6D7618C EQ PUSH2 0x386 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x8EE52B4E GT PUSH2 0xDE JUMPI DUP1 PUSH4 0x8EE52B4E EQ PUSH2 0x322 JUMPI DUP1 PUSH4 0x9A3B6185 EQ PUSH2 0x335 JUMPI DUP1 PUSH4 0xA3C2F6B6 EQ PUSH2 0x33D JUMPI DUP1 PUSH4 0xAE2DAE17 EQ PUSH2 0x345 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x76F15D5B EQ PUSH2 0x2F2 JUMPI DUP1 PUSH4 0x7833BEC0 EQ PUSH2 0x2FA JUMPI DUP1 PUSH4 0x7A791E6E EQ PUSH2 0x31A JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x4303A542 GT PUSH2 0x17C JUMPI DUP1 PUSH4 0x59C28ADD GT PUSH2 0x14B JUMPI DUP1 PUSH4 0x59C28ADD EQ PUSH2 0x2B4 JUMPI DUP1 PUSH4 0x5BA3C7C0 EQ PUSH2 0x2C9 JUMPI DUP1 PUSH4 0x63D69C88 EQ PUSH2 0x2D1 JUMPI DUP1 PUSH4 0x647341EB EQ PUSH2 0x2E4 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x4303A542 EQ PUSH2 0x287 JUMPI DUP1 PUSH4 0x4582EAB2 EQ PUSH2 0x28F JUMPI DUP1 PUSH4 0x45FDBDB7 EQ PUSH2 0x297 JUMPI DUP1 PUSH4 0x586F84B2 EQ PUSH2 0x29F JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x2E1A7D4D GT PUSH2 0x1B8 JUMPI DUP1 PUSH4 0x2E1A7D4D EQ PUSH2 0x224 JUMPI DUP1 PUSH4 0x3687617D EQ PUSH2 0x237 JUMPI DUP1 PUSH4 0x36B32396 EQ PUSH2 0x259 JUMPI DUP1 PUSH4 0x3E9EF66A EQ PUSH2 0x279 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH3 0x9E437 EQ PUSH2 0x1DE JUMPI DUP1 PUSH4 0x527C28F EQ PUSH2 0x1E8 JUMPI DUP1 PUSH4 0x1310E444 EQ PUSH2 0x1FB JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1E6 PUSH2 0x3C4 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xC7F JUMP JUMPDEST PUSH2 0x401 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x209 CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH2 0x404 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x139A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x1E6 PUSH2 0x232 CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH2 0x40B JUMP JUMPDEST PUSH2 0x24A PUSH2 0x245 CALLDATASIZE PUSH1 0x4 PUSH2 0xEAC JUMP JUMPDEST PUSH2 0x45C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1103 JUMP JUMPDEST PUSH2 0x26C PUSH2 0x267 CALLDATASIZE PUSH1 0x4 PUSH2 0xCBC JUMP JUMPDEST PUSH2 0x4FC JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1045 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xCFF JUMP JUMPDEST PUSH2 0x20E PUSH2 0x5DE JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x5E5 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x64A JUMP JUMPDEST PUSH2 0x2A7 PUSH2 0x67C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1325 JUMP JUMPDEST PUSH2 0x2BC PUSH2 0x684 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1330 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x68C JUMP JUMPDEST PUSH2 0x26C PUSH2 0x2DF CALLDATASIZE PUSH1 0x4 PUSH2 0xC2D JUMP JUMPDEST PUSH2 0x6F1 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xE77 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x6FA JUMP JUMPDEST PUSH2 0x30D PUSH2 0x308 CALLDATASIZE PUSH1 0x4 PUSH2 0xD4D JUMP JUMPDEST PUSH2 0x708 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1239 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x7C5 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x330 CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH2 0x7CA JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x7D0 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x7DB JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xDE7 JUMP JUMPDEST PUSH2 0x35B PUSH2 0x7E0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP3 SWAP2 SWAP1 PUSH2 0x13A3 JUMP JUMPDEST PUSH2 0x371 PUSH2 0x819 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1066 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x81E JUMP JUMPDEST PUSH2 0x38E PUSH2 0x855 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1387 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x9AE JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x3B1 CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH2 0x1F6 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3F6 SWAP1 PUSH2 0x1202 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST JUMP JUMPDEST POP JUMP JUMPDEST POP PUSH2 0x7C7 SWAP1 JUMP JUMPDEST CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0x7FCF532C15F0A6DB0BD6D0E038BEA71D30D808C7D98CB3BF7268A95BF5081B65 DUP3 PUSH1 0x40 MLOAD PUSH2 0x451 SWAP2 SWAP1 PUSH2 0x139A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 POP JUMP JUMPDEST POP POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x4 DUP1 DUP3 MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP4 MLOAD DUP1 DUP6 ADD DUP6 MSTORE DUP3 DUP2 MSTORE PUSH32 0x8765432100000000000000000000000000000000000000000000000000000000 DUP2 DUP4 ADD MSTORE DUP5 MLOAD DUP1 DUP7 ADD SWAP1 SWAP6 MSTORE SWAP2 DUP5 MSTORE PUSH32 0x616D657400000000000000000000000000000000000000000000000000000000 SWAP1 DUP5 ADD MSTORE SWAP1 SWAP4 SWAP1 SWAP3 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x1C DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE POP SWAP1 POP PUSH1 0x0 DUP2 DUP8 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x54D SWAP3 SWAP2 SWAP1 PUSH2 0x1023 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 SWAP1 POP PUSH1 0x1 DUP2 DUP8 DUP8 DUP8 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x588 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x10E5 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x5AA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0x7C7 JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x14 DUP2 MSTORE PUSH32 0x5245564552545F574954485F434F4E5354414E54000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH2 0x3F6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x1145 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3F6 SWAP1 PUSH2 0x11CB JUMP JUMPDEST PUSH2 0x5E2 PUSH2 0x9B4 JUMP JUMPDEST PUSH2 0x5E2 PUSH2 0x9CC JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x15 DUP2 MSTORE PUSH32 0x524551554952455F574954485F434F4E5354414E540000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH2 0x3F6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x1145 JUMP JUMPDEST POP SWAP3 SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 DUP2 SWAP1 SSTORE SWAP1 JUMP JUMPDEST PUSH2 0x710 PUSH2 0x9EC JUMP JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x80 DUP2 ADD DUP3 MSTORE SWAP2 DUP3 MSTORE DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x4 DUP1 DUP3 MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP4 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP1 DUP6 ADD SWAP3 SWAP1 SWAP3 MSTORE DUP3 MLOAD DUP1 DUP5 ADD DUP5 MSTORE DUP2 DUP2 MSTORE PUSH32 0x8765432100000000000000000000000000000000000000000000000000000000 DUP2 DUP5 ADD MSTORE DUP5 DUP5 ADD MSTORE DUP3 MLOAD DUP1 DUP5 ADD SWAP1 SWAP4 MSTORE DUP3 MSTORE PUSH32 0x616D657400000000000000000000000000000000000000000000000000000000 SWAP1 DUP3 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE SWAP1 JUMP JUMPDEST PUSH2 0x3FF JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x1 SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x5 DUP2 MSTORE PUSH32 0x68656C6C6F000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x1 SWAP2 JUMP JUMPDEST PUSH1 0x60 SWAP1 JUMP JUMPDEST PUSH32 0x61A6029A4C7DDEE5824D171331EECBD015D26A271310A223718B837FACB5B771 PUSH1 0x40 MLOAD PUSH2 0x84B SWAP1 PUSH2 0x115F JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMP JUMPDEST PUSH2 0x85D PUSH2 0xA1A JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x2 DUP1 DUP3 MSTORE PUSH1 0x60 DUP3 DUP2 ADD SWAP1 SWAP4 MSTORE DUP2 PUSH1 0x20 ADD JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0x873 JUMPI SWAP1 POP POP SWAP1 POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x3078313233000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x8CD JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x3078333231000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 PUSH1 0x1 DUP2 MLOAD DUP2 LT PUSH2 0x91B JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 ADD DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 DUP1 MLOAD PUSH1 0xC0 DUP2 ADD DUP3 MSTORE PUSH1 0x5 PUSH1 0x80 DUP3 ADD DUP2 DUP2 MSTORE PUSH32 0x3078313233000000000000000000000000000000000000000000000000000000 PUSH1 0xA0 DUP5 ADD MSTORE DUP3 MSTORE DUP2 DUP5 ADD MSTORE DUP1 DUP3 ADD SWAP4 SWAP1 SWAP4 MSTORE DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x3 DUP2 MSTORE PUSH32 0x6162630000000000000000000000000000000000000000000000000000000000 SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP3 ADD MSTORE SWAP1 POP SWAP1 JUMP JUMPDEST PUSH2 0x4D2 SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9C7 PUSH2 0xA48 JUMP JUMPDEST SWAP1 MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9DF PUSH2 0xA1A JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x80 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9FF PUSH2 0xA5B JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x80 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH4 0xFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xA8C JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xAA2 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH1 0x20 PUSH2 0xAB1 DUP2 DUP3 DUP5 MUL ADD PUSH2 0x13BC JUMP JUMPDEST DUP3 DUP2 MSTORE SWAP3 POP DUP1 DUP4 ADD DUP5 DUP3 ADD PUSH1 0x0 JUMPDEST DUP5 DUP2 LT ISZERO PUSH2 0xAE8 JUMPI PUSH2 0xAD6 DUP9 DUP6 DUP5 CALLDATALOAD DUP11 ADD ADD PUSH2 0xAF3 JUMP JUMPDEST DUP4 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0xABF JUMP JUMPDEST POP POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xB03 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB19 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0xB4A PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP5 ADD AND ADD PUSH2 0x13BC JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xB61 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP5 ADD CALLDATACOPY PUSH1 0x0 SWAP1 DUP3 ADD PUSH1 0x20 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB8B JUMPI DUP1 DUP2 REVERT JUMPDEST PUSH2 0xB95 PUSH1 0x80 PUSH2 0x13BC JUMP JUMPDEST SWAP1 POP PUSH1 0x0 DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xBB0 JUMPI DUP3 DUP4 REVERT JUMPDEST PUSH2 0xBBC DUP7 DUP4 DUP8 ADD PUSH2 0xAF3 JUMP JUMPDEST DUP5 MSTORE PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH4 0xFFFFFFFF DUP3 AND DUP3 EQ PUSH2 0xBD6 JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD MSTORE PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xBEF JUMPI DUP3 DUP4 REVERT JUMPDEST PUSH2 0xBFB DUP7 DUP4 DUP8 ADD PUSH2 0xA7C JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE PUSH1 0x60 DUP6 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xC13 JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0xC20 DUP6 DUP3 DUP7 ADD PUSH2 0xAF3 JUMP JUMPDEST PUSH1 0x60 DUP5 ADD MSTORE POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xC45 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xC50 DUP2 PUSH2 0x1413 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD PUSH2 0xC6E DUP2 PUSH2 0x1413 JUMP JUMPDEST SWAP5 SWAP8 SWAP4 SWAP7 POP SWAP2 SWAP5 PUSH1 0x80 ADD CALLDATALOAD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xC91 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xCA8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xCB4 DUP5 DUP3 DUP6 ADD PUSH2 0xA7C JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xCD2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH1 0xFF DUP2 AND DUP2 EQ PUSH2 0xCEA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP7 SWAP4 SWAP6 POP POP POP POP PUSH1 0x40 DUP3 ADD CALLDATALOAD SWAP2 PUSH1 0x60 ADD CALLDATALOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xD28 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xCB4 DUP5 DUP3 DUP6 ADD PUSH2 0xAF3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD46 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD5E JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD75 JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x60 DUP2 DUP8 SUB SLT ISZERO PUSH2 0xD87 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0xD91 PUSH1 0x60 PUSH2 0x13BC JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP4 MSTORE PUSH1 0x20 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xDA8 JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xDB4 DUP8 DUP3 DUP5 ADD PUSH2 0xAF3 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MSTORE POP PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xDCB JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xDD7 DUP8 DUP3 DUP5 ADD PUSH2 0xAF3 JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDF8 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xE0F JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x40 DUP2 DUP8 SUB SLT ISZERO PUSH2 0xE21 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0xE2B PUSH1 0x40 PUSH2 0x13BC JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xE3B JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xE47 DUP8 DUP3 DUP5 ADD PUSH2 0xB7A JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xE5B JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xE67 DUP8 DUP3 DUP5 ADD PUSH2 0xAF3 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE89 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xEA0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xCB4 DUP5 DUP3 DUP6 ADD PUSH2 0xB7A JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xEC0 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP4 CALLDATALOAD SWAP3 POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xEDE JUMPI DUP3 DUP4 REVERT JUMPDEST PUSH2 0xEEA DUP8 DUP4 DUP9 ADD PUSH2 0xAF3 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xEFF JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0xF0C DUP7 DUP3 DUP8 ADD PUSH2 0xAF3 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0xF2E DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x13E3 JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD PUSH1 0x80 DUP5 MSTORE PUSH2 0xF75 PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x20 SWAP2 POP PUSH4 0xFFFFFFFF DUP3 DUP6 ADD MLOAD AND DUP3 DUP7 ADD MSTORE PUSH1 0x40 DUP5 ADD MLOAD DUP6 DUP3 SUB PUSH1 0x40 DUP8 ADD MSTORE DUP2 DUP2 MLOAD DUP1 DUP5 MSTORE DUP5 DUP5 ADD SWAP2 POP DUP5 DUP6 DUP3 MUL DUP6 ADD ADD DUP6 DUP5 ADD PUSH1 0x0 SWAP5 POP JUMPDEST DUP3 DUP6 LT ISZERO PUSH2 0xFFC JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP7 DUP4 SUB ADD DUP5 MSTORE PUSH2 0xFE8 DUP3 DUP3 MLOAD PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x1 SWAP6 SWAP1 SWAP6 ADD SWAP5 SWAP4 DUP8 ADD SWAP4 SWAP2 POP DUP7 ADD PUSH2 0xFAE JUMP JUMPDEST POP PUSH1 0x60 DUP9 ADD MLOAD SWAP6 POP DUP9 DUP2 SUB PUSH1 0x60 DUP11 ADD MSTORE PUSH2 0x1016 DUP2 DUP8 PUSH2 0xF16 JUMP JUMPDEST SWAP10 SWAP9 POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 MLOAD PUSH2 0x1035 DUP2 DUP5 PUSH1 0x20 DUP9 ADD PUSH2 0x13E3 JUMP JUMPDEST SWAP2 SWAP1 SWAP2 ADD SWAP2 DUP3 MSTORE POP PUSH1 0x20 ADD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 ADD DUP2 DUP5 MSTORE DUP1 DUP6 MLOAD DUP1 DUP4 MSTORE PUSH1 0x40 DUP7 ADD SWAP2 POP PUSH1 0x40 DUP5 DUP3 MUL DUP8 ADD ADD SWAP3 POP DUP4 DUP8 ADD PUSH1 0x0 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0x10D8 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 DUP9 DUP7 SUB ADD DUP5 MSTORE PUSH2 0x10C6 DUP6 DUP4 MLOAD PUSH2 0xF60 JUMP JUMPDEST SWAP5 POP SWAP3 DUP6 ADD SWAP3 SWAP1 DUP6 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x108C JUMP JUMPDEST POP SWAP3 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST SWAP4 DUP5 MSTORE PUSH1 0xFF SWAP3 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 MSTORE PUSH2 0x1116 PUSH1 0x60 DUP4 ADD DUP7 PUSH2 0xF16 JUMP JUMPDEST DUP3 DUP2 SUB PUSH1 0x20 DUP5 ADD MSTORE PUSH2 0x1128 DUP2 DUP7 PUSH2 0xF16 JUMP JUMPDEST DUP4 DUP2 SUB PUSH1 0x40 DUP6 ADD MSTORE PUSH2 0x113A DUP2 DUP7 PUSH2 0xF16 JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0x1158 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xF16 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 DUP3 MSTORE PUSH1 0x4 SWAP1 DUP3 ADD MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0x5 SWAP1 DUP3 ADD MSTORE PUSH32 0x6C6F72656D000000000000000000000000000000000000000000000000000000 PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0xD SWAP1 DUP3 ADD MSTORE PUSH32 0x53494D504C455F52455645525400000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0xE SWAP1 DUP3 ADD MSTORE PUSH32 0x53494D504C455F52455155495245000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE DUP3 MLOAD PUSH1 0x80 PUSH1 0x20 DUP5 ADD MSTORE DUP1 MLOAD PUSH1 0xA0 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0x60 PUSH1 0xC0 DUP6 ADD MSTORE PUSH2 0x1269 PUSH2 0x100 DUP6 ADD DUP3 PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MLOAD SWAP2 POP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 DUP6 DUP3 SUB ADD PUSH1 0xE0 DUP7 ADD MSTORE PUSH2 0x12A4 DUP2 DUP4 PUSH2 0xF16 JUMP JUMPDEST SWAP3 POP POP POP PUSH1 0x20 DUP5 ADD MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP1 DUP6 DUP5 SUB ADD PUSH1 0x40 DUP7 ADD MSTORE PUSH2 0x12E2 DUP4 DUP4 PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x40 DUP8 ADD MLOAD SWAP4 POP DUP2 DUP7 DUP3 SUB ADD PUSH1 0x60 DUP8 ADD MSTORE PUSH2 0x12FD DUP2 DUP6 PUSH2 0xF16 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP7 ADD MLOAD SWAP3 POP DUP1 DUP6 DUP4 SUB ADD PUSH1 0x80 DUP7 ADD MSTORE POP PUSH2 0x131C DUP2 DUP4 PUSH2 0xF16 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST SWAP1 MLOAD MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE DUP3 MLOAD PUSH1 0x40 PUSH1 0x20 DUP5 ADD MSTORE PUSH2 0x134C PUSH1 0x60 DUP5 ADD DUP3 PUSH2 0xF60 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MLOAD SWAP2 POP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP5 DUP3 SUB ADD PUSH1 0x40 DUP6 ADD MSTORE PUSH2 0x131C DUP2 DUP4 PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0x1158 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xF60 JUMP JUMPDEST SWAP1 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP4 DUP3 MSTORE PUSH1 0x40 PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0xCB4 PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0xF16 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x13DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x13FE JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x13E6 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x140D JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x401 JUMPI PUSH1 0x0 DUP1 REVERT INVALID LOG3 PUSH6 0x627A7A723158 KECCAK256 PUSH32 0x854B76FC684DE0BE1F1A5DB2D486BC187FF28D1E99D27CA0F61B452A1942F6C PUSH6 0x78706572696D PUSH6 0x6E74616CF564 PUSH20 0x6F6C634300050B00400000000000000000000000 ", - "sourceMap": "641:6754:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;641:6754:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1496:107;;;:::i;:::-;;3110:63;;;;;;;;;:::i;6359:128::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;4968:84;;;;;;;;;:::i;6982:345::-;;;;;;;;;:::i;:::-;;;;;;;;;;2288:334;;;;;;;;;:::i;:::-;;;;;;;;2948:52;;;;;;;5964:117;;;:::i;1389:101::-;;;:::i;1286:97::-;;;:::i;4321:153::-;;;:::i;:::-;;;;;;;;4053:73;;;:::i;:::-;;;;;;;;1609:111;;;:::i;2776:166::-;;;;;;;;;:::i;3319:52::-;;;;;;;4500:72;;;:::i;6560:317::-;;;;;;;;;:::i;:::-;;;;;;;;5773:112;;;:::i;989:140::-;;;;;;;;;:::i;4577:69::-;;;:::i;862:121::-;;;:::i;3984:64::-;;;;;;;4652:134;;;:::i;:::-;;;;;;;;;3809:80;;;:::i;:::-;;;;;;;;5118:125;;;:::i;3453:350::-;;;:::i;:::-;;;;;;;;1135:145;;;:::i;6160:123::-;;;;;;;;;:::i;4792:47::-;;;;;;;1496:107;1564:32;;;;;;;;;;;;;;;;;;;;1496:107::o;3110:63::-;;:::o;6359:128::-;-1:-1:-1;6476:4:0;;6359:128::o;4968:84::-;5029:10;5018:27;;;5041:3;5018:27;;;;;;;;;;;;;;;4968:84;:::o;6982:345::-;-1:-1:-1;;7229:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6982:345:0:o;2288:334::-;2399:21;2436:19;:56;;;;;;;;;;;;;;;;;;;2502:20;2552:6;2560:4;2535:30;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;2535:30:0;;;2525:41;;;;;;2502:64;;2583:32;2593:12;2607:1;2610;2613;2583:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;2583:32:0;;;;;;2288:334;-1:-1:-1;;;;;;;;2288:334:0:o;5964:117::-;6070:4;5964:117;;:::o;1389:101::-;1469:13;;;;;;;;;;;;;;;;1462:21;;;;;;;1469:13;1462:21;;;;1286:97;1353:23;;;;;;;;;;;4321:153;4415:51;;:::i;4053:73::-;4103:19;;:::i;1609:111::-;1698:14;;;;;;;;;;;;;;;;1683:30;;;;;;;1698:14;1683:30;;;;2776:166;-1:-1:-1;2934:1:0;;2776:166;-1:-1:-1;;;2776:166:0:o;4500:72::-;4540:4;4555:14;;4568:1;4555:14;;;;;4500:72;:::o;6560:317::-;6674:20;;:::i;:::-;-1:-1:-1;6717:153:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6560:317::o;5773:112::-;5857:21;;989:140;1117:1;:5;;989:140::o;4577:69::-;4629:9;:14;;4642:1;4629:14;;;4577:69::o;862:121::-;975:1;862:121;:::o;4652:134::-;4760:19;;;;;;;;;;;;;;;;;4768:1;4652:134;:::o;3809:80::-;3870:15;3809:80;:::o;5118:125::-;5167:69;;;;;;;;;;;;;;;5118:125::o;3453:350::-;3497:15;;:::i;:::-;3551:14;;;3563:1;3551:14;;;3524:24;3551:14;;;;;;;;;;;;;;;;;;;;;;;;;;3524:41;;3575:22;;;;;;;;;;;;;;;;;:9;3585:1;3575:12;;;;;;;;;;;;;:22;;;;3607;;;;;;;;;;;;;;;;;:9;3617:1;3607:12;;;;;;;;;;;;;;;;;;:22;;;;3647:149;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3647:149:0;;;;-1:-1:-1;3453:350:0;:::o;1135:145::-;711:4;1135:145;:::o;641:6754::-;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;158:685:-1:-;;276:3;269:4;261:6;257:17;253:27;243:2;;-1:-1;;284:12;243:2;331:6;318:20;32471:18;32463:6;32460:30;32457:2;;;-1:-1;;32493:12;32457:2;32538:4;353:81;32601:4;32538;32530:6;32526:17;32591:15;353:81;;;462:21;;;344:90;-1:-1;519:14;;;494:17;;;614:1;599:238;624:6;621:1;618:13;599:238;;;731:42;769:3;506:4;707:3;694:17;498:6;682:30;;731:42;;;719:55;;788:14;;;;816;;;;646:1;639:9;599:238;;;603:14;;;;;236:607;;;;;1706:432;;1803:3;1796:4;1788:6;1784:17;1780:27;1770:2;;-1:-1;;1811:12;1770:2;1858:6;1845:20;33078:18;33070:6;33067:30;33064:2;;;-1:-1;;33100:12;33064:2;1880:60;33241:4;33173:9;1796:4;33158:6;33154:17;33150:33;33231:15;1880:60;;;1871:69;;1960:6;1953:5;1946:21;2064:3;33241:4;2055:6;1988;2046:16;;2043:25;2040:2;;;2081:1;;2071:12;2040:2;37579:6;33241:4;1988:6;1984:17;33241:4;2022:5;2018:16;37556:30;37635:1;37617:16;;;33241:4;37617:16;37610:27;2022:5;1763:375;-1:-1;;1763:375;5221:1071;;5329:4;5317:9;5312:3;5308:19;5304:30;5301:2;;;-1:-1;;5337:12;5301:2;5365:20;5329:4;5365:20;;;5356:29;;5468:1;5453:17;5440:31;5491:18;;5483:6;5480:30;5477:2;;;5523:1;5520;5513:12;5477:2;5557:54;5607:3;5598:6;5587:9;5583:22;5557:54;;;5540:15;5533:79;5678:2;5735:9;5731:22;7616:20;7607:29;;37386:10;38693:5;37375:22;38669:5;38666:34;38656:2;;38714:1;38711;38704:12;38656:2;5711:48;5678:2;5697:5;5693:16;5686:74;5865:2;5854:9;5850:18;5837:32;5823:46;;5889:18;5881:6;5878:30;5875:2;;;5921:1;5918;5911:12;5875:2;5956:75;6027:3;6018:6;6007:9;6003:22;5956:75;;;5865:2;5942:5;5938:16;5931:101;6124:2;6113:9;6109:18;6096:32;6082:46;;6148:18;6140:6;6137:30;6134:2;;;6180:1;6177;6170:12;6134:2;;6215:55;6266:3;6257:6;6246:9;6242:22;6215:55;;;6124:2;6201:5;6197:16;6190:81;;;5295:997;;;;;7818:743;;;;;;7990:3;7978:9;7969:7;7965:23;7961:33;7958:2;;;-1:-1;;7997:12;7958:2;85:6;72:20;97:33;124:5;97:33;;;8049:63;-1:-1;8149:2;8188:22;;7480:20;;-1:-1;8257:2;8296:22;;7480:20;;-1:-1;8365:2;8404:22;;72:20;97:33;72:20;97:33;;;7952:609;;;;-1:-1;7952:609;;8473:3;8513:22;7480:20;;7952:609;-1:-1;;7952:609;8568:387;;8702:2;8690:9;8681:7;8677:23;8673:32;8670:2;;;-1:-1;;8708:12;8670:2;8766:17;8753:31;8804:18;8796:6;8793:30;8790:2;;;-1:-1;;8826:12;8790:2;8856:83;8931:7;8922:6;8911:9;8907:22;8856:83;;;8846:93;8664:291;-1:-1;;;;8664:291;8962:613;;;;;9115:3;9103:9;9094:7;9090:23;9086:33;9083:2;;;-1:-1;;9122:12;9083:2;1648:6;1635:20;9174:63;;9274:2;9315:9;9311:22;7750:20;37480:4;38813:5;37469:16;38790:5;38787:33;38777:2;;-1:-1;;38824:12;38777:2;9077:498;;9282:61;;-1:-1;;;;9380:2;9419:22;;1635:20;;9488:2;9527:22;1635:20;;9077:498;9582:345;;9695:2;9683:9;9674:7;9670:23;9666:32;9663:2;;;-1:-1;;9701:12;9663:2;9759:17;9746:31;9797:18;9789:6;9786:30;9783:2;;;-1:-1;;9819:12;9783:2;9849:62;9903:7;9894:6;9883:9;9879:22;9849:62;;9934:239;;10037:2;10025:9;10016:7;10012:23;10008:32;10005:2;;;-1:-1;;10043:12;10005:2;-1:-1;2661:20;;9999:174;-1:-1;9999:174;10534:385;;10667:2;10655:9;10646:7;10642:23;10638:32;10635:2;;;10683:1;10680;10673:12;10635:2;10731:17;10718:31;10769:18;;10761:6;10758:30;10755:2;;;10801:1;10798;10791:12;10755:2;10886:6;10875:9;10871:22;3780:4;3768:9;3763:3;3759:19;3755:30;3752:2;;;3798:1;3795;3788:12;3752:2;3816:20;3780:4;3816:20;;;3807:29;;7493:6;7480:20;3899:15;3892:74;10667:2;4043:9;4039:18;4026:32;4078:18;4070:6;4067:30;4064:2;;;4110:1;4107;4100:12;4064:2;4145:54;4195:3;4186:6;4175:9;4171:22;4145:54;;;10667:2;4131:5;4127:16;4120:80;;4288:2;4277:9;4273:18;4260:32;4312:18;4304:6;4301:30;4298:2;;;4344:1;4341;4334:12;4298:2;4379:55;4430:3;4421:6;4410:9;4406:22;4379:55;;;4288:2;4361:16;;4354:81;-1:-1;4365:5;;10629:290;-1:-1;;;;;10629:290;10926:385;;11059:2;11047:9;11038:7;11034:23;11030:32;11027:2;;;11075:1;11072;11065:12;11027:2;11123:17;11110:31;11161:18;;11153:6;11150:30;11147:2;;;11193:1;11190;11183:12;11147:2;11278:6;11267:9;11263:22;4619:4;4607:9;4602:3;4598:19;4594:30;4591:2;;;4637:1;4634;4627:12;4591:2;4655:20;4619:4;4655:20;;;4646:29;;4745:17;4732:31;4783:18;4775:6;4772:30;4769:2;;;4815:1;4812;4805:12;4769:2;4849:68;4913:3;4904:6;4893:9;4889:22;4849:68;;;4832:15;4825:93;;11059:2;5003:9;4999:18;4986:32;5038:18;5030:6;5027:30;5024:2;;;5070:1;5067;5060:12;5024:2;5105:55;5156:3;5147:6;5136:9;5132:22;5105:55;;;11059:2;5087:16;;5080:81;-1:-1;5091:5;;11021:290;-1:-1;;;;;11021:290;11318:373;;11445:2;11433:9;11424:7;11420:23;11416:32;11413:2;;;-1:-1;;11451:12;11413:2;11509:17;11496:31;11547:18;11539:6;11536:30;11533:2;;;-1:-1;;11569:12;11533:2;11599:76;11667:7;11658:6;11647:9;11643:22;11599:76;;11946:701;;;;12103:2;12091:9;12082:7;12078:23;12074:32;12071:2;;;12119:1;12116;12109:12;12071:2;7493:6;7480:20;12161:63;;12289:2;12278:9;12274:18;12261:32;12313:18;;12305:6;12302:30;12299:2;;;12345:1;12342;12335:12;12299:2;12365:62;12419:7;12410:6;12399:9;12395:22;12365:62;;;12355:72;;12492:2;12481:9;12477:18;12464:32;12450:46;;12516:18;12508:6;12505:30;12502:2;;;12548:1;12545;12538:12;12502:2;;12568:63;12623:7;12614:6;12603:9;12599:22;12568:63;;;12558:73;;;12065:582;;;;;;15443:343;;15585:5;34685:12;35771:6;35766:3;35759:19;15678:52;15723:6;35808:4;35803:3;35799:14;35808:4;15704:5;15700:16;15678:52;;;38097:2;38077:14;38093:7;38073:28;15742:39;;;;35808:4;15742:39;;15533:253;-1:-1;;15533:253;22988:1078;;23212:15;23206:22;23135:4;23248:13;23241:37;23293:67;23135:4;23130:3;23126:14;23341:12;23293:67;;;23450:4;;;37386:10;23450:4;23443:5;23439:16;23433:23;37375:22;23517:4;23512:3;23508:14;25494:36;23618:4;23611:5;23607:16;23601:23;23670:3;23664:4;23660:14;23618:4;23648:3;23644:14;23637:38;23690:109;13419:5;34685:12;35771:6;35766:3;35759:19;35808:4;35803:3;35799:14;13431:88;;23450:4;13584;13576:6;13572:17;35803:3;13563:27;;34370:4;13662:5;34361:14;-1:-1;13707:10;;13701:341;13726:6;13723:1;13720:13;13701:341;;;13778:20;35803:3;13782:4;13778:20;;13773:3;13766:33;12766:60;12822:3;13833:6;13827:13;12766:60;;;13748:1;13741:9;;;;;14021:14;;;;13847:82;-1:-1;35485:14;;13701:341;;;13705:14;23887:4;23880:5;23876:16;23870:23;23850:43;;23939:3;23933:4;23929:14;23887:4;23917:3;23913:14;23906:38;23959:69;24023:4;24009:12;23959:69;;;24050:11;23108:958;-1:-1;;;;;;;;;23108:958;25656:401;;15953:5;34685:12;16064:52;16109:6;16104:3;16097:4;16090:5;16086:16;16064:52;;;16128:16;;;;15235:37;;;-1:-1;16097:4;26020:12;;25809:248;-1:-1;25809:248;26064:213;37180:42;37169:54;;;;13153:37;;26182:2;26167:18;;26153:124;26284:437;;26490:2;;26479:9;26475:18;26530:20;26511:17;26504:47;26565:146;14406:5;34685:12;35771:6;35766:3;35759:19;35799:14;26479:9;35799:14;14418:112;;35799:14;14595:4;14587:6;14583:17;26479:9;14574:27;;14562:39;;34370:4;14691:5;34361:14;-1:-1;14730:387;14755:6;14752:1;14749:13;14730:387;;;14807:20;26479:9;14811:4;14807:20;;14802:3;14795:33;12980:88;13064:3;14862:6;14856:13;12980:88;;;14876:110;-1:-1;15096:14;;;;35485;;;;14777:1;14770:9;14730:387;;;-1:-1;26557:154;;26461:260;-1:-1;;;;;;;26461:260;26728:539;15235:37;;;37480:4;37469:16;;;;27087:2;27072:18;;25609:35;27170:2;27155:18;;15235:37;27253:2;27238:18;;15235:37;26926:3;26911:19;;26897:370;27274:691;;27504:2;27525:17;27518:47;27579:76;27504:2;27493:9;27489:18;27641:6;27579:76;;;27703:9;27697:4;27693:20;27688:2;27677:9;27673:18;27666:48;27728:76;27799:4;27790:6;27728:76;;;27852:9;27846:4;27842:20;27837:2;27826:9;27822:18;27815:48;27877:78;27950:4;27941:6;27877:78;;;27869:86;27475:490;-1:-1;;;;;;;27475:490;27972:293;;28106:2;28127:17;28120:47;28181:74;28106:2;28095:9;28091:18;28241:6;28181:74;;;28173:82;28077:188;-1:-1;;;28077:188;28272:710;28563:2;28577:47;;;18099:1;28548:18;;;35759:19;18134:66;35799:14;;;18114:87;18220:12;35808:4;28786:18;;28779:48;;;17729:1;18220:12;;;35759:19;17764:66;35799:14;;;17744:87;17850:12;;;28534:448;28989:407;29180:2;29194:47;;;18471:2;29165:18;;;35759:19;18507:66;35799:14;;;18487:87;18593:12;;;29151:245;29403:407;29594:2;29608:47;;;18844:2;29579:18;;;35759:19;18880:66;35799:14;;;18860:87;18966:12;;;29565:245;29817:381;;29995:2;30016:17;30009:47;20161:15;20155:22;20088:4;29995:2;29984:9;29980:18;20190:37;19281:15;19275:22;20079:14;29984:9;20079:14;15235:37;29995:2;19436:5;19432:16;19426:23;19210:4;19469:14;29984:9;19469:14;19462:38;19515:67;19201:14;29984:9;19201:14;19563:12;19515:67;;;19666:4;19659:5;19655:16;19649:23;19629:43;;19708:14;29984:9;19712:4;19708:14;;19692;29984:9;19692:14;19685:38;19738:69;19802:4;19788:12;19738:69;;;19829:11;;;;29995:2;20428:5;20424:16;20418:23;20477:14;;29984:9;20481:4;20477:14;;19666:4;29984:9;20461:14;20454:38;20507:67;20569:4;20555:12;20507:67;;;19666:4;20653:5;20649:16;20643:23;20623:43;;20702:14;29984:9;20706:4;20702:14;;19210:4;29984:9;20686:14;20679:38;20732:67;20794:4;20780:12;20732:67;;;20724:75;;;19210:4;20878:5;20874:16;20868:23;20848:43;;20927:14;29984:9;20931:4;20927:14;;20088:4;29984:9;20911:14;20904:38;;20957:69;21021:4;21007:12;20957:69;;;30062:126;29966:232;-1:-1;;;;;29966:232;30205:453;21492:22;;22809;15235:37;;30443:2;30428:18;;30414:244;30665:377;;30841:2;30862:17;30855:47;22009:15;22003:22;21930:4;30841:2;30830:9;30826:18;22038:37;22090:95;21921:14;30830:9;21921:14;22166:12;22090:95;;;30841:2;22270:5;22266:16;22260:23;22240:43;;22319:14;30830:9;22323:4;22319:14;;21930:4;30830:9;22303:14;22296:38;22349:69;22413:4;22399:12;22349:69;;31049:353;;31213:2;31234:17;31227:47;31288:104;31213:2;31202:9;31198:18;31378:6;31288:104;;31409:213;15235:37;;;31527:2;31512:18;;31498:124;31629:412;;15265:5;15242:3;15235:37;31795:2;31913;31902:9;31898:18;31891:48;31953:78;31795:2;31784:9;31780:18;32017:6;31953:78;;32048:256;32110:2;32104:9;32136:17;;;32211:18;32196:34;;32232:22;;;32193:62;32190:2;;;32268:1;;32258:12;32190:2;32110;32277:22;32088:216;;-1:-1;32088:216;37652:268;37717:1;37724:101;37738:6;37735:1;37732:13;37724:101;;;37805:11;;;37799:18;37786:11;;;37779:39;37760:2;37753:10;37724:101;;;37840:6;37837:1;37834:13;37831:2;;;37717:1;37896:6;37891:3;37887:16;37880:27;37831:2;;37701:219;;;;38114:117;37180:42;38201:5;37169:54;38176:5;38173:35;38163:2;;38222:1;;38212:12" + "object": "0x608060405234801561001057600080fd5b50600436106101d95760003560e01c806376f15d5b11610104578063bb607362116100a2578063d88be12f11610071578063d88be12f1461039b578063ee8b86fb146103a3578063f408fb3114610279578063fa315f9d146103b6576101d9565b8063bb60736214610353578063bdab168814610369578063cd3c0b971461037e578063d6d7618c14610386576101d9565b80638ee52b4e116100de5780638ee52b4e146103225780639a3b618514610335578063a3c2f6b61461033d578063ae2dae1714610345576101d9565b806376f15d5b146102f25780637833bec0146102fa5780637a791e6e1461031a576101d9565b80634303a5421161017c57806359c28add1161014b57806359c28add146102b45780635ba3c7c0146102c957806363d69c88146102d1578063647341eb146102e4576101d9565b80634303a542146102875780634582eab21461028f57806345fdbdb714610297578063586f84b21461029f576101d9565b80632e1a7d4d116101b85780632e1a7d4d146102245780633687617d1461023757806336b32396146102595780633e9ef66a14610279576101d9565b806209e437146101de5780630527c28f146101e85780631310e444146101fb575b600080fd5b6101e66103c4565b005b6101e66101f6366004610c7f565b610401565b61020e610209366004610d87565b610404565b60405161021b91906113e8565b60405180910390f35b6101e6610232366004610d87565b61040b565b61024a610245366004610efc565b61045c565b60405161021b93929190611151565b61026c610267366004610d0b565b6104fc565b60405161021b9190611094565b6101e66101f6366004610d4c565b61020e6105de565b6101e66105e5565b6101e661064a565b6102a761067c565b60405161021b9190611373565b6102bc610684565b60405161021b919061137e565b6101e661068c565b61026c6102df366004610c2e565b6106f1565b6101e66101f6366004610ec9565b61020e6106fa565b61030d610308366004610d9f565b610708565b60405161021b9190611287565b6101e66107c5565b61020e610330366004610d87565b6107ca565b6101e66107d0565b61020e6107db565b6101e66101f6366004610e39565b61035b6107e0565b60405161021b9291906113f1565b610371610819565b60405161021b91906110b5565b6101e661081e565b61038e610855565b60405161021b91906113d5565b61020e6109ae565b6101e66103b1366004610d87565b6101f6565b6101e66101f6366004610d87565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f690611250565b60405180910390fd5b565b50565b506107c790565b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b658260405161045191906113e8565b60405180910390a250565b505060408051808201825260048082527f1234567800000000000000000000000000000000000000000000000000000000602080840191909152835180850185528281527f87654321000000000000000000000000000000000000000000000000000000008183015284518086019095529184527f616d657400000000000000000000000000000000000000000000000000000000908401529093909250565b600060606040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525090506000818760405160200161054d929190611072565b604051602081830303815290604052805190602001209050600181878787604051600081526020016040526040516105889493929190611133565b6020604051602081039080840390855afa1580156105aa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015198975050505050505050565b6107c75b90565b604080518082018252601481527f5245564552545f574954485f434f4e5354414e54000000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611193565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f690611219565b6105e26109b4565b6105e26109cc565b604080518082018252601581527f524551554952455f574954485f434f4e5354414e540000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611193565b50929392505050565b600080546001019081905590565b6107106109ec565b50604080516080810182529182528051808201825260048082527f123456780000000000000000000000000000000000000000000000000000000060208381019190915280850192909252825180840184528181527f87654321000000000000000000000000000000000000000000000000000000008184015284840152825180840190935282527f616d65740000000000000000000000000000000000000000000000000000000090820152606082015290565b6103ff565b60010190565b600080546001019055565b600190565b60408051808201909152600581527f68656c6c6f0000000000000000000000000000000000000000000000000000006020820152600191565b606090565b7f61a6029a4c7ddee5824d171331eecbd015d26a271310a223718b837facb5b77160405161084b906111ad565b60405180910390a1565b61085d610a1a565b6040805160028082526060828101909352816020015b60608152602001906001900390816108735790505090506040518060400160405280600581526020017f3078313233000000000000000000000000000000000000000000000000000000815250816000815181106108cd57fe5b60200260200101819052506040518060400160405280600581526020017f30783332310000000000000000000000000000000000000000000000000000008152508160018151811061091b57fe5b6020908102919091018101919091526040805160c0810182526005608082018181527f307831323300000000000000000000000000000000000000000000000000000060a0840152825281840152808201939093528051808201909152600381527f6162630000000000000000000000000000000000000000000000000000000000918101919091526060820152905090565b6104d290565b60405180602001604052806109c7610a48565b905290565b60405180604001604052806109df610a1a565b8152602001606081525090565b60405180608001604052806109ff610a5b565b81526020016060815260200160608152602001606081525090565b604051806080016040528060608152602001600063ffffffff16815260200160608152602001606081525090565b6040518060200160405280600081525090565b60405180606001604052806000815260200160608152602001606081525090565b600082601f830112610a8c578081fd5b8135610a9f610a9a82611431565b61140a565b8181529150602080830190840160005b83811015610adc57610ac78760208435890101610ae6565b83526020928301929190910190600101610aaf565b5050505092915050565b600082601f830112610af6578081fd5b813567ffffffffffffffff811115610b0c578182fd5b610b3d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161140a565b9150808252836020828501011115610b5457600080fd5b8060208401602084013760009082016020015292915050565b600060808284031215610b7e578081fd5b610b88608061140a565b9050813567ffffffffffffffff80821115610ba257600080fd5b610bae85838601610ae6565b8352610bbd8560208601610c14565b60208401526040840135915080821115610bd657600080fd5b610be285838601610a7c565b60408401526060840135915080821115610bfb57600080fd5b50610c0884828501610ae6565b60608301525092915050565b803563ffffffff81168114610c2857600080fd5b92915050565b600080600080600060a08688031215610c45578081fd5b8535610c5081611481565b945060208601359350604086013592506060860135610c6e81611481565b949793965091946080013592915050565b60006020808385031215610c91578182fd5b823567ffffffffffffffff811115610ca7578283fd5b80840185601f820112610cb8578384fd5b80359150610cc8610a9a83611431565b82815283810190828501865b85811015610cfd57610ceb8a888435880101610ae6565b84529286019290860190600101610cd4565b509098975050505050505050565b60008060008060808587031215610d20578384fd5b84359350602085013560ff81168114610d37578384fd5b93969395505050506040820135916060013590565b600060208284031215610d5d578081fd5b813567ffffffffffffffff811115610d73578182fd5b610d7f84828501610ae6565b949350505050565b600060208284031215610d98578081fd5b5035919050565b600060208284031215610db0578081fd5b813567ffffffffffffffff80821115610dc7578283fd5b81840160608187031215610dd9578384fd5b610de3606061140a565b925080358352602081013582811115610dfa578485fd5b610e0687828401610ae6565b602085015250604081013582811115610e1d578485fd5b610e2987828401610ae6565b6040850152509195945050505050565b600060208284031215610e4a578081fd5b813567ffffffffffffffff80821115610e61578283fd5b81840160408187031215610e73578384fd5b610e7d604061140a565b9250803582811115610e8d578485fd5b610e9987828401610b6d565b845250602081013582811115610ead578485fd5b610eb987828401610ae6565b6020850152509195945050505050565b600060208284031215610eda578081fd5b813567ffffffffffffffff811115610ef0578182fd5b610d7f84828501610b6d565b600080600060608486031215610f10578081fd5b83359250602084013567ffffffffffffffff80821115610f2e578283fd5b610f3a87838801610ae6565b93506040860135915080821115610f4f578283fd5b50610f5c86828701610ae6565b9150509250925092565b60008151808452610f7e816020860160208601611451565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000815160808452610fc56080850182610f66565b6020915063ffffffff828501511682860152604084015185820360408701528181518084528484019150848582028501018584018794505b8285101561104b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868303018452611037828251610f66565b600195909501949387019391508601610ffd565b506060880151955088810360608a01526110658187610f66565b9998505050505050505050565b60008351611084818460208801611451565b9190910191825250602001919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611126577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452611114858351610fb0565b945092850192908501906001016110da565b5092979650505050505050565b93845260ff9290921660208401526040830152606082015260800190565b6000606082526111646060830186610f66565b82810360208401526111768186610f66565b83810360408501526111888186610f66565b979650505050505050565b6000602082526111a66020830184610f66565b9392505050565b60408082526004908201527f123456780000000000000000000000000000000000000000000000000000000060608201526080602082018190526005908201527f6c6f72656d00000000000000000000000000000000000000000000000000000060a082015260c00190565b6020808252600d908201527f53494d504c455f52455645525400000000000000000000000000000000000000604082015260600190565b6020808252600e908201527f53494d504c455f52455155495245000000000000000000000000000000000000604082015260600190565b600060208252825160806020840152805160a08401526020810151606060c08501526112b7610100850182610f66565b604083015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608582030160e08601526112f28183610f66565b9250505060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808584030160408601526113308383610f66565b604087015193508186820301606087015261134b8185610f66565b92505060608601519250808583030160808601525061136a8183610f66565b95945050505050565b905151815260200190565b60006020825282516040602084015261139a6060840182610fb0565b602085015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084820301604085015261136a8183610f66565b6000602082526111a66020830184610fb0565b90815260200190565b600083825260406020830152610d7f6040830184610f66565b60405181810167ffffffffffffffff8111828210171561142957600080fd5b604052919050565b600067ffffffffffffffff821115611447578081fd5b5060209081020190565b60005b8381101561146c578181015183820152602001611454565b8381111561147b576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461040157600080fdfea365627a7a723158204f5b227587475ada330d11bfb46020f41172555bd06234eaaad1a7d10a4c2a396c6578706572696d656e74616cf564736f6c634300050c0040", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x1D9 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x76F15D5B GT PUSH2 0x104 JUMPI DUP1 PUSH4 0xBB607362 GT PUSH2 0xA2 JUMPI DUP1 PUSH4 0xD88BE12F GT PUSH2 0x71 JUMPI DUP1 PUSH4 0xD88BE12F EQ PUSH2 0x39B JUMPI DUP1 PUSH4 0xEE8B86FB EQ PUSH2 0x3A3 JUMPI DUP1 PUSH4 0xF408FB31 EQ PUSH2 0x279 JUMPI DUP1 PUSH4 0xFA315F9D EQ PUSH2 0x3B6 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0xBB607362 EQ PUSH2 0x353 JUMPI DUP1 PUSH4 0xBDAB1688 EQ PUSH2 0x369 JUMPI DUP1 PUSH4 0xCD3C0B97 EQ PUSH2 0x37E JUMPI DUP1 PUSH4 0xD6D7618C EQ PUSH2 0x386 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x8EE52B4E GT PUSH2 0xDE JUMPI DUP1 PUSH4 0x8EE52B4E EQ PUSH2 0x322 JUMPI DUP1 PUSH4 0x9A3B6185 EQ PUSH2 0x335 JUMPI DUP1 PUSH4 0xA3C2F6B6 EQ PUSH2 0x33D JUMPI DUP1 PUSH4 0xAE2DAE17 EQ PUSH2 0x345 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x76F15D5B EQ PUSH2 0x2F2 JUMPI DUP1 PUSH4 0x7833BEC0 EQ PUSH2 0x2FA JUMPI DUP1 PUSH4 0x7A791E6E EQ PUSH2 0x31A JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x4303A542 GT PUSH2 0x17C JUMPI DUP1 PUSH4 0x59C28ADD GT PUSH2 0x14B JUMPI DUP1 PUSH4 0x59C28ADD EQ PUSH2 0x2B4 JUMPI DUP1 PUSH4 0x5BA3C7C0 EQ PUSH2 0x2C9 JUMPI DUP1 PUSH4 0x63D69C88 EQ PUSH2 0x2D1 JUMPI DUP1 PUSH4 0x647341EB EQ PUSH2 0x2E4 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x4303A542 EQ PUSH2 0x287 JUMPI DUP1 PUSH4 0x4582EAB2 EQ PUSH2 0x28F JUMPI DUP1 PUSH4 0x45FDBDB7 EQ PUSH2 0x297 JUMPI DUP1 PUSH4 0x586F84B2 EQ PUSH2 0x29F JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH4 0x2E1A7D4D GT PUSH2 0x1B8 JUMPI DUP1 PUSH4 0x2E1A7D4D EQ PUSH2 0x224 JUMPI DUP1 PUSH4 0x3687617D EQ PUSH2 0x237 JUMPI DUP1 PUSH4 0x36B32396 EQ PUSH2 0x259 JUMPI DUP1 PUSH4 0x3E9EF66A EQ PUSH2 0x279 JUMPI PUSH2 0x1D9 JUMP JUMPDEST DUP1 PUSH3 0x9E437 EQ PUSH2 0x1DE JUMPI DUP1 PUSH4 0x527C28F EQ PUSH2 0x1E8 JUMPI DUP1 PUSH4 0x1310E444 EQ PUSH2 0x1FB JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1E6 PUSH2 0x3C4 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xC7F JUMP JUMPDEST PUSH2 0x401 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x209 CALLDATASIZE PUSH1 0x4 PUSH2 0xD87 JUMP JUMPDEST PUSH2 0x404 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x13E8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x1E6 PUSH2 0x232 CALLDATASIZE PUSH1 0x4 PUSH2 0xD87 JUMP JUMPDEST PUSH2 0x40B JUMP JUMPDEST PUSH2 0x24A PUSH2 0x245 CALLDATASIZE PUSH1 0x4 PUSH2 0xEFC JUMP JUMPDEST PUSH2 0x45C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1151 JUMP JUMPDEST PUSH2 0x26C PUSH2 0x267 CALLDATASIZE PUSH1 0x4 PUSH2 0xD0B JUMP JUMPDEST PUSH2 0x4FC JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1094 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xD4C JUMP JUMPDEST PUSH2 0x20E PUSH2 0x5DE JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x5E5 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x64A JUMP JUMPDEST PUSH2 0x2A7 PUSH2 0x67C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1373 JUMP JUMPDEST PUSH2 0x2BC PUSH2 0x684 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x137E JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x68C JUMP JUMPDEST PUSH2 0x26C PUSH2 0x2DF CALLDATASIZE PUSH1 0x4 PUSH2 0xC2E JUMP JUMPDEST PUSH2 0x6F1 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xEC9 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x6FA JUMP JUMPDEST PUSH2 0x30D PUSH2 0x308 CALLDATASIZE PUSH1 0x4 PUSH2 0xD9F JUMP JUMPDEST PUSH2 0x708 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x1287 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x7C5 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x330 CALLDATASIZE PUSH1 0x4 PUSH2 0xD87 JUMP JUMPDEST PUSH2 0x7CA JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x7D0 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x7DB JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xE39 JUMP JUMPDEST PUSH2 0x35B PUSH2 0x7E0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP3 SWAP2 SWAP1 PUSH2 0x13F1 JUMP JUMPDEST PUSH2 0x371 PUSH2 0x819 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x10B5 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x81E JUMP JUMPDEST PUSH2 0x38E PUSH2 0x855 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x21B SWAP2 SWAP1 PUSH2 0x13D5 JUMP JUMPDEST PUSH2 0x20E PUSH2 0x9AE JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x3B1 CALLDATASIZE PUSH1 0x4 PUSH2 0xD87 JUMP JUMPDEST PUSH2 0x1F6 JUMP JUMPDEST PUSH2 0x1E6 PUSH2 0x1F6 CALLDATASIZE PUSH1 0x4 PUSH2 0xD87 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3F6 SWAP1 PUSH2 0x1250 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST JUMP JUMPDEST POP JUMP JUMPDEST POP PUSH2 0x7C7 SWAP1 JUMP JUMPDEST CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0x7FCF532C15F0A6DB0BD6D0E038BEA71D30D808C7D98CB3BF7268A95BF5081B65 DUP3 PUSH1 0x40 MLOAD PUSH2 0x451 SWAP2 SWAP1 PUSH2 0x13E8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 POP JUMP JUMPDEST POP POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x4 DUP1 DUP3 MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP4 MLOAD DUP1 DUP6 ADD DUP6 MSTORE DUP3 DUP2 MSTORE PUSH32 0x8765432100000000000000000000000000000000000000000000000000000000 DUP2 DUP4 ADD MSTORE DUP5 MLOAD DUP1 DUP7 ADD SWAP1 SWAP6 MSTORE SWAP2 DUP5 MSTORE PUSH32 0x616D657400000000000000000000000000000000000000000000000000000000 SWAP1 DUP5 ADD MSTORE SWAP1 SWAP4 SWAP1 SWAP3 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x1C DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE POP SWAP1 POP PUSH1 0x0 DUP2 DUP8 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x54D SWAP3 SWAP2 SWAP1 PUSH2 0x1072 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 SWAP1 POP PUSH1 0x1 DUP2 DUP8 DUP8 DUP8 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x588 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1133 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x5AA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0x7C7 JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x14 DUP2 MSTORE PUSH32 0x5245564552545F574954485F434F4E5354414E54000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH2 0x3F6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x1193 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3F6 SWAP1 PUSH2 0x1219 JUMP JUMPDEST PUSH2 0x5E2 PUSH2 0x9B4 JUMP JUMPDEST PUSH2 0x5E2 PUSH2 0x9CC JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x15 DUP2 MSTORE PUSH32 0x524551554952455F574954485F434F4E5354414E540000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH2 0x3F6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x1193 JUMP JUMPDEST POP SWAP3 SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 DUP2 SWAP1 SSTORE SWAP1 JUMP JUMPDEST PUSH2 0x710 PUSH2 0x9EC JUMP JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x80 DUP2 ADD DUP3 MSTORE SWAP2 DUP3 MSTORE DUP1 MLOAD DUP1 DUP3 ADD DUP3 MSTORE PUSH1 0x4 DUP1 DUP3 MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP4 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP1 DUP6 ADD SWAP3 SWAP1 SWAP3 MSTORE DUP3 MLOAD DUP1 DUP5 ADD DUP5 MSTORE DUP2 DUP2 MSTORE PUSH32 0x8765432100000000000000000000000000000000000000000000000000000000 DUP2 DUP5 ADD MSTORE DUP5 DUP5 ADD MSTORE DUP3 MLOAD DUP1 DUP5 ADD SWAP1 SWAP4 MSTORE DUP3 MSTORE PUSH32 0x616D657400000000000000000000000000000000000000000000000000000000 SWAP1 DUP3 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE SWAP1 JUMP JUMPDEST PUSH2 0x3FF JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x1 SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x5 DUP2 MSTORE PUSH32 0x68656C6C6F000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x1 SWAP2 JUMP JUMPDEST PUSH1 0x60 SWAP1 JUMP JUMPDEST PUSH32 0x61A6029A4C7DDEE5824D171331EECBD015D26A271310A223718B837FACB5B771 PUSH1 0x40 MLOAD PUSH2 0x84B SWAP1 PUSH2 0x11AD JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMP JUMPDEST PUSH2 0x85D PUSH2 0xA1A JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x2 DUP1 DUP3 MSTORE PUSH1 0x60 DUP3 DUP2 ADD SWAP1 SWAP4 MSTORE DUP2 PUSH1 0x20 ADD JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0x873 JUMPI SWAP1 POP POP SWAP1 POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x3078313233000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x8CD JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x3078333231000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 PUSH1 0x1 DUP2 MLOAD DUP2 LT PUSH2 0x91B JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 ADD DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 DUP1 MLOAD PUSH1 0xC0 DUP2 ADD DUP3 MSTORE PUSH1 0x5 PUSH1 0x80 DUP3 ADD DUP2 DUP2 MSTORE PUSH32 0x3078313233000000000000000000000000000000000000000000000000000000 PUSH1 0xA0 DUP5 ADD MSTORE DUP3 MSTORE DUP2 DUP5 ADD MSTORE DUP1 DUP3 ADD SWAP4 SWAP1 SWAP4 MSTORE DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x3 DUP2 MSTORE PUSH32 0x6162630000000000000000000000000000000000000000000000000000000000 SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP3 ADD MSTORE SWAP1 POP SWAP1 JUMP JUMPDEST PUSH2 0x4D2 SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9C7 PUSH2 0xA48 JUMP JUMPDEST SWAP1 MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9DF PUSH2 0xA1A JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x80 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x9FF PUSH2 0xA5B JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x80 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH4 0xFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xA8C JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0xA9F PUSH2 0xA9A DUP3 PUSH2 0x1431 JUMP JUMPDEST PUSH2 0x140A JUMP JUMPDEST DUP2 DUP2 MSTORE SWAP2 POP PUSH1 0x20 DUP1 DUP4 ADD SWAP1 DUP5 ADD PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xADC JUMPI PUSH2 0xAC7 DUP8 PUSH1 0x20 DUP5 CALLDATALOAD DUP10 ADD ADD PUSH2 0xAE6 JUMP JUMPDEST DUP4 MSTORE PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0xAAF JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xAF6 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB0C JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0xB3D PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP5 ADD AND ADD PUSH2 0x140A JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xB54 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP5 ADD CALLDATACOPY PUSH1 0x0 SWAP1 DUP3 ADD PUSH1 0x20 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB7E JUMPI DUP1 DUP2 REVERT JUMPDEST PUSH2 0xB88 PUSH1 0x80 PUSH2 0x140A JUMP JUMPDEST SWAP1 POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xBA2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBAE DUP6 DUP4 DUP7 ADD PUSH2 0xAE6 JUMP JUMPDEST DUP4 MSTORE PUSH2 0xBBD DUP6 PUSH1 0x20 DUP7 ADD PUSH2 0xC14 JUMP JUMPDEST PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP5 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xBD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBE2 DUP6 DUP4 DUP7 ADD PUSH2 0xA7C JUMP JUMPDEST PUSH1 0x40 DUP5 ADD MSTORE PUSH1 0x60 DUP5 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xBFB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xC08 DUP5 DUP3 DUP6 ADD PUSH2 0xAE6 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP1 CALLDATALOAD PUSH4 0xFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0xC28 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xC45 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xC50 DUP2 PUSH2 0x1481 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD PUSH2 0xC6E DUP2 PUSH2 0x1481 JUMP JUMPDEST SWAP5 SWAP8 SWAP4 SWAP7 POP SWAP2 SWAP5 PUSH1 0x80 ADD CALLDATALOAD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xC91 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xCA7 JUMPI DUP3 DUP4 REVERT JUMPDEST DUP1 DUP5 ADD DUP6 PUSH1 0x1F DUP3 ADD SLT PUSH2 0xCB8 JUMPI DUP4 DUP5 REVERT JUMPDEST DUP1 CALLDATALOAD SWAP2 POP PUSH2 0xCC8 PUSH2 0xA9A DUP4 PUSH2 0x1431 JUMP JUMPDEST DUP3 DUP2 MSTORE DUP4 DUP2 ADD SWAP1 DUP3 DUP6 ADD DUP7 JUMPDEST DUP6 DUP2 LT ISZERO PUSH2 0xCFD JUMPI PUSH2 0xCEB DUP11 DUP9 DUP5 CALLDATALOAD DUP9 ADD ADD PUSH2 0xAE6 JUMP JUMPDEST DUP5 MSTORE SWAP3 DUP7 ADD SWAP3 SWAP1 DUP7 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0xCD4 JUMP JUMPDEST POP SWAP1 SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xD20 JUMPI DUP4 DUP5 REVERT JUMPDEST DUP5 CALLDATALOAD SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH1 0xFF DUP2 AND DUP2 EQ PUSH2 0xD37 JUMPI DUP4 DUP5 REVERT JUMPDEST SWAP4 SWAP7 SWAP4 SWAP6 POP POP POP POP PUSH1 0x40 DUP3 ADD CALLDATALOAD SWAP2 PUSH1 0x60 ADD CALLDATALOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD5D JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xD73 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0xD7F DUP5 DUP3 DUP6 ADD PUSH2 0xAE6 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD98 JUMPI DUP1 DUP2 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDB0 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xDC7 JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x60 DUP2 DUP8 SUB SLT ISZERO PUSH2 0xDD9 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0xDE3 PUSH1 0x60 PUSH2 0x140A JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP4 MSTORE PUSH1 0x20 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xDFA JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xE06 DUP8 DUP3 DUP5 ADD PUSH2 0xAE6 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MSTORE POP PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xE1D JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xE29 DUP8 DUP3 DUP5 ADD PUSH2 0xAE6 JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE4A JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xE61 JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x40 DUP2 DUP8 SUB SLT ISZERO PUSH2 0xE73 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0xE7D PUSH1 0x40 PUSH2 0x140A JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xE8D JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xE99 DUP8 DUP3 DUP5 ADD PUSH2 0xB6D JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0xEAD JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0xEB9 DUP8 DUP3 DUP5 ADD PUSH2 0xAE6 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xEDA JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xEF0 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0xD7F DUP5 DUP3 DUP6 ADD PUSH2 0xB6D JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xF10 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP4 CALLDATALOAD SWAP3 POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xF2E JUMPI DUP3 DUP4 REVERT JUMPDEST PUSH2 0xF3A DUP8 DUP4 DUP9 ADD PUSH2 0xAE6 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xF4F JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0xF5C DUP7 DUP3 DUP8 ADD PUSH2 0xAE6 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0xF7E DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1451 JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD PUSH1 0x80 DUP5 MSTORE PUSH2 0xFC5 PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x20 SWAP2 POP PUSH4 0xFFFFFFFF DUP3 DUP6 ADD MLOAD AND DUP3 DUP7 ADD MSTORE PUSH1 0x40 DUP5 ADD MLOAD DUP6 DUP3 SUB PUSH1 0x40 DUP8 ADD MSTORE DUP2 DUP2 MLOAD DUP1 DUP5 MSTORE DUP5 DUP5 ADD SWAP2 POP DUP5 DUP6 DUP3 MUL DUP6 ADD ADD DUP6 DUP5 ADD DUP8 SWAP5 POP JUMPDEST DUP3 DUP6 LT ISZERO PUSH2 0x104B JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP7 DUP4 SUB ADD DUP5 MSTORE PUSH2 0x1037 DUP3 DUP3 MLOAD PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x1 SWAP6 SWAP1 SWAP6 ADD SWAP5 SWAP4 DUP8 ADD SWAP4 SWAP2 POP DUP7 ADD PUSH2 0xFFD JUMP JUMPDEST POP PUSH1 0x60 DUP9 ADD MLOAD SWAP6 POP DUP9 DUP2 SUB PUSH1 0x60 DUP11 ADD MSTORE PUSH2 0x1065 DUP2 DUP8 PUSH2 0xF66 JUMP JUMPDEST SWAP10 SWAP9 POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 MLOAD PUSH2 0x1084 DUP2 DUP5 PUSH1 0x20 DUP9 ADD PUSH2 0x1451 JUMP JUMPDEST SWAP2 SWAP1 SWAP2 ADD SWAP2 DUP3 MSTORE POP PUSH1 0x20 ADD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 ADD DUP2 DUP5 MSTORE DUP1 DUP6 MLOAD DUP1 DUP4 MSTORE PUSH1 0x40 DUP7 ADD SWAP2 POP PUSH1 0x40 DUP5 DUP3 MUL DUP8 ADD ADD SWAP3 POP DUP4 DUP8 ADD DUP6 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0x1126 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 DUP9 DUP7 SUB ADD DUP5 MSTORE PUSH2 0x1114 DUP6 DUP4 MLOAD PUSH2 0xFB0 JUMP JUMPDEST SWAP5 POP SWAP3 DUP6 ADD SWAP3 SWAP1 DUP6 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x10DA JUMP JUMPDEST POP SWAP3 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST SWAP4 DUP5 MSTORE PUSH1 0xFF SWAP3 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 MSTORE PUSH2 0x1164 PUSH1 0x60 DUP4 ADD DUP7 PUSH2 0xF66 JUMP JUMPDEST DUP3 DUP2 SUB PUSH1 0x20 DUP5 ADD MSTORE PUSH2 0x1176 DUP2 DUP7 PUSH2 0xF66 JUMP JUMPDEST DUP4 DUP2 SUB PUSH1 0x40 DUP6 ADD MSTORE PUSH2 0x1188 DUP2 DUP7 PUSH2 0xF66 JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0x11A6 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xF66 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 DUP3 MSTORE PUSH1 0x4 SWAP1 DUP3 ADD MSTORE PUSH32 0x1234567800000000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0x5 SWAP1 DUP3 ADD MSTORE PUSH32 0x6C6F72656D000000000000000000000000000000000000000000000000000000 PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0xD SWAP1 DUP3 ADD MSTORE PUSH32 0x53494D504C455F52455645525400000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0xE SWAP1 DUP3 ADD MSTORE PUSH32 0x53494D504C455F52455155495245000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE DUP3 MLOAD PUSH1 0x80 PUSH1 0x20 DUP5 ADD MSTORE DUP1 MLOAD PUSH1 0xA0 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0x60 PUSH1 0xC0 DUP6 ADD MSTORE PUSH2 0x12B7 PUSH2 0x100 DUP6 ADD DUP3 PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MLOAD SWAP2 POP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 DUP6 DUP3 SUB ADD PUSH1 0xE0 DUP7 ADD MSTORE PUSH2 0x12F2 DUP2 DUP4 PUSH2 0xF66 JUMP JUMPDEST SWAP3 POP POP POP PUSH1 0x20 DUP5 ADD MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP1 DUP6 DUP5 SUB ADD PUSH1 0x40 DUP7 ADD MSTORE PUSH2 0x1330 DUP4 DUP4 PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x40 DUP8 ADD MLOAD SWAP4 POP DUP2 DUP7 DUP3 SUB ADD PUSH1 0x60 DUP8 ADD MSTORE PUSH2 0x134B DUP2 DUP6 PUSH2 0xF66 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP7 ADD MLOAD SWAP3 POP DUP1 DUP6 DUP4 SUB ADD PUSH1 0x80 DUP7 ADD MSTORE POP PUSH2 0x136A DUP2 DUP4 PUSH2 0xF66 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST SWAP1 MLOAD MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE DUP3 MLOAD PUSH1 0x40 PUSH1 0x20 DUP5 ADD MSTORE PUSH2 0x139A PUSH1 0x60 DUP5 ADD DUP3 PUSH2 0xFB0 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MLOAD SWAP2 POP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP5 DUP3 SUB ADD PUSH1 0x40 DUP6 ADD MSTORE PUSH2 0x136A DUP2 DUP4 PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0x11A6 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xFB0 JUMP JUMPDEST SWAP1 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP4 DUP3 MSTORE PUSH1 0x40 PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0xD7F PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0xF66 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x1429 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1447 JUMPI DUP1 DUP2 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x146C JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1454 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x147B JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x401 JUMPI PUSH1 0x0 DUP1 REVERT INVALID LOG3 PUSH6 0x627A7A723158 KECCAK256 0x4f JUMPDEST 0x22 PUSH22 0x87475ADA330D11BFB46020F41172555BD06234EAAAD1 0xa7 0xd1 EXP 0x4c 0x2a CODECOPY PUSH13 0x6578706572696D656E74616CF5 PUSH5 0x736F6C6343 STOP SDIV 0xc STOP BLOCKHASH ", + "sourceMap": "641:6754:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;641:6754:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1496:107;;;:::i;:::-;;3110:63;;;;;;;;;:::i;6359:128::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;4968:84;;;;;;;;;:::i;6982:345::-;;;;;;;;;:::i;:::-;;;;;;;;;;2288:334;;;;;;;;;:::i;:::-;;;;;;;;2948:52;;;;;;;5964:117;;;:::i;1389:101::-;;;:::i;1286:97::-;;;:::i;4321:153::-;;;:::i;:::-;;;;;;;;4053:73;;;:::i;:::-;;;;;;;;1609:111;;;:::i;2776:166::-;;;;;;;;;:::i;3319:52::-;;;;;;;4500:72;;;:::i;6560:317::-;;;;;;;;;:::i;:::-;;;;;;;;5773:112;;;:::i;989:140::-;;;;;;;;;:::i;4577:69::-;;;:::i;862:121::-;;;:::i;3984:64::-;;;;;;;4652:134;;;:::i;:::-;;;;;;;;;3809:80;;;:::i;:::-;;;;;;;;5118:125;;;:::i;3453:350::-;;;:::i;:::-;;;;;;;;1135:145;;;:::i;6160:123::-;;;;;;;;;:::i;4792:47::-;;;;;;;1496:107;1564:32;;;;;;;;;;;;;;;;;;;;1496:107::o;3110:63::-;;:::o;6359:128::-;-1:-1:-1;6476:4:0;;6359:128::o;4968:84::-;5029:10;5018:27;;;5041:3;5018:27;;;;;;;;;;;;;;;4968:84;:::o;6982:345::-;-1:-1:-1;;7229:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6982:345:0:o;2288:334::-;2399:21;2436:19;:56;;;;;;;;;;;;;;;;;;;2502:20;2552:6;2560:4;2535:30;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;2535:30:0;;;2525:41;;;;;;2502:64;;2583:32;2593:12;2607:1;2610;2613;2583:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;2583:32:0;;;;;;2288:334;-1:-1:-1;;;;;;;;2288:334:0:o;5964:117::-;6070:4;5964:117;;:::o;1389:101::-;1469:13;;;;;;;;;;;;;;;;1462:21;;;;;;;1469:13;1462:21;;;;1286:97;1353:23;;;;;;;;;;;4321:153;4415:51;;:::i;4053:73::-;4103:19;;:::i;1609:111::-;1698:14;;;;;;;;;;;;;;;;1683:30;;;;;;;1698:14;1683:30;;;;2776:166;-1:-1:-1;2934:1:0;;2776:166;-1:-1:-1;;;2776:166:0:o;4500:72::-;4540:4;4555:14;;4568:1;4555:14;;;;;4500:72;:::o;6560:317::-;6674:20;;:::i;:::-;-1:-1:-1;6717:153:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6560:317::o;5773:112::-;5857:21;;989:140;1117:1;:5;;989:140::o;4577:69::-;4629:9;:14;;4642:1;4629:14;;;4577:69::o;862:121::-;975:1;862:121;:::o;4652:134::-;4760:19;;;;;;;;;;;;;;;;;4768:1;4652:134;:::o;3809:80::-;3870:15;3809:80;:::o;5118:125::-;5167:69;;;;;;;;;;;;;;;5118:125::o;3453:350::-;3497:15;;:::i;:::-;3551:14;;;3563:1;3551:14;;;3524:24;3551:14;;;;;;;;;;;;;;;;;;;;;;;;;;3524:41;;3575:22;;;;;;;;;;;;;;;;;:9;3585:1;3575:12;;;;;;;;;;;;;:22;;;;3607;;;;;;;;;;;;;;;;;:9;3617:1;3607:12;;;;;;;;;;;;;;;;;;:22;;;;3647:149;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3647:149:0;;;;-1:-1:-1;3453:350:0;:::o;1135:145::-;711:4;1135:145;:::o;641:6754::-;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;158:685:-1:-;;276:3;269:4;261:6;257:17;253:27;243:2;;-1:-1;;284:12;243:2;331:6;318:20;353:81;368:65;426:6;368:65;;;353:81;;;462:21;;;344:90;-1:-1;506:4;519:14;;;;494:17;;614:1;599:238;624:6;621:1;618:13;599:238;;;731:42;769:3;506:4;707:3;694:17;498:6;682:30;;731:42;;;719:55;;506:4;788:14;;;;816;;;;;646:1;639:9;599:238;;;603:14;;;;236:607;;;;;1706:432;;1803:3;1796:4;1788:6;1784:17;1780:27;1770:2;;-1:-1;;1811:12;1770:2;1858:6;1845:20;33078:18;33070:6;33067:30;33064:2;;;-1:-1;;33100:12;33064:2;1880:60;33241:4;33173:9;1796:4;33158:6;33154:17;33150:33;33231:15;1880:60;;;1871:69;;1960:6;1953:5;1946:21;2064:3;33241:4;2055:6;1988;2046:16;;2043:25;2040:2;;;2081:1;;2071:12;2040:2;37579:6;33241:4;1988:6;1984:17;33241:4;2022:5;2018:16;37556:30;37635:1;37617:16;;;33241:4;37617:16;37610:27;2022:5;1763:375;-1:-1;;1763:375;5221:1071;;5329:4;5317:9;5312:3;5308:19;5304:30;5301:2;;;-1:-1;;5337:12;5301:2;5365:20;5329:4;5365:20;;;5356:29;;5453:17;5440:31;5491:18;;5483:6;5480:30;5477:2;;;5468:1;;5513:12;5477:2;5557:54;5607:3;5598:6;5587:9;5583:22;5557:54;;;5540:15;5533:79;5711:48;5755:3;5678:2;5735:9;5731:22;5711:48;;;5678:2;5697:5;5693:16;5686:74;5865:2;5854:9;5850:18;5837:32;5823:46;;5491:18;5881:6;5878:30;5875:2;;;5468:1;;5911:12;5875:2;5956:75;6027:3;6018:6;6007:9;6003:22;5956:75;;;5865:2;5942:5;5938:16;5931:101;6124:2;6113:9;6109:18;6096:32;6082:46;;5491:18;6140:6;6137:30;6134:2;;;5468:1;;6170:12;6134:2;;6215:55;6266:3;6257:6;6246:9;6242:22;6215:55;;;6124:2;6201:5;6197:16;6190:81;;5295:997;;;;;7550:128;7616:20;;37386:10;37375:22;;38666:34;;38656:2;;38714:1;;38704:12;38656:2;7601:77;;;;;7818:743;;;;;;7990:3;7978:9;7969:7;7965:23;7961:33;7958:2;;;-1:-1;;7997:12;7958:2;85:6;72:20;97:33;124:5;97:33;;;8049:63;-1:-1;8149:2;8188:22;;7480:20;;-1:-1;8257:2;8296:22;;7480:20;;-1:-1;8365:2;8404:22;;72:20;97:33;72:20;97:33;;;7952:609;;;;-1:-1;7952:609;;8473:3;8513:22;7480:20;;7952:609;-1:-1;;7952:609;8568:387;;8702:2;;8690:9;8681:7;8677:23;8673:32;8670:2;;;-1:-1;;8708:12;8670:2;8766:17;8753:31;8804:18;8796:6;8793:30;8790:2;;;-1:-1;;8826:12;8790:2;8922:6;8911:9;8907:22;989:3;982:4;974:6;970:17;966:27;956:2;;-1:-1;;997:12;956:2;1044:6;1031:20;1017:34;;1066:85;1081:69;1143:6;1081:69;;1066:85;1179:21;;;1236:14;;;;1211:17;;;-1:-1;1316:238;1341:6;1338:1;1335:13;1316:238;;;1448:42;1486:3;8702:2;1424:3;1411:17;1215:6;1399:30;;1448:42;;;1436:55;;1505:14;;;;1533;;;;1363:1;1356:9;1316:238;;;-1:-1;8846:93;;8664:291;-1:-1;;;;;;;;8664:291;8962:613;;;;;9115:3;9103:9;9094:7;9090:23;9086:33;9083:2;;;-1:-1;;9122:12;9083:2;1648:6;1635:20;9174:63;;9274:2;9315:9;9311:22;7750:20;37480:4;38813:5;37469:16;38790:5;38787:33;38777:2;;-1:-1;;38824:12;38777:2;9077:498;;9282:61;;-1:-1;;;;9380:2;9419:22;;1635:20;;9488:2;9527:22;1635:20;;9077:498;9582:345;;9695:2;9683:9;9674:7;9670:23;9666:32;9663:2;;;-1:-1;;9701:12;9663:2;9759:17;9746:31;9797:18;9789:6;9786:30;9783:2;;;-1:-1;;9819:12;9783:2;9849:62;9903:7;9894:6;9883:9;9879:22;9849:62;;;9839:72;9657:270;-1:-1;;;;9657:270;9934:239;;10037:2;10025:9;10016:7;10012:23;10008:32;10005:2;;;-1:-1;;10043:12;10005:2;-1:-1;2661:20;;9999:174;-1:-1;9999:174;10534:385;;10667:2;10655:9;10646:7;10642:23;10638:32;10635:2;;;-1:-1;;10673:12;10635:2;10731:17;10718:31;10769:18;;10761:6;10758:30;10755:2;;;-1:-1;;10791:12;10755:2;10886:6;10875:9;10871:22;3780:4;3768:9;3763:3;3759:19;3755:30;3752:2;;;-1:-1;;3788:12;3752:2;3816:20;3780:4;3816:20;;;3807:29;;3937:22;7480:20;3899:15;3892:74;10667:2;4043:9;4039:18;4026:32;10769:18;4070:6;4067:30;4064:2;;;-1:-1;;4100:12;4064:2;4145:54;4195:3;4186:6;4175:9;4171:22;4145:54;;;10667:2;4131:5;4127:16;4120:80;;4288:2;4277:9;4273:18;4260:32;10769:18;4304:6;4301:30;4298:2;;;-1:-1;;4334:12;4298:2;4379:55;4430:3;4421:6;4410:9;4406:22;4379:55;;;4288:2;4361:16;;4354:81;-1:-1;4365:5;;10629:290;-1:-1;;;;;10629:290;10926:385;;11059:2;11047:9;11038:7;11034:23;11030:32;11027:2;;;-1:-1;;11065:12;11027:2;11123:17;11110:31;11161:18;;11153:6;11150:30;11147:2;;;-1:-1;;11183:12;11147:2;11278:6;11267:9;11263:22;4619:4;4607:9;4602:3;4598:19;4594:30;4591:2;;;-1:-1;;4627:12;4591:2;4655:20;4619:4;4655:20;;;4646:29;;4745:17;4732:31;11161:18;4775:6;4772:30;4769:2;;;-1:-1;;4805:12;4769:2;4849:68;4913:3;4904:6;4893:9;4889:22;4849:68;;;4832:15;4825:93;;11059:2;5003:9;4999:18;4986:32;11161:18;5030:6;5027:30;5024:2;;;-1:-1;;5060:12;5024:2;5105:55;5156:3;5147:6;5136:9;5132:22;5105:55;;;11059:2;5087:16;;5080:81;-1:-1;5091:5;;11021:290;-1:-1;;;;;11021:290;11318:373;;11445:2;11433:9;11424:7;11420:23;11416:32;11413:2;;;-1:-1;;11451:12;11413:2;11509:17;11496:31;11547:18;11539:6;11536:30;11533:2;;;-1:-1;;11569:12;11533:2;11599:76;11667:7;11658:6;11647:9;11643:22;11599:76;;11946:701;;;;12103:2;12091:9;12082:7;12078:23;12074:32;12071:2;;;-1:-1;;12109:12;12071:2;7493:6;7480:20;12161:63;;12289:2;12278:9;12274:18;12261:32;12313:18;;12305:6;12302:30;12299:2;;;-1:-1;;12335:12;12299:2;12365:62;12419:7;12410:6;12399:9;12395:22;12365:62;;;12355:72;;12492:2;12481:9;12477:18;12464:32;12450:46;;12313:18;12508:6;12505:30;12502:2;;;-1:-1;;12538:12;12502:2;;12568:63;12623:7;12614:6;12603:9;12599:22;12568:63;;;12558:73;;;12065:582;;;;;;15443:343;;15585:5;34685:12;35771:6;35766:3;35759:19;15678:52;15723:6;35808:4;35803:3;35799:14;35808:4;15704:5;15700:16;15678:52;;;38097:2;38077:14;38093:7;38073:28;15742:39;;;;35808:4;15742:39;;15533:253;-1:-1;;15533:253;22988:1078;;23212:15;23206:22;23135:4;23248:13;23241:37;23293:67;23135:4;23130:3;23126:14;23341:12;23293:67;;;23450:4;;;37386:10;23450:4;23443:5;23439:16;23433:23;37375:22;23450:4;23512:3;23508:14;25494:36;23618:4;23611:5;23607:16;23601:23;23670:3;23664:4;23660:14;23618:4;23648:3;23644:14;23637:38;23690:109;13419:5;34685:12;35771:6;35766:3;35759:19;23450:4;35803:3;35799:14;13431:88;;23450:4;;13576:6;13572:17;35803:3;13563:27;;23450:4;13662:5;34361:14;-1:-1;13707:10;;13701:341;13726:6;13723:1;13720:13;13701:341;;;13778:20;35803:3;13782:4;13778:20;;13773:3;13766:33;12766:60;12822:3;13833:6;13827:13;12766:60;;;13748:1;13741:9;;;;;14021:14;;;;13847:82;-1:-1;35485:14;;13701:341;;;13705:14;23887:4;23880:5;23876:16;23870:23;23850:43;;23939:3;23933:4;23929:14;23887:4;23917:3;23913:14;23906:38;23959:69;24023:4;24009:12;23959:69;;;24050:11;23108:958;-1:-1;;;;;;;;;23108:958;25656:401;;15953:5;34685:12;16064:52;16109:6;16104:3;16097:4;16090:5;16086:16;16064:52;;;16128:16;;;;15235:37;;;-1:-1;16097:4;26020:12;;25809:248;-1:-1;25809:248;26064:213;37180:42;37169:54;;;;13153:37;;26182:2;26167:18;;26153:124;26284:437;;26490:2;;26479:9;26475:18;26490:2;26511:17;26504:47;26565:146;14406:5;34685:12;35771:6;35766:3;35759:19;35799:14;26479:9;35799:14;14418:112;;35799:14;26490:2;14587:6;14583:17;26479:9;14574:27;;14562:39;;26490:2;14691:5;34361:14;-1:-1;14730:387;14755:6;14752:1;14749:13;14730:387;;;14807:20;26479:9;14811:4;14807:20;;14802:3;14795:33;12980:88;13064:3;14862:6;14856:13;12980:88;;;14876:110;-1:-1;15096:14;;;;35485;;;;14777:1;14770:9;14730:387;;;-1:-1;26557:154;;26461:260;-1:-1;;;;;;;26461:260;26728:539;15235:37;;;37480:4;37469:16;;;;27087:2;27072:18;;25609:35;27170:2;27155:18;;15235:37;27253:2;27238:18;;15235:37;26926:3;26911:19;;26897:370;27274:691;;27504:2;27525:17;27518:47;27579:76;27504:2;27493:9;27489:18;27641:6;27579:76;;;27703:9;27697:4;27693:20;27688:2;27677:9;27673:18;27666:48;27728:76;27799:4;27790:6;27728:76;;;27852:9;27846:4;27842:20;27837:2;27826:9;27822:18;27815:48;27877:78;27950:4;27941:6;27877:78;;;27869:86;27475:490;-1:-1;;;;;;;27475:490;27972:293;;28106:2;28127:17;28120:47;28181:74;28106:2;28095:9;28091:18;28241:6;28181:74;;;28173:82;28077:188;-1:-1;;;28077:188;28272:710;28563:2;28577:47;;;18099:1;28548:18;;;35759:19;18134:66;35799:14;;;18114:87;18220:12;35808:4;28786:18;;28779:48;;;17729:1;18220:12;;;35759:19;17764:66;35799:14;;;17744:87;17850:12;;;28534:448;28989:407;29180:2;29194:47;;;18471:2;29165:18;;;35759:19;18507:66;35799:14;;;18487:87;18593:12;;;29151:245;29403:407;29594:2;29608:47;;;18844:2;29579:18;;;35759:19;18880:66;35799:14;;;18860:87;18966:12;;;29565:245;29817:381;;29995:2;30016:17;30009:47;20161:15;20155:22;20088:4;29995:2;29984:9;29980:18;20190:37;19281:15;19275:22;20079:14;29984:9;20079:14;15235:37;29995:2;19436:5;19432:16;19426:23;19210:4;19469:14;29984:9;19469:14;19462:38;19515:67;19201:14;29984:9;19201:14;19563:12;19515:67;;;19666:4;19659:5;19655:16;19649:23;19629:43;;19708:14;29984:9;19712:4;19708:14;;19692;29984:9;19692:14;19685:38;19738:69;19802:4;19788:12;19738:69;;;19829:11;;;;29995:2;20428:5;20424:16;20418:23;20477:14;;29984:9;20481:4;20477:14;;19666:4;29984:9;20461:14;20454:38;20507:67;20569:4;20555:12;20507:67;;;19666:4;20653:5;20649:16;20643:23;20623:43;;20477:14;29984:9;20706:4;20702:14;;19210:4;29984:9;20686:14;20679:38;20732:67;20794:4;20780:12;20732:67;;;20724:75;;;19210:4;20878:5;20874:16;20868:23;20848:43;;20477:14;29984:9;20931:4;20927:14;;20088:4;29984:9;20911:14;20904:38;;20957:69;21021:4;21007:12;20957:69;;;30062:126;29966:232;-1:-1;;;;;29966:232;30205:453;21492:22;;22809;15235:37;;30443:2;30428:18;;30414:244;30665:377;;30841:2;30862:17;30855:47;22009:15;22003:22;21930:4;30841:2;30830:9;30826:18;22038:37;22090:95;21921:14;30830:9;21921:14;22166:12;22090:95;;;30841:2;22270:5;22266:16;22260:23;22240:43;;22319:14;30830:9;22323:4;22319:14;;21930:4;30830:9;22303:14;22296:38;22349:69;22413:4;22399:12;22349:69;;31049:353;;31213:2;31234:17;31227:47;31288:104;31213:2;31202:9;31198:18;31378:6;31288:104;;31409:213;15235:37;;;31527:2;31512:18;;31498:124;31629:412;;15265:5;15242:3;15235:37;31795:2;31913;31902:9;31898:18;31891:48;31953:78;31795:2;31784:9;31780:18;32017:6;31953:78;;32048:256;32110:2;32104:9;32136:17;;;32211:18;32196:34;;32232:22;;;32193:62;32190:2;;;32268:1;;32258:12;32190:2;32110;32277:22;32088:216;;-1:-1;32088:216;32311:305;;32471:18;32463:6;32460:30;32457:2;;;-1:-1;;32493:12;32457:2;-1:-1;32538:4;32526:17;;;32591:15;;32394:222;37652:268;37717:1;37724:101;37738:6;37735:1;37732:13;37724:101;;;37805:11;;;37799:18;37786:11;;;37779:39;37760:2;37753:10;37724:101;;;37840:6;37837:1;37834:13;37831:2;;;37717:1;37896:6;37891:3;37887:16;37880:27;37831:2;;37701:219;;;;38114:117;37180:42;38201:5;37169:54;38176:5;38173:35;38163:2;;38222:1;;38212:12" } } }, @@ -813,12 +813,12 @@ } }, "sourceCodes": { - "AbiGenDummy.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma experimental ABIEncoderV2;\n\npragma solidity ^0.5.5;\n\n\ncontract AbiGenDummy\n{\n\n uint256 constant internal SOME_CONSTANT = 1234;\n string constant internal REVERT_REASON = \"REVERT_WITH_CONSTANT\";\n string constant internal REQUIRE_REASON = \"REQUIRE_WITH_CONSTANT\";\n\n function simplePureFunction ()\n public\n pure\n returns (uint256 result)\n {\n return 1;\n }\n\n function simplePureFunctionWithInput (uint256 x)\n public\n pure\n returns (uint256 sum)\n {\n return 1 + x;\n }\n\n function pureFunctionWithConstant ()\n public\n pure\n returns (uint256 someConstant)\n {\n return SOME_CONSTANT;\n }\n\n function simpleRevert ()\n public\n pure\n {\n revert(\"SIMPLE_REVERT\");\n }\n\n function revertWithConstant ()\n public\n pure\n {\n revert(REVERT_REASON);\n }\n\n function simpleRequire ()\n public\n pure\n {\n require(0 > 1, \"SIMPLE_REQUIRE\");\n }\n\n function requireWithConstant ()\n public\n pure\n {\n require(0 > 1, REQUIRE_REASON);\n }\n\n /// @dev test that devdocs will be generated and\n /// that multiline devdocs will look okay\n /// @param hash description of some hash. Let's make this line super long to demonstrate hanging indents for method params. It has to be more than one hundred twenty columns.\n /// @param v some v, recovery id\n /// @param r ECDSA r output\n /// @param s ECDSA s output\n /// @return the signerAddress that created this signature. this line too is super long in order to demonstrate the proper hanging indentation in generated code.\n function ecrecoverFn(bytes32 hash, uint8 v, bytes32 r, bytes32 s)\n public\n pure\n returns (address signerAddress)\n {\n bytes memory prefix = \"\\x19Ethereum Signed Message:\\n32\";\n bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, hash));\n return ecrecover(prefixedHash, v, r, s);\n }\n\n // test: generated code should normalize address inputs to lowercase\n // add extra inputs to make sure it works with address in any position\n function withAddressInput(address x, uint256 a, uint256 b, address y, uint256 c)\n public\n pure\n returns (address z)\n {\n return x;\n }\n\n function acceptsBytes(bytes memory a) public pure {}\n\n /// @dev a method that accepts an array of bytes\n /// @param a the array of bytes being accepted\n function acceptsAnArrayOfBytes(bytes[] memory a) public pure {}\n\n struct Struct {\n bytes someBytes;\n uint32 anInteger;\n bytes[] aDynamicArrayOfBytes;\n string aString;\n }\n\n function structInput(Struct memory s) public pure {}\n\n /// @dev a method that returns a struct\n /// @return a Struct struct\n function structOutput() public pure returns(Struct memory s) {\n bytes[] memory byteArray = new bytes[](2);\n byteArray[0] = \"0x123\";\n byteArray[1] = \"0x321\";\n\n return Struct({\n someBytes: \"0x123\",\n anInteger: 5,\n aDynamicArrayOfBytes: byteArray,\n aString: \"abc\"\n });\n }\n\n function methodReturningArrayOfStructs() public pure returns(Struct[] memory) {}\n\n struct NestedStruct {\n Struct innerStruct;\n string description;\n }\n\n function nestedStructInput(NestedStruct memory n) public pure {}\n function nestedStructOutput() public pure returns(NestedStruct memory) {}\n\n struct StructNotDirectlyUsedAnywhere {\n uint256 aField;\n }\n\n struct NestedStructWithInnerStructNotUsedElsewhere {\n StructNotDirectlyUsedAnywhere innerStruct;\n }\n\n function methodUsingNestedStructWithInnerStructNotUsedElsewhere()\n public pure returns(NestedStructWithInnerStructNotUsedElsewhere memory)\n {}\n\n uint someState;\n function nonPureMethod() public returns(uint) { return someState += 1; }\n function nonPureMethodThatReturnsNothing() public { someState += 1; }\n\n function methodReturningMultipleValues()\n public pure returns (uint256, string memory)\n {\n return (1, \"hello\");\n }\n\n function overloadedMethod(int a) public pure {}\n function overloadedMethod(string memory a) public pure {}\n\n\n event Withdrawal(address indexed _owner, uint _value);\n\n function withdraw(uint wad) public {\n emit Withdrawal(msg.sender, wad);\n }\n\n event SimpleEvent(bytes someBytes, string someString);\n\n function emitSimpleEvent() public {\n emit SimpleEvent(\n hex'12345678',\n \"lorem\"\n );\n }\n\n // begin tests for `decodeTransactionData`, `decodeReturnData`\n /// @dev complex input is dynamic and more difficult to decode than simple input.\n struct ComplexInput {\n uint256 foo;\n bytes bar;\n string car;\n }\n\n /// @dev complex input is dynamic and more difficult to decode than simple input.\n struct ComplexOutput {\n ComplexInput input;\n bytes lorem;\n bytes ipsum;\n string dolor;\n }\n\n /// @dev Tests decoding when both input and output are empty.\n function noInputNoOutput()\n public\n pure\n {\n // NOP\n require(true == true);\n }\n\n /// @dev Tests decoding when input is empty and output is non-empty.\n function noInputSimpleOutput()\n public\n pure\n returns (uint256)\n {\n return 1991;\n }\n\n /// @dev Tests decoding when input is not empty but output is empty.\n function simpleInputNoOutput(uint256)\n public\n pure\n {\n // NOP\n require(true == true);\n }\n\n /// @dev Tests decoding when both input and output are non-empty.\n function simpleInputSimpleOutput(uint256)\n public\n pure\n returns (uint256)\n {\n return 1991;\n }\n\n /// @dev Tests decoding when the input and output are complex.\n function complexInputComplexOutput(ComplexInput memory complexInput)\n public\n pure\n returns (ComplexOutput memory)\n {\n return ComplexOutput({\n input: complexInput,\n lorem: hex'12345678',\n ipsum: hex'87654321',\n dolor: \"amet\"\n });\n }\n\n /// @dev Tests decoding when the input and output are complex and have more than one argument.\n function multiInputMultiOutput(\n uint256,\n bytes memory,\n string memory\n )\n public\n pure\n returns (\n bytes memory,\n bytes memory,\n string memory\n )\n {\n return (\n hex'12345678',\n hex'87654321',\n \"amet\"\n );\n }\n\n // end tests for `decodeTransactionData`, `decodeReturnData`\n}\n" + "AbiGenDummy.sol": "/*\n\n Copyright 2019 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma experimental ABIEncoderV2;\n\npragma solidity ^0.5.5;\n\n\ncontract AbiGenDummy\n{\n\n uint256 constant internal SOME_CONSTANT = 1234;\n string constant internal REVERT_REASON = \"REVERT_WITH_CONSTANT\";\n string constant internal REQUIRE_REASON = \"REQUIRE_WITH_CONSTANT\";\n\n function simplePureFunction ()\n public\n pure\n returns (uint256 result)\n {\n return 1;\n }\n\n function simplePureFunctionWithInput (uint256 x)\n public\n pure\n returns (uint256 sum)\n {\n return 1 + x;\n }\n\n function pureFunctionWithConstant ()\n public\n pure\n returns (uint256 someConstant)\n {\n return SOME_CONSTANT;\n }\n\n function simpleRevert ()\n public\n pure\n {\n revert(\"SIMPLE_REVERT\");\n }\n\n function revertWithConstant ()\n public\n pure\n {\n revert(REVERT_REASON);\n }\n\n function simpleRequire ()\n public\n pure\n {\n require(0 > 1, \"SIMPLE_REQUIRE\");\n }\n\n function requireWithConstant ()\n public\n pure\n {\n require(0 > 1, REQUIRE_REASON);\n }\n\n /// @dev test that devdocs will be generated and\n /// that multiline devdocs will look okay\n /// @param hash description of some hash. Let's make this line super long to demonstrate hanging indents for method params. It has to be more than one hundred twenty columns.\n /// @param v some v, recovery id\n /// @param r ECDSA r output\n /// @param s ECDSA s output\n /// @return the signerAddress that created this signature. this line too is super long in order to demonstrate the proper hanging indentation in generated code.\n function ecrecoverFn(bytes32 hash, uint8 v, bytes32 r, bytes32 s)\n public\n pure\n returns (address signerAddress)\n {\n bytes memory prefix = \"\\x19Ethereum Signed Message:\\n32\";\n bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, hash));\n return ecrecover(prefixedHash, v, r, s);\n }\n\n // test: generated code should normalize address inputs to lowercase\n // add extra inputs to make sure it works with address in any position\n function withAddressInput(address x, uint256 a, uint256 b, address y, uint256 c)\n public\n pure\n returns (address z)\n {\n return x;\n }\n\n function acceptsBytes(bytes memory a) public pure {}\n\n /// @dev a method that accepts an array of bytes\n /// @param a the array of bytes being accepted\n function acceptsAnArrayOfBytes(bytes[] memory a) public pure {}\n\n struct Struct {\n bytes someBytes;\n uint32 anInteger;\n bytes[] aDynamicArrayOfBytes;\n string aString;\n }\n\n function structInput(Struct memory s) public pure {}\n\n /// @dev a method that returns a struct\n /// @return a Struct struct\n function structOutput() public pure returns(Struct memory s) {\n bytes[] memory byteArray = new bytes[](2);\n byteArray[0] = \"0x123\";\n byteArray[1] = \"0x321\";\n\n return Struct({\n someBytes: \"0x123\",\n anInteger: 5,\n aDynamicArrayOfBytes: byteArray,\n aString: \"abc\"\n });\n }\n\n function methodReturningArrayOfStructs() public pure returns(Struct[] memory) {}\n\n struct NestedStruct {\n Struct innerStruct;\n string description;\n }\n\n function nestedStructInput(NestedStruct memory n) public pure {}\n function nestedStructOutput() public pure returns(NestedStruct memory) {}\n\n struct StructNotDirectlyUsedAnywhere {\n uint256 aField;\n }\n\n struct NestedStructWithInnerStructNotUsedElsewhere {\n StructNotDirectlyUsedAnywhere innerStruct;\n }\n\n function methodUsingNestedStructWithInnerStructNotUsedElsewhere()\n public pure returns(NestedStructWithInnerStructNotUsedElsewhere memory)\n {}\n\n uint someState;\n function nonPureMethod() public returns(uint) { return someState += 1; }\n function nonPureMethodThatReturnsNothing() public { someState += 1; }\n\n function methodReturningMultipleValues()\n public pure returns (uint256, string memory)\n {\n return (1, \"hello\");\n }\n\n function overloadedMethod(int a) public pure {}\n function overloadedMethod(string memory a) public pure {}\n\n\n event Withdrawal(address indexed _owner, uint _value);\n\n function withdraw(uint wad) public {\n emit Withdrawal(msg.sender, wad);\n }\n\n event SimpleEvent(bytes someBytes, string someString);\n\n function emitSimpleEvent() public {\n emit SimpleEvent(\n hex'12345678',\n \"lorem\"\n );\n }\n\n // begin tests for `decodeTransactionData`, `decodeReturnData`\n /// @dev complex input is dynamic and more difficult to decode than simple input.\n struct ComplexInput {\n uint256 foo;\n bytes bar;\n string car;\n }\n\n /// @dev complex input is dynamic and more difficult to decode than simple input.\n struct ComplexOutput {\n ComplexInput input;\n bytes lorem;\n bytes ipsum;\n string dolor;\n }\n\n /// @dev Tests decoding when both input and output are empty.\n function noInputNoOutput()\n public\n pure\n {\n // NOP\n require(true == true);\n }\n\n /// @dev Tests decoding when input is empty and output is non-empty.\n function noInputSimpleOutput()\n public\n pure\n returns (uint256)\n {\n return 1991;\n }\n\n /// @dev Tests decoding when input is not empty but output is empty.\n function simpleInputNoOutput(uint256)\n public\n pure\n {\n // NOP\n require(true == true);\n }\n\n /// @dev Tests decoding when both input and output are non-empty.\n function simpleInputSimpleOutput(uint256)\n public\n pure\n returns (uint256)\n {\n return 1991;\n }\n\n /// @dev Tests decoding when the input and output are complex.\n function complexInputComplexOutput(ComplexInput memory complexInput)\n public\n pure\n returns (ComplexOutput memory)\n {\n return ComplexOutput({\n input: complexInput,\n lorem: hex'12345678',\n ipsum: hex'87654321',\n dolor: \"amet\"\n });\n }\n\n /// @dev Tests decoding when the input and output are complex and have more than one argument.\n function multiInputMultiOutput(\n uint256,\n bytes memory,\n string memory\n )\n public\n pure\n returns (\n bytes memory,\n bytes memory,\n string memory\n )\n {\n return (\n hex'12345678',\n hex'87654321',\n \"amet\"\n );\n }\n\n // end tests for `decodeTransactionData`, `decodeReturnData`\n}\n" }, - "sourceTreeHashHex": "0x99694ecb2e7ed146b4d0030335f82b2190ee0f4b2639514f3aebdd99ae2decf0", + "sourceTreeHashHex": "0xe85eeae56e9951f6082d8885c3b93cdfd91334f45394bd3e841a28cfe287062c", "compiler": { "name": "solc", - "version": "soljson-v0.5.11+commit.c082d0b4.js", + "version": "soljson-v0.5.12+commit.7709ece9.js", "settings": { "optimizer": { "enabled": true, diff --git a/packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json b/packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json index 047fc3ea79..162cc32ce3 100644 --- a/packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json +++ b/packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json @@ -9,14 +9,14 @@ "evm": { "bytecode": { "linkReferences": {}, - "object": "0x60556023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea265627a7a72305820b14322cd05aa1dcae66812e472d3ab85cced78118ea7f9a5098d073b2accc45964736f6c634300050a0032", - "opcodes": "PUSH1 0x55 PUSH1 0x23 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x16 JUMPI INVALID JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH6 0x627A7A723058 KECCAK256 0xb1 NUMBER 0x22 0xcd SDIV 0xaa SAR 0xca 0xe6 PUSH9 0x12E472D3AB85CCED78 GT DUP15 0xa7 0xf9 0xa5 MULMOD DUP14 SMOD EXTCODESIZE 0x2a 0xcc 0xc4 MSIZE PUSH5 0x736F6C6343 STOP SDIV EXP STOP ORIGIN ", + "object": "0x60556023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea265627a7a72315820725ed7971b4c6a8dad5ee5e2dfb2083612f69a239b2ad69690a85c8e21d5f23864736f6c634300050c0032", + "opcodes": "PUSH1 0x55 PUSH1 0x23 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x16 JUMPI INVALID JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 PUSH19 0x5ED7971B4C6A8DAD5EE5E2DFB2083612F69A23 SWAP12 0x2a 0xd6 SWAP7 SWAP1 0xa8 0x5c DUP15 0x21 0xd5 CALLCODE CODESIZE PUSH5 0x736F6C6343 STOP SDIV 0xc STOP ORIGIN ", "sourceMap": "606:385:1:-;;132:2:-1;166:7;155:9;146:7;137:37;255:7;249:14;246:1;241:23;235:4;232:33;222:2;;269:9;222:2;293:9;290:1;283:20;323:4;314:7;306:22;347:7;338;331:24" }, "deployedBytecode": { "linkReferences": {}, - "object": "0x73000000000000000000000000000000000000000030146080604052600080fdfea265627a7a72305820b14322cd05aa1dcae66812e472d3ab85cced78118ea7f9a5098d073b2accc45964736f6c634300050a0032", - "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH6 0x627A7A723058 KECCAK256 0xb1 NUMBER 0x22 0xcd SDIV 0xaa SAR 0xca 0xe6 PUSH9 0x12E472D3AB85CCED78 GT DUP15 0xa7 0xf9 0xa5 MULMOD DUP14 SMOD EXTCODESIZE 0x2a 0xcc 0xc4 MSIZE PUSH5 0x736F6C6343 STOP SDIV EXP STOP ORIGIN ", + "object": "0x73000000000000000000000000000000000000000030146080604052600080fdfea265627a7a72315820725ed7971b4c6a8dad5ee5e2dfb2083612f69a239b2ad69690a85c8e21d5f23864736f6c634300050c0032", + "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 PUSH19 0x5ED7971B4C6A8DAD5EE5E2DFB2083612F69A23 SWAP12 0x2a 0xd6 SWAP7 SWAP1 0xa8 0x5c DUP15 0x21 0xd5 CALLCODE CODESIZE PUSH5 0x736F6C6343 STOP SDIV 0xc STOP ORIGIN ", "sourceMap": "606:385:1:-;;;;;;;;" } } @@ -29,10 +29,10 @@ "sourceCodes": { "LibDummy.sol": "/*\n\n Copyright 2019 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity ^0.5.5;\n\n\nlibrary LibDummy {\n\n using LibDummy for uint256;\n uint256 constant internal SOME_CONSTANT = 1234;\n\n function addOne (uint256 x)\n internal\n pure\n returns (uint256 sum)\n {\n return x + 1;\n }\n\n function addConstant (uint256 x)\n internal\n pure\n returns (uint256 someConstant)\n {\n return x + SOME_CONSTANT;\n }\n}\n" }, - "sourceTreeHashHex": "0xe9654f3d694bd3513dddbcc0ccd7a75739bf63dc92b974e163f191122416fdb6", + "sourceTreeHashHex": "0xd7314c6b96d3195f1d6823802c5a01b0090fe630f4908495ba19d9c298b3ded1", "compiler": { "name": "solc", - "version": "soljson-v0.5.10+commit.5a6ea5b1.js", + "version": "soljson-v0.5.12+commit.7709ece9.js", "settings": { "optimizer": { "enabled": true, diff --git a/packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json b/packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json index b020c5e896..b2c6c86742 100644 --- a/packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json +++ b/packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json @@ -7,6 +7,7 @@ "constant": true, "inputs": [ { + "internalType": "uint256", "name": "x", "type": "uint256" } @@ -14,6 +15,7 @@ "name": "publicAddConstant", "outputs": [ { + "internalType": "uint256", "name": "result", "type": "uint256" } @@ -26,6 +28,7 @@ "constant": true, "inputs": [ { + "internalType": "uint256", "name": "x", "type": "uint256" } @@ -33,6 +36,7 @@ "name": "publicAddOne", "outputs": [ { + "internalType": "uint256", "name": "result", "type": "uint256" } @@ -48,14 +52,14 @@ "evm": { "bytecode": { "linkReferences": {}, - "object": "0x608060405234801561001057600080fd5b5060d78061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806322935e921460375780632b82fdf0146063575b600080fd5b605160048036036020811015604b57600080fd5b5035607d565b60408051918252519081900360200190f35b605160048036036020811015607757600080fd5b5035608c565b60006086826095565b92915050565b6000608682609c565b6104d20190565b6001019056fea265627a7a72305820ddb720d14b34694daaefebcbd729af6ae04fa2232481812dd8fde63d6a4c32c164736f6c634300050a0032", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0xD7 DUP1 PUSH2 0x1F PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH1 0x32 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x22935E92 EQ PUSH1 0x37 JUMPI DUP1 PUSH4 0x2B82FDF0 EQ PUSH1 0x63 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x51 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH1 0x4B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH1 0x7D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST PUSH1 0x51 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH1 0x77 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH1 0x8C JUMP JUMPDEST PUSH1 0x0 PUSH1 0x86 DUP3 PUSH1 0x95 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x86 DUP3 PUSH1 0x9C JUMP JUMPDEST PUSH2 0x4D2 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 JUMP INVALID LOG2 PUSH6 0x627A7A723058 KECCAK256 0xdd 0xb7 KECCAK256 0xd1 0x4b CALLVALUE PUSH10 0x4DAAEFEBCBD729AF6AE0 0x4f LOG2 0x23 0x24 DUP2 DUP2 0x2d 0xd8 REVERT 0xe6 RETURNDATASIZE PUSH11 0x4C32C164736F6C63430005 EXP STOP ORIGIN ", + "object": "0x608060405234801561001057600080fd5b5060d78061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806322935e921460375780632b82fdf0146063575b600080fd5b605160048036036020811015604b57600080fd5b5035607d565b60408051918252519081900360200190f35b605160048036036020811015607757600080fd5b5035608c565b60006086826095565b92915050565b6000608682609c565b6104d20190565b6001019056fea265627a7a72315820863e53f0da474a1275d583d88852313fe053941e79bddd5279abd812b31e020c64736f6c634300050c0032", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0xD7 DUP1 PUSH2 0x1F PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH1 0x32 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x22935E92 EQ PUSH1 0x37 JUMPI DUP1 PUSH4 0x2B82FDF0 EQ PUSH1 0x63 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x51 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH1 0x4B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH1 0x7D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST PUSH1 0x51 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH1 0x77 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH1 0x8C JUMP JUMPDEST PUSH1 0x0 PUSH1 0x86 DUP3 PUSH1 0x95 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x86 DUP3 PUSH1 0x9C JUMP JUMPDEST PUSH2 0x4D2 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 JUMP INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 DUP7 RETURNDATACOPY MSTORE8 CREATE 0xda SELFBALANCE 0x4a SLT PUSH22 0xD583D88852313FE053941E79BDDD5279ABD812B31E02 0xc PUSH5 0x736F6C6343 STOP SDIV 0xc STOP ORIGIN ", "sourceMap": "632:346:2:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;632:346:2;;;;;;;" }, "deployedBytecode": { "linkReferences": {}, - "object": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c806322935e921460375780632b82fdf0146063575b600080fd5b605160048036036020811015604b57600080fd5b5035607d565b60408051918252519081900360200190f35b605160048036036020811015607757600080fd5b5035608c565b60006086826095565b92915050565b6000608682609c565b6104d20190565b6001019056fea265627a7a72305820ddb720d14b34694daaefebcbd729af6ae04fa2232481812dd8fde63d6a4c32c164736f6c634300050a0032", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH1 0x32 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x22935E92 EQ PUSH1 0x37 JUMPI DUP1 PUSH4 0x2B82FDF0 EQ PUSH1 0x63 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x51 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH1 0x4B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH1 0x7D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST PUSH1 0x51 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH1 0x77 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH1 0x8C JUMP JUMPDEST PUSH1 0x0 PUSH1 0x86 DUP3 PUSH1 0x95 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x86 DUP3 PUSH1 0x9C JUMP JUMPDEST PUSH2 0x4D2 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 JUMP INVALID LOG2 PUSH6 0x627A7A723058 KECCAK256 0xdd 0xb7 KECCAK256 0xd1 0x4b CALLVALUE PUSH10 0x4DAAEFEBCBD729AF6AE0 0x4f LOG2 0x23 0x24 DUP2 DUP2 0x2d 0xd8 REVERT 0xe6 RETURNDATASIZE PUSH11 0x4C32C164736F6C63430005 EXP STOP ORIGIN ", + "object": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c806322935e921460375780632b82fdf0146063575b600080fd5b605160048036036020811015604b57600080fd5b5035607d565b60408051918252519081900360200190f35b605160048036036020811015607757600080fd5b5035608c565b60006086826095565b92915050565b6000608682609c565b6104d20190565b6001019056fea265627a7a72315820863e53f0da474a1275d583d88852313fe053941e79bddd5279abd812b31e020c64736f6c634300050c0032", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH1 0x32 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x22935E92 EQ PUSH1 0x37 JUMPI DUP1 PUSH4 0x2B82FDF0 EQ PUSH1 0x63 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x51 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH1 0x4B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH1 0x7D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST PUSH1 0x51 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH1 0x77 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH1 0x8C JUMP JUMPDEST PUSH1 0x0 PUSH1 0x86 DUP3 PUSH1 0x95 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x86 DUP3 PUSH1 0x9C JUMP JUMPDEST PUSH2 0x4D2 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 JUMP INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 DUP7 RETURNDATACOPY MSTORE8 CREATE 0xda SELFBALANCE 0x4a SLT PUSH22 0xD583D88852313FE053941E79BDDD5279ABD812B31E02 0xc PUSH5 0x736F6C6343 STOP SDIV 0xc STOP ORIGIN ", "sourceMap": "632:346:2:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;632:346:2;;;;;;;;;;;;;;;;;;;;;;;;833:143;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;833:143:2;;:::i;:::-;;;;;;;;;;;;;;;;694:133;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;694:133:2;;:::i;833:143::-;917:14;954:15;:1;:13;:15::i;:::-;947:22;833:143;-1:-1:-1;;833:143:2:o;694:133::-;773:14;810:10;:1;:8;:10::i;842:147:1:-;704:4;965:17;;842:147::o;715:121::-;828:1;824:5;;715:121::o" } } @@ -72,10 +76,10 @@ "TestLibDummy.sol": "/*\n\n Copyright 2019 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity ^0.5.5;\n\nimport \"./LibDummy.sol\";\n\n\ncontract TestLibDummy {\n\n using LibDummy for uint256;\n\n function publicAddOne (uint256 x)\n public\n pure\n returns (uint256 result)\n {\n return x.addOne();\n }\n\n function publicAddConstant (uint256 x)\n public\n pure\n returns (uint256 result)\n {\n return x.addConstant();\n }\n}\n", "LibDummy.sol": "/*\n\n Copyright 2019 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity ^0.5.5;\n\n\nlibrary LibDummy {\n\n using LibDummy for uint256;\n uint256 constant internal SOME_CONSTANT = 1234;\n\n function addOne (uint256 x)\n internal\n pure\n returns (uint256 sum)\n {\n return x + 1;\n }\n\n function addConstant (uint256 x)\n internal\n pure\n returns (uint256 someConstant)\n {\n return x + SOME_CONSTANT;\n }\n}\n" }, - "sourceTreeHashHex": "0xca99c7d7de9db975842de61e6ec01debdada66cf91d28fc3f2983de3011560dc", + "sourceTreeHashHex": "0xd7efa9dfeb2bbdec2bead8b892d1288c1398b34216d26c6a48bffb25c692bbc0", "compiler": { "name": "solc", - "version": "soljson-v0.5.10+commit.5a6ea5b1.js", + "version": "soljson-v0.5.12+commit.7709ece9.js", "settings": { "optimizer": { "enabled": true, diff --git a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py index 3982f02477..f3aead82fe 100644 --- a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py @@ -46,7 +46,7 @@ class AbiGenDummyValidator( # type: ignore pass -class Tuple0x246f9407(TypedDict): +class Tuple0xf95128ef(TypedDict): """Python representation of a tuple or struct. Solidity compiler output does not include the names of structs that appear @@ -62,10 +62,14 @@ class Tuple0x246f9407(TypedDict): accomplished via `str.encode("utf_8")`:code: """ - aField: int + foo: int + bar: Union[bytes, str] -class Tuple0x1b9da225(TypedDict): + car: str + + +class Tuple0xa057bf41(TypedDict): """Python representation of a tuple or struct. Solidity compiler output does not include the names of structs that appear @@ -81,10 +85,16 @@ class Tuple0x1b9da225(TypedDict): accomplished via `str.encode("utf_8")`:code: """ - innerStruct: Tuple0x246f9407 + input: Tuple0xf95128ef + lorem: Union[bytes, str] -class Tuple0xcf8ad995(TypedDict): + ipsum: Union[bytes, str] + + dolor: str + + +class Tuple0x246f9407(TypedDict): """Python representation of a tuple or struct. Solidity compiler output does not include the names of structs that appear @@ -100,16 +110,10 @@ class Tuple0xcf8ad995(TypedDict): accomplished via `str.encode("utf_8")`:code: """ - someBytes: Union[bytes, str] - - anInteger: int - - aDynamicArrayOfBytes: List[Union[bytes, str]] - - aString: str + aField: int -class Tuple0xc9bdd2d5(TypedDict): +class Tuple0x1b9da225(TypedDict): """Python representation of a tuple or struct. Solidity compiler output does not include the names of structs that appear @@ -125,12 +129,10 @@ class Tuple0xc9bdd2d5(TypedDict): accomplished via `str.encode("utf_8")`:code: """ - innerStruct: Tuple0xcf8ad995 - - description: str + innerStruct: Tuple0x246f9407 -class Tuple0xf95128ef(TypedDict): +class Tuple0xcf8ad995(TypedDict): """Python representation of a tuple or struct. Solidity compiler output does not include the names of structs that appear @@ -146,14 +148,16 @@ class Tuple0xf95128ef(TypedDict): accomplished via `str.encode("utf_8")`:code: """ - foo: int + someBytes: Union[bytes, str] - bar: Union[bytes, str] + anInteger: int - car: str + aDynamicArrayOfBytes: List[Union[bytes, str]] + aString: str -class Tuple0xa057bf41(TypedDict): + +class Tuple0xc9bdd2d5(TypedDict): """Python representation of a tuple or struct. Solidity compiler output does not include the names of structs that appear @@ -169,53 +173,9 @@ class Tuple0xa057bf41(TypedDict): accomplished via `str.encode("utf_8")`:code: """ - input: Tuple0xf95128ef - - lorem: Union[bytes, str] - - ipsum: Union[bytes, str] - - dolor: str - - -class SimpleRequireMethod(ContractMethod): - """Various interfaces to the simpleRequire method.""" - - def __init__( - self, - web3_or_provider: Union[Web3, BaseProvider], - contract_address: str, - contract_function: ContractFunction, - validator: Validator = None, - ): - """Persist instance data.""" - super().__init__(web3_or_provider, contract_address, validator) - self.underlying_method = contract_function - - def call(self, tx_params: Optional[TxParams] = None) -> None: - """Execute underlying contract method via eth_call. - - :param tx_params: transaction parameters - - """ - tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().call(tx_params.as_dict()) - - def send_transaction( - self, tx_params: Optional[TxParams] = None - ) -> Union[HexBytes, bytes]: - """Execute underlying contract method via eth_sendTransaction. - - :param tx_params: transaction parameters - - """ - tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().transact(tx_params.as_dict()) + innerStruct: Tuple0xcf8ad995 - def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: - """Estimate gas consumption of method call.""" - tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().estimateGas(tx_params.as_dict()) + description: str class AcceptsAnArrayOfBytesMethod(ContractMethod): @@ -280,8 +240,8 @@ def estimate_gas( return self.underlying_method(a).estimateGas(tx_params.as_dict()) -class SimpleInputSimpleOutputMethod(ContractMethod): - """Various interfaces to the simpleInputSimpleOutput method.""" +class AcceptsBytesMethod(ContractMethod): + """Various interfaces to the acceptsBytes method.""" def __init__( self, @@ -294,54 +254,48 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, index_0: int): - """Validate the inputs to the simpleInputSimpleOutput method.""" + def validate_and_normalize_inputs(self, a: Union[bytes, str]): + """Validate the inputs to the acceptsBytes method.""" self.validator.assert_valid( - method_name="simpleInputSimpleOutput", - parameter_name="index_0", - argument_value=index_0, + method_name="acceptsBytes", parameter_name="a", argument_value=a ) - # safeguard against fractional inputs - index_0 = int(index_0) - return index_0 + return a - def call(self, index_0: int, tx_params: Optional[TxParams] = None) -> int: + def call( + self, a: Union[bytes, str], tx_params: Optional[TxParams] = None + ) -> None: """Execute underlying contract method via eth_call. - Tests decoding when both input and output are non-empty. - :param tx_params: transaction parameters """ - (index_0) = self.validate_and_normalize_inputs(index_0) + (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(index_0).call(tx_params.as_dict()) + return self.underlying_method(a).call(tx_params.as_dict()) def send_transaction( - self, index_0: int, tx_params: Optional[TxParams] = None + self, a: Union[bytes, str], tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. - Tests decoding when both input and output are non-empty. - :param tx_params: transaction parameters """ - (index_0) = self.validate_and_normalize_inputs(index_0) + (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(index_0).transact(tx_params.as_dict()) + return self.underlying_method(a).transact(tx_params.as_dict()) def estimate_gas( - self, index_0: int, tx_params: Optional[TxParams] = None + self, a: Union[bytes, str], tx_params: Optional[TxParams] = None ) -> int: """Estimate gas consumption of method call.""" - (index_0) = self.validate_and_normalize_inputs(index_0) + (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(index_0).estimateGas(tx_params.as_dict()) + return self.underlying_method(a).estimateGas(tx_params.as_dict()) -class WithdrawMethod(ContractMethod): - """Various interfaces to the withdraw method.""" +class ComplexInputComplexOutputMethod(ContractMethod): + """Various interfaces to the complexInputComplexOutput method.""" def __init__( self, @@ -354,49 +308,64 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, wad: int): - """Validate the inputs to the withdraw method.""" + def validate_and_normalize_inputs(self, complex_input: Tuple0xf95128ef): + """Validate the inputs to the complexInputComplexOutput method.""" self.validator.assert_valid( - method_name="withdraw", parameter_name="wad", argument_value=wad + method_name="complexInputComplexOutput", + parameter_name="complexInput", + argument_value=complex_input, ) - # safeguard against fractional inputs - wad = int(wad) - return wad + return complex_input def call( - self, wad: int, tx_params: Optional[TxParams] = None - ) -> Union[None, Union[HexBytes, bytes]]: + self, + complex_input: Tuple0xf95128ef, + tx_params: Optional[TxParams] = None, + ) -> Tuple0xa057bf41: """Execute underlying contract method via eth_call. + Tests decoding when the input and output are complex. + :param tx_params: transaction parameters - :returns: the return value of the underlying method. + """ - (wad) = self.validate_and_normalize_inputs(wad) + (complex_input) = self.validate_and_normalize_inputs(complex_input) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(wad).call(tx_params.as_dict()) + return self.underlying_method(complex_input).call(tx_params.as_dict()) def send_transaction( - self, wad: int, tx_params: Optional[TxParams] = None + self, + complex_input: Tuple0xf95128ef, + tx_params: Optional[TxParams] = None, ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. + Tests decoding when the input and output are complex. + :param tx_params: transaction parameters + """ - (wad) = self.validate_and_normalize_inputs(wad) + (complex_input) = self.validate_and_normalize_inputs(complex_input) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(wad).transact(tx_params.as_dict()) + return self.underlying_method(complex_input).transact( + tx_params.as_dict() + ) def estimate_gas( - self, wad: int, tx_params: Optional[TxParams] = None + self, + complex_input: Tuple0xf95128ef, + tx_params: Optional[TxParams] = None, ) -> int: """Estimate gas consumption of method call.""" - (wad) = self.validate_and_normalize_inputs(wad) + (complex_input) = self.validate_and_normalize_inputs(complex_input) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(wad).estimateGas(tx_params.as_dict()) + return self.underlying_method(complex_input).estimateGas( + tx_params.as_dict() + ) -class MultiInputMultiOutputMethod(ContractMethod): - """Various interfaces to the multiInputMultiOutput method.""" +class EcrecoverFnMethod(ContractMethod): + """Various interfaces to the ecrecoverFn method.""" def __init__( self, @@ -410,93 +379,105 @@ def __init__( self.underlying_method = contract_function def validate_and_normalize_inputs( - self, index_0: int, index_1: Union[bytes, str], index_2: str + self, + _hash: Union[bytes, str], + v: int, + r: Union[bytes, str], + s: Union[bytes, str], ): - """Validate the inputs to the multiInputMultiOutput method.""" + """Validate the inputs to the ecrecoverFn method.""" self.validator.assert_valid( - method_name="multiInputMultiOutput", - parameter_name="index_0", - argument_value=index_0, + method_name="ecrecoverFn", + parameter_name="hash", + argument_value=_hash, ) - # safeguard against fractional inputs - index_0 = int(index_0) self.validator.assert_valid( - method_name="multiInputMultiOutput", - parameter_name="index_1", - argument_value=index_1, + method_name="ecrecoverFn", parameter_name="v", argument_value=v ) self.validator.assert_valid( - method_name="multiInputMultiOutput", - parameter_name="index_2", - argument_value=index_2, + method_name="ecrecoverFn", parameter_name="r", argument_value=r ) - return (index_0, index_1, index_2) + self.validator.assert_valid( + method_name="ecrecoverFn", parameter_name="s", argument_value=s + ) + return (_hash, v, r, s) def call( self, - index_0: int, - index_1: Union[bytes, str], - index_2: str, + _hash: Union[bytes, str], + v: int, + r: Union[bytes, str], + s: Union[bytes, str], tx_params: Optional[TxParams] = None, - ) -> Tuple[Union[bytes, str], Union[bytes, str], str]: + ) -> str: """Execute underlying contract method via eth_call. - Tests decoding when the input and output are complex and have more than - one argument. + test that devdocs will be generated and that multiline devdocs will + look okay + :param hash: description of some hash. Let's make this line super long + to demonstrate hanging indents for method params. It has to be more + than one hundred twenty columns. + :param r: ECDSA r output + :param s: ECDSA s output + :param v: some v, recovery id :param tx_params: transaction parameters - + :returns: the signerAddress that created this signature. this line too + is super long in order to demonstrate the proper hanging + indentation in generated code. """ - (index_0, index_1, index_2) = self.validate_and_normalize_inputs( - index_0, index_1, index_2 - ) + (_hash, v, r, s) = self.validate_and_normalize_inputs(_hash, v, r, s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(index_0, index_1, index_2).call( - tx_params.as_dict() - ) + return self.underlying_method(_hash, v, r, s).call(tx_params.as_dict()) def send_transaction( self, - index_0: int, - index_1: Union[bytes, str], - index_2: str, - tx_params: Optional[TxParams] = None, - ) -> Union[HexBytes, bytes]: + _hash: Union[bytes, str], + v: int, + r: Union[bytes, str], + s: Union[bytes, str], + tx_params: Optional[TxParams] = None, + ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. - Tests decoding when the input and output are complex and have more than - one argument. + test that devdocs will be generated and that multiline devdocs will + look okay + :param hash: description of some hash. Let's make this line super long + to demonstrate hanging indents for method params. It has to be more + than one hundred twenty columns. + :param r: ECDSA r output + :param s: ECDSA s output + :param v: some v, recovery id :param tx_params: transaction parameters - + :returns: the signerAddress that created this signature. this line too + is super long in order to demonstrate the proper hanging + indentation in generated code. """ - (index_0, index_1, index_2) = self.validate_and_normalize_inputs( - index_0, index_1, index_2 - ) + (_hash, v, r, s) = self.validate_and_normalize_inputs(_hash, v, r, s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(index_0, index_1, index_2).transact( + return self.underlying_method(_hash, v, r, s).transact( tx_params.as_dict() ) def estimate_gas( self, - index_0: int, - index_1: Union[bytes, str], - index_2: str, + _hash: Union[bytes, str], + v: int, + r: Union[bytes, str], + s: Union[bytes, str], tx_params: Optional[TxParams] = None, ) -> int: """Estimate gas consumption of method call.""" - (index_0, index_1, index_2) = self.validate_and_normalize_inputs( - index_0, index_1, index_2 - ) + (_hash, v, r, s) = self.validate_and_normalize_inputs(_hash, v, r, s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(index_0, index_1, index_2).estimateGas( + return self.underlying_method(_hash, v, r, s).estimateGas( tx_params.as_dict() ) -class EcrecoverFnMethod(ContractMethod): - """Various interfaces to the ecrecoverFn method.""" +class EmitSimpleEventMethod(ContractMethod): + """Various interfaces to the emitSimpleEvent method.""" def __init__( self, @@ -509,106 +490,35 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs( - self, - _hash: Union[bytes, str], - v: int, - r: Union[bytes, str], - s: Union[bytes, str], - ): - """Validate the inputs to the ecrecoverFn method.""" - self.validator.assert_valid( - method_name="ecrecoverFn", - parameter_name="hash", - argument_value=_hash, - ) - self.validator.assert_valid( - method_name="ecrecoverFn", parameter_name="v", argument_value=v - ) - self.validator.assert_valid( - method_name="ecrecoverFn", parameter_name="r", argument_value=r - ) - self.validator.assert_valid( - method_name="ecrecoverFn", parameter_name="s", argument_value=s - ) - return (_hash, v, r, s) - def call( - self, - _hash: Union[bytes, str], - v: int, - r: Union[bytes, str], - s: Union[bytes, str], - tx_params: Optional[TxParams] = None, - ) -> str: + self, tx_params: Optional[TxParams] = None + ) -> Union[None, Union[HexBytes, bytes]]: """Execute underlying contract method via eth_call. - test that devdocs will be generated and that multiline devdocs will - look okay - - :param hash: description of some hash. Let's make this line super long - to demonstrate hanging indents for method params. It has to be more - than one hundred twenty columns. - :param r: ECDSA r output - :param s: ECDSA s output - :param v: some v, recovery id :param tx_params: transaction parameters - :returns: the signerAddress that created this signature. this line too - is super long in order to demonstrate the proper hanging - indentation in generated code. + :returns: the return value of the underlying method. """ - (_hash, v, r, s) = self.validate_and_normalize_inputs(_hash, v, r, s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(_hash, v, r, s).call(tx_params.as_dict()) + return self.underlying_method().call(tx_params.as_dict()) def send_transaction( - self, - _hash: Union[bytes, str], - v: int, - r: Union[bytes, str], - s: Union[bytes, str], - tx_params: Optional[TxParams] = None, + self, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. - test that devdocs will be generated and that multiline devdocs will - look okay - - :param hash: description of some hash. Let's make this line super long - to demonstrate hanging indents for method params. It has to be more - than one hundred twenty columns. - :param r: ECDSA r output - :param s: ECDSA s output - :param v: some v, recovery id :param tx_params: transaction parameters - :returns: the signerAddress that created this signature. this line too - is super long in order to demonstrate the proper hanging - indentation in generated code. """ - (_hash, v, r, s) = self.validate_and_normalize_inputs(_hash, v, r, s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(_hash, v, r, s).transact( - tx_params.as_dict() - ) + return self.underlying_method().transact(tx_params.as_dict()) - def estimate_gas( - self, - _hash: Union[bytes, str], - v: int, - r: Union[bytes, str], - s: Union[bytes, str], - tx_params: Optional[TxParams] = None, - ) -> int: + def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: """Estimate gas consumption of method call.""" - (_hash, v, r, s) = self.validate_and_normalize_inputs(_hash, v, r, s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(_hash, v, r, s).estimateGas( - tx_params.as_dict() - ) + return self.underlying_method().estimateGas(tx_params.as_dict()) -class AcceptsBytesMethod(ContractMethod): - """Various interfaces to the acceptsBytes method.""" +class MethodReturningArrayOfStructsMethod(ContractMethod): + """Various interfaces to the methodReturningArrayOfStructs method.""" def __init__( self, @@ -621,48 +531,36 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, a: Union[bytes, str]): - """Validate the inputs to the acceptsBytes method.""" - self.validator.assert_valid( - method_name="acceptsBytes", parameter_name="a", argument_value=a - ) - return a - def call( - self, a: Union[bytes, str], tx_params: Optional[TxParams] = None - ) -> None: + self, tx_params: Optional[TxParams] = None + ) -> List[Tuple0xcf8ad995]: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters """ - (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(a).call(tx_params.as_dict()) + return self.underlying_method().call(tx_params.as_dict()) def send_transaction( - self, a: Union[bytes, str], tx_params: Optional[TxParams] = None + self, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters """ - (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(a).transact(tx_params.as_dict()) + return self.underlying_method().transact(tx_params.as_dict()) - def estimate_gas( - self, a: Union[bytes, str], tx_params: Optional[TxParams] = None - ) -> int: + def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: """Estimate gas consumption of method call.""" - (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(a).estimateGas(tx_params.as_dict()) + return self.underlying_method().estimateGas(tx_params.as_dict()) -class NoInputSimpleOutputMethod(ContractMethod): - """Various interfaces to the noInputSimpleOutput method.""" +class MethodReturningMultipleValuesMethod(ContractMethod): + """Various interfaces to the methodReturningMultipleValues method.""" def __init__( self, @@ -675,11 +573,9 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call(self, tx_params: Optional[TxParams] = None) -> int: + def call(self, tx_params: Optional[TxParams] = None) -> Tuple[int, str]: """Execute underlying contract method via eth_call. - Tests decoding when input is empty and output is non-empty. - :param tx_params: transaction parameters """ @@ -691,8 +587,6 @@ def send_transaction( ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. - Tests decoding when input is empty and output is non-empty. - :param tx_params: transaction parameters """ @@ -705,8 +599,10 @@ def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: return self.underlying_method().estimateGas(tx_params.as_dict()) -class RevertWithConstantMethod(ContractMethod): - """Various interfaces to the revertWithConstant method.""" +class MethodUsingNestedStructWithInnerStructNotUsedElsewhereMethod( + ContractMethod +): + """Various interfaces to the methodUsingNestedStructWithInnerStructNotUsedElsewhere method.""" def __init__( self, @@ -719,7 +615,7 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call(self, tx_params: Optional[TxParams] = None) -> None: + def call(self, tx_params: Optional[TxParams] = None) -> Tuple0x1b9da225: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters @@ -745,8 +641,8 @@ def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: return self.underlying_method().estimateGas(tx_params.as_dict()) -class SimpleRevertMethod(ContractMethod): - """Various interfaces to the simpleRevert method.""" +class MultiInputMultiOutputMethod(ContractMethod): + """Various interfaces to the multiInputMultiOutput method.""" def __init__( self, @@ -759,36 +655,94 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call(self, tx_params: Optional[TxParams] = None) -> None: + def validate_and_normalize_inputs( + self, index_0: int, index_1: Union[bytes, str], index_2: str + ): + """Validate the inputs to the multiInputMultiOutput method.""" + self.validator.assert_valid( + method_name="multiInputMultiOutput", + parameter_name="index_0", + argument_value=index_0, + ) + # safeguard against fractional inputs + index_0 = int(index_0) + self.validator.assert_valid( + method_name="multiInputMultiOutput", + parameter_name="index_1", + argument_value=index_1, + ) + self.validator.assert_valid( + method_name="multiInputMultiOutput", + parameter_name="index_2", + argument_value=index_2, + ) + return (index_0, index_1, index_2) + + def call( + self, + index_0: int, + index_1: Union[bytes, str], + index_2: str, + tx_params: Optional[TxParams] = None, + ) -> Tuple[Union[bytes, str], Union[bytes, str], str]: """Execute underlying contract method via eth_call. + Tests decoding when the input and output are complex and have more than + one argument. + :param tx_params: transaction parameters """ + (index_0, index_1, index_2) = self.validate_and_normalize_inputs( + index_0, index_1, index_2 + ) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().call(tx_params.as_dict()) + return self.underlying_method(index_0, index_1, index_2).call( + tx_params.as_dict() + ) def send_transaction( - self, tx_params: Optional[TxParams] = None + self, + index_0: int, + index_1: Union[bytes, str], + index_2: str, + tx_params: Optional[TxParams] = None, ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. + Tests decoding when the input and output are complex and have more than + one argument. + :param tx_params: transaction parameters """ + (index_0, index_1, index_2) = self.validate_and_normalize_inputs( + index_0, index_1, index_2 + ) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().transact(tx_params.as_dict()) + return self.underlying_method(index_0, index_1, index_2).transact( + tx_params.as_dict() + ) - def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: + def estimate_gas( + self, + index_0: int, + index_1: Union[bytes, str], + index_2: str, + tx_params: Optional[TxParams] = None, + ) -> int: """Estimate gas consumption of method call.""" + (index_0, index_1, index_2) = self.validate_and_normalize_inputs( + index_0, index_1, index_2 + ) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().estimateGas(tx_params.as_dict()) + return self.underlying_method(index_0, index_1, index_2).estimateGas( + tx_params.as_dict() + ) -class MethodUsingNestedStructWithInnerStructNotUsedElsewhereMethod( - ContractMethod -): - """Various interfaces to the methodUsingNestedStructWithInnerStructNotUsedElsewhere method.""" +class NestedStructInputMethod(ContractMethod): + """Various interfaces to the nestedStructInput method.""" def __init__( self, @@ -801,30 +755,46 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call(self, tx_params: Optional[TxParams] = None) -> Tuple0x1b9da225: + def validate_and_normalize_inputs(self, n: Tuple0xc9bdd2d5): + """Validate the inputs to the nestedStructInput method.""" + self.validator.assert_valid( + method_name="nestedStructInput", + parameter_name="n", + argument_value=n, + ) + return n + + def call( + self, n: Tuple0xc9bdd2d5, tx_params: Optional[TxParams] = None + ) -> None: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters """ + (n) = self.validate_and_normalize_inputs(n) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().call(tx_params.as_dict()) + return self.underlying_method(n).call(tx_params.as_dict()) def send_transaction( - self, tx_params: Optional[TxParams] = None + self, n: Tuple0xc9bdd2d5, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters """ + (n) = self.validate_and_normalize_inputs(n) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().transact(tx_params.as_dict()) + return self.underlying_method(n).transact(tx_params.as_dict()) - def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: + def estimate_gas( + self, n: Tuple0xc9bdd2d5, tx_params: Optional[TxParams] = None + ) -> int: """Estimate gas consumption of method call.""" + (n) = self.validate_and_normalize_inputs(n) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().estimateGas(tx_params.as_dict()) + return self.underlying_method(n).estimateGas(tx_params.as_dict()) class NestedStructOutputMethod(ContractMethod): @@ -867,8 +837,8 @@ def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: return self.underlying_method().estimateGas(tx_params.as_dict()) -class RequireWithConstantMethod(ContractMethod): - """Various interfaces to the requireWithConstant method.""" +class NoInputNoOutputMethod(ContractMethod): + """Various interfaces to the noInputNoOutput method.""" def __init__( self, @@ -884,6 +854,8 @@ def __init__( def call(self, tx_params: Optional[TxParams] = None) -> None: """Execute underlying contract method via eth_call. + Tests decoding when both input and output are empty. + :param tx_params: transaction parameters """ @@ -895,6 +867,8 @@ def send_transaction( ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. + Tests decoding when both input and output are empty. + :param tx_params: transaction parameters """ @@ -907,8 +881,8 @@ def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: return self.underlying_method().estimateGas(tx_params.as_dict()) -class WithAddressInputMethod(ContractMethod): - """Various interfaces to the withAddressInput method.""" +class NoInputSimpleOutputMethod(ContractMethod): + """Various interfaces to the noInputSimpleOutput method.""" def __init__( self, @@ -921,102 +895,79 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs( - self, x: str, a: int, b: int, y: str, c: int - ): - """Validate the inputs to the withAddressInput method.""" - self.validator.assert_valid( - method_name="withAddressInput", - parameter_name="x", - argument_value=x, - ) - x = self.validate_and_checksum_address(x) - self.validator.assert_valid( - method_name="withAddressInput", - parameter_name="a", - argument_value=a, - ) - # safeguard against fractional inputs - a = int(a) - self.validator.assert_valid( - method_name="withAddressInput", - parameter_name="b", - argument_value=b, - ) - # safeguard against fractional inputs - b = int(b) - self.validator.assert_valid( - method_name="withAddressInput", - parameter_name="y", - argument_value=y, - ) - y = self.validate_and_checksum_address(y) - self.validator.assert_valid( - method_name="withAddressInput", - parameter_name="c", - argument_value=c, - ) - # safeguard against fractional inputs - c = int(c) - return (x, a, b, y, c) - - def call( - self, - x: str, - a: int, - b: int, - y: str, - c: int, - tx_params: Optional[TxParams] = None, - ) -> str: + def call(self, tx_params: Optional[TxParams] = None) -> int: """Execute underlying contract method via eth_call. + Tests decoding when input is empty and output is non-empty. + :param tx_params: transaction parameters """ - (x, a, b, y, c) = self.validate_and_normalize_inputs(x, a, b, y, c) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(x, a, b, y, c).call(tx_params.as_dict()) + return self.underlying_method().call(tx_params.as_dict()) def send_transaction( - self, - x: str, - a: int, - b: int, - y: str, - c: int, - tx_params: Optional[TxParams] = None, + self, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. + Tests decoding when input is empty and output is non-empty. + :param tx_params: transaction parameters """ - (x, a, b, y, c) = self.validate_and_normalize_inputs(x, a, b, y, c) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(x, a, b, y, c).transact( - tx_params.as_dict() - ) + return self.underlying_method().transact(tx_params.as_dict()) - def estimate_gas( + def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: + """Estimate gas consumption of method call.""" + tx_params = super().normalize_tx_params(tx_params) + return self.underlying_method().estimateGas(tx_params.as_dict()) + + +class NonPureMethodMethod(ContractMethod): + """Various interfaces to the nonPureMethod method.""" + + def __init__( self, - x: str, - a: int, - b: int, - y: str, - c: int, - tx_params: Optional[TxParams] = None, - ) -> int: + web3_or_provider: Union[Web3, BaseProvider], + contract_address: str, + contract_function: ContractFunction, + validator: Validator = None, + ): + """Persist instance data.""" + super().__init__(web3_or_provider, contract_address, validator) + self.underlying_method = contract_function + + def call( + self, tx_params: Optional[TxParams] = None + ) -> Union[int, Union[HexBytes, bytes]]: + """Execute underlying contract method via eth_call. + + :param tx_params: transaction parameters + :returns: the return value of the underlying method. + """ + tx_params = super().normalize_tx_params(tx_params) + return self.underlying_method().call(tx_params.as_dict()) + + def send_transaction( + self, tx_params: Optional[TxParams] = None + ) -> Union[HexBytes, bytes]: + """Execute underlying contract method via eth_sendTransaction. + + :param tx_params: transaction parameters + """ + tx_params = super().normalize_tx_params(tx_params) + return self.underlying_method().transact(tx_params.as_dict()) + + def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: """Estimate gas consumption of method call.""" - (x, a, b, y, c) = self.validate_and_normalize_inputs(x, a, b, y, c) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(x, a, b, y, c).estimateGas( - tx_params.as_dict() - ) + return self.underlying_method().estimateGas(tx_params.as_dict()) -class StructInputMethod(ContractMethod): - """Various interfaces to the structInput method.""" +class NonPureMethodThatReturnsNothingMethod(ContractMethod): + """Various interfaces to the nonPureMethodThatReturnsNothing method.""" def __init__( self, @@ -1029,48 +980,35 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, s: Tuple0xcf8ad995): - """Validate the inputs to the structInput method.""" - self.validator.assert_valid( - method_name="structInput", parameter_name="s", argument_value=s - ) - return s - def call( - self, s: Tuple0xcf8ad995, tx_params: Optional[TxParams] = None - ) -> None: + self, tx_params: Optional[TxParams] = None + ) -> Union[None, Union[HexBytes, bytes]]: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters - + :returns: the return value of the underlying method. """ - (s) = self.validate_and_normalize_inputs(s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(s).call(tx_params.as_dict()) + return self.underlying_method().call(tx_params.as_dict()) def send_transaction( - self, s: Tuple0xcf8ad995, tx_params: Optional[TxParams] = None + self, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters - """ - (s) = self.validate_and_normalize_inputs(s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(s).transact(tx_params.as_dict()) + return self.underlying_method().transact(tx_params.as_dict()) - def estimate_gas( - self, s: Tuple0xcf8ad995, tx_params: Optional[TxParams] = None - ) -> int: + def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: """Estimate gas consumption of method call.""" - (s) = self.validate_and_normalize_inputs(s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(s).estimateGas(tx_params.as_dict()) + return self.underlying_method().estimateGas(tx_params.as_dict()) -class NonPureMethodMethod(ContractMethod): - """Various interfaces to the nonPureMethod method.""" +class OverloadedMethod2Method(ContractMethod): + """Various interfaces to the overloadedMethod method.""" def __init__( self, @@ -1083,35 +1021,48 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call( - self, tx_params: Optional[TxParams] = None - ) -> Union[int, Union[HexBytes, bytes]]: + def validate_and_normalize_inputs(self, a: str): + """Validate the inputs to the overloadedMethod method.""" + self.validator.assert_valid( + method_name="overloadedMethod", + parameter_name="a", + argument_value=a, + ) + return a + + def call(self, a: str, tx_params: Optional[TxParams] = None) -> None: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters - :returns: the return value of the underlying method. + """ + (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().call(tx_params.as_dict()) + return self.underlying_method(a).call(tx_params.as_dict()) def send_transaction( - self, tx_params: Optional[TxParams] = None + self, a: str, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters + """ + (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().transact(tx_params.as_dict()) + return self.underlying_method(a).transact(tx_params.as_dict()) - def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: + def estimate_gas( + self, a: str, tx_params: Optional[TxParams] = None + ) -> int: """Estimate gas consumption of method call.""" + (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().estimateGas(tx_params.as_dict()) + return self.underlying_method(a).estimateGas(tx_params.as_dict()) -class ComplexInputComplexOutputMethod(ContractMethod): - """Various interfaces to the complexInputComplexOutput method.""" +class OverloadedMethod1Method(ContractMethod): + """Various interfaces to the overloadedMethod method.""" def __init__( self, @@ -1124,64 +1075,48 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, complex_input: Tuple0xf95128ef): - """Validate the inputs to the complexInputComplexOutput method.""" + def validate_and_normalize_inputs(self, a: int): + """Validate the inputs to the overloadedMethod method.""" self.validator.assert_valid( - method_name="complexInputComplexOutput", - parameter_name="complexInput", - argument_value=complex_input, + method_name="overloadedMethod", + parameter_name="a", + argument_value=a, ) - return complex_input + return a - def call( - self, - complex_input: Tuple0xf95128ef, - tx_params: Optional[TxParams] = None, - ) -> Tuple0xa057bf41: + def call(self, a: int, tx_params: Optional[TxParams] = None) -> None: """Execute underlying contract method via eth_call. - Tests decoding when the input and output are complex. - :param tx_params: transaction parameters """ - (complex_input) = self.validate_and_normalize_inputs(complex_input) + (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(complex_input).call(tx_params.as_dict()) + return self.underlying_method(a).call(tx_params.as_dict()) def send_transaction( - self, - complex_input: Tuple0xf95128ef, - tx_params: Optional[TxParams] = None, + self, a: int, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. - Tests decoding when the input and output are complex. - :param tx_params: transaction parameters """ - (complex_input) = self.validate_and_normalize_inputs(complex_input) + (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(complex_input).transact( - tx_params.as_dict() - ) + return self.underlying_method(a).transact(tx_params.as_dict()) def estimate_gas( - self, - complex_input: Tuple0xf95128ef, - tx_params: Optional[TxParams] = None, + self, a: int, tx_params: Optional[TxParams] = None ) -> int: """Estimate gas consumption of method call.""" - (complex_input) = self.validate_and_normalize_inputs(complex_input) + (a) = self.validate_and_normalize_inputs(a) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(complex_input).estimateGas( - tx_params.as_dict() - ) + return self.underlying_method(a).estimateGas(tx_params.as_dict()) -class NoInputNoOutputMethod(ContractMethod): - """Various interfaces to the noInputNoOutput method.""" +class PureFunctionWithConstantMethod(ContractMethod): + """Various interfaces to the pureFunctionWithConstant method.""" def __init__( self, @@ -1194,11 +1129,9 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call(self, tx_params: Optional[TxParams] = None) -> None: + def call(self, tx_params: Optional[TxParams] = None) -> int: """Execute underlying contract method via eth_call. - Tests decoding when both input and output are empty. - :param tx_params: transaction parameters """ @@ -1210,8 +1143,6 @@ def send_transaction( ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. - Tests decoding when both input and output are empty. - :param tx_params: transaction parameters """ @@ -1224,8 +1155,8 @@ def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: return self.underlying_method().estimateGas(tx_params.as_dict()) -class SimplePureFunctionWithInputMethod(ContractMethod): - """Various interfaces to the simplePureFunctionWithInput method.""" +class RequireWithConstantMethod(ContractMethod): + """Various interfaces to the requireWithConstant method.""" def __init__( self, @@ -1238,50 +1169,34 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, x: int): - """Validate the inputs to the simplePureFunctionWithInput method.""" - self.validator.assert_valid( - method_name="simplePureFunctionWithInput", - parameter_name="x", - argument_value=x, - ) - # safeguard against fractional inputs - x = int(x) - return x - - def call(self, x: int, tx_params: Optional[TxParams] = None) -> int: + def call(self, tx_params: Optional[TxParams] = None) -> None: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters """ - (x) = self.validate_and_normalize_inputs(x) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(x).call(tx_params.as_dict()) + return self.underlying_method().call(tx_params.as_dict()) def send_transaction( - self, x: int, tx_params: Optional[TxParams] = None + self, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters """ - (x) = self.validate_and_normalize_inputs(x) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(x).transact(tx_params.as_dict()) + return self.underlying_method().transact(tx_params.as_dict()) - def estimate_gas( - self, x: int, tx_params: Optional[TxParams] = None - ) -> int: + def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: """Estimate gas consumption of method call.""" - (x) = self.validate_and_normalize_inputs(x) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(x).estimateGas(tx_params.as_dict()) + return self.underlying_method().estimateGas(tx_params.as_dict()) -class NonPureMethodThatReturnsNothingMethod(ContractMethod): - """Various interfaces to the nonPureMethodThatReturnsNothing method.""" +class RevertWithConstantMethod(ContractMethod): + """Various interfaces to the revertWithConstant method.""" def __init__( self, @@ -1294,13 +1209,11 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call( - self, tx_params: Optional[TxParams] = None - ) -> Union[None, Union[HexBytes, bytes]]: + def call(self, tx_params: Optional[TxParams] = None) -> None: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters - :returns: the return value of the underlying method. + """ tx_params = super().normalize_tx_params(tx_params) return self.underlying_method().call(tx_params.as_dict()) @@ -1311,6 +1224,7 @@ def send_transaction( """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters + """ tx_params = super().normalize_tx_params(tx_params) return self.underlying_method().transact(tx_params.as_dict()) @@ -1321,8 +1235,8 @@ def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: return self.underlying_method().estimateGas(tx_params.as_dict()) -class SimplePureFunctionMethod(ContractMethod): - """Various interfaces to the simplePureFunction method.""" +class SimpleInputNoOutputMethod(ContractMethod): + """Various interfaces to the simpleInputNoOutput method.""" def __init__( self, @@ -1335,34 +1249,54 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call(self, tx_params: Optional[TxParams] = None) -> int: + def validate_and_normalize_inputs(self, index_0: int): + """Validate the inputs to the simpleInputNoOutput method.""" + self.validator.assert_valid( + method_name="simpleInputNoOutput", + parameter_name="index_0", + argument_value=index_0, + ) + # safeguard against fractional inputs + index_0 = int(index_0) + return index_0 + + def call(self, index_0: int, tx_params: Optional[TxParams] = None) -> None: """Execute underlying contract method via eth_call. + Tests decoding when input is not empty but output is empty. + :param tx_params: transaction parameters """ + (index_0) = self.validate_and_normalize_inputs(index_0) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().call(tx_params.as_dict()) + return self.underlying_method(index_0).call(tx_params.as_dict()) def send_transaction( - self, tx_params: Optional[TxParams] = None + self, index_0: int, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. + Tests decoding when input is not empty but output is empty. + :param tx_params: transaction parameters """ + (index_0) = self.validate_and_normalize_inputs(index_0) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().transact(tx_params.as_dict()) + return self.underlying_method(index_0).transact(tx_params.as_dict()) - def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: + def estimate_gas( + self, index_0: int, tx_params: Optional[TxParams] = None + ) -> int: """Estimate gas consumption of method call.""" + (index_0) = self.validate_and_normalize_inputs(index_0) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().estimateGas(tx_params.as_dict()) + return self.underlying_method(index_0).estimateGas(tx_params.as_dict()) -class NestedStructInputMethod(ContractMethod): - """Various interfaces to the nestedStructInput method.""" +class SimpleInputSimpleOutputMethod(ContractMethod): + """Various interfaces to the simpleInputSimpleOutput method.""" def __init__( self, @@ -1375,50 +1309,54 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, n: Tuple0xc9bdd2d5): - """Validate the inputs to the nestedStructInput method.""" + def validate_and_normalize_inputs(self, index_0: int): + """Validate the inputs to the simpleInputSimpleOutput method.""" self.validator.assert_valid( - method_name="nestedStructInput", - parameter_name="n", - argument_value=n, + method_name="simpleInputSimpleOutput", + parameter_name="index_0", + argument_value=index_0, ) - return n + # safeguard against fractional inputs + index_0 = int(index_0) + return index_0 - def call( - self, n: Tuple0xc9bdd2d5, tx_params: Optional[TxParams] = None - ) -> None: + def call(self, index_0: int, tx_params: Optional[TxParams] = None) -> int: """Execute underlying contract method via eth_call. + Tests decoding when both input and output are non-empty. + :param tx_params: transaction parameters """ - (n) = self.validate_and_normalize_inputs(n) + (index_0) = self.validate_and_normalize_inputs(index_0) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(n).call(tx_params.as_dict()) + return self.underlying_method(index_0).call(tx_params.as_dict()) def send_transaction( - self, n: Tuple0xc9bdd2d5, tx_params: Optional[TxParams] = None + self, index_0: int, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. + Tests decoding when both input and output are non-empty. + :param tx_params: transaction parameters """ - (n) = self.validate_and_normalize_inputs(n) + (index_0) = self.validate_and_normalize_inputs(index_0) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(n).transact(tx_params.as_dict()) + return self.underlying_method(index_0).transact(tx_params.as_dict()) def estimate_gas( - self, n: Tuple0xc9bdd2d5, tx_params: Optional[TxParams] = None + self, index_0: int, tx_params: Optional[TxParams] = None ) -> int: """Estimate gas consumption of method call.""" - (n) = self.validate_and_normalize_inputs(n) + (index_0) = self.validate_and_normalize_inputs(index_0) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(n).estimateGas(tx_params.as_dict()) + return self.underlying_method(index_0).estimateGas(tx_params.as_dict()) -class MethodReturningMultipleValuesMethod(ContractMethod): - """Various interfaces to the methodReturningMultipleValues method.""" +class SimplePureFunctionMethod(ContractMethod): + """Various interfaces to the simplePureFunction method.""" def __init__( self, @@ -1431,7 +1369,7 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call(self, tx_params: Optional[TxParams] = None) -> Tuple[int, str]: + def call(self, tx_params: Optional[TxParams] = None) -> int: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters @@ -1457,8 +1395,8 @@ def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: return self.underlying_method().estimateGas(tx_params.as_dict()) -class MethodReturningArrayOfStructsMethod(ContractMethod): - """Various interfaces to the methodReturningArrayOfStructs method.""" +class SimplePureFunctionWithInputMethod(ContractMethod): + """Various interfaces to the simplePureFunctionWithInput method.""" def __init__( self, @@ -1471,36 +1409,50 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call( - self, tx_params: Optional[TxParams] = None - ) -> List[Tuple0xcf8ad995]: + def validate_and_normalize_inputs(self, x: int): + """Validate the inputs to the simplePureFunctionWithInput method.""" + self.validator.assert_valid( + method_name="simplePureFunctionWithInput", + parameter_name="x", + argument_value=x, + ) + # safeguard against fractional inputs + x = int(x) + return x + + def call(self, x: int, tx_params: Optional[TxParams] = None) -> int: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters """ + (x) = self.validate_and_normalize_inputs(x) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().call(tx_params.as_dict()) + return self.underlying_method(x).call(tx_params.as_dict()) def send_transaction( - self, tx_params: Optional[TxParams] = None + self, x: int, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters """ + (x) = self.validate_and_normalize_inputs(x) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().transact(tx_params.as_dict()) + return self.underlying_method(x).transact(tx_params.as_dict()) - def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: + def estimate_gas( + self, x: int, tx_params: Optional[TxParams] = None + ) -> int: """Estimate gas consumption of method call.""" + (x) = self.validate_and_normalize_inputs(x) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().estimateGas(tx_params.as_dict()) + return self.underlying_method(x).estimateGas(tx_params.as_dict()) -class EmitSimpleEventMethod(ContractMethod): - """Various interfaces to the emitSimpleEvent method.""" +class SimpleRequireMethod(ContractMethod): + """Various interfaces to the simpleRequire method.""" def __init__( self, @@ -1513,13 +1465,11 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call( - self, tx_params: Optional[TxParams] = None - ) -> Union[None, Union[HexBytes, bytes]]: + def call(self, tx_params: Optional[TxParams] = None) -> None: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters - :returns: the return value of the underlying method. + """ tx_params = super().normalize_tx_params(tx_params) return self.underlying_method().call(tx_params.as_dict()) @@ -1530,6 +1480,7 @@ def send_transaction( """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters + """ tx_params = super().normalize_tx_params(tx_params) return self.underlying_method().transact(tx_params.as_dict()) @@ -1540,8 +1491,8 @@ def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: return self.underlying_method().estimateGas(tx_params.as_dict()) -class StructOutputMethod(ContractMethod): - """Various interfaces to the structOutput method.""" +class SimpleRevertMethod(ContractMethod): + """Various interfaces to the simpleRevert method.""" def __init__( self, @@ -1554,13 +1505,11 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call(self, tx_params: Optional[TxParams] = None) -> Tuple0xcf8ad995: + def call(self, tx_params: Optional[TxParams] = None) -> None: """Execute underlying contract method via eth_call. - a method that returns a struct - :param tx_params: transaction parameters - :returns: a Struct struct + """ tx_params = super().normalize_tx_params(tx_params) return self.underlying_method().call(tx_params.as_dict()) @@ -1570,10 +1519,8 @@ def send_transaction( ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. - a method that returns a struct - :param tx_params: transaction parameters - :returns: a Struct struct + """ tx_params = super().normalize_tx_params(tx_params) return self.underlying_method().transact(tx_params.as_dict()) @@ -1584,8 +1531,8 @@ def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: return self.underlying_method().estimateGas(tx_params.as_dict()) -class PureFunctionWithConstantMethod(ContractMethod): - """Various interfaces to the pureFunctionWithConstant method.""" +class StructInputMethod(ContractMethod): + """Various interfaces to the structInput method.""" def __init__( self, @@ -1598,34 +1545,48 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def call(self, tx_params: Optional[TxParams] = None) -> int: + def validate_and_normalize_inputs(self, s: Tuple0xcf8ad995): + """Validate the inputs to the structInput method.""" + self.validator.assert_valid( + method_name="structInput", parameter_name="s", argument_value=s + ) + return s + + def call( + self, s: Tuple0xcf8ad995, tx_params: Optional[TxParams] = None + ) -> None: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters """ + (s) = self.validate_and_normalize_inputs(s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().call(tx_params.as_dict()) + return self.underlying_method(s).call(tx_params.as_dict()) def send_transaction( - self, tx_params: Optional[TxParams] = None + self, s: Tuple0xcf8ad995, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters """ + (s) = self.validate_and_normalize_inputs(s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().transact(tx_params.as_dict()) + return self.underlying_method(s).transact(tx_params.as_dict()) - def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: + def estimate_gas( + self, s: Tuple0xcf8ad995, tx_params: Optional[TxParams] = None + ) -> int: """Estimate gas consumption of method call.""" + (s) = self.validate_and_normalize_inputs(s) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method().estimateGas(tx_params.as_dict()) + return self.underlying_method(s).estimateGas(tx_params.as_dict()) -class SimpleInputNoOutputMethod(ContractMethod): - """Various interfaces to the simpleInputNoOutput method.""" +class StructOutputMethod(ContractMethod): + """Various interfaces to the structOutput method.""" def __init__( self, @@ -1638,54 +1599,38 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, index_0: int): - """Validate the inputs to the simpleInputNoOutput method.""" - self.validator.assert_valid( - method_name="simpleInputNoOutput", - parameter_name="index_0", - argument_value=index_0, - ) - # safeguard against fractional inputs - index_0 = int(index_0) - return index_0 - - def call(self, index_0: int, tx_params: Optional[TxParams] = None) -> None: + def call(self, tx_params: Optional[TxParams] = None) -> Tuple0xcf8ad995: """Execute underlying contract method via eth_call. - Tests decoding when input is not empty but output is empty. + a method that returns a struct :param tx_params: transaction parameters - + :returns: a Struct struct """ - (index_0) = self.validate_and_normalize_inputs(index_0) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(index_0).call(tx_params.as_dict()) + return self.underlying_method().call(tx_params.as_dict()) def send_transaction( - self, index_0: int, tx_params: Optional[TxParams] = None + self, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. - Tests decoding when input is not empty but output is empty. + a method that returns a struct :param tx_params: transaction parameters - + :returns: a Struct struct """ - (index_0) = self.validate_and_normalize_inputs(index_0) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(index_0).transact(tx_params.as_dict()) + return self.underlying_method().transact(tx_params.as_dict()) - def estimate_gas( - self, index_0: int, tx_params: Optional[TxParams] = None - ) -> int: + def estimate_gas(self, tx_params: Optional[TxParams] = None) -> int: """Estimate gas consumption of method call.""" - (index_0) = self.validate_and_normalize_inputs(index_0) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(index_0).estimateGas(tx_params.as_dict()) + return self.underlying_method().estimateGas(tx_params.as_dict()) -class OverloadedMethod2Method(ContractMethod): - """Various interfaces to the overloadedMethod method.""" +class WithAddressInputMethod(ContractMethod): + """Various interfaces to the withAddressInput method.""" def __init__( self, @@ -1698,48 +1643,102 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, a: str): - """Validate the inputs to the overloadedMethod method.""" + def validate_and_normalize_inputs( + self, x: str, a: int, b: int, y: str, c: int + ): + """Validate the inputs to the withAddressInput method.""" self.validator.assert_valid( - method_name="overloadedMethod", + method_name="withAddressInput", + parameter_name="x", + argument_value=x, + ) + x = self.validate_and_checksum_address(x) + self.validator.assert_valid( + method_name="withAddressInput", parameter_name="a", argument_value=a, ) - return a + # safeguard against fractional inputs + a = int(a) + self.validator.assert_valid( + method_name="withAddressInput", + parameter_name="b", + argument_value=b, + ) + # safeguard against fractional inputs + b = int(b) + self.validator.assert_valid( + method_name="withAddressInput", + parameter_name="y", + argument_value=y, + ) + y = self.validate_and_checksum_address(y) + self.validator.assert_valid( + method_name="withAddressInput", + parameter_name="c", + argument_value=c, + ) + # safeguard against fractional inputs + c = int(c) + return (x, a, b, y, c) - def call(self, a: str, tx_params: Optional[TxParams] = None) -> None: + def call( + self, + x: str, + a: int, + b: int, + y: str, + c: int, + tx_params: Optional[TxParams] = None, + ) -> str: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters """ - (a) = self.validate_and_normalize_inputs(a) + (x, a, b, y, c) = self.validate_and_normalize_inputs(x, a, b, y, c) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(a).call(tx_params.as_dict()) + return self.underlying_method(x, a, b, y, c).call(tx_params.as_dict()) def send_transaction( - self, a: str, tx_params: Optional[TxParams] = None + self, + x: str, + a: int, + b: int, + y: str, + c: int, + tx_params: Optional[TxParams] = None, ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters """ - (a) = self.validate_and_normalize_inputs(a) + (x, a, b, y, c) = self.validate_and_normalize_inputs(x, a, b, y, c) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(a).transact(tx_params.as_dict()) + return self.underlying_method(x, a, b, y, c).transact( + tx_params.as_dict() + ) def estimate_gas( - self, a: str, tx_params: Optional[TxParams] = None + self, + x: str, + a: int, + b: int, + y: str, + c: int, + tx_params: Optional[TxParams] = None, ) -> int: """Estimate gas consumption of method call.""" - (a) = self.validate_and_normalize_inputs(a) + (x, a, b, y, c) = self.validate_and_normalize_inputs(x, a, b, y, c) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(a).estimateGas(tx_params.as_dict()) + return self.underlying_method(x, a, b, y, c).estimateGas( + tx_params.as_dict() + ) -class OverloadedMethod1Method(ContractMethod): - """Various interfaces to the overloadedMethod method.""" +class WithdrawMethod(ContractMethod): + """Various interfaces to the withdraw method.""" def __init__( self, @@ -1752,44 +1751,45 @@ def __init__( super().__init__(web3_or_provider, contract_address, validator) self.underlying_method = contract_function - def validate_and_normalize_inputs(self, a: int): - """Validate the inputs to the overloadedMethod method.""" + def validate_and_normalize_inputs(self, wad: int): + """Validate the inputs to the withdraw method.""" self.validator.assert_valid( - method_name="overloadedMethod", - parameter_name="a", - argument_value=a, + method_name="withdraw", parameter_name="wad", argument_value=wad ) - return a + # safeguard against fractional inputs + wad = int(wad) + return wad - def call(self, a: int, tx_params: Optional[TxParams] = None) -> None: + def call( + self, wad: int, tx_params: Optional[TxParams] = None + ) -> Union[None, Union[HexBytes, bytes]]: """Execute underlying contract method via eth_call. :param tx_params: transaction parameters - + :returns: the return value of the underlying method. """ - (a) = self.validate_and_normalize_inputs(a) + (wad) = self.validate_and_normalize_inputs(wad) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(a).call(tx_params.as_dict()) + return self.underlying_method(wad).call(tx_params.as_dict()) def send_transaction( - self, a: int, tx_params: Optional[TxParams] = None + self, wad: int, tx_params: Optional[TxParams] = None ) -> Union[HexBytes, bytes]: """Execute underlying contract method via eth_sendTransaction. :param tx_params: transaction parameters - """ - (a) = self.validate_and_normalize_inputs(a) + (wad) = self.validate_and_normalize_inputs(wad) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(a).transact(tx_params.as_dict()) + return self.underlying_method(wad).transact(tx_params.as_dict()) def estimate_gas( - self, a: int, tx_params: Optional[TxParams] = None + self, wad: int, tx_params: Optional[TxParams] = None ) -> int: """Estimate gas consumption of method call.""" - (a) = self.validate_and_normalize_inputs(a) + (wad) = self.validate_and_normalize_inputs(wad) tx_params = super().normalize_tx_params(tx_params) - return self.underlying_method(a).estimateGas(tx_params.as_dict()) + return self.underlying_method(wad).estimateGas(tx_params.as_dict()) # pylint: disable=too-many-public-methods,too-many-instance-attributes @@ -1800,59 +1800,54 @@ class AbiGenDummy: which can be accomplished via `str.encode("utf_8")`:code:. """ - simple_require: SimpleRequireMethod - """Constructor-initialized instance of - :class:`SimpleRequireMethod`. - """ - accepts_an_array_of_bytes: AcceptsAnArrayOfBytesMethod """Constructor-initialized instance of :class:`AcceptsAnArrayOfBytesMethod`. """ - simple_input_simple_output: SimpleInputSimpleOutputMethod + accepts_bytes: AcceptsBytesMethod """Constructor-initialized instance of - :class:`SimpleInputSimpleOutputMethod`. + :class:`AcceptsBytesMethod`. """ - withdraw: WithdrawMethod + complex_input_complex_output: ComplexInputComplexOutputMethod """Constructor-initialized instance of - :class:`WithdrawMethod`. + :class:`ComplexInputComplexOutputMethod`. """ - multi_input_multi_output: MultiInputMultiOutputMethod + ecrecover_fn: EcrecoverFnMethod """Constructor-initialized instance of - :class:`MultiInputMultiOutputMethod`. + :class:`EcrecoverFnMethod`. """ - ecrecover_fn: EcrecoverFnMethod + emit_simple_event: EmitSimpleEventMethod """Constructor-initialized instance of - :class:`EcrecoverFnMethod`. + :class:`EmitSimpleEventMethod`. """ - accepts_bytes: AcceptsBytesMethod + method_returning_array_of_structs: MethodReturningArrayOfStructsMethod """Constructor-initialized instance of - :class:`AcceptsBytesMethod`. + :class:`MethodReturningArrayOfStructsMethod`. """ - no_input_simple_output: NoInputSimpleOutputMethod + method_returning_multiple_values: MethodReturningMultipleValuesMethod """Constructor-initialized instance of - :class:`NoInputSimpleOutputMethod`. + :class:`MethodReturningMultipleValuesMethod`. """ - revert_with_constant: RevertWithConstantMethod + method_using_nested_struct_with_inner_struct_not_used_elsewhere: MethodUsingNestedStructWithInnerStructNotUsedElsewhereMethod """Constructor-initialized instance of - :class:`RevertWithConstantMethod`. + :class:`MethodUsingNestedStructWithInnerStructNotUsedElsewhereMethod`. """ - simple_revert: SimpleRevertMethod + multi_input_multi_output: MultiInputMultiOutputMethod """Constructor-initialized instance of - :class:`SimpleRevertMethod`. + :class:`MultiInputMultiOutputMethod`. """ - method_using_nested_struct_with_inner_struct_not_used_elsewhere: MethodUsingNestedStructWithInnerStructNotUsedElsewhereMethod + nested_struct_input: NestedStructInputMethod """Constructor-initialized instance of - :class:`MethodUsingNestedStructWithInnerStructNotUsedElsewhereMethod`. + :class:`NestedStructInputMethod`. """ nested_struct_output: NestedStructOutputMethod @@ -1860,94 +1855,99 @@ class AbiGenDummy: :class:`NestedStructOutputMethod`. """ - require_with_constant: RequireWithConstantMethod + no_input_no_output: NoInputNoOutputMethod """Constructor-initialized instance of - :class:`RequireWithConstantMethod`. + :class:`NoInputNoOutputMethod`. """ - with_address_input: WithAddressInputMethod + no_input_simple_output: NoInputSimpleOutputMethod """Constructor-initialized instance of - :class:`WithAddressInputMethod`. + :class:`NoInputSimpleOutputMethod`. """ - struct_input: StructInputMethod + non_pure_method: NonPureMethodMethod """Constructor-initialized instance of - :class:`StructInputMethod`. + :class:`NonPureMethodMethod`. """ - non_pure_method: NonPureMethodMethod + non_pure_method_that_returns_nothing: NonPureMethodThatReturnsNothingMethod """Constructor-initialized instance of - :class:`NonPureMethodMethod`. + :class:`NonPureMethodThatReturnsNothingMethod`. """ - complex_input_complex_output: ComplexInputComplexOutputMethod + overloaded_method2: OverloadedMethod2Method """Constructor-initialized instance of - :class:`ComplexInputComplexOutputMethod`. + :class:`OverloadedMethod2Method`. """ - no_input_no_output: NoInputNoOutputMethod + overloaded_method1: OverloadedMethod1Method """Constructor-initialized instance of - :class:`NoInputNoOutputMethod`. + :class:`OverloadedMethod1Method`. """ - simple_pure_function_with_input: SimplePureFunctionWithInputMethod + pure_function_with_constant: PureFunctionWithConstantMethod """Constructor-initialized instance of - :class:`SimplePureFunctionWithInputMethod`. + :class:`PureFunctionWithConstantMethod`. """ - non_pure_method_that_returns_nothing: NonPureMethodThatReturnsNothingMethod + require_with_constant: RequireWithConstantMethod """Constructor-initialized instance of - :class:`NonPureMethodThatReturnsNothingMethod`. + :class:`RequireWithConstantMethod`. """ - simple_pure_function: SimplePureFunctionMethod + revert_with_constant: RevertWithConstantMethod """Constructor-initialized instance of - :class:`SimplePureFunctionMethod`. + :class:`RevertWithConstantMethod`. """ - nested_struct_input: NestedStructInputMethod + simple_input_no_output: SimpleInputNoOutputMethod """Constructor-initialized instance of - :class:`NestedStructInputMethod`. + :class:`SimpleInputNoOutputMethod`. """ - method_returning_multiple_values: MethodReturningMultipleValuesMethod + simple_input_simple_output: SimpleInputSimpleOutputMethod """Constructor-initialized instance of - :class:`MethodReturningMultipleValuesMethod`. + :class:`SimpleInputSimpleOutputMethod`. """ - method_returning_array_of_structs: MethodReturningArrayOfStructsMethod + simple_pure_function: SimplePureFunctionMethod """Constructor-initialized instance of - :class:`MethodReturningArrayOfStructsMethod`. + :class:`SimplePureFunctionMethod`. """ - emit_simple_event: EmitSimpleEventMethod + simple_pure_function_with_input: SimplePureFunctionWithInputMethod """Constructor-initialized instance of - :class:`EmitSimpleEventMethod`. + :class:`SimplePureFunctionWithInputMethod`. """ - struct_output: StructOutputMethod + simple_require: SimpleRequireMethod """Constructor-initialized instance of - :class:`StructOutputMethod`. + :class:`SimpleRequireMethod`. """ - pure_function_with_constant: PureFunctionWithConstantMethod + simple_revert: SimpleRevertMethod """Constructor-initialized instance of - :class:`PureFunctionWithConstantMethod`. + :class:`SimpleRevertMethod`. """ - simple_input_no_output: SimpleInputNoOutputMethod + struct_input: StructInputMethod """Constructor-initialized instance of - :class:`SimpleInputNoOutputMethod`. + :class:`StructInputMethod`. """ - overloaded_method2: OverloadedMethod2Method + struct_output: StructOutputMethod """Constructor-initialized instance of - :class:`OverloadedMethod2Method`. + :class:`StructOutputMethod`. """ - overloaded_method1: OverloadedMethod1Method + with_address_input: WithAddressInputMethod """Constructor-initialized instance of - :class:`OverloadedMethod1Method`. + :class:`WithAddressInputMethod`. + """ + + withdraw: WithdrawMethod + """Constructor-initialized instance of + :class:`WithdrawMethod`. """ def __init__( @@ -2007,77 +2007,73 @@ def __init__( abi=AbiGenDummy.abi(), ).functions - self.simple_require = SimpleRequireMethod( + self.accepts_an_array_of_bytes = AcceptsAnArrayOfBytesMethod( web3_or_provider, contract_address, - functions.simpleRequire, + functions.acceptsAnArrayOfBytes, validator, ) - self.accepts_an_array_of_bytes = AcceptsAnArrayOfBytesMethod( + self.accepts_bytes = AcceptsBytesMethod( web3_or_provider, contract_address, - functions.acceptsAnArrayOfBytes, + functions.acceptsBytes, validator, ) - self.simple_input_simple_output = SimpleInputSimpleOutputMethod( + self.complex_input_complex_output = ComplexInputComplexOutputMethod( web3_or_provider, contract_address, - functions.simpleInputSimpleOutput, + functions.complexInputComplexOutput, validator, ) - self.withdraw = WithdrawMethod( - web3_or_provider, contract_address, functions.withdraw, validator - ) - - self.multi_input_multi_output = MultiInputMultiOutputMethod( + self.ecrecover_fn = EcrecoverFnMethod( web3_or_provider, contract_address, - functions.multiInputMultiOutput, + functions.ecrecoverFn, validator, ) - self.ecrecover_fn = EcrecoverFnMethod( + self.emit_simple_event = EmitSimpleEventMethod( web3_or_provider, contract_address, - functions.ecrecoverFn, + functions.emitSimpleEvent, validator, ) - self.accepts_bytes = AcceptsBytesMethod( + self.method_returning_array_of_structs = MethodReturningArrayOfStructsMethod( web3_or_provider, contract_address, - functions.acceptsBytes, + functions.methodReturningArrayOfStructs, validator, ) - self.no_input_simple_output = NoInputSimpleOutputMethod( + self.method_returning_multiple_values = MethodReturningMultipleValuesMethod( web3_or_provider, contract_address, - functions.noInputSimpleOutput, + functions.methodReturningMultipleValues, validator, ) - self.revert_with_constant = RevertWithConstantMethod( + self.method_using_nested_struct_with_inner_struct_not_used_elsewhere = MethodUsingNestedStructWithInnerStructNotUsedElsewhereMethod( web3_or_provider, contract_address, - functions.revertWithConstant, + functions.methodUsingNestedStructWithInnerStructNotUsedElsewhere, validator, ) - self.simple_revert = SimpleRevertMethod( + self.multi_input_multi_output = MultiInputMultiOutputMethod( web3_or_provider, contract_address, - functions.simpleRevert, + functions.multiInputMultiOutput, validator, ) - self.method_using_nested_struct_with_inner_struct_not_used_elsewhere = MethodUsingNestedStructWithInnerStructNotUsedElsewhereMethod( + self.nested_struct_input = NestedStructInputMethod( web3_or_provider, contract_address, - functions.methodUsingNestedStructWithInnerStructNotUsedElsewhere, + functions.nestedStructInput, validator, ) @@ -2088,138 +2084,142 @@ def __init__( validator, ) - self.require_with_constant = RequireWithConstantMethod( + self.no_input_no_output = NoInputNoOutputMethod( web3_or_provider, contract_address, - functions.requireWithConstant, + functions.noInputNoOutput, validator, ) - self.with_address_input = WithAddressInputMethod( + self.no_input_simple_output = NoInputSimpleOutputMethod( web3_or_provider, contract_address, - functions.withAddressInput, + functions.noInputSimpleOutput, validator, ) - self.struct_input = StructInputMethod( + self.non_pure_method = NonPureMethodMethod( web3_or_provider, contract_address, - functions.structInput, + functions.nonPureMethod, validator, ) - self.non_pure_method = NonPureMethodMethod( + self.non_pure_method_that_returns_nothing = NonPureMethodThatReturnsNothingMethod( web3_or_provider, contract_address, - functions.nonPureMethod, + functions.nonPureMethodThatReturnsNothing, validator, ) - self.complex_input_complex_output = ComplexInputComplexOutputMethod( + self.overloaded_method2 = OverloadedMethod2Method( web3_or_provider, contract_address, - functions.complexInputComplexOutput, + functions.overloadedMethod, validator, ) - self.no_input_no_output = NoInputNoOutputMethod( + self.overloaded_method1 = OverloadedMethod1Method( web3_or_provider, contract_address, - functions.noInputNoOutput, + functions.overloadedMethod, validator, ) - self.simple_pure_function_with_input = SimplePureFunctionWithInputMethod( + self.pure_function_with_constant = PureFunctionWithConstantMethod( web3_or_provider, contract_address, - functions.simplePureFunctionWithInput, + functions.pureFunctionWithConstant, validator, ) - self.non_pure_method_that_returns_nothing = NonPureMethodThatReturnsNothingMethod( + self.require_with_constant = RequireWithConstantMethod( web3_or_provider, contract_address, - functions.nonPureMethodThatReturnsNothing, + functions.requireWithConstant, validator, ) - self.simple_pure_function = SimplePureFunctionMethod( + self.revert_with_constant = RevertWithConstantMethod( web3_or_provider, contract_address, - functions.simplePureFunction, + functions.revertWithConstant, validator, ) - self.nested_struct_input = NestedStructInputMethod( + self.simple_input_no_output = SimpleInputNoOutputMethod( web3_or_provider, contract_address, - functions.nestedStructInput, + functions.simpleInputNoOutput, validator, ) - self.method_returning_multiple_values = MethodReturningMultipleValuesMethod( + self.simple_input_simple_output = SimpleInputSimpleOutputMethod( web3_or_provider, contract_address, - functions.methodReturningMultipleValues, + functions.simpleInputSimpleOutput, validator, ) - self.method_returning_array_of_structs = MethodReturningArrayOfStructsMethod( + self.simple_pure_function = SimplePureFunctionMethod( web3_or_provider, contract_address, - functions.methodReturningArrayOfStructs, + functions.simplePureFunction, validator, ) - self.emit_simple_event = EmitSimpleEventMethod( + self.simple_pure_function_with_input = SimplePureFunctionWithInputMethod( web3_or_provider, contract_address, - functions.emitSimpleEvent, + functions.simplePureFunctionWithInput, validator, ) - self.struct_output = StructOutputMethod( + self.simple_require = SimpleRequireMethod( web3_or_provider, contract_address, - functions.structOutput, + functions.simpleRequire, validator, ) - self.pure_function_with_constant = PureFunctionWithConstantMethod( + self.simple_revert = SimpleRevertMethod( web3_or_provider, contract_address, - functions.pureFunctionWithConstant, + functions.simpleRevert, validator, ) - self.simple_input_no_output = SimpleInputNoOutputMethod( + self.struct_input = StructInputMethod( web3_or_provider, contract_address, - functions.simpleInputNoOutput, + functions.structInput, validator, ) - self.overloaded_method2 = OverloadedMethod2Method( + self.struct_output = StructOutputMethod( web3_or_provider, contract_address, - functions.overloadedMethod, + functions.structOutput, validator, ) - self.overloaded_method1 = OverloadedMethod1Method( + self.with_address_input = WithAddressInputMethod( web3_or_provider, contract_address, - functions.overloadedMethod, + functions.withAddressInput, validator, ) - def get_withdrawal_event( + self.withdraw = WithdrawMethod( + web3_or_provider, contract_address, functions.withdraw, validator + ) + + def get_simple_event_event( self, tx_hash: Union[HexBytes, bytes] ) -> Tuple[AttributeDict]: - """Get log entry for Withdrawal event. + """Get log entry for SimpleEvent event. - :param tx_hash: hash of transaction emitting Withdrawal event + :param tx_hash: hash of transaction emitting SimpleEvent event """ tx_receipt = self._web3_eth.getTransactionReceipt(tx_hash) return ( @@ -2227,16 +2227,16 @@ def get_withdrawal_event( address=to_checksum_address(self.contract_address), abi=AbiGenDummy.abi(), ) - .events.Withdrawal() + .events.SimpleEvent() .processReceipt(tx_receipt) ) - def get_simple_event_event( + def get_withdrawal_event( self, tx_hash: Union[HexBytes, bytes] ) -> Tuple[AttributeDict]: - """Get log entry for SimpleEvent event. + """Get log entry for Withdrawal event. - :param tx_hash: hash of transaction emitting SimpleEvent event + :param tx_hash: hash of transaction emitting Withdrawal event """ tx_receipt = self._web3_eth.getTransactionReceipt(tx_hash) return ( @@ -2244,7 +2244,7 @@ def get_simple_event_event( address=to_checksum_address(self.contract_address), abi=AbiGenDummy.abi(), ) - .events.SimpleEvent() + .events.Withdrawal() .processReceipt(tx_receipt) ) @@ -2252,7 +2252,7 @@ def get_simple_event_event( def abi(): """Return the ABI to the underlying contract.""" return json.loads( - '[{"constant":true,"inputs":[],"name":"simpleRequire","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes[]","name":"a","type":"bytes[]"}],"name":"acceptsAnArrayOfBytes","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index_0","type":"uint256"}],"name":"simpleInputSimpleOutput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index_0","type":"uint256"},{"internalType":"bytes","name":"index_1","type":"bytes"},{"internalType":"string","name":"index_2","type":"string"}],"name":"multiInputMultiOutput","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ecrecoverFn","outputs":[{"internalType":"address","name":"signerAddress","type":"address"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"a","type":"bytes"}],"name":"acceptsBytes","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"noInputSimpleOutput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"revertWithConstant","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"simpleRevert","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"methodUsingNestedStructWithInnerStructNotUsedElsewhere","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"aField","type":"uint256"}],"internalType":"struct AbiGenDummy.StructNotDirectlyUsedAnywhere","name":"innerStruct","type":"tuple"}],"internalType":"struct AbiGenDummy.NestedStructWithInnerStructNotUsedElsewhere","name":"","type":"tuple"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"nestedStructOutput","outputs":[{"components":[{"components":[{"internalType":"bytes","name":"someBytes","type":"bytes"},{"internalType":"uint32","name":"anInteger","type":"uint32"},{"internalType":"bytes[]","name":"aDynamicArrayOfBytes","type":"bytes[]"},{"internalType":"string","name":"aString","type":"string"}],"internalType":"struct AbiGenDummy.Struct","name":"innerStruct","type":"tuple"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct AbiGenDummy.NestedStruct","name":"","type":"tuple"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"requireWithConstant","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"x","type":"address"},{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"},{"internalType":"address","name":"y","type":"address"},{"internalType":"uint256","name":"c","type":"uint256"}],"name":"withAddressInput","outputs":[{"internalType":"address","name":"z","type":"address"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"bytes","name":"someBytes","type":"bytes"},{"internalType":"uint32","name":"anInteger","type":"uint32"},{"internalType":"bytes[]","name":"aDynamicArrayOfBytes","type":"bytes[]"},{"internalType":"string","name":"aString","type":"string"}],"internalType":"struct AbiGenDummy.Struct","name":"s","type":"tuple"}],"name":"structInput","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"nonPureMethod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"uint256","name":"foo","type":"uint256"},{"internalType":"bytes","name":"bar","type":"bytes"},{"internalType":"string","name":"car","type":"string"}],"internalType":"struct AbiGenDummy.ComplexInput","name":"complexInput","type":"tuple"}],"name":"complexInputComplexOutput","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"foo","type":"uint256"},{"internalType":"bytes","name":"bar","type":"bytes"},{"internalType":"string","name":"car","type":"string"}],"internalType":"struct AbiGenDummy.ComplexInput","name":"input","type":"tuple"},{"internalType":"bytes","name":"lorem","type":"bytes"},{"internalType":"bytes","name":"ipsum","type":"bytes"},{"internalType":"string","name":"dolor","type":"string"}],"internalType":"struct AbiGenDummy.ComplexOutput","name":"","type":"tuple"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"noInputNoOutput","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"simplePureFunctionWithInput","outputs":[{"internalType":"uint256","name":"sum","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"nonPureMethodThatReturnsNothing","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"simplePureFunction","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"components":[{"components":[{"internalType":"bytes","name":"someBytes","type":"bytes"},{"internalType":"uint32","name":"anInteger","type":"uint32"},{"internalType":"bytes[]","name":"aDynamicArrayOfBytes","type":"bytes[]"},{"internalType":"string","name":"aString","type":"string"}],"internalType":"struct AbiGenDummy.Struct","name":"innerStruct","type":"tuple"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct AbiGenDummy.NestedStruct","name":"n","type":"tuple"}],"name":"nestedStructInput","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"methodReturningMultipleValues","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"methodReturningArrayOfStructs","outputs":[{"components":[{"internalType":"bytes","name":"someBytes","type":"bytes"},{"internalType":"uint32","name":"anInteger","type":"uint32"},{"internalType":"bytes[]","name":"aDynamicArrayOfBytes","type":"bytes[]"},{"internalType":"string","name":"aString","type":"string"}],"internalType":"struct AbiGenDummy.Struct[]","name":"","type":"tuple[]"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"emitSimpleEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"structOutput","outputs":[{"components":[{"internalType":"bytes","name":"someBytes","type":"bytes"},{"internalType":"uint32","name":"anInteger","type":"uint32"},{"internalType":"bytes[]","name":"aDynamicArrayOfBytes","type":"bytes[]"},{"internalType":"string","name":"aString","type":"string"}],"internalType":"struct AbiGenDummy.Struct","name":"s","type":"tuple"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"pureFunctionWithConstant","outputs":[{"internalType":"uint256","name":"someConstant","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index_0","type":"uint256"}],"name":"simpleInputNoOutput","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"a","type":"string"}],"name":"overloadedMethod","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"int256","name":"a","type":"int256"}],"name":"overloadedMethod","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Withdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"someBytes","type":"bytes"},{"indexed":false,"internalType":"string","name":"someString","type":"string"}],"name":"SimpleEvent","type":"event"}]' # noqa: E501 (line-too-long) + '[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"someBytes","type":"bytes"},{"indexed":false,"internalType":"string","name":"someString","type":"string"}],"name":"SimpleEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Withdrawal","type":"event"},{"constant":true,"inputs":[{"internalType":"bytes[]","name":"a","type":"bytes[]"}],"name":"acceptsAnArrayOfBytes","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"a","type":"bytes"}],"name":"acceptsBytes","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"uint256","name":"foo","type":"uint256"},{"internalType":"bytes","name":"bar","type":"bytes"},{"internalType":"string","name":"car","type":"string"}],"internalType":"struct AbiGenDummy.ComplexInput","name":"complexInput","type":"tuple"}],"name":"complexInputComplexOutput","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"foo","type":"uint256"},{"internalType":"bytes","name":"bar","type":"bytes"},{"internalType":"string","name":"car","type":"string"}],"internalType":"struct AbiGenDummy.ComplexInput","name":"input","type":"tuple"},{"internalType":"bytes","name":"lorem","type":"bytes"},{"internalType":"bytes","name":"ipsum","type":"bytes"},{"internalType":"string","name":"dolor","type":"string"}],"internalType":"struct AbiGenDummy.ComplexOutput","name":"","type":"tuple"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ecrecoverFn","outputs":[{"internalType":"address","name":"signerAddress","type":"address"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"emitSimpleEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"methodReturningArrayOfStructs","outputs":[{"components":[{"internalType":"bytes","name":"someBytes","type":"bytes"},{"internalType":"uint32","name":"anInteger","type":"uint32"},{"internalType":"bytes[]","name":"aDynamicArrayOfBytes","type":"bytes[]"},{"internalType":"string","name":"aString","type":"string"}],"internalType":"struct AbiGenDummy.Struct[]","name":"","type":"tuple[]"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"methodReturningMultipleValues","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"methodUsingNestedStructWithInnerStructNotUsedElsewhere","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"aField","type":"uint256"}],"internalType":"struct AbiGenDummy.StructNotDirectlyUsedAnywhere","name":"innerStruct","type":"tuple"}],"internalType":"struct AbiGenDummy.NestedStructWithInnerStructNotUsedElsewhere","name":"","type":"tuple"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index_0","type":"uint256"},{"internalType":"bytes","name":"index_1","type":"bytes"},{"internalType":"string","name":"index_2","type":"string"}],"name":"multiInputMultiOutput","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"components":[{"components":[{"internalType":"bytes","name":"someBytes","type":"bytes"},{"internalType":"uint32","name":"anInteger","type":"uint32"},{"internalType":"bytes[]","name":"aDynamicArrayOfBytes","type":"bytes[]"},{"internalType":"string","name":"aString","type":"string"}],"internalType":"struct AbiGenDummy.Struct","name":"innerStruct","type":"tuple"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct AbiGenDummy.NestedStruct","name":"n","type":"tuple"}],"name":"nestedStructInput","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"nestedStructOutput","outputs":[{"components":[{"components":[{"internalType":"bytes","name":"someBytes","type":"bytes"},{"internalType":"uint32","name":"anInteger","type":"uint32"},{"internalType":"bytes[]","name":"aDynamicArrayOfBytes","type":"bytes[]"},{"internalType":"string","name":"aString","type":"string"}],"internalType":"struct AbiGenDummy.Struct","name":"innerStruct","type":"tuple"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct AbiGenDummy.NestedStruct","name":"","type":"tuple"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"noInputNoOutput","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"noInputSimpleOutput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"nonPureMethod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"nonPureMethodThatReturnsNothing","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"a","type":"string"}],"name":"overloadedMethod","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"int256","name":"a","type":"int256"}],"name":"overloadedMethod","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"pureFunctionWithConstant","outputs":[{"internalType":"uint256","name":"someConstant","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"requireWithConstant","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"revertWithConstant","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index_0","type":"uint256"}],"name":"simpleInputNoOutput","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index_0","type":"uint256"}],"name":"simpleInputSimpleOutput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"simplePureFunction","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"simplePureFunctionWithInput","outputs":[{"internalType":"uint256","name":"sum","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"simpleRequire","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"simpleRevert","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"bytes","name":"someBytes","type":"bytes"},{"internalType":"uint32","name":"anInteger","type":"uint32"},{"internalType":"bytes[]","name":"aDynamicArrayOfBytes","type":"bytes[]"},{"internalType":"string","name":"aString","type":"string"}],"internalType":"struct AbiGenDummy.Struct","name":"s","type":"tuple"}],"name":"structInput","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"structOutput","outputs":[{"components":[{"internalType":"bytes","name":"someBytes","type":"bytes"},{"internalType":"uint32","name":"anInteger","type":"uint32"},{"internalType":"bytes[]","name":"aDynamicArrayOfBytes","type":"bytes[]"},{"internalType":"string","name":"aString","type":"string"}],"internalType":"struct AbiGenDummy.Struct","name":"s","type":"tuple"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"x","type":"address"},{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"},{"internalType":"address","name":"y","type":"address"},{"internalType":"uint256","name":"c","type":"uint256"}],"name":"withAddressInput","outputs":[{"internalType":"address","name":"z","type":"address"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]' # noqa: E501 (line-too-long) ) diff --git a/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py index 321893ee3a..b25be89c2f 100644 --- a/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py @@ -245,7 +245,7 @@ def __init__( def abi(): """Return the ABI to the underlying contract.""" return json.loads( - '[{"constant":true,"inputs":[{"name":"x","type":"uint256"}],"name":"publicAddConstant","outputs":[{"name":"result","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"x","type":"uint256"}],"name":"publicAddOne","outputs":[{"name":"result","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"}]' # noqa: E501 (line-too-long) + '[{"constant":true,"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"publicAddConstant","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"publicAddOne","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"}]' # noqa: E501 (line-too-long) ) diff --git a/packages/abi-gen/test-cli/output/typescript/abi_gen_dummy.ts b/packages/abi-gen/test-cli/output/typescript/abi_gen_dummy.ts index 816a927f33..71fd822b91 100644 --- a/packages/abi-gen/test-cli/output/typescript/abi_gen_dummy.ts +++ b/packages/abi-gen/test-cli/output/typescript/abi_gen_dummy.ts @@ -31,16 +31,11 @@ import { assert } from '@0x/assert'; import * as ethers from 'ethers'; // tslint:enable:no-unused-variable -export type AbiGenDummyEventArgs = AbiGenDummyWithdrawalEventArgs | AbiGenDummySimpleEventEventArgs; +export type AbiGenDummyEventArgs = AbiGenDummySimpleEventEventArgs | AbiGenDummyWithdrawalEventArgs; export enum AbiGenDummyEvents { - Withdrawal = 'Withdrawal', SimpleEvent = 'SimpleEvent', -} - -export interface AbiGenDummyWithdrawalEventArgs extends DecodedLogArgs { - _owner: string; - _value: BigNumber; + Withdrawal = 'Withdrawal', } export interface AbiGenDummySimpleEventEventArgs extends DecodedLogArgs { @@ -48,6 +43,11 @@ export interface AbiGenDummySimpleEventEventArgs extends DecodedLogArgs { someString: string; } +export interface AbiGenDummyWithdrawalEventArgs extends DecodedLogArgs { + _owner: string; + _value: BigNumber; +} + /* istanbul ignore next */ // tslint:disable:no-parameter-reassignment // tslint:disable-next-line:class-name @@ -56,14 +56,19 @@ export class AbiGenDummyContract extends BaseContract { * @ignore */ public static deployedBytecode = - '0x608060405234801561001057600080fd5b50600436106101d95760003560e01c806376f15d5b11610104578063bb607362116100a2578063d88be12f11610071578063d88be12f1461039b578063ee8b86fb146103a3578063f408fb3114610279578063fa315f9d146103b6576101d9565b8063bb60736214610353578063bdab168814610369578063cd3c0b971461037e578063d6d7618c14610386576101d9565b80638ee52b4e116100de5780638ee52b4e146103225780639a3b618514610335578063a3c2f6b61461033d578063ae2dae1714610345576101d9565b806376f15d5b146102f25780637833bec0146102fa5780637a791e6e1461031a576101d9565b80634303a5421161017c57806359c28add1161014b57806359c28add146102b45780635ba3c7c0146102c957806363d69c88146102d1578063647341eb146102e4576101d9565b80634303a542146102875780634582eab21461028f57806345fdbdb714610297578063586f84b21461029f576101d9565b80632e1a7d4d116101b85780632e1a7d4d146102245780633687617d1461023757806336b32396146102595780633e9ef66a14610279576101d9565b806209e437146101de5780630527c28f146101e85780631310e444146101fb575b600080fd5b6101e66103c4565b005b6101e66101f6366004610c7f565b610401565b61020e610209366004610d34565b610404565b60405161021b919061139a565b60405180910390f35b6101e6610232366004610d34565b61040b565b61024a610245366004610eac565b61045c565b60405161021b93929190611103565b61026c610267366004610cbc565b6104fc565b60405161021b9190611045565b6101e66101f6366004610cff565b61020e6105de565b6101e66105e5565b6101e661064a565b6102a761067c565b60405161021b9190611325565b6102bc610684565b60405161021b9190611330565b6101e661068c565b61026c6102df366004610c2d565b6106f1565b6101e66101f6366004610e77565b61020e6106fa565b61030d610308366004610d4d565b610708565b60405161021b9190611239565b6101e66107c5565b61020e610330366004610d34565b6107ca565b6101e66107d0565b61020e6107db565b6101e66101f6366004610de7565b61035b6107e0565b60405161021b9291906113a3565b610371610819565b60405161021b9190611066565b6101e661081e565b61038e610855565b60405161021b9190611387565b61020e6109ae565b6101e66103b1366004610d34565b6101f6565b6101e66101f6366004610d34565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f690611202565b60405180910390fd5b565b50565b506107c790565b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6582604051610451919061139a565b60405180910390a250565b505060408051808201825260048082527f1234567800000000000000000000000000000000000000000000000000000000602080840191909152835180850185528281527f87654321000000000000000000000000000000000000000000000000000000008183015284518086019095529184527f616d657400000000000000000000000000000000000000000000000000000000908401529093909250565b600060606040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525090506000818760405160200161054d929190611023565b6040516020818303038152906040528051906020012090506001818787876040516000815260200160405260405161058894939291906110e5565b6020604051602081039080840390855afa1580156105aa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015198975050505050505050565b6107c75b90565b604080518082018252601481527f5245564552545f574954485f434f4e5354414e54000000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611145565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f6906111cb565b6105e26109b4565b6105e26109cc565b604080518082018252601581527f524551554952455f574954485f434f4e5354414e540000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611145565b50929392505050565b600080546001019081905590565b6107106109ec565b50604080516080810182529182528051808201825260048082527f123456780000000000000000000000000000000000000000000000000000000060208381019190915280850192909252825180840184528181527f87654321000000000000000000000000000000000000000000000000000000008184015284840152825180840190935282527f616d65740000000000000000000000000000000000000000000000000000000090820152606082015290565b6103ff565b60010190565b600080546001019055565b600190565b60408051808201909152600581527f68656c6c6f0000000000000000000000000000000000000000000000000000006020820152600191565b606090565b7f61a6029a4c7ddee5824d171331eecbd015d26a271310a223718b837facb5b77160405161084b9061115f565b60405180910390a1565b61085d610a1a565b6040805160028082526060828101909352816020015b60608152602001906001900390816108735790505090506040518060400160405280600581526020017f3078313233000000000000000000000000000000000000000000000000000000815250816000815181106108cd57fe5b60200260200101819052506040518060400160405280600581526020017f30783332310000000000000000000000000000000000000000000000000000008152508160018151811061091b57fe5b6020908102919091018101919091526040805160c0810182526005608082018181527f307831323300000000000000000000000000000000000000000000000000000060a0840152825281840152808201939093528051808201909152600381527f6162630000000000000000000000000000000000000000000000000000000000918101919091526060820152905090565b6104d290565b60405180602001604052806109c7610a48565b905290565b60405180604001604052806109df610a1a565b8152602001606081525090565b60405180608001604052806109ff610a5b565b81526020016060815260200160608152602001606081525090565b604051806080016040528060608152602001600063ffffffff16815260200160608152602001606081525090565b6040518060200160405280600081525090565b60405180606001604052806000815260200160608152602001606081525090565b600082601f830112610a8c578081fd5b813567ffffffffffffffff811115610aa2578182fd5b6020610ab181828402016113bc565b828152925080830184820160005b84811015610ae857610ad6888584358a0101610af3565b83529183019190830190600101610abf565b505050505092915050565b600082601f830112610b03578081fd5b813567ffffffffffffffff811115610b19578182fd5b610b4a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016113bc565b9150808252836020828501011115610b6157600080fd5b8060208401602084013760009082016020015292915050565b600060808284031215610b8b578081fd5b610b9560806113bc565b90506000823567ffffffffffffffff80821115610bb0578283fd5b610bbc86838701610af3565b84526020850135915063ffffffff82168214610bd6578283fd5b8160208501526040850135915080821115610bef578283fd5b610bfb86838701610a7c565b60408501526060850135915080821115610c13578283fd5b50610c2085828601610af3565b6060840152505092915050565b600080600080600060a08688031215610c4557600080fd5b8535610c5081611413565b945060208601359350604086013592506060860135610c6e81611413565b949793965091946080013592915050565b600060208284031215610c9157600080fd5b813567ffffffffffffffff811115610ca857600080fd5b610cb484828501610a7c565b949350505050565b60008060008060808587031215610cd257600080fd5b84359350602085013560ff81168114610cea57600080fd5b93969395505050506040820135916060013590565b600060208284031215610d1157600080fd5b813567ffffffffffffffff811115610d2857600080fd5b610cb484828501610af3565b600060208284031215610d4657600080fd5b5035919050565b600060208284031215610d5e578081fd5b813567ffffffffffffffff80821115610d75578283fd5b81840160608187031215610d87578384fd5b610d9160606113bc565b925080358352602081013582811115610da8578485fd5b610db487828401610af3565b602085015250604081013582811115610dcb578485fd5b610dd787828401610af3565b6040850152509195945050505050565b600060208284031215610df8578081fd5b813567ffffffffffffffff80821115610e0f578283fd5b81840160408187031215610e21578384fd5b610e2b60406113bc565b9250803582811115610e3b578485fd5b610e4787828401610b7a565b845250602081013582811115610e5b578485fd5b610e6787828401610af3565b6020850152509195945050505050565b600060208284031215610e8957600080fd5b813567ffffffffffffffff811115610ea057600080fd5b610cb484828501610b7a565b600080600060608486031215610ec0578081fd5b83359250602084013567ffffffffffffffff80821115610ede578283fd5b610eea87838801610af3565b93506040860135915080821115610eff578283fd5b50610f0c86828701610af3565b9150509250925092565b60008151808452610f2e8160208601602086016113e3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000815160808452610f756080850182610f16565b6020915063ffffffff82850151168286015260408401518582036040870152818151808452848401915084858202850101858401600094505b82851015610ffc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868303018452610fe8828251610f16565b600195909501949387019391508601610fae565b506060880151955088810360608a01526110168187610f16565b9998505050505050505050565b600083516110358184602088016113e3565b9190910191825250602001919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600060208083018184528085518083526040860191506040848202870101925083870160005b828110156110d8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526110c6858351610f60565b9450928501929085019060010161108c565b5092979650505050505050565b93845260ff9290921660208401526040830152606082015260800190565b6000606082526111166060830186610f16565b82810360208401526111288186610f16565b838103604085015261113a8186610f16565b979650505050505050565b6000602082526111586020830184610f16565b9392505050565b60408082526004908201527f123456780000000000000000000000000000000000000000000000000000000060608201526080602082018190526005908201527f6c6f72656d00000000000000000000000000000000000000000000000000000060a082015260c00190565b6020808252600d908201527f53494d504c455f52455645525400000000000000000000000000000000000000604082015260600190565b6020808252600e908201527f53494d504c455f52455155495245000000000000000000000000000000000000604082015260600190565b600060208252825160806020840152805160a08401526020810151606060c0850152611269610100850182610f16565b604083015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608582030160e08601526112a48183610f16565b9250505060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808584030160408601526112e28383610f16565b60408701519350818682030160608701526112fd8185610f16565b92505060608601519250808583030160808601525061131c8183610f16565b95945050505050565b905151815260200190565b60006020825282516040602084015261134c6060840182610f60565b602085015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084820301604085015261131c8183610f16565b6000602082526111586020830184610f60565b90815260200190565b600083825260406020830152610cb46040830184610f16565b60405181810167ffffffffffffffff811182821017156113db57600080fd5b604052919050565b60005b838110156113fe5781810151838201526020016113e6565b8381111561140d576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461040157600080fdfea365627a7a723158207f0854b76fc684de0be1f1a5db2d486bc187ff28d1e99d27ca0f61b452a1942f6c6578706572696d656e74616cf564736f6c634300050b0040'; - public simpleRequire = { + '0x608060405234801561001057600080fd5b50600436106101d95760003560e01c806376f15d5b11610104578063bb607362116100a2578063d88be12f11610071578063d88be12f1461039b578063ee8b86fb146103a3578063f408fb3114610279578063fa315f9d146103b6576101d9565b8063bb60736214610353578063bdab168814610369578063cd3c0b971461037e578063d6d7618c14610386576101d9565b80638ee52b4e116100de5780638ee52b4e146103225780639a3b618514610335578063a3c2f6b61461033d578063ae2dae1714610345576101d9565b806376f15d5b146102f25780637833bec0146102fa5780637a791e6e1461031a576101d9565b80634303a5421161017c57806359c28add1161014b57806359c28add146102b45780635ba3c7c0146102c957806363d69c88146102d1578063647341eb146102e4576101d9565b80634303a542146102875780634582eab21461028f57806345fdbdb714610297578063586f84b21461029f576101d9565b80632e1a7d4d116101b85780632e1a7d4d146102245780633687617d1461023757806336b32396146102595780633e9ef66a14610279576101d9565b806209e437146101de5780630527c28f146101e85780631310e444146101fb575b600080fd5b6101e66103c4565b005b6101e66101f6366004610c7f565b610401565b61020e610209366004610d87565b610404565b60405161021b91906113e8565b60405180910390f35b6101e6610232366004610d87565b61040b565b61024a610245366004610efc565b61045c565b60405161021b93929190611151565b61026c610267366004610d0b565b6104fc565b60405161021b9190611094565b6101e66101f6366004610d4c565b61020e6105de565b6101e66105e5565b6101e661064a565b6102a761067c565b60405161021b9190611373565b6102bc610684565b60405161021b919061137e565b6101e661068c565b61026c6102df366004610c2e565b6106f1565b6101e66101f6366004610ec9565b61020e6106fa565b61030d610308366004610d9f565b610708565b60405161021b9190611287565b6101e66107c5565b61020e610330366004610d87565b6107ca565b6101e66107d0565b61020e6107db565b6101e66101f6366004610e39565b61035b6107e0565b60405161021b9291906113f1565b610371610819565b60405161021b91906110b5565b6101e661081e565b61038e610855565b60405161021b91906113d5565b61020e6109ae565b6101e66103b1366004610d87565b6101f6565b6101e66101f6366004610d87565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f690611250565b60405180910390fd5b565b50565b506107c790565b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b658260405161045191906113e8565b60405180910390a250565b505060408051808201825260048082527f1234567800000000000000000000000000000000000000000000000000000000602080840191909152835180850185528281527f87654321000000000000000000000000000000000000000000000000000000008183015284518086019095529184527f616d657400000000000000000000000000000000000000000000000000000000908401529093909250565b600060606040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525090506000818760405160200161054d929190611072565b604051602081830303815290604052805190602001209050600181878787604051600081526020016040526040516105889493929190611133565b6020604051602081039080840390855afa1580156105aa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015198975050505050505050565b6107c75b90565b604080518082018252601481527f5245564552545f574954485f434f4e5354414e54000000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611193565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f690611219565b6105e26109b4565b6105e26109cc565b604080518082018252601581527f524551554952455f574954485f434f4e5354414e540000000000000000000000602082015290517f08c379a00000000000000000000000000000000000000000000000000000000081526103f69190600401611193565b50929392505050565b600080546001019081905590565b6107106109ec565b50604080516080810182529182528051808201825260048082527f123456780000000000000000000000000000000000000000000000000000000060208381019190915280850192909252825180840184528181527f87654321000000000000000000000000000000000000000000000000000000008184015284840152825180840190935282527f616d65740000000000000000000000000000000000000000000000000000000090820152606082015290565b6103ff565b60010190565b600080546001019055565b600190565b60408051808201909152600581527f68656c6c6f0000000000000000000000000000000000000000000000000000006020820152600191565b606090565b7f61a6029a4c7ddee5824d171331eecbd015d26a271310a223718b837facb5b77160405161084b906111ad565b60405180910390a1565b61085d610a1a565b6040805160028082526060828101909352816020015b60608152602001906001900390816108735790505090506040518060400160405280600581526020017f3078313233000000000000000000000000000000000000000000000000000000815250816000815181106108cd57fe5b60200260200101819052506040518060400160405280600581526020017f30783332310000000000000000000000000000000000000000000000000000008152508160018151811061091b57fe5b6020908102919091018101919091526040805160c0810182526005608082018181527f307831323300000000000000000000000000000000000000000000000000000060a0840152825281840152808201939093528051808201909152600381527f6162630000000000000000000000000000000000000000000000000000000000918101919091526060820152905090565b6104d290565b60405180602001604052806109c7610a48565b905290565b60405180604001604052806109df610a1a565b8152602001606081525090565b60405180608001604052806109ff610a5b565b81526020016060815260200160608152602001606081525090565b604051806080016040528060608152602001600063ffffffff16815260200160608152602001606081525090565b6040518060200160405280600081525090565b60405180606001604052806000815260200160608152602001606081525090565b600082601f830112610a8c578081fd5b8135610a9f610a9a82611431565b61140a565b8181529150602080830190840160005b83811015610adc57610ac78760208435890101610ae6565b83526020928301929190910190600101610aaf565b5050505092915050565b600082601f830112610af6578081fd5b813567ffffffffffffffff811115610b0c578182fd5b610b3d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161140a565b9150808252836020828501011115610b5457600080fd5b8060208401602084013760009082016020015292915050565b600060808284031215610b7e578081fd5b610b88608061140a565b9050813567ffffffffffffffff80821115610ba257600080fd5b610bae85838601610ae6565b8352610bbd8560208601610c14565b60208401526040840135915080821115610bd657600080fd5b610be285838601610a7c565b60408401526060840135915080821115610bfb57600080fd5b50610c0884828501610ae6565b60608301525092915050565b803563ffffffff81168114610c2857600080fd5b92915050565b600080600080600060a08688031215610c45578081fd5b8535610c5081611481565b945060208601359350604086013592506060860135610c6e81611481565b949793965091946080013592915050565b60006020808385031215610c91578182fd5b823567ffffffffffffffff811115610ca7578283fd5b80840185601f820112610cb8578384fd5b80359150610cc8610a9a83611431565b82815283810190828501865b85811015610cfd57610ceb8a888435880101610ae6565b84529286019290860190600101610cd4565b509098975050505050505050565b60008060008060808587031215610d20578384fd5b84359350602085013560ff81168114610d37578384fd5b93969395505050506040820135916060013590565b600060208284031215610d5d578081fd5b813567ffffffffffffffff811115610d73578182fd5b610d7f84828501610ae6565b949350505050565b600060208284031215610d98578081fd5b5035919050565b600060208284031215610db0578081fd5b813567ffffffffffffffff80821115610dc7578283fd5b81840160608187031215610dd9578384fd5b610de3606061140a565b925080358352602081013582811115610dfa578485fd5b610e0687828401610ae6565b602085015250604081013582811115610e1d578485fd5b610e2987828401610ae6565b6040850152509195945050505050565b600060208284031215610e4a578081fd5b813567ffffffffffffffff80821115610e61578283fd5b81840160408187031215610e73578384fd5b610e7d604061140a565b9250803582811115610e8d578485fd5b610e9987828401610b6d565b845250602081013582811115610ead578485fd5b610eb987828401610ae6565b6020850152509195945050505050565b600060208284031215610eda578081fd5b813567ffffffffffffffff811115610ef0578182fd5b610d7f84828501610b6d565b600080600060608486031215610f10578081fd5b83359250602084013567ffffffffffffffff80821115610f2e578283fd5b610f3a87838801610ae6565b93506040860135915080821115610f4f578283fd5b50610f5c86828701610ae6565b9150509250925092565b60008151808452610f7e816020860160208601611451565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000815160808452610fc56080850182610f66565b6020915063ffffffff828501511682860152604084015185820360408701528181518084528484019150848582028501018584018794505b8285101561104b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868303018452611037828251610f66565b600195909501949387019391508601610ffd565b506060880151955088810360608a01526110658187610f66565b9998505050505050505050565b60008351611084818460208801611451565b9190910191825250602001919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611126577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452611114858351610fb0565b945092850192908501906001016110da565b5092979650505050505050565b93845260ff9290921660208401526040830152606082015260800190565b6000606082526111646060830186610f66565b82810360208401526111768186610f66565b83810360408501526111888186610f66565b979650505050505050565b6000602082526111a66020830184610f66565b9392505050565b60408082526004908201527f123456780000000000000000000000000000000000000000000000000000000060608201526080602082018190526005908201527f6c6f72656d00000000000000000000000000000000000000000000000000000060a082015260c00190565b6020808252600d908201527f53494d504c455f52455645525400000000000000000000000000000000000000604082015260600190565b6020808252600e908201527f53494d504c455f52455155495245000000000000000000000000000000000000604082015260600190565b600060208252825160806020840152805160a08401526020810151606060c08501526112b7610100850182610f66565b604083015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608582030160e08601526112f28183610f66565b9250505060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808584030160408601526113308383610f66565b604087015193508186820301606087015261134b8185610f66565b92505060608601519250808583030160808601525061136a8183610f66565b95945050505050565b905151815260200190565b60006020825282516040602084015261139a6060840182610fb0565b602085015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084820301604085015261136a8183610f66565b6000602082526111a66020830184610fb0565b90815260200190565b600083825260406020830152610d7f6040830184610f66565b60405181810167ffffffffffffffff8111828210171561142957600080fd5b604052919050565b600067ffffffffffffffff821115611447578081fd5b5060209081020190565b60005b8381101561146c578181015183820152602001611454565b8381111561147b576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461040157600080fdfea365627a7a723158204f5b227587475ada330d11bfb46020f41172555bd06234eaaad1a7d10a4c2a396c6578706572696d656e74616cf564736f6c634300050c0040'; + /** + * a method that accepts an array of bytes + */ + public acceptsAnArrayOfBytes = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. + * @param a the array of bytes being accepted */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + async callAsync(a: string[], callData: Partial = {}, defaultBlock?: BlockParam): Promise { + assert.isArray('a', a); assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -73,7 +78,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('simpleRequire()', []); + const encodedData = self._strictEncodeArguments('acceptsAnArrayOfBytes(bytes[])', [a]); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -85,7 +90,7 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('simpleRequire()'); + const abiEncoder = self._lookupAbiEncoder('acceptsAnArrayOfBytes(bytes[])'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming @@ -95,11 +100,13 @@ export class AbiGenDummyContract extends BaseContract { * Returns the ABI encoded transaction data needed to send an Ethereum transaction calling this method. Before * sending the Ethereum tx, this encoded tx data can first be sent to a separate signing service or can be used * to create a 0x transaction (see protocol spec for more details). + * @param a the array of bytes being accepted * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(): string { + getABIEncodedTransactionData(a: string[]): string { + assert.isArray('a', a); const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('simpleRequire()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('acceptsAnArrayOfBytes(bytes[])', [a]); return abiEncodedTransactionData; }, /** @@ -107,11 +114,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): void { + getABIDecodedTransactionData(callData: string): [string[]] { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleRequire()'); + const abiEncoder = self._lookupAbiEncoder('acceptsAnArrayOfBytes(bytes[])'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); + const abiDecodedCallData = abiEncoder.strictDecode<[string[]]>(callData); return abiDecodedCallData; }, /** @@ -121,7 +128,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleRequire()'); + const abiEncoder = self._lookupAbiEncoder('acceptsAnArrayOfBytes(bytes[])'); // tslint:disable boolean-naming const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; @@ -131,22 +138,18 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleRequire()'); + const abiEncoder = self._lookupAbiEncoder('acceptsAnArrayOfBytes(bytes[])'); return abiEncoder.getSelector(); }, }; - /** - * a method that accepts an array of bytes - */ - public acceptsAnArrayOfBytes = { + public acceptsBytes = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. - * @param a the array of bytes being accepted */ - async callAsync(a: string[], callData: Partial = {}, defaultBlock?: BlockParam): Promise { - assert.isArray('a', a); + async callAsync(a: string, callData: Partial = {}, defaultBlock?: BlockParam): Promise { + assert.isString('a', a); assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -156,7 +159,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('acceptsAnArrayOfBytes(bytes[])', [a]); + const encodedData = self._strictEncodeArguments('acceptsBytes(bytes)', [a]); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -168,7 +171,7 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('acceptsAnArrayOfBytes(bytes[])'); + const abiEncoder = self._lookupAbiEncoder('acceptsBytes(bytes)'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming @@ -178,13 +181,12 @@ export class AbiGenDummyContract extends BaseContract { * Returns the ABI encoded transaction data needed to send an Ethereum transaction calling this method. Before * sending the Ethereum tx, this encoded tx data can first be sent to a separate signing service or can be used * to create a 0x transaction (see protocol spec for more details). - * @param a the array of bytes being accepted * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(a: string[]): string { - assert.isArray('a', a); + getABIEncodedTransactionData(a: string): string { + assert.isString('a', a); const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('acceptsAnArrayOfBytes(bytes[])', [a]); + const abiEncodedTransactionData = self._strictEncodeArguments('acceptsBytes(bytes)', [a]); return abiEncodedTransactionData; }, /** @@ -192,11 +194,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): [string[]] { + getABIDecodedTransactionData(callData: string): [string] { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('acceptsAnArrayOfBytes(bytes[])'); + const abiEncoder = self._lookupAbiEncoder('acceptsBytes(bytes)'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode<[string[]]>(callData); + const abiDecodedCallData = abiEncoder.strictDecode<[string]>(callData); return abiDecodedCallData; }, /** @@ -206,7 +208,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('acceptsAnArrayOfBytes(bytes[])'); + const abiEncoder = self._lookupAbiEncoder('acceptsBytes(bytes)'); // tslint:disable boolean-naming const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; @@ -216,25 +218,29 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('acceptsAnArrayOfBytes(bytes[])'); + const abiEncoder = self._lookupAbiEncoder('acceptsBytes(bytes)'); return abiEncoder.getSelector(); }, }; /** - * Tests decoding when both input and output are non-empty. + * Tests decoding when the input and output are complex. */ - public simpleInputSimpleOutput = { + public complexInputComplexOutput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ async callAsync( - index_0: BigNumber, + complexInput: { foo: BigNumber; bar: string; car: string }, callData: Partial = {}, defaultBlock?: BlockParam, - ): Promise { - assert.isBigNumber('index_0', index_0); + ): Promise<{ + input: { foo: BigNumber; bar: string; car: string }; + lorem: string; + ipsum: string; + dolor: string; + }> { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -244,7 +250,9 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('simpleInputSimpleOutput(uint256)', [index_0]); + const encodedData = self._strictEncodeArguments('complexInputComplexOutput((uint256,bytes,string))', [ + complexInput, + ]); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -256,9 +264,14 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('simpleInputSimpleOutput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('complexInputComplexOutput((uint256,bytes,string))'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue<{ + input: { foo: BigNumber; bar: string; car: string }; + lorem: string; + ipsum: string; + dolor: string; + }>(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -268,12 +281,137 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(index_0: BigNumber): string { - assert.isBigNumber('index_0', index_0); + getABIEncodedTransactionData(complexInput: { foo: BigNumber; bar: string; car: string }): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('simpleInputSimpleOutput(uint256)', [ - index_0, + const abiEncodedTransactionData = self._strictEncodeArguments( + 'complexInputComplexOutput((uint256,bytes,string))', + [complexInput], + ); + return abiEncodedTransactionData; + }, + /** + * Decode the ABI-encoded transaction data into its input arguments + * @param callData The ABI-encoded transaction data + * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. + */ + getABIDecodedTransactionData(callData: string): { foo: BigNumber; bar: string; car: string } { + const self = (this as any) as AbiGenDummyContract; + const abiEncoder = self._lookupAbiEncoder('complexInputComplexOutput((uint256,bytes,string))'); + // tslint:disable boolean-naming + const abiDecodedCallData = abiEncoder.strictDecode<{ foo: BigNumber; bar: string; car: string }>(callData); + return abiDecodedCallData; + }, + /** + * Decode the ABI-encoded return data from a transaction + * @param returnData the data returned after transaction execution + * @returns An array representing the output results in order. Keynames of nested structs are preserved. + */ + getABIDecodedReturnData( + returnData: string, + ): { input: { foo: BigNumber; bar: string; car: string }; lorem: string; ipsum: string; dolor: string } { + const self = (this as any) as AbiGenDummyContract; + const abiEncoder = self._lookupAbiEncoder('complexInputComplexOutput((uint256,bytes,string))'); + // tslint:disable boolean-naming + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<{ + input: { foo: BigNumber; bar: string; car: string }; + lorem: string; + ipsum: string; + dolor: string; + }>(returnData); + return abiDecodedReturnData; + }, + /** + * Returns the 4 byte function selector as a hex string. + */ + getSelector(): string { + const self = (this as any) as AbiGenDummyContract; + const abiEncoder = self._lookupAbiEncoder('complexInputComplexOutput((uint256,bytes,string))'); + return abiEncoder.getSelector(); + }, + }; + /** + * test that devdocs will be generated and + * that multiline devdocs will look okay + */ + public ecrecoverFn = { + /** + * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an + * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas + * since they don't modify state. + * @param hash description of some hash. Let's make this line super long to + * demonstrate hanging indents for method params. It has to be more than + * one hundred twenty columns. + * @param v some v, recovery id + * @param r ECDSA r output + * @param s ECDSA s output + * @returns the signerAddress that created this signature. this line too is super long in order to demonstrate the proper hanging indentation in generated code. + */ + async callAsync( + hash: string, + v: number | BigNumber, + r: string, + s: string, + callData: Partial = {}, + defaultBlock?: BlockParam, + ): Promise { + assert.isString('hash', hash); + assert.isNumberOrBigNumber('v', v); + assert.isString('r', r); + assert.isString('s', s); + assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ + schemas.addressSchema, + schemas.numberSchema, + schemas.jsNumber, + ]); + if (defaultBlock !== undefined) { + assert.isBlockParam('defaultBlock', defaultBlock); + } + const self = (this as any) as AbiGenDummyContract; + const encodedData = self._strictEncodeArguments('ecrecoverFn(bytes32,uint8,bytes32,bytes32)', [ + hash, + v, + r, + s, ]); + const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); + + let rawCallResult; + try { + rawCallResult = await self._evmExecAsync(encodedDataBytes); + } catch (err) { + BaseContract._throwIfThrownErrorIsRevertError(err); + throw err; + } + BaseContract._throwIfCallResultIsRevertError(rawCallResult); + + const abiEncoder = self._lookupAbiEncoder('ecrecoverFn(bytes32,uint8,bytes32,bytes32)'); + // tslint:disable boolean-naming + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + // tslint:enable boolean-naming + return result; + }, + /** + * Returns the ABI encoded transaction data needed to send an Ethereum transaction calling this method. Before + * sending the Ethereum tx, this encoded tx data can first be sent to a separate signing service or can be used + * to create a 0x transaction (see protocol spec for more details). + * @param hash description of some hash. Let's make this line super long to + * demonstrate hanging indents for method params. It has to be more than + * one hundred twenty columns. + * @param v some v, recovery id + * @param r ECDSA r output + * @param s ECDSA s output + * @returns The ABI encoded transaction data as a string + */ + getABIEncodedTransactionData(hash: string, v: number | BigNumber, r: string, s: string): string { + assert.isString('hash', hash); + assert.isNumberOrBigNumber('v', v); + assert.isString('r', r); + assert.isString('s', s); + const self = (this as any) as AbiGenDummyContract; + const abiEncodedTransactionData = self._strictEncodeArguments( + 'ecrecoverFn(bytes32,uint8,bytes32,bytes32)', + [hash, v, r, s], + ); return abiEncodedTransactionData; }, /** @@ -281,11 +419,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): BigNumber { + getABIDecodedTransactionData(callData: string): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleInputSimpleOutput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('ecrecoverFn(bytes32,uint8,bytes32,bytes32)'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -293,11 +431,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): BigNumber { + getABIDecodedReturnData(returnData: string): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleInputSimpleOutput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('ecrecoverFn(bytes32,uint8,bytes32,bytes32)'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -305,11 +443,11 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleInputSimpleOutput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('ecrecoverFn(bytes32,uint8,bytes32,bytes32)'); return abiEncoder.getSelector(); }, }; - public withdraw = { + public emitSimpleEvent = { /** * Sends an Ethereum transaction executing this method with the supplied parameters. This is a read/write * Ethereum operation and will cost gas. @@ -317,13 +455,11 @@ export class AbiGenDummyContract extends BaseContract { * @returns The hash of the transaction */ async sendTransactionAsync( - wad: BigNumber, txData?: Partial | undefined, opts: SendTransactionOpts = { shouldValidate: true }, ): Promise { - assert.isBigNumber('wad', wad); const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('withdraw(uint256)', [wad]); + const encodedData = self._strictEncodeArguments('emitSimpleEvent()', []); const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( { to: self.address, @@ -337,7 +473,7 @@ export class AbiGenDummyContract extends BaseContract { } if (opts.shouldValidate !== false) { - await self.withdraw.callAsync(wad, txDataWithDefaults); + await self.emitSimpleEvent.callAsync(txDataWithDefaults); } const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); @@ -351,13 +487,11 @@ export class AbiGenDummyContract extends BaseContract { * @returns A promise that resolves when the transaction is successful */ awaitTransactionSuccessAsync( - wad: BigNumber, txData?: Partial, opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, ): PromiseWithTransactionHash { - assert.isBigNumber('wad', wad); const self = (this as any) as AbiGenDummyContract; - const txHashPromise = self.withdraw.sendTransactionAsync(wad, txData, opts); + const txHashPromise = self.emitSimpleEvent.sendTransactionAsync(txData, opts); return new PromiseWithTransactionHash( txHashPromise, (async (): Promise => { @@ -375,10 +509,9 @@ export class AbiGenDummyContract extends BaseContract { * @param txData Additional data for transaction * @returns The hash of the transaction */ - async estimateGasAsync(wad: BigNumber, txData?: Partial | undefined): Promise { - assert.isBigNumber('wad', wad); + async estimateGasAsync(txData?: Partial | undefined): Promise { const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('withdraw(uint256)', [wad]); + const encodedData = self._strictEncodeArguments('emitSimpleEvent()', []); const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( { to: self.address, @@ -399,8 +532,7 @@ export class AbiGenDummyContract extends BaseContract { * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(wad: BigNumber, callData: Partial = {}, defaultBlock?: BlockParam): Promise { - assert.isBigNumber('wad', wad); + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -410,7 +542,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('withdraw(uint256)', [wad]); + const encodedData = self._strictEncodeArguments('emitSimpleEvent()', []); const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( { to: self.address, @@ -430,7 +562,7 @@ export class AbiGenDummyContract extends BaseContract { throw err; } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('withdraw(uint256)'); + const abiEncoder = self._lookupAbiEncoder('emitSimpleEvent()'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming @@ -442,10 +574,9 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(wad: BigNumber): string { - assert.isBigNumber('wad', wad); + getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('withdraw(uint256)', [wad]); + const abiEncodedTransactionData = self._strictEncodeArguments('emitSimpleEvent()', []); return abiEncodedTransactionData; }, /** @@ -453,11 +584,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): [BigNumber] { + getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('withdraw(uint256)'); + const abiEncoder = self._lookupAbiEncoder('emitSimpleEvent()'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode<[BigNumber]>(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -467,7 +598,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('withdraw(uint256)'); + const abiEncoder = self._lookupAbiEncoder('emitSimpleEvent()'); // tslint:disable boolean-naming const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; @@ -477,29 +608,20 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('withdraw(uint256)'); + const abiEncoder = self._lookupAbiEncoder('emitSimpleEvent()'); return abiEncoder.getSelector(); }, }; - /** - * Tests decoding when the input and output are complex and have more than one argument. - */ - public multiInputMultiOutput = { + public methodReturningArrayOfStructs = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ async callAsync( - index_0: BigNumber, - index_1: string, - index_2: string, callData: Partial = {}, defaultBlock?: BlockParam, - ): Promise<[string, string, string]> { - assert.isBigNumber('index_0', index_0); - assert.isString('index_1', index_1); - assert.isString('index_2', index_2); + ): Promise> { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -509,11 +631,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('multiInputMultiOutput(uint256,bytes,string)', [ - index_0, - index_1, - index_2, - ]); + const encodedData = self._strictEncodeArguments('methodReturningArrayOfStructs()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -525,9 +643,11 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('multiInputMultiOutput(uint256,bytes,string)'); + const abiEncoder = self._lookupAbiEncoder('methodReturningArrayOfStructs()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue<[string, string, string]>(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue< + Array<{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }> + >(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -537,15 +657,9 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(index_0: BigNumber, index_1: string, index_2: string): string { - assert.isBigNumber('index_0', index_0); - assert.isString('index_1', index_1); - assert.isString('index_2', index_2); + getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments( - 'multiInputMultiOutput(uint256,bytes,string)', - [index_0, index_1, index_2], - ); + const abiEncodedTransactionData = self._strictEncodeArguments('methodReturningArrayOfStructs()', []); return abiEncodedTransactionData; }, /** @@ -553,11 +667,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): [BigNumber, string, string] { + getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('multiInputMultiOutput(uint256,bytes,string)'); + const abiEncoder = self._lookupAbiEncoder('methodReturningArrayOfStructs()'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode<[BigNumber, string, string]>(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -565,11 +679,15 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): [string, string, string] { + getABIDecodedReturnData( + returnData: string, + ): Array<{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }> { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('multiInputMultiOutput(uint256,bytes,string)'); + const abiEncoder = self._lookupAbiEncoder('methodReturningArrayOfStructs()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<[string, string, string]>(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue< + Array<{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }> + >(returnData); return abiDecodedReturnData; }, /** @@ -577,39 +695,17 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('multiInputMultiOutput(uint256,bytes,string)'); + const abiEncoder = self._lookupAbiEncoder('methodReturningArrayOfStructs()'); return abiEncoder.getSelector(); }, }; - /** - * test that devdocs will be generated and - * that multiline devdocs will look okay - */ - public ecrecoverFn = { + public methodReturningMultipleValues = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. - * @param hash description of some hash. Let's make this line super long to - * demonstrate hanging indents for method params. It has to be more than - * one hundred twenty columns. - * @param v some v, recovery id - * @param r ECDSA r output - * @param s ECDSA s output - * @returns the signerAddress that created this signature. this line too is super long in order to demonstrate the proper hanging indentation in generated code. */ - async callAsync( - hash: string, - v: number | BigNumber, - r: string, - s: string, - callData: Partial = {}, - defaultBlock?: BlockParam, - ): Promise { - assert.isString('hash', hash); - assert.isNumberOrBigNumber('v', v); - assert.isString('r', r); - assert.isString('s', s); + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise<[BigNumber, string]> { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -619,12 +715,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('ecrecoverFn(bytes32,uint8,bytes32,bytes32)', [ - hash, - v, - r, - s, - ]); + const encodedData = self._strictEncodeArguments('methodReturningMultipleValues()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -636,9 +727,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('ecrecoverFn(bytes32,uint8,bytes32,bytes32)'); + const abiEncoder = self._lookupAbiEncoder('methodReturningMultipleValues()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue<[BigNumber, string]>(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -646,24 +737,11 @@ export class AbiGenDummyContract extends BaseContract { * Returns the ABI encoded transaction data needed to send an Ethereum transaction calling this method. Before * sending the Ethereum tx, this encoded tx data can first be sent to a separate signing service or can be used * to create a 0x transaction (see protocol spec for more details). - * @param hash description of some hash. Let's make this line super long to - * demonstrate hanging indents for method params. It has to be more than - * one hundred twenty columns. - * @param v some v, recovery id - * @param r ECDSA r output - * @param s ECDSA s output * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(hash: string, v: number | BigNumber, r: string, s: string): string { - assert.isString('hash', hash); - assert.isNumberOrBigNumber('v', v); - assert.isString('r', r); - assert.isString('s', s); + getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments( - 'ecrecoverFn(bytes32,uint8,bytes32,bytes32)', - [hash, v, r, s], - ); + const abiEncodedTransactionData = self._strictEncodeArguments('methodReturningMultipleValues()', []); return abiEncodedTransactionData; }, /** @@ -671,11 +749,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): string { + getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('ecrecoverFn(bytes32,uint8,bytes32,bytes32)'); + const abiEncoder = self._lookupAbiEncoder('methodReturningMultipleValues()'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -683,11 +761,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): string { + getABIDecodedReturnData(returnData: string): [BigNumber, string] { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('ecrecoverFn(bytes32,uint8,bytes32,bytes32)'); + const abiEncoder = self._lookupAbiEncoder('methodReturningMultipleValues()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<[BigNumber, string]>(returnData); return abiDecodedReturnData; }, /** @@ -695,18 +773,20 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('ecrecoverFn(bytes32,uint8,bytes32,bytes32)'); + const abiEncoder = self._lookupAbiEncoder('methodReturningMultipleValues()'); return abiEncoder.getSelector(); }, }; - public acceptsBytes = { + public methodUsingNestedStructWithInnerStructNotUsedElsewhere = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(a: string, callData: Partial = {}, defaultBlock?: BlockParam): Promise { - assert.isString('a', a); + async callAsync( + callData: Partial = {}, + defaultBlock?: BlockParam, + ): Promise<{ innerStruct: { aField: BigNumber } }> { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -716,7 +796,10 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('acceptsBytes(bytes)', [a]); + const encodedData = self._strictEncodeArguments( + 'methodUsingNestedStructWithInnerStructNotUsedElsewhere()', + [], + ); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -728,9 +811,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('acceptsBytes(bytes)'); + const abiEncoder = self._lookupAbiEncoder('methodUsingNestedStructWithInnerStructNotUsedElsewhere()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue<{ innerStruct: { aField: BigNumber } }>(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -740,10 +823,12 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(a: string): string { - assert.isString('a', a); + getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('acceptsBytes(bytes)', [a]); + const abiEncodedTransactionData = self._strictEncodeArguments( + 'methodUsingNestedStructWithInnerStructNotUsedElsewhere()', + [], + ); return abiEncodedTransactionData; }, /** @@ -751,11 +836,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): [string] { + getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('acceptsBytes(bytes)'); + const abiEncoder = self._lookupAbiEncoder('methodUsingNestedStructWithInnerStructNotUsedElsewhere()'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode<[string]>(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -763,11 +848,13 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): void { + getABIDecodedReturnData(returnData: string): { innerStruct: { aField: BigNumber } } { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('acceptsBytes(bytes)'); + const abiEncoder = self._lookupAbiEncoder('methodUsingNestedStructWithInnerStructNotUsedElsewhere()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<{ innerStruct: { aField: BigNumber } }>( + returnData, + ); return abiDecodedReturnData; }, /** @@ -775,20 +862,29 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('acceptsBytes(bytes)'); + const abiEncoder = self._lookupAbiEncoder('methodUsingNestedStructWithInnerStructNotUsedElsewhere()'); return abiEncoder.getSelector(); }, }; /** - * Tests decoding when input is empty and output is non-empty. + * Tests decoding when the input and output are complex and have more than one argument. */ - public noInputSimpleOutput = { + public multiInputMultiOutput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + async callAsync( + index_0: BigNumber, + index_1: string, + index_2: string, + callData: Partial = {}, + defaultBlock?: BlockParam, + ): Promise<[string, string, string]> { + assert.isBigNumber('index_0', index_0); + assert.isString('index_1', index_1); + assert.isString('index_2', index_2); assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -798,7 +894,11 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('noInputSimpleOutput()', []); + const encodedData = self._strictEncodeArguments('multiInputMultiOutput(uint256,bytes,string)', [ + index_0, + index_1, + index_2, + ]); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -810,9 +910,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('noInputSimpleOutput()'); + const abiEncoder = self._lookupAbiEncoder('multiInputMultiOutput(uint256,bytes,string)'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue<[string, string, string]>(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -822,9 +922,15 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(): string { + getABIEncodedTransactionData(index_0: BigNumber, index_1: string, index_2: string): string { + assert.isBigNumber('index_0', index_0); + assert.isString('index_1', index_1); + assert.isString('index_2', index_2); const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('noInputSimpleOutput()', []); + const abiEncodedTransactionData = self._strictEncodeArguments( + 'multiInputMultiOutput(uint256,bytes,string)', + [index_0, index_1, index_2], + ); return abiEncodedTransactionData; }, /** @@ -832,11 +938,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): void { + getABIDecodedTransactionData(callData: string): [BigNumber, string, string] { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('noInputSimpleOutput()'); + const abiEncoder = self._lookupAbiEncoder('multiInputMultiOutput(uint256,bytes,string)'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); + const abiDecodedCallData = abiEncoder.strictDecode<[BigNumber, string, string]>(callData); return abiDecodedCallData; }, /** @@ -844,11 +950,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): BigNumber { + getABIDecodedReturnData(returnData: string): [string, string, string] { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('noInputSimpleOutput()'); + const abiEncoder = self._lookupAbiEncoder('multiInputMultiOutput(uint256,bytes,string)'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<[string, string, string]>(returnData); return abiDecodedReturnData; }, /** @@ -856,17 +962,29 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('noInputSimpleOutput()'); + const abiEncoder = self._lookupAbiEncoder('multiInputMultiOutput(uint256,bytes,string)'); return abiEncoder.getSelector(); }, }; - public revertWithConstant = { + public nestedStructInput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + async callAsync( + n: { + innerStruct: { + someBytes: string; + anInteger: number | BigNumber; + aDynamicArrayOfBytes: string[]; + aString: string; + }; + description: string; + }, + callData: Partial = {}, + defaultBlock?: BlockParam, + ): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -876,7 +994,10 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('revertWithConstant()', []); + const encodedData = self._strictEncodeArguments( + 'nestedStructInput(((bytes,uint32,bytes[],string),string))', + [n], + ); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -888,7 +1009,7 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('revertWithConstant()'); + const abiEncoder = self._lookupAbiEncoder('nestedStructInput(((bytes,uint32,bytes[],string),string))'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming @@ -900,9 +1021,20 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(): string { + getABIEncodedTransactionData(n: { + innerStruct: { + someBytes: string; + anInteger: number | BigNumber; + aDynamicArrayOfBytes: string[]; + aString: string; + }; + description: string; + }): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('revertWithConstant()', []); + const abiEncodedTransactionData = self._strictEncodeArguments( + 'nestedStructInput(((bytes,uint32,bytes[],string),string))', + [n], + ); return abiEncodedTransactionData; }, /** @@ -910,11 +1042,30 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): void { + getABIDecodedTransactionData( + callData: string, + ): [ + { + innerStruct: { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }; + description: string; + } + ] { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('revertWithConstant()'); + const abiEncoder = self._lookupAbiEncoder('nestedStructInput(((bytes,uint32,bytes[],string),string))'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); + const abiDecodedCallData = abiEncoder.strictDecode< + [ + { + innerStruct: { + someBytes: string; + anInteger: number; + aDynamicArrayOfBytes: string[]; + aString: string; + }; + description: string; + } + ] + >(callData); return abiDecodedCallData; }, /** @@ -924,7 +1075,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('revertWithConstant()'); + const abiEncoder = self._lookupAbiEncoder('nestedStructInput(((bytes,uint32,bytes[],string),string))'); // tslint:disable boolean-naming const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; @@ -934,17 +1085,23 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('revertWithConstant()'); + const abiEncoder = self._lookupAbiEncoder('nestedStructInput(((bytes,uint32,bytes[],string),string))'); return abiEncoder.getSelector(); }, }; - public simpleRevert = { + public nestedStructOutput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + async callAsync( + callData: Partial = {}, + defaultBlock?: BlockParam, + ): Promise<{ + innerStruct: { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }; + description: string; + }> { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -954,7 +1111,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('simpleRevert()', []); + const encodedData = self._strictEncodeArguments('nestedStructOutput()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -966,9 +1123,12 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('simpleRevert()'); + const abiEncoder = self._lookupAbiEncoder('nestedStructOutput()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue<{ + innerStruct: { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }; + description: string; + }>(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -980,7 +1140,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('simpleRevert()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('nestedStructOutput()', []); return abiEncodedTransactionData; }, /** @@ -990,7 +1150,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleRevert()'); + const abiEncoder = self._lookupAbiEncoder('nestedStructOutput()'); // tslint:disable boolean-naming const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; @@ -1000,11 +1160,19 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): void { + getABIDecodedReturnData( + returnData: string, + ): { + innerStruct: { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }; + description: string; + } { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleRevert()'); + const abiEncoder = self._lookupAbiEncoder('nestedStructOutput()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<{ + innerStruct: { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }; + description: string; + }>(returnData); return abiDecodedReturnData; }, /** @@ -1012,20 +1180,20 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleRevert()'); + const abiEncoder = self._lookupAbiEncoder('nestedStructOutput()'); return abiEncoder.getSelector(); }, }; - public methodUsingNestedStructWithInnerStructNotUsedElsewhere = { + /** + * Tests decoding when both input and output are empty. + */ + public noInputNoOutput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync( - callData: Partial = {}, - defaultBlock?: BlockParam, - ): Promise<{ innerStruct: { aField: BigNumber } }> { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -1035,10 +1203,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments( - 'methodUsingNestedStructWithInnerStructNotUsedElsewhere()', - [], - ); + const encodedData = self._strictEncodeArguments('noInputNoOutput()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -1050,9 +1215,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('methodUsingNestedStructWithInnerStructNotUsedElsewhere()'); + const abiEncoder = self._lookupAbiEncoder('noInputNoOutput()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue<{ innerStruct: { aField: BigNumber } }>(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -1064,10 +1229,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments( - 'methodUsingNestedStructWithInnerStructNotUsedElsewhere()', - [], - ); + const abiEncodedTransactionData = self._strictEncodeArguments('noInputNoOutput()', []); return abiEncodedTransactionData; }, /** @@ -1077,7 +1239,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('methodUsingNestedStructWithInnerStructNotUsedElsewhere()'); + const abiEncoder = self._lookupAbiEncoder('noInputNoOutput()'); // tslint:disable boolean-naming const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; @@ -1087,13 +1249,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): { innerStruct: { aField: BigNumber } } { + getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('methodUsingNestedStructWithInnerStructNotUsedElsewhere()'); + const abiEncoder = self._lookupAbiEncoder('noInputNoOutput()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<{ innerStruct: { aField: BigNumber } }>( - returnData, - ); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -1101,23 +1261,20 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('methodUsingNestedStructWithInnerStructNotUsedElsewhere()'); + const abiEncoder = self._lookupAbiEncoder('noInputNoOutput()'); return abiEncoder.getSelector(); }, }; - public nestedStructOutput = { + /** + * Tests decoding when input is empty and output is non-empty. + */ + public noInputSimpleOutput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync( - callData: Partial = {}, - defaultBlock?: BlockParam, - ): Promise<{ - innerStruct: { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }; - description: string; - }> { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -1127,7 +1284,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('nestedStructOutput()', []); + const encodedData = self._strictEncodeArguments('noInputSimpleOutput()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -1139,12 +1296,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('nestedStructOutput()'); + const abiEncoder = self._lookupAbiEncoder('noInputSimpleOutput()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue<{ - innerStruct: { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }; - description: string; - }>(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -1156,7 +1310,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('nestedStructOutput()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('noInputSimpleOutput()', []); return abiEncodedTransactionData; }, /** @@ -1166,7 +1320,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nestedStructOutput()'); + const abiEncoder = self._lookupAbiEncoder('noInputSimpleOutput()'); // tslint:disable boolean-naming const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; @@ -1176,19 +1330,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData( - returnData: string, - ): { - innerStruct: { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }; - description: string; - } { + getABIDecodedReturnData(returnData: string): BigNumber { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nestedStructOutput()'); + const abiEncoder = self._lookupAbiEncoder('noInputSimpleOutput()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<{ - innerStruct: { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }; - description: string; - }>(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -1196,201 +1342,96 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nestedStructOutput()'); + const abiEncoder = self._lookupAbiEncoder('noInputSimpleOutput()'); return abiEncoder.getSelector(); }, }; - public requireWithConstant = { + public nonPureMethod = { /** - * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an - * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas - * since they don't modify state. + * Sends an Ethereum transaction executing this method with the supplied parameters. This is a read/write + * Ethereum operation and will cost gas. + * @param txData Additional data for transaction + * @returns The hash of the transaction */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { - assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ - schemas.addressSchema, - schemas.numberSchema, - schemas.jsNumber, - ]); - if (defaultBlock !== undefined) { - assert.isBlockParam('defaultBlock', defaultBlock); - } + async sendTransactionAsync( + txData?: Partial | undefined, + opts: SendTransactionOpts = { shouldValidate: true }, + ): Promise { const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('requireWithConstant()', []); - const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); + const encodedData = self._strictEncodeArguments('nonPureMethod()', []); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...txData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + if (txDataWithDefaults.from !== undefined) { + txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); + } - let rawCallResult; - try { - rawCallResult = await self._evmExecAsync(encodedDataBytes); - } catch (err) { - BaseContract._throwIfThrownErrorIsRevertError(err); - throw err; + if (opts.shouldValidate !== false) { + await self.nonPureMethod.callAsync(txDataWithDefaults); } - BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('requireWithConstant()'); - // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); - // tslint:enable boolean-naming - return result; + const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + return txHash; }, /** - * Returns the ABI encoded transaction data needed to send an Ethereum transaction calling this method. Before - * sending the Ethereum tx, this encoded tx data can first be sent to a separate signing service or can be used - * to create a 0x transaction (see protocol spec for more details). - * @returns The ABI encoded transaction data as a string + * Sends an Ethereum transaction and waits until the transaction has been successfully mined without reverting. + * If the transaction was mined, but reverted, an error is thrown. + * @param txData Additional data for transaction + * @param pollingIntervalMs Interval at which to poll for success + * @returns A promise that resolves when the transaction is successful */ - getABIEncodedTransactionData(): string { + awaitTransactionSuccessAsync( + txData?: Partial, + opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, + ): PromiseWithTransactionHash { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('requireWithConstant()', []); - return abiEncodedTransactionData; + const txHashPromise = self.nonPureMethod.sendTransactionAsync(txData, opts); + return new PromiseWithTransactionHash( + txHashPromise, + (async (): Promise => { + // When the transaction hash resolves, wait for it to be mined. + return self._web3Wrapper.awaitTransactionSuccessAsync( + await txHashPromise, + opts.pollingIntervalMs, + opts.timeoutMs, + ); + })(), + ); }, /** - * Decode the ABI-encoded transaction data into its input arguments - * @param callData The ABI-encoded transaction data - * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. + * Estimates the gas cost of sending an Ethereum transaction calling this method with these arguments. + * @param txData Additional data for transaction + * @returns The hash of the transaction */ - getABIDecodedTransactionData(callData: string): void { + async estimateGasAsync(txData?: Partial | undefined): Promise { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('requireWithConstant()'); - // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); - return abiDecodedCallData; - }, - /** - * Decode the ABI-encoded return data from a transaction - * @param returnData the data returned after transaction execution - * @returns An array representing the output results in order. Keynames of nested structs are preserved. - */ - getABIDecodedReturnData(returnData: string): void { - const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('requireWithConstant()'); - // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); - return abiDecodedReturnData; - }, - /** - * Returns the 4 byte function selector as a hex string. - */ - getSelector(): string { - const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('requireWithConstant()'); - return abiEncoder.getSelector(); - }, - }; - public withAddressInput = { - /** - * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an - * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas - * since they don't modify state. - */ - async callAsync( - x: string, - a: BigNumber, - b: BigNumber, - y: string, - c: BigNumber, - callData: Partial = {}, - defaultBlock?: BlockParam, - ): Promise { - assert.isString('x', x); - assert.isBigNumber('a', a); - assert.isBigNumber('b', b); - assert.isString('y', y); - assert.isBigNumber('c', c); - assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ - schemas.addressSchema, - schemas.numberSchema, - schemas.jsNumber, - ]); - if (defaultBlock !== undefined) { - assert.isBlockParam('defaultBlock', defaultBlock); - } - const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments( - 'withAddressInput(address,uint256,uint256,address,uint256)', - [x.toLowerCase(), a, b, y.toLowerCase(), c], + const encodedData = self._strictEncodeArguments('nonPureMethod()', []); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...txData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), ); - const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); - - let rawCallResult; - try { - rawCallResult = await self._evmExecAsync(encodedDataBytes); - } catch (err) { - BaseContract._throwIfThrownErrorIsRevertError(err); - throw err; + if (txDataWithDefaults.from !== undefined) { + txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); } - BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('withAddressInput(address,uint256,uint256,address,uint256)'); - // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); - // tslint:enable boolean-naming - return result; - }, - /** - * Returns the ABI encoded transaction data needed to send an Ethereum transaction calling this method. Before - * sending the Ethereum tx, this encoded tx data can first be sent to a separate signing service or can be used - * to create a 0x transaction (see protocol spec for more details). - * @returns The ABI encoded transaction data as a string - */ - getABIEncodedTransactionData(x: string, a: BigNumber, b: BigNumber, y: string, c: BigNumber): string { - assert.isString('x', x); - assert.isBigNumber('a', a); - assert.isBigNumber('b', b); - assert.isString('y', y); - assert.isBigNumber('c', c); - const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments( - 'withAddressInput(address,uint256,uint256,address,uint256)', - [x.toLowerCase(), a, b, y.toLowerCase(), c], - ); - return abiEncodedTransactionData; - }, - /** - * Decode the ABI-encoded transaction data into its input arguments - * @param callData The ABI-encoded transaction data - * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. - */ - getABIDecodedTransactionData(callData: string): string { - const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('withAddressInput(address,uint256,uint256,address,uint256)'); - // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); - return abiDecodedCallData; - }, - /** - * Decode the ABI-encoded return data from a transaction - * @param returnData the data returned after transaction execution - * @returns An array representing the output results in order. Keynames of nested structs are preserved. - */ - getABIDecodedReturnData(returnData: string): string { - const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('withAddressInput(address,uint256,uint256,address,uint256)'); - // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); - return abiDecodedReturnData; - }, - /** - * Returns the 4 byte function selector as a hex string. - */ - getSelector(): string { - const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('withAddressInput(address,uint256,uint256,address,uint256)'); - return abiEncoder.getSelector(); + const gas = await self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + return gas; }, - }; - public structInput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync( - s: { someBytes: string; anInteger: number | BigNumber; aDynamicArrayOfBytes: string[]; aString: string }, - callData: Partial = {}, - defaultBlock?: BlockParam, - ): Promise { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -1400,21 +1441,29 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('structInput((bytes,uint32,bytes[],string))', [s]); - const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); - + const encodedData = self._strictEncodeArguments('nonPureMethod()', []); + const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...callData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + callDataWithDefaults.from = callDataWithDefaults.from + ? callDataWithDefaults.from.toLowerCase() + : callDataWithDefaults.from; let rawCallResult; try { - rawCallResult = await self._evmExecAsync(encodedDataBytes); + rawCallResult = await self._web3Wrapper.callAsync(callDataWithDefaults, defaultBlock); } catch (err) { BaseContract._throwIfThrownErrorIsRevertError(err); throw err; } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - - const abiEncoder = self._lookupAbiEncoder('structInput((bytes,uint32,bytes[],string))'); + const abiEncoder = self._lookupAbiEncoder('nonPureMethod()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -1424,17 +1473,9 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(s: { - someBytes: string; - anInteger: number | BigNumber; - aDynamicArrayOfBytes: string[]; - aString: string; - }): string { + getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments( - 'structInput((bytes,uint32,bytes[],string))', - [s], - ); + const abiEncodedTransactionData = self._strictEncodeArguments('nonPureMethod()', []); return abiEncodedTransactionData; }, /** @@ -1442,15 +1483,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData( - callData: string, - ): [{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }] { + getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('structInput((bytes,uint32,bytes[],string))'); + const abiEncoder = self._lookupAbiEncoder('nonPureMethod()'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode< - [{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }] - >(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -1458,11 +1495,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): void { + getABIDecodedReturnData(returnData: string): BigNumber { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('structInput((bytes,uint32,bytes[],string))'); + const abiEncoder = self._lookupAbiEncoder('nonPureMethod()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -1470,11 +1507,11 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('structInput((bytes,uint32,bytes[],string))'); + const abiEncoder = self._lookupAbiEncoder('nonPureMethod()'); return abiEncoder.getSelector(); }, }; - public nonPureMethod = { + public nonPureMethodThatReturnsNothing = { /** * Sends an Ethereum transaction executing this method with the supplied parameters. This is a read/write * Ethereum operation and will cost gas. @@ -1486,7 +1523,7 @@ export class AbiGenDummyContract extends BaseContract { opts: SendTransactionOpts = { shouldValidate: true }, ): Promise { const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('nonPureMethod()', []); + const encodedData = self._strictEncodeArguments('nonPureMethodThatReturnsNothing()', []); const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( { to: self.address, @@ -1500,7 +1537,7 @@ export class AbiGenDummyContract extends BaseContract { } if (opts.shouldValidate !== false) { - await self.nonPureMethod.callAsync(txDataWithDefaults); + await self.nonPureMethodThatReturnsNothing.callAsync(txDataWithDefaults); } const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); @@ -1518,7 +1555,7 @@ export class AbiGenDummyContract extends BaseContract { opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, ): PromiseWithTransactionHash { const self = (this as any) as AbiGenDummyContract; - const txHashPromise = self.nonPureMethod.sendTransactionAsync(txData, opts); + const txHashPromise = self.nonPureMethodThatReturnsNothing.sendTransactionAsync(txData, opts); return new PromiseWithTransactionHash( txHashPromise, (async (): Promise => { @@ -1538,7 +1575,7 @@ export class AbiGenDummyContract extends BaseContract { */ async estimateGasAsync(txData?: Partial | undefined): Promise { const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('nonPureMethod()', []); + const encodedData = self._strictEncodeArguments('nonPureMethodThatReturnsNothing()', []); const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( { to: self.address, @@ -1559,7 +1596,7 @@ export class AbiGenDummyContract extends BaseContract { * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -1569,7 +1606,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('nonPureMethod()', []); + const encodedData = self._strictEncodeArguments('nonPureMethodThatReturnsNothing()', []); const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( { to: self.address, @@ -1589,9 +1626,9 @@ export class AbiGenDummyContract extends BaseContract { throw err; } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('nonPureMethod()'); + const abiEncoder = self._lookupAbiEncoder('nonPureMethodThatReturnsNothing()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -1603,7 +1640,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('nonPureMethod()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('nonPureMethodThatReturnsNothing()', []); return abiEncodedTransactionData; }, /** @@ -1613,7 +1650,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nonPureMethod()'); + const abiEncoder = self._lookupAbiEncoder('nonPureMethodThatReturnsNothing()'); // tslint:disable boolean-naming const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; @@ -1623,11 +1660,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): BigNumber { + getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nonPureMethod()'); + const abiEncoder = self._lookupAbiEncoder('nonPureMethodThatReturnsNothing()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -1635,29 +1672,18 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nonPureMethod()'); + const abiEncoder = self._lookupAbiEncoder('nonPureMethodThatReturnsNothing()'); return abiEncoder.getSelector(); }, }; - /** - * Tests decoding when the input and output are complex. - */ - public complexInputComplexOutput = { + public overloadedMethod2 = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync( - complexInput: { foo: BigNumber; bar: string; car: string }, - callData: Partial = {}, - defaultBlock?: BlockParam, - ): Promise<{ - input: { foo: BigNumber; bar: string; car: string }; - lorem: string; - ipsum: string; - dolor: string; - }> { + async callAsync(a: string, callData: Partial = {}, defaultBlock?: BlockParam): Promise { + assert.isString('a', a); assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -1667,9 +1693,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('complexInputComplexOutput((uint256,bytes,string))', [ - complexInput, - ]); + const encodedData = self._strictEncodeArguments('overloadedMethod(string)', [a]); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -1681,14 +1705,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('complexInputComplexOutput((uint256,bytes,string))'); + const abiEncoder = self._lookupAbiEncoder('overloadedMethod(string)'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue<{ - input: { foo: BigNumber; bar: string; car: string }; - lorem: string; - ipsum: string; - dolor: string; - }>(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -1698,12 +1717,10 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(complexInput: { foo: BigNumber; bar: string; car: string }): string { + getABIEncodedTransactionData(a: string): string { + assert.isString('a', a); const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments( - 'complexInputComplexOutput((uint256,bytes,string))', - [complexInput], - ); + const abiEncodedTransactionData = self._strictEncodeArguments('overloadedMethod(string)', [a]); return abiEncodedTransactionData; }, /** @@ -1711,11 +1728,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): { foo: BigNumber; bar: string; car: string } { + getABIDecodedTransactionData(callData: string): [string] { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('complexInputComplexOutput((uint256,bytes,string))'); + const abiEncoder = self._lookupAbiEncoder('overloadedMethod(string)'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode<{ foo: BigNumber; bar: string; car: string }>(callData); + const abiDecodedCallData = abiEncoder.strictDecode<[string]>(callData); return abiDecodedCallData; }, /** @@ -1723,18 +1740,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData( - returnData: string, - ): { input: { foo: BigNumber; bar: string; car: string }; lorem: string; ipsum: string; dolor: string } { + getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('complexInputComplexOutput((uint256,bytes,string))'); + const abiEncoder = self._lookupAbiEncoder('overloadedMethod(string)'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<{ - input: { foo: BigNumber; bar: string; car: string }; - lorem: string; - ipsum: string; - dolor: string; - }>(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -1742,20 +1752,18 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('complexInputComplexOutput((uint256,bytes,string))'); + const abiEncoder = self._lookupAbiEncoder('overloadedMethod(string)'); return abiEncoder.getSelector(); }, }; - /** - * Tests decoding when both input and output are empty. - */ - public noInputNoOutput = { + public overloadedMethod1 = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + async callAsync(a: BigNumber, callData: Partial = {}, defaultBlock?: BlockParam): Promise { + assert.isBigNumber('a', a); assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -1765,7 +1773,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('noInputNoOutput()', []); + const encodedData = self._strictEncodeArguments('overloadedMethod(int256)', [a]); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -1777,7 +1785,7 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('noInputNoOutput()'); + const abiEncoder = self._lookupAbiEncoder('overloadedMethod(int256)'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming @@ -1789,9 +1797,10 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(): string { + getABIEncodedTransactionData(a: BigNumber): string { + assert.isBigNumber('a', a); const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('noInputNoOutput()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('overloadedMethod(int256)', [a]); return abiEncodedTransactionData; }, /** @@ -1799,11 +1808,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): void { + getABIDecodedTransactionData(callData: string): [BigNumber] { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('noInputNoOutput()'); + const abiEncoder = self._lookupAbiEncoder('overloadedMethod(int256)'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); + const abiDecodedCallData = abiEncoder.strictDecode<[BigNumber]>(callData); return abiDecodedCallData; }, /** @@ -1813,7 +1822,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('noInputNoOutput()'); + const abiEncoder = self._lookupAbiEncoder('overloadedMethod(int256)'); // tslint:disable boolean-naming const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; @@ -1823,18 +1832,17 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('noInputNoOutput()'); + const abiEncoder = self._lookupAbiEncoder('overloadedMethod(int256)'); return abiEncoder.getSelector(); }, }; - public simplePureFunctionWithInput = { + public pureFunctionWithConstant = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(x: BigNumber, callData: Partial = {}, defaultBlock?: BlockParam): Promise { - assert.isBigNumber('x', x); + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -1844,7 +1852,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('simplePureFunctionWithInput(uint256)', [x]); + const encodedData = self._strictEncodeArguments('pureFunctionWithConstant()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -1856,7 +1864,7 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('simplePureFunctionWithInput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('pureFunctionWithConstant()'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming @@ -1868,10 +1876,9 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(x: BigNumber): string { - assert.isBigNumber('x', x); + getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('simplePureFunctionWithInput(uint256)', [x]); + const abiEncodedTransactionData = self._strictEncodeArguments('pureFunctionWithConstant()', []); return abiEncodedTransactionData; }, /** @@ -1879,11 +1886,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): BigNumber { + getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simplePureFunctionWithInput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('pureFunctionWithConstant()'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -1893,7 +1900,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedReturnData(returnData: string): BigNumber { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simplePureFunctionWithInput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('pureFunctionWithConstant()'); // tslint:disable boolean-naming const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; @@ -1903,90 +1910,11 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simplePureFunctionWithInput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('pureFunctionWithConstant()'); return abiEncoder.getSelector(); }, }; - public nonPureMethodThatReturnsNothing = { - /** - * Sends an Ethereum transaction executing this method with the supplied parameters. This is a read/write - * Ethereum operation and will cost gas. - * @param txData Additional data for transaction - * @returns The hash of the transaction - */ - async sendTransactionAsync( - txData?: Partial | undefined, - opts: SendTransactionOpts = { shouldValidate: true }, - ): Promise { - const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('nonPureMethodThatReturnsNothing()', []); - const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( - { - to: self.address, - ...txData, - data: encodedData, - }, - self._web3Wrapper.getContractDefaults(), - ); - if (txDataWithDefaults.from !== undefined) { - txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); - } - - if (opts.shouldValidate !== false) { - await self.nonPureMethodThatReturnsNothing.callAsync(txDataWithDefaults); - } - - const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); - return txHash; - }, - /** - * Sends an Ethereum transaction and waits until the transaction has been successfully mined without reverting. - * If the transaction was mined, but reverted, an error is thrown. - * @param txData Additional data for transaction - * @param pollingIntervalMs Interval at which to poll for success - * @returns A promise that resolves when the transaction is successful - */ - awaitTransactionSuccessAsync( - txData?: Partial, - opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, - ): PromiseWithTransactionHash { - const self = (this as any) as AbiGenDummyContract; - const txHashPromise = self.nonPureMethodThatReturnsNothing.sendTransactionAsync(txData, opts); - return new PromiseWithTransactionHash( - txHashPromise, - (async (): Promise => { - // When the transaction hash resolves, wait for it to be mined. - return self._web3Wrapper.awaitTransactionSuccessAsync( - await txHashPromise, - opts.pollingIntervalMs, - opts.timeoutMs, - ); - })(), - ); - }, - /** - * Estimates the gas cost of sending an Ethereum transaction calling this method with these arguments. - * @param txData Additional data for transaction - * @returns The hash of the transaction - */ - async estimateGasAsync(txData?: Partial | undefined): Promise { - const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('nonPureMethodThatReturnsNothing()', []); - const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( - { - to: self.address, - ...txData, - data: encodedData, - }, - self._web3Wrapper.getContractDefaults(), - ); - if (txDataWithDefaults.from !== undefined) { - txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); - } - - const gas = await self._web3Wrapper.estimateGasAsync(txDataWithDefaults); - return gas; - }, + public requireWithConstant = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas @@ -2002,27 +1930,19 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('nonPureMethodThatReturnsNothing()', []); - const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( - { - to: self.address, - ...callData, - data: encodedData, - }, - self._web3Wrapper.getContractDefaults(), - ); - callDataWithDefaults.from = callDataWithDefaults.from - ? callDataWithDefaults.from.toLowerCase() - : callDataWithDefaults.from; + const encodedData = self._strictEncodeArguments('requireWithConstant()', []); + const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); + let rawCallResult; try { - rawCallResult = await self._web3Wrapper.callAsync(callDataWithDefaults, defaultBlock); + rawCallResult = await self._evmExecAsync(encodedDataBytes); } catch (err) { BaseContract._throwIfThrownErrorIsRevertError(err); throw err; } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('nonPureMethodThatReturnsNothing()'); + + const abiEncoder = self._lookupAbiEncoder('requireWithConstant()'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming @@ -2036,7 +1956,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('nonPureMethodThatReturnsNothing()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('requireWithConstant()', []); return abiEncodedTransactionData; }, /** @@ -2046,7 +1966,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nonPureMethodThatReturnsNothing()'); + const abiEncoder = self._lookupAbiEncoder('requireWithConstant()'); // tslint:disable boolean-naming const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; @@ -2058,7 +1978,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nonPureMethodThatReturnsNothing()'); + const abiEncoder = self._lookupAbiEncoder('requireWithConstant()'); // tslint:disable boolean-naming const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; @@ -2068,17 +1988,17 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nonPureMethodThatReturnsNothing()'); + const abiEncoder = self._lookupAbiEncoder('requireWithConstant()'); return abiEncoder.getSelector(); }, }; - public simplePureFunction = { + public revertWithConstant = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -2088,7 +2008,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('simplePureFunction()', []); + const encodedData = self._strictEncodeArguments('revertWithConstant()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -2100,9 +2020,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('simplePureFunction()'); + const abiEncoder = self._lookupAbiEncoder('revertWithConstant()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -2114,7 +2034,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('simplePureFunction()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('revertWithConstant()', []); return abiEncodedTransactionData; }, /** @@ -2124,7 +2044,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simplePureFunction()'); + const abiEncoder = self._lookupAbiEncoder('revertWithConstant()'); // tslint:disable boolean-naming const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; @@ -2134,11 +2054,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): BigNumber { + getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simplePureFunction()'); + const abiEncoder = self._lookupAbiEncoder('revertWithConstant()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -2146,29 +2066,25 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simplePureFunction()'); + const abiEncoder = self._lookupAbiEncoder('revertWithConstant()'); return abiEncoder.getSelector(); }, }; - public nestedStructInput = { + /** + * Tests decoding when input is not empty but output is empty. + */ + public simpleInputNoOutput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ async callAsync( - n: { - innerStruct: { - someBytes: string; - anInteger: number | BigNumber; - aDynamicArrayOfBytes: string[]; - aString: string; - }; - description: string; - }, + index_0: BigNumber, callData: Partial = {}, defaultBlock?: BlockParam, ): Promise { + assert.isBigNumber('index_0', index_0); assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -2178,10 +2094,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments( - 'nestedStructInput(((bytes,uint32,bytes[],string),string))', - [n], - ); + const encodedData = self._strictEncodeArguments('simpleInputNoOutput(uint256)', [index_0]); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -2193,7 +2106,7 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('nestedStructInput(((bytes,uint32,bytes[],string),string))'); + const abiEncoder = self._lookupAbiEncoder('simpleInputNoOutput(uint256)'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming @@ -2205,20 +2118,10 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(n: { - innerStruct: { - someBytes: string; - anInteger: number | BigNumber; - aDynamicArrayOfBytes: string[]; - aString: string; - }; - description: string; - }): string { + getABIEncodedTransactionData(index_0: BigNumber): string { + assert.isBigNumber('index_0', index_0); const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments( - 'nestedStructInput(((bytes,uint32,bytes[],string),string))', - [n], - ); + const abiEncodedTransactionData = self._strictEncodeArguments('simpleInputNoOutput(uint256)', [index_0]); return abiEncodedTransactionData; }, /** @@ -2226,30 +2129,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData( - callData: string, - ): [ - { - innerStruct: { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }; - description: string; - } - ] { + getABIDecodedTransactionData(callData: string): [BigNumber] { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nestedStructInput(((bytes,uint32,bytes[],string),string))'); + const abiEncoder = self._lookupAbiEncoder('simpleInputNoOutput(uint256)'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode< - [ - { - innerStruct: { - someBytes: string; - anInteger: number; - aDynamicArrayOfBytes: string[]; - aString: string; - }; - description: string; - } - ] - >(callData); + const abiDecodedCallData = abiEncoder.strictDecode<[BigNumber]>(callData); return abiDecodedCallData; }, /** @@ -2259,7 +2143,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nestedStructInput(((bytes,uint32,bytes[],string),string))'); + const abiEncoder = self._lookupAbiEncoder('simpleInputNoOutput(uint256)'); // tslint:disable boolean-naming const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; @@ -2269,17 +2153,25 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('nestedStructInput(((bytes,uint32,bytes[],string),string))'); + const abiEncoder = self._lookupAbiEncoder('simpleInputNoOutput(uint256)'); return abiEncoder.getSelector(); }, }; - public methodReturningMultipleValues = { + /** + * Tests decoding when both input and output are non-empty. + */ + public simpleInputSimpleOutput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise<[BigNumber, string]> { + async callAsync( + index_0: BigNumber, + callData: Partial = {}, + defaultBlock?: BlockParam, + ): Promise { + assert.isBigNumber('index_0', index_0); assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -2289,7 +2181,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('methodReturningMultipleValues()', []); + const encodedData = self._strictEncodeArguments('simpleInputSimpleOutput(uint256)', [index_0]); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -2301,9 +2193,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('methodReturningMultipleValues()'); + const abiEncoder = self._lookupAbiEncoder('simpleInputSimpleOutput(uint256)'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue<[BigNumber, string]>(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -2313,9 +2205,12 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(): string { + getABIEncodedTransactionData(index_0: BigNumber): string { + assert.isBigNumber('index_0', index_0); const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('methodReturningMultipleValues()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('simpleInputSimpleOutput(uint256)', [ + index_0, + ]); return abiEncodedTransactionData; }, /** @@ -2323,11 +2218,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): void { + getABIDecodedTransactionData(callData: string): BigNumber { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('methodReturningMultipleValues()'); + const abiEncoder = self._lookupAbiEncoder('simpleInputSimpleOutput(uint256)'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -2335,11 +2230,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): [BigNumber, string] { + getABIDecodedReturnData(returnData: string): BigNumber { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('methodReturningMultipleValues()'); + const abiEncoder = self._lookupAbiEncoder('simpleInputSimpleOutput(uint256)'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<[BigNumber, string]>(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -2347,20 +2242,17 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('methodReturningMultipleValues()'); + const abiEncoder = self._lookupAbiEncoder('simpleInputSimpleOutput(uint256)'); return abiEncoder.getSelector(); }, }; - public methodReturningArrayOfStructs = { + public simplePureFunction = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync( - callData: Partial = {}, - defaultBlock?: BlockParam, - ): Promise> { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -2370,7 +2262,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('methodReturningArrayOfStructs()', []); + const encodedData = self._strictEncodeArguments('simplePureFunction()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -2382,11 +2274,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('methodReturningArrayOfStructs()'); + const abiEncoder = self._lookupAbiEncoder('simplePureFunction()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue< - Array<{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }> - >(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -2398,7 +2288,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('methodReturningArrayOfStructs()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('simplePureFunction()', []); return abiEncodedTransactionData; }, /** @@ -2408,7 +2298,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('methodReturningArrayOfStructs()'); + const abiEncoder = self._lookupAbiEncoder('simplePureFunction()'); // tslint:disable boolean-naming const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; @@ -2418,15 +2308,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData( - returnData: string, - ): Array<{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }> { + getABIDecodedReturnData(returnData: string): BigNumber { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('methodReturningArrayOfStructs()'); + const abiEncoder = self._lookupAbiEncoder('simplePureFunction()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue< - Array<{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }> - >(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -2434,96 +2320,18 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('methodReturningArrayOfStructs()'); + const abiEncoder = self._lookupAbiEncoder('simplePureFunction()'); return abiEncoder.getSelector(); }, }; - public emitSimpleEvent = { - /** - * Sends an Ethereum transaction executing this method with the supplied parameters. This is a read/write - * Ethereum operation and will cost gas. - * @param txData Additional data for transaction - * @returns The hash of the transaction - */ - async sendTransactionAsync( - txData?: Partial | undefined, - opts: SendTransactionOpts = { shouldValidate: true }, - ): Promise { - const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('emitSimpleEvent()', []); - const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( - { - to: self.address, - ...txData, - data: encodedData, - }, - self._web3Wrapper.getContractDefaults(), - ); - if (txDataWithDefaults.from !== undefined) { - txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); - } - - if (opts.shouldValidate !== false) { - await self.emitSimpleEvent.callAsync(txDataWithDefaults); - } - - const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); - return txHash; - }, - /** - * Sends an Ethereum transaction and waits until the transaction has been successfully mined without reverting. - * If the transaction was mined, but reverted, an error is thrown. - * @param txData Additional data for transaction - * @param pollingIntervalMs Interval at which to poll for success - * @returns A promise that resolves when the transaction is successful - */ - awaitTransactionSuccessAsync( - txData?: Partial, - opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, - ): PromiseWithTransactionHash { - const self = (this as any) as AbiGenDummyContract; - const txHashPromise = self.emitSimpleEvent.sendTransactionAsync(txData, opts); - return new PromiseWithTransactionHash( - txHashPromise, - (async (): Promise => { - // When the transaction hash resolves, wait for it to be mined. - return self._web3Wrapper.awaitTransactionSuccessAsync( - await txHashPromise, - opts.pollingIntervalMs, - opts.timeoutMs, - ); - })(), - ); - }, - /** - * Estimates the gas cost of sending an Ethereum transaction calling this method with these arguments. - * @param txData Additional data for transaction - * @returns The hash of the transaction - */ - async estimateGasAsync(txData?: Partial | undefined): Promise { - const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('emitSimpleEvent()', []); - const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( - { - to: self.address, - ...txData, - data: encodedData, - }, - self._web3Wrapper.getContractDefaults(), - ); - if (txDataWithDefaults.from !== undefined) { - txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); - } - - const gas = await self._web3Wrapper.estimateGasAsync(txDataWithDefaults); - return gas; - }, + public simplePureFunctionWithInput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + async callAsync(x: BigNumber, callData: Partial = {}, defaultBlock?: BlockParam): Promise { + assert.isBigNumber('x', x); assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -2533,29 +2341,21 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('emitSimpleEvent()', []); - const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( - { - to: self.address, - ...callData, - data: encodedData, - }, - self._web3Wrapper.getContractDefaults(), - ); - callDataWithDefaults.from = callDataWithDefaults.from - ? callDataWithDefaults.from.toLowerCase() - : callDataWithDefaults.from; + const encodedData = self._strictEncodeArguments('simplePureFunctionWithInput(uint256)', [x]); + const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); + let rawCallResult; try { - rawCallResult = await self._web3Wrapper.callAsync(callDataWithDefaults, defaultBlock); + rawCallResult = await self._evmExecAsync(encodedDataBytes); } catch (err) { BaseContract._throwIfThrownErrorIsRevertError(err); throw err; } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('emitSimpleEvent()'); + + const abiEncoder = self._lookupAbiEncoder('simplePureFunctionWithInput(uint256)'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -2565,9 +2365,10 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(): string { + getABIEncodedTransactionData(x: BigNumber): string { + assert.isBigNumber('x', x); const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('emitSimpleEvent()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('simplePureFunctionWithInput(uint256)', [x]); return abiEncodedTransactionData; }, /** @@ -2575,11 +2376,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): void { + getABIDecodedTransactionData(callData: string): BigNumber { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('emitSimpleEvent()'); + const abiEncoder = self._lookupAbiEncoder('simplePureFunctionWithInput(uint256)'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -2587,11 +2388,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): void { + getABIDecodedReturnData(returnData: string): BigNumber { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('emitSimpleEvent()'); + const abiEncoder = self._lookupAbiEncoder('simplePureFunctionWithInput(uint256)'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -2599,24 +2400,17 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('emitSimpleEvent()'); + const abiEncoder = self._lookupAbiEncoder('simplePureFunctionWithInput(uint256)'); return abiEncoder.getSelector(); }, }; - /** - * a method that returns a struct - */ - public structOutput = { + public simpleRequire = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. - * @returns a Struct struct */ - async callAsync( - callData: Partial = {}, - defaultBlock?: BlockParam, - ): Promise<{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }> { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -2626,7 +2420,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('structOutput()', []); + const encodedData = self._strictEncodeArguments('simpleRequire()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -2638,14 +2432,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('structOutput()'); + const abiEncoder = self._lookupAbiEncoder('simpleRequire()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue<{ - someBytes: string; - anInteger: number; - aDynamicArrayOfBytes: string[]; - aString: string; - }>(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -2657,7 +2446,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('structOutput()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('simpleRequire()', []); return abiEncodedTransactionData; }, /** @@ -2667,7 +2456,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('structOutput()'); + const abiEncoder = self._lookupAbiEncoder('simpleRequire()'); // tslint:disable boolean-naming const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; @@ -2677,18 +2466,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData( - returnData: string, - ): { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string } { + getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('structOutput()'); + const abiEncoder = self._lookupAbiEncoder('simpleRequire()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<{ - someBytes: string; - anInteger: number; - aDynamicArrayOfBytes: string[]; - aString: string; - }>(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -2696,17 +2478,17 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('structOutput()'); + const abiEncoder = self._lookupAbiEncoder('simpleRequire()'); return abiEncoder.getSelector(); }, }; - public pureFunctionWithConstant = { + public simpleRevert = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -2716,7 +2498,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('pureFunctionWithConstant()', []); + const encodedData = self._strictEncodeArguments('simpleRevert()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -2728,9 +2510,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('pureFunctionWithConstant()'); + const abiEncoder = self._lookupAbiEncoder('simpleRevert()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -2742,7 +2524,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('pureFunctionWithConstant()', []); + const abiEncodedTransactionData = self._strictEncodeArguments('simpleRevert()', []); return abiEncodedTransactionData; }, /** @@ -2752,7 +2534,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('pureFunctionWithConstant()'); + const abiEncoder = self._lookupAbiEncoder('simpleRevert()'); // tslint:disable boolean-naming const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; @@ -2762,11 +2544,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): BigNumber { + getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('pureFunctionWithConstant()'); + const abiEncoder = self._lookupAbiEncoder('simpleRevert()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -2774,25 +2556,21 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('pureFunctionWithConstant()'); + const abiEncoder = self._lookupAbiEncoder('simpleRevert()'); return abiEncoder.getSelector(); }, }; - /** - * Tests decoding when input is not empty but output is empty. - */ - public simpleInputNoOutput = { + public structInput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ async callAsync( - index_0: BigNumber, + s: { someBytes: string; anInteger: number | BigNumber; aDynamicArrayOfBytes: string[]; aString: string }, callData: Partial = {}, defaultBlock?: BlockParam, ): Promise { - assert.isBigNumber('index_0', index_0); assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -2802,7 +2580,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('simpleInputNoOutput(uint256)', [index_0]); + const encodedData = self._strictEncodeArguments('structInput((bytes,uint32,bytes[],string))', [s]); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -2814,7 +2592,7 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('simpleInputNoOutput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('structInput((bytes,uint32,bytes[],string))'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming @@ -2826,10 +2604,17 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(index_0: BigNumber): string { - assert.isBigNumber('index_0', index_0); + getABIEncodedTransactionData(s: { + someBytes: string; + anInteger: number | BigNumber; + aDynamicArrayOfBytes: string[]; + aString: string; + }): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('simpleInputNoOutput(uint256)', [index_0]); + const abiEncodedTransactionData = self._strictEncodeArguments( + 'structInput((bytes,uint32,bytes[],string))', + [s], + ); return abiEncodedTransactionData; }, /** @@ -2837,11 +2622,15 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): [BigNumber] { + getABIDecodedTransactionData( + callData: string, + ): [{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }] { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleInputNoOutput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('structInput((bytes,uint32,bytes[],string))'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode<[BigNumber]>(callData); + const abiDecodedCallData = abiEncoder.strictDecode< + [{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }] + >(callData); return abiDecodedCallData; }, /** @@ -2851,7 +2640,7 @@ export class AbiGenDummyContract extends BaseContract { */ getABIDecodedReturnData(returnData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleInputNoOutput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('structInput((bytes,uint32,bytes[],string))'); // tslint:disable boolean-naming const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; @@ -2861,18 +2650,24 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('simpleInputNoOutput(uint256)'); + const abiEncoder = self._lookupAbiEncoder('structInput((bytes,uint32,bytes[],string))'); return abiEncoder.getSelector(); }, }; - public overloadedMethod2 = { + /** + * a method that returns a struct + */ + public structOutput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. + * @returns a Struct struct */ - async callAsync(a: string, callData: Partial = {}, defaultBlock?: BlockParam): Promise { - assert.isString('a', a); + async callAsync( + callData: Partial = {}, + defaultBlock?: BlockParam, + ): Promise<{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }> { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -2882,7 +2677,7 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('overloadedMethod(string)', [a]); + const encodedData = self._strictEncodeArguments('structOutput()', []); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -2894,9 +2689,14 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('overloadedMethod(string)'); + const abiEncoder = self._lookupAbiEncoder('structOutput()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue<{ + someBytes: string; + anInteger: number; + aDynamicArrayOfBytes: string[]; + aString: string; + }>(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -2906,10 +2706,9 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(a: string): string { - assert.isString('a', a); + getABIEncodedTransactionData(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('overloadedMethod(string)', [a]); + const abiEncodedTransactionData = self._strictEncodeArguments('structOutput()', []); return abiEncodedTransactionData; }, /** @@ -2917,11 +2716,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): [string] { + getABIDecodedTransactionData(callData: string): void { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('overloadedMethod(string)'); + const abiEncoder = self._lookupAbiEncoder('structOutput()'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode<[string]>(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -2929,11 +2728,18 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): void { + getABIDecodedReturnData( + returnData: string, + ): { someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string } { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('overloadedMethod(string)'); + const abiEncoder = self._lookupAbiEncoder('structOutput()'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<{ + someBytes: string; + anInteger: number; + aDynamicArrayOfBytes: string[]; + aString: string; + }>(returnData); return abiDecodedReturnData; }, /** @@ -2941,18 +2747,30 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('overloadedMethod(string)'); + const abiEncoder = self._lookupAbiEncoder('structOutput()'); return abiEncoder.getSelector(); }, }; - public overloadedMethod1 = { + public withAddressInput = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas * since they don't modify state. */ - async callAsync(a: BigNumber, callData: Partial = {}, defaultBlock?: BlockParam): Promise { + async callAsync( + x: string, + a: BigNumber, + b: BigNumber, + y: string, + c: BigNumber, + callData: Partial = {}, + defaultBlock?: BlockParam, + ): Promise { + assert.isString('x', x); assert.isBigNumber('a', a); + assert.isBigNumber('b', b); + assert.isString('y', y); + assert.isBigNumber('c', c); assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -2962,7 +2780,10 @@ export class AbiGenDummyContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const self = (this as any) as AbiGenDummyContract; - const encodedData = self._strictEncodeArguments('overloadedMethod(int256)', [a]); + const encodedData = self._strictEncodeArguments( + 'withAddressInput(address,uint256,uint256,address,uint256)', + [x.toLowerCase(), a, b, y.toLowerCase(), c], + ); const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); let rawCallResult; @@ -2974,9 +2795,9 @@ export class AbiGenDummyContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('overloadedMethod(int256)'); + const abiEncoder = self._lookupAbiEncoder('withAddressInput(address,uint256,uint256,address,uint256)'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, @@ -2986,10 +2807,17 @@ export class AbiGenDummyContract extends BaseContract { * to create a 0x transaction (see protocol spec for more details). * @returns The ABI encoded transaction data as a string */ - getABIEncodedTransactionData(a: BigNumber): string { + getABIEncodedTransactionData(x: string, a: BigNumber, b: BigNumber, y: string, c: BigNumber): string { + assert.isString('x', x); assert.isBigNumber('a', a); + assert.isBigNumber('b', b); + assert.isString('y', y); + assert.isBigNumber('c', c); const self = (this as any) as AbiGenDummyContract; - const abiEncodedTransactionData = self._strictEncodeArguments('overloadedMethod(int256)', [a]); + const abiEncodedTransactionData = self._strictEncodeArguments( + 'withAddressInput(address,uint256,uint256,address,uint256)', + [x.toLowerCase(), a, b, y.toLowerCase(), c], + ); return abiEncodedTransactionData; }, /** @@ -2997,11 +2825,11 @@ export class AbiGenDummyContract extends BaseContract { * @param callData The ABI-encoded transaction data * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. */ - getABIDecodedTransactionData(callData: string): [BigNumber] { + getABIDecodedTransactionData(callData: string): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('overloadedMethod(int256)'); + const abiEncoder = self._lookupAbiEncoder('withAddressInput(address,uint256,uint256,address,uint256)'); // tslint:disable boolean-naming - const abiDecodedCallData = abiEncoder.strictDecode<[BigNumber]>(callData); + const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; }, /** @@ -3009,11 +2837,11 @@ export class AbiGenDummyContract extends BaseContract { * @param returnData the data returned after transaction execution * @returns An array representing the output results in order. Keynames of nested structs are preserved. */ - getABIDecodedReturnData(returnData: string): void { + getABIDecodedReturnData(returnData: string): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('overloadedMethod(int256)'); + const abiEncoder = self._lookupAbiEncoder('withAddressInput(address,uint256,uint256,address,uint256)'); // tslint:disable boolean-naming - const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); return abiDecodedReturnData; }, /** @@ -3021,165 +2849,375 @@ export class AbiGenDummyContract extends BaseContract { */ getSelector(): string { const self = (this as any) as AbiGenDummyContract; - const abiEncoder = self._lookupAbiEncoder('overloadedMethod(int256)'); + const abiEncoder = self._lookupAbiEncoder('withAddressInput(address,uint256,uint256,address,uint256)'); return abiEncoder.getSelector(); }, }; - private readonly _subscriptionManager: SubscriptionManager; - public static async deployFrom0xArtifactAsync( - artifact: ContractArtifact | SimpleContractArtifact, - supportedProvider: SupportedProvider, - txDefaults: Partial, - logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact }, - ): Promise { - assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ - schemas.addressSchema, - schemas.numberSchema, - schemas.jsNumber, - ]); - if (artifact.compilerOutput === undefined) { - throw new Error('Compiler output not found in the artifact file'); - } - const provider = providerUtils.standardizeOrThrow(supportedProvider); - const bytecode = artifact.compilerOutput.evm.bytecode.object; - const abi = artifact.compilerOutput.abi; - const logDecodeDependenciesAbiOnly: { [contractName: string]: ContractAbi } = {}; - if (Object.keys(logDecodeDependencies) !== undefined) { - for (const key of Object.keys(logDecodeDependencies)) { - logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi; + public withdraw = { + /** + * Sends an Ethereum transaction executing this method with the supplied parameters. This is a read/write + * Ethereum operation and will cost gas. + * @param txData Additional data for transaction + * @returns The hash of the transaction + */ + async sendTransactionAsync( + wad: BigNumber, + txData?: Partial | undefined, + opts: SendTransactionOpts = { shouldValidate: true }, + ): Promise { + assert.isBigNumber('wad', wad); + const self = (this as any) as AbiGenDummyContract; + const encodedData = self._strictEncodeArguments('withdraw(uint256)', [wad]); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...txData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + if (txDataWithDefaults.from !== undefined) { + txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); } - } - return AbiGenDummyContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly); - } - public static async deployAsync( - bytecode: string, - abi: ContractAbi, - supportedProvider: SupportedProvider, - txDefaults: Partial, - logDecodeDependencies: { [contractName: string]: ContractAbi }, - ): Promise { - assert.isHexString('bytecode', bytecode); - assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ - schemas.addressSchema, - schemas.numberSchema, - schemas.jsNumber, - ]); - const provider = providerUtils.standardizeOrThrow(supportedProvider); - const constructorAbi = BaseContract._lookupConstructorAbi(abi); - [] = BaseContract._formatABIDataItemList(constructorAbi.inputs, [], BaseContract._bigNumberToString); - const iface = new ethers.utils.Interface(abi); - const deployInfo = iface.deployFunction; - const txData = deployInfo.encode(bytecode, []); - const web3Wrapper = new Web3Wrapper(provider); - const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( - { data: txData }, - txDefaults, - web3Wrapper.estimateGasAsync.bind(web3Wrapper), - ); - const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults); - logUtils.log(`transactionHash: ${txHash}`); - const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); - logUtils.log(`AbiGenDummy successfully deployed at ${txReceipt.contractAddress}`); - const contractInstance = new AbiGenDummyContract( - txReceipt.contractAddress as string, - provider, - txDefaults, - logDecodeDependencies, - ); - contractInstance.constructorArgs = []; - return contractInstance; - } - /** - * @returns The contract ABI - */ - public static ABI(): ContractAbi { - const abi = [ - { - constant: true, - inputs: [], - name: 'simpleRequire', - outputs: [], - payable: false, - stateMutability: 'pure', - type: 'function', - }, + if (opts.shouldValidate !== false) { + await self.withdraw.callAsync(wad, txDataWithDefaults); + } + + const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + return txHash; + }, + /** + * Sends an Ethereum transaction and waits until the transaction has been successfully mined without reverting. + * If the transaction was mined, but reverted, an error is thrown. + * @param txData Additional data for transaction + * @param pollingIntervalMs Interval at which to poll for success + * @returns A promise that resolves when the transaction is successful + */ + awaitTransactionSuccessAsync( + wad: BigNumber, + txData?: Partial, + opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, + ): PromiseWithTransactionHash { + assert.isBigNumber('wad', wad); + const self = (this as any) as AbiGenDummyContract; + const txHashPromise = self.withdraw.sendTransactionAsync(wad, txData, opts); + return new PromiseWithTransactionHash( + txHashPromise, + (async (): Promise => { + // When the transaction hash resolves, wait for it to be mined. + return self._web3Wrapper.awaitTransactionSuccessAsync( + await txHashPromise, + opts.pollingIntervalMs, + opts.timeoutMs, + ); + })(), + ); + }, + /** + * Estimates the gas cost of sending an Ethereum transaction calling this method with these arguments. + * @param txData Additional data for transaction + * @returns The hash of the transaction + */ + async estimateGasAsync(wad: BigNumber, txData?: Partial | undefined): Promise { + assert.isBigNumber('wad', wad); + const self = (this as any) as AbiGenDummyContract; + const encodedData = self._strictEncodeArguments('withdraw(uint256)', [wad]); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...txData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + if (txDataWithDefaults.from !== undefined) { + txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); + } + + const gas = await self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + return gas; + }, + /** + * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an + * Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas + * since they don't modify state. + */ + async callAsync(wad: BigNumber, callData: Partial = {}, defaultBlock?: BlockParam): Promise { + assert.isBigNumber('wad', wad); + assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ + schemas.addressSchema, + schemas.numberSchema, + schemas.jsNumber, + ]); + if (defaultBlock !== undefined) { + assert.isBlockParam('defaultBlock', defaultBlock); + } + const self = (this as any) as AbiGenDummyContract; + const encodedData = self._strictEncodeArguments('withdraw(uint256)', [wad]); + const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...callData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + callDataWithDefaults.from = callDataWithDefaults.from + ? callDataWithDefaults.from.toLowerCase() + : callDataWithDefaults.from; + let rawCallResult; + try { + rawCallResult = await self._web3Wrapper.callAsync(callDataWithDefaults, defaultBlock); + } catch (err) { + BaseContract._throwIfThrownErrorIsRevertError(err); + throw err; + } + BaseContract._throwIfCallResultIsRevertError(rawCallResult); + const abiEncoder = self._lookupAbiEncoder('withdraw(uint256)'); + // tslint:disable boolean-naming + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + // tslint:enable boolean-naming + return result; + }, + /** + * Returns the ABI encoded transaction data needed to send an Ethereum transaction calling this method. Before + * sending the Ethereum tx, this encoded tx data can first be sent to a separate signing service or can be used + * to create a 0x transaction (see protocol spec for more details). + * @returns The ABI encoded transaction data as a string + */ + getABIEncodedTransactionData(wad: BigNumber): string { + assert.isBigNumber('wad', wad); + const self = (this as any) as AbiGenDummyContract; + const abiEncodedTransactionData = self._strictEncodeArguments('withdraw(uint256)', [wad]); + return abiEncodedTransactionData; + }, + /** + * Decode the ABI-encoded transaction data into its input arguments + * @param callData The ABI-encoded transaction data + * @returns An array representing the input arguments in order. Keynames of nested structs are preserved. + */ + getABIDecodedTransactionData(callData: string): [BigNumber] { + const self = (this as any) as AbiGenDummyContract; + const abiEncoder = self._lookupAbiEncoder('withdraw(uint256)'); + // tslint:disable boolean-naming + const abiDecodedCallData = abiEncoder.strictDecode<[BigNumber]>(callData); + return abiDecodedCallData; + }, + /** + * Decode the ABI-encoded return data from a transaction + * @param returnData the data returned after transaction execution + * @returns An array representing the output results in order. Keynames of nested structs are preserved. + */ + getABIDecodedReturnData(returnData: string): void { + const self = (this as any) as AbiGenDummyContract; + const abiEncoder = self._lookupAbiEncoder('withdraw(uint256)'); + // tslint:disable boolean-naming + const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue(returnData); + return abiDecodedReturnData; + }, + /** + * Returns the 4 byte function selector as a hex string. + */ + getSelector(): string { + const self = (this as any) as AbiGenDummyContract; + const abiEncoder = self._lookupAbiEncoder('withdraw(uint256)'); + return abiEncoder.getSelector(); + }, + }; + private readonly _subscriptionManager: SubscriptionManager; + public static async deployFrom0xArtifactAsync( + artifact: ContractArtifact | SimpleContractArtifact, + supportedProvider: SupportedProvider, + txDefaults: Partial, + logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact }, + ): Promise { + assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ + schemas.addressSchema, + schemas.numberSchema, + schemas.jsNumber, + ]); + if (artifact.compilerOutput === undefined) { + throw new Error('Compiler output not found in the artifact file'); + } + const provider = providerUtils.standardizeOrThrow(supportedProvider); + const bytecode = artifact.compilerOutput.evm.bytecode.object; + const abi = artifact.compilerOutput.abi; + const logDecodeDependenciesAbiOnly: { [contractName: string]: ContractAbi } = {}; + if (Object.keys(logDecodeDependencies) !== undefined) { + for (const key of Object.keys(logDecodeDependencies)) { + logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi; + } + } + return AbiGenDummyContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly); + } + public static async deployAsync( + bytecode: string, + abi: ContractAbi, + supportedProvider: SupportedProvider, + txDefaults: Partial, + logDecodeDependencies: { [contractName: string]: ContractAbi }, + ): Promise { + assert.isHexString('bytecode', bytecode); + assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ + schemas.addressSchema, + schemas.numberSchema, + schemas.jsNumber, + ]); + const provider = providerUtils.standardizeOrThrow(supportedProvider); + const constructorAbi = BaseContract._lookupConstructorAbi(abi); + [] = BaseContract._formatABIDataItemList(constructorAbi.inputs, [], BaseContract._bigNumberToString); + const iface = new ethers.utils.Interface(abi); + const deployInfo = iface.deployFunction; + const txData = deployInfo.encode(bytecode, []); + const web3Wrapper = new Web3Wrapper(provider); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { data: txData }, + txDefaults, + web3Wrapper.estimateGasAsync.bind(web3Wrapper), + ); + const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults); + logUtils.log(`transactionHash: ${txHash}`); + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); + logUtils.log(`AbiGenDummy successfully deployed at ${txReceipt.contractAddress}`); + const contractInstance = new AbiGenDummyContract( + txReceipt.contractAddress as string, + provider, + txDefaults, + logDecodeDependencies, + ); + contractInstance.constructorArgs = []; + return contractInstance; + } + + /** + * @returns The contract ABI + */ + public static ABI(): ContractAbi { + const abi = [ { - constant: true, + anonymous: false, inputs: [ { - name: 'a', - type: 'bytes[]', + name: 'someBytes', + type: 'bytes', + indexed: false, + }, + { + name: 'someString', + type: 'string', + indexed: false, }, ], - name: 'acceptsAnArrayOfBytes', + name: 'SimpleEvent', outputs: [], - payable: false, - stateMutability: 'pure', - type: 'function', + type: 'event', }, { - constant: true, + anonymous: false, inputs: [ { - name: 'index_0', + name: '_owner', + type: 'address', + indexed: true, + }, + { + name: '_value', type: 'uint256', + indexed: false, }, ], - name: 'simpleInputSimpleOutput', - outputs: [ + name: 'Withdrawal', + outputs: [], + type: 'event', + }, + { + constant: true, + inputs: [ { - name: '', - type: 'uint256', + name: 'a', + type: 'bytes[]', }, ], + name: 'acceptsAnArrayOfBytes', + outputs: [], payable: false, stateMutability: 'pure', type: 'function', }, { - constant: false, + constant: true, inputs: [ { - name: 'wad', - type: 'uint256', + name: 'a', + type: 'bytes', }, ], - name: 'withdraw', + name: 'acceptsBytes', outputs: [], payable: false, - stateMutability: 'nonpayable', + stateMutability: 'pure', type: 'function', }, { constant: true, inputs: [ { - name: 'index_0', - type: 'uint256', - }, - { - name: 'index_1', - type: 'bytes', - }, - { - name: 'index_2', - type: 'string', + name: 'complexInput', + type: 'tuple', + components: [ + { + name: 'foo', + type: 'uint256', + }, + { + name: 'bar', + type: 'bytes', + }, + { + name: 'car', + type: 'string', + }, + ], }, ], - name: 'multiInputMultiOutput', + name: 'complexInputComplexOutput', outputs: [ { name: '', - type: 'bytes', - }, - { - name: '', - type: 'bytes', - }, - { - name: '', - type: 'string', + type: 'tuple', + components: [ + { + name: 'input', + type: 'tuple', + components: [ + { + name: 'foo', + type: 'uint256', + }, + { + name: 'bar', + type: 'bytes', + }, + { + name: 'car', + type: 'string', + }, + ], + }, + { + name: 'lorem', + type: 'bytes', + }, + { + name: 'ipsum', + type: 'bytes', + }, + { + name: 'dolor', + type: 'string', + }, + ], }, ], payable: false, @@ -3218,27 +3256,40 @@ export class AbiGenDummyContract extends BaseContract { type: 'function', }, { - constant: true, - inputs: [ - { - name: 'a', - type: 'bytes', - }, - ], - name: 'acceptsBytes', + constant: false, + inputs: [], + name: 'emitSimpleEvent', outputs: [], payable: false, - stateMutability: 'pure', + stateMutability: 'nonpayable', type: 'function', }, { constant: true, inputs: [], - name: 'noInputSimpleOutput', + name: 'methodReturningArrayOfStructs', outputs: [ { name: '', - type: 'uint256', + type: 'tuple[]', + components: [ + { + name: 'someBytes', + type: 'bytes', + }, + { + name: 'anInteger', + type: 'uint32', + }, + { + name: 'aDynamicArrayOfBytes', + type: 'bytes[]', + }, + { + name: 'aString', + type: 'string', + }, + ], }, ], payable: false, @@ -3248,17 +3299,17 @@ export class AbiGenDummyContract extends BaseContract { { constant: true, inputs: [], - name: 'revertWithConstant', - outputs: [], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'simpleRevert', - outputs: [], + name: 'methodReturningMultipleValues', + outputs: [ + { + name: '', + type: 'uint256', + }, + { + name: '', + type: 'string', + }, + ], payable: false, stateMutability: 'pure', type: 'function', @@ -3291,11 +3342,44 @@ export class AbiGenDummyContract extends BaseContract { }, { constant: true, - inputs: [], - name: 'nestedStructOutput', + inputs: [ + { + name: 'index_0', + type: 'uint256', + }, + { + name: 'index_1', + type: 'bytes', + }, + { + name: 'index_2', + type: 'string', + }, + ], + name: 'multiInputMultiOutput', outputs: [ { name: '', + type: 'bytes', + }, + { + name: '', + type: 'bytes', + }, + { + name: '', + type: 'string', + }, + ], + payable: false, + stateMutability: 'pure', + type: 'function', + }, + { + constant: true, + inputs: [ + { + name: 'n', type: 'tuple', components: [ { @@ -3327,14 +3411,7 @@ export class AbiGenDummyContract extends BaseContract { ], }, ], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'requireWithConstant', + name: 'nestedStructInput', outputs: [], payable: false, stateMutability: 'pure', @@ -3342,154 +3419,101 @@ export class AbiGenDummyContract extends BaseContract { }, { constant: true, - inputs: [ - { - name: 'x', - type: 'address', - }, - { - name: 'a', - type: 'uint256', - }, - { - name: 'b', - type: 'uint256', - }, - { - name: 'y', - type: 'address', - }, - { - name: 'c', - type: 'uint256', - }, - ], - name: 'withAddressInput', + inputs: [], + name: 'nestedStructOutput', outputs: [ { - name: 'z', - type: 'address', - }, - ], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: 's', + name: '', type: 'tuple', components: [ { - name: 'someBytes', - type: 'bytes', - }, - { - name: 'anInteger', - type: 'uint32', - }, - { - name: 'aDynamicArrayOfBytes', - type: 'bytes[]', + name: 'innerStruct', + type: 'tuple', + components: [ + { + name: 'someBytes', + type: 'bytes', + }, + { + name: 'anInteger', + type: 'uint32', + }, + { + name: 'aDynamicArrayOfBytes', + type: 'bytes[]', + }, + { + name: 'aString', + type: 'string', + }, + ], }, { - name: 'aString', + name: 'description', type: 'string', }, ], }, ], - name: 'structInput', - outputs: [], payable: false, stateMutability: 'pure', type: 'function', }, { - constant: false, + constant: true, inputs: [], - name: 'nonPureMethod', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], + name: 'noInputNoOutput', + outputs: [], payable: false, - stateMutability: 'nonpayable', + stateMutability: 'pure', type: 'function', }, { constant: true, - inputs: [ - { - name: 'complexInput', - type: 'tuple', - components: [ - { - name: 'foo', - type: 'uint256', - }, - { - name: 'bar', - type: 'bytes', - }, - { - name: 'car', - type: 'string', - }, - ], - }, - ], - name: 'complexInputComplexOutput', + inputs: [], + name: 'noInputSimpleOutput', outputs: [ { name: '', - type: 'tuple', - components: [ - { - name: 'input', - type: 'tuple', - components: [ - { - name: 'foo', - type: 'uint256', - }, - { - name: 'bar', - type: 'bytes', - }, - { - name: 'car', - type: 'string', - }, - ], - }, - { - name: 'lorem', - type: 'bytes', - }, - { - name: 'ipsum', - type: 'bytes', - }, - { - name: 'dolor', - type: 'string', - }, - ], + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'pure', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'nonPureMethod', + outputs: [ + { + name: '', + type: 'uint256', }, ], payable: false, - stateMutability: 'pure', + stateMutability: 'nonpayable', type: 'function', }, { - constant: true, + constant: false, inputs: [], - name: 'noInputNoOutput', + name: 'nonPureMethodThatReturnsNothing', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + name: 'a', + type: 'string', + }, + ], + name: 'overloadedMethod', outputs: [], payable: false, stateMutability: 'pure', @@ -3499,14 +3523,23 @@ export class AbiGenDummyContract extends BaseContract { constant: true, inputs: [ { - name: 'x', - type: 'uint256', + name: 'a', + type: 'int256', }, ], - name: 'simplePureFunctionWithInput', + name: 'overloadedMethod', + outputs: [], + payable: false, + stateMutability: 'pure', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pureFunctionWithConstant', outputs: [ { - name: 'sum', + name: 'someConstant', type: 'uint256', }, ], @@ -3515,24 +3548,33 @@ export class AbiGenDummyContract extends BaseContract { type: 'function', }, { - constant: false, + constant: true, inputs: [], - name: 'nonPureMethodThatReturnsNothing', + name: 'requireWithConstant', outputs: [], payable: false, - stateMutability: 'nonpayable', + stateMutability: 'pure', type: 'function', }, { constant: true, inputs: [], - name: 'simplePureFunction', - outputs: [ + name: 'revertWithConstant', + outputs: [], + payable: false, + stateMutability: 'pure', + type: 'function', + }, + { + constant: true, + inputs: [ { - name: 'result', + name: 'index_0', type: 'uint256', }, ], + name: 'simpleInputNoOutput', + outputs: [], payable: false, stateMutability: 'pure', type: 'function', @@ -3541,40 +3583,17 @@ export class AbiGenDummyContract extends BaseContract { constant: true, inputs: [ { - name: 'n', - type: 'tuple', - components: [ - { - name: 'innerStruct', - type: 'tuple', - components: [ - { - name: 'someBytes', - type: 'bytes', - }, - { - name: 'anInteger', - type: 'uint32', - }, - { - name: 'aDynamicArrayOfBytes', - type: 'bytes[]', - }, - { - name: 'aString', - type: 'string', - }, - ], - }, - { - name: 'description', - type: 'string', - }, - ], + name: 'index_0', + type: 'uint256', + }, + ], + name: 'simpleInputSimpleOutput', + outputs: [ + { + name: '', + type: 'uint256', }, ], - name: 'nestedStructInput', - outputs: [], payable: false, stateMutability: 'pure', type: 'function', @@ -3582,15 +3601,30 @@ export class AbiGenDummyContract extends BaseContract { { constant: true, inputs: [], - name: 'methodReturningMultipleValues', + name: 'simplePureFunction', outputs: [ { - name: '', + name: 'result', type: 'uint256', }, + ], + payable: false, + stateMutability: 'pure', + type: 'function', + }, + { + constant: true, + inputs: [ { - name: '', - type: 'string', + name: 'x', + type: 'uint256', + }, + ], + name: 'simplePureFunctionWithInput', + outputs: [ + { + name: 'sum', + type: 'uint256', }, ], payable: false, @@ -3600,11 +3634,27 @@ export class AbiGenDummyContract extends BaseContract { { constant: true, inputs: [], - name: 'methodReturningArrayOfStructs', - outputs: [ + name: 'simpleRequire', + outputs: [], + payable: false, + stateMutability: 'pure', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'simpleRevert', + outputs: [], + payable: false, + stateMutability: 'pure', + type: 'function', + }, + { + constant: true, + inputs: [ { - name: '', - type: 'tuple[]', + name: 's', + type: 'tuple', components: [ { name: 'someBytes', @@ -3625,17 +3675,10 @@ export class AbiGenDummyContract extends BaseContract { ], }, ], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: false, - inputs: [], - name: 'emitSimpleEvent', + name: 'structInput', outputs: [], payable: false, - stateMutability: 'nonpayable', + stateMutability: 'pure', type: 'function', }, { @@ -3672,95 +3715,52 @@ export class AbiGenDummyContract extends BaseContract { }, { constant: true, - inputs: [], - name: 'pureFunctionWithConstant', - outputs: [ + inputs: [ { - name: 'someConstant', + name: 'x', + type: 'address', + }, + { + name: 'a', type: 'uint256', }, - ], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: true, - inputs: [ { - name: 'index_0', + name: 'b', type: 'uint256', }, - ], - name: 'simpleInputNoOutput', - outputs: [], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: true, - inputs: [ { - name: 'a', - type: 'string', + name: 'y', + type: 'address', + }, + { + name: 'c', + type: 'uint256', }, ], - name: 'overloadedMethod', - outputs: [], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: true, - inputs: [ + name: 'withAddressInput', + outputs: [ { - name: 'a', - type: 'int256', + name: 'z', + type: 'address', }, ], - name: 'overloadedMethod', - outputs: [], payable: false, stateMutability: 'pure', type: 'function', }, { - anonymous: false, + constant: false, inputs: [ { - name: '_owner', - type: 'address', - indexed: true, - }, - { - name: '_value', + name: 'wad', type: 'uint256', - indexed: false, - }, - ], - name: 'Withdrawal', - outputs: [], - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - name: 'someBytes', - type: 'bytes', - indexed: false, - }, - { - name: 'someString', - type: 'string', - indexed: false, }, ], - name: 'SimpleEvent', + name: 'withdraw', outputs: [], - type: 'event', + payable: false, + stateMutability: 'nonpayable', + type: 'function', }, ] as ContractAbi; return abi; diff --git a/packages/abi-gen/test-cli/output/typescript/test_lib_dummy.ts b/packages/abi-gen/test-cli/output/typescript/test_lib_dummy.ts index 0af33346f0..b1721f5ca3 100644 --- a/packages/abi-gen/test-cli/output/typescript/test_lib_dummy.ts +++ b/packages/abi-gen/test-cli/output/typescript/test_lib_dummy.ts @@ -38,7 +38,7 @@ export class TestLibDummyContract extends BaseContract { * @ignore */ public static deployedBytecode = - '0x6080604052348015600f57600080fd5b506004361060325760003560e01c806322935e921460375780632b82fdf0146063575b600080fd5b605160048036036020811015604b57600080fd5b5035607d565b60408051918252519081900360200190f35b605160048036036020811015607757600080fd5b5035608c565b60006086826095565b92915050565b6000608682609c565b6104d20190565b6001019056fea265627a7a72305820ddb720d14b34694daaefebcbd729af6ae04fa2232481812dd8fde63d6a4c32c164736f6c634300050a0032'; + '0x6080604052348015600f57600080fd5b506004361060325760003560e01c806322935e921460375780632b82fdf0146063575b600080fd5b605160048036036020811015604b57600080fd5b5035607d565b60408051918252519081900360200190f35b605160048036036020811015607757600080fd5b5035608c565b60006086826095565b92915050565b6000608682609c565b6104d20190565b6001019056fea265627a7a72315820863e53f0da474a1275d583d88852313fe053941e79bddd5279abd812b31e020c64736f6c634300050c0032'; public publicAddConstant = { /** * Sends a read-only call to the contract method. Returns the result that would happen if one were to send an From 510e341d0256f3f3837d86a7fedee74ad9ff026b Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 1 Nov 2019 15:57:13 -0400 Subject: [PATCH 24/35] Sync `monorepo$ yarn test` exclusions to CI config --- .circleci/config.yml | 10 +++++++++- package.json | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 61e62d9eab..e6a834f0dc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -78,7 +78,9 @@ jobs: keys: - repo-{{ .Environment.CIRCLE_SHA1 }} - run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-asset-proxy @0x/contracts-exchange-forwarder @0x/contracts-tests @0x/contracts-staking @0x/contracts-coordinator - # TODO(dorothy-zbornak): Re-enable after updating this package for 3.0. + # TODO(dorothy-zbornak): Re-enable after updating this package for + # 3.0. At that time, also remove exclusion from monorepo + # package.json's test script. # - run: yarn wsrun test:circleci @0x/contracts-extensions test-publish: resource_class: medium+ @@ -116,6 +118,9 @@ jobs: - run: yarn wsrun test:circleci @0x/abi-gen # TODO (xianny): Needs to be updated for 3.0 # - run: yarn wsrun test:circleci @0x/asset-buyer + # TODO: Needs to be updated for 3.0. At that time, also remove + # exclusion from monorepo package.json's test script. + # - run: yarn wsrun test:circleci @0x/asset-swapper - run: yarn wsrun test:circleci @0x/contract-artifacts - run: yarn wsrun test:circleci @0x/assert - run: yarn wsrun test:circleci @0x/base-contract @@ -125,6 +130,9 @@ jobs: - run: yarn wsrun test:circleci @0x/dev-utils - run: yarn wsrun test:circleci @0x/json-schemas - run: yarn wsrun test:circleci @0x/order-utils + # TODO: Needs to be updated for 3.0. At that time, also remove + # exclusion from monorepo package.json's test script. + # - run: yarn wsrun test:circleci @0x/orderbook - run: yarn wsrun test:circleci @0x/sol-compiler - run: yarn wsrun test:circleci @0x/sol-tracing-utils - run: yarn wsrun test:circleci @0x/sol-doc diff --git a/package.json b/package.json index d80b0ac141..fb1fcef0e3 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "contracts:watch": "wsrun watch $PKG --parallel --exclude-missing", "remove_node_modules": "lerna clean --yes; rm -rf node_modules", "rebuild": "run-s clean build", - "test": "wsrun test $PKG --fast-exit --serial --exclude-missing", + "test": "wsrun test $PKG --fast-exit --serial --exclude-missing --exclude @0x/asset-swapper --exclude @0x/orderbook --exclude @0x/contracts-extensions", "test:contracts": "wsrun test -p ${npm_package_config_contractsPackages} -c --fast-exit --serial --exclude-missing", "generate_doc": "node ./packages/monorepo-scripts/lib/doc_generate.js", "upload_md_docs": "aws s3 rm --recursive s3://docs-markdown; wsrun s3:sync_md_docs --exclude-missing", From 23b8009b8ab484d4ee575e4bb304f479fee36db2 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 1 Nov 2019 23:58:20 -0400 Subject: [PATCH 25/35] utils: fix typo in comment --- packages/utils/src/provider_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/utils/src/provider_utils.ts b/packages/utils/src/provider_utils.ts index 0a9849bdb9..de8e881a68 100644 --- a/packages/utils/src/provider_utils.ts +++ b/packages/utils/src/provider_utils.ts @@ -99,7 +99,7 @@ export const providerUtils = { /** * Retrieve the chain ID from a supported provider. * @param supportedProvider A supported provider instance. - * @return A promise thar resolves to the chain ID of the network the provider + * @return A promise that resolves to the chain ID of the network the provider * is connected to. */ async getChainIdAsync(supportedProvider: SupportedProvider): Promise { From 6064a2b60d302936a7a47c7a5085e64c2adbf86b Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 1 Nov 2019 16:48:12 -0400 Subject: [PATCH 26/35] sra-spec: correct typo --- packages/connect/test/http_client_test.ts | 8 ++++---- packages/sra-spec/src/parameters.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/connect/test/http_client_test.ts b/packages/connect/test/http_client_test.ts index f799ca8494..41955bc314 100644 --- a/packages/connect/test/http_client_test.ts +++ b/packages/connect/test/http_client_test.ts @@ -53,9 +53,9 @@ describe('HttpClient', () => { assetDataA: assetData, page: 3, perPage: 50, - networkdId: 42, + networkId: 42, }; - const urlWithQuery = `${url}?assetDataA=${assetData}&networkdId=42&page=3&perPage=50`; + const urlWithQuery = `${url}?assetDataA=${assetData}&networkId=42&page=3&perPage=50`; fetchMock.get(urlWithQuery, assetDataPairsResponseJSON); const assetDataPairs = await relayerClient.getAssetPairsAsync(assetPairsRequestOpts); expect(assetDataPairs).to.be.deep.equal(assetDataPairsResponse); @@ -78,9 +78,9 @@ describe('HttpClient', () => { assetDataAddress, page: 3, perPage: 50, - networkdId: 42, + networkId: 42, }; - const urlWithQuery = `${url}?assetDataAddress=${assetDataAddress}&networkdId=42&page=3&perPage=50`; + const urlWithQuery = `${url}?assetDataAddress=${assetDataAddress}&networkId=42&page=3&perPage=50`; fetchMock.get(urlWithQuery, ordersResponseJSON); const orders = await relayerClient.getOrdersAsync(ordersRequest); expect(orders).to.be.deep.equal(ordersResponse); diff --git a/packages/sra-spec/src/parameters.ts b/packages/sra-spec/src/parameters.ts index 48ffb036df..60281b203d 100644 --- a/packages/sra-spec/src/parameters.ts +++ b/packages/sra-spec/src/parameters.ts @@ -22,7 +22,7 @@ export const paginationParameters: ParameterObject[] = [ }, ]; -export const networkdIdParameter: ParameterObject = { +export const networkIdParameter: ParameterObject = { name: 'networkId', in: 'query', description: 'The id of the Ethereum network', @@ -35,5 +35,5 @@ export const networkdIdParameter: ParameterObject = { export const generateParameters = (parameters: ParameterObject[], isPaginated: boolean = false): ParameterObject[] => { const optionalParameters = isPaginated ? paginationParameters : []; - return [...parameters, networkdIdParameter, ...optionalParameters]; + return [...parameters, networkIdParameter, ...optionalParameters]; }; From de1b3951eef5f89f5d943428da7f5901e4b9f012 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 1 Nov 2019 17:22:22 -0400 Subject: [PATCH 27/35] contract-wrappers: TODO after coord.-server update --- packages/contract-wrappers/test/coordinator_wrapper_test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/contract-wrappers/test/coordinator_wrapper_test.ts b/packages/contract-wrappers/test/coordinator_wrapper_test.ts index 05de597884..66acc6bde2 100644 --- a/packages/contract-wrappers/test/coordinator_wrapper_test.ts +++ b/packages/contract-wrappers/test/coordinator_wrapper_test.ts @@ -111,6 +111,7 @@ describe.skip('CoordinatorWrapper', () => { const coordinatorServerConfigs = { HTTP_PORT: 3000, // Only used in default instantiation in 0x-coordinator-server/server.js; not used here NETWORK_ID_TO_SETTINGS: { + // TODO: change to CHAIN_ID_TO_SETTINGS when @0x/coordinator-server is ready [config.networkId]: { FEE_RECIPIENTS: [ { @@ -138,6 +139,7 @@ describe.skip('CoordinatorWrapper', () => { }, }, NETWORK_ID_TO_CONTRACT_ADDRESSES: { + // TODO: change to CHAIN_ID_TO_CONTRACT_ADDRESSES when @0x/coordinator-server is ready [config.networkId]: contractAddresses, }, // Optional selective delay on fill requests From 629af134aa53d77cc852014bfccdfa688b557cc8 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 1 Nov 2019 16:46:13 -0400 Subject: [PATCH 28/35] Refactor networkId to chainId everywhere --- contracts/test-utils/src/constants.ts | 1 - packages/0x.js/src/index.ts | 6 +- packages/abi-gen/src/index.ts | 8 +-- .../fixtures/artifacts/AbiGenDummy.json | 2 +- .../test-cli/fixtures/artifacts/LibDummy.json | 2 +- .../fixtures/artifacts/TestLibDummy.json | 2 +- packages/asset-buyer/src/asset_buyer.ts | 20 +++--- packages/asset-buyer/src/constants.ts | 6 +- .../standard_relayer_api_order_provider.ts | 14 ++-- packages/asset-buyer/src/types.ts | 6 +- packages/asset-swapper/src/constants.ts | 6 +- .../exchange_swap_quote_consumer.ts | 10 +-- .../forwarder_swap_quote_consumer.ts | 10 +-- .../quote_consumers/swap_quote_consumer.ts | 10 +-- packages/asset-swapper/src/swap_quoter.ts | 12 ++-- packages/asset-swapper/src/types.ts | 12 ++-- .../test/exchange_swap_quote_consumer_test.ts | 10 +-- .../forwarder_swap_quote_consumer_test.ts | 8 +-- .../test/swap_quote_consumer_test.ts | 8 +-- .../test/swap_quote_consumer_utils_test.ts | 8 +-- packages/connect/src/http_client.ts | 12 ++-- packages/connect/test/http_client_test.ts | 16 ++--- packages/contract-addresses/addresses.json | 2 +- packages/contract-addresses/src/index.ts | 20 +++--- .../src/contract_wrappers.ts | 6 +- .../src/coordinator_wrapper.ts | 20 +++--- packages/contract-wrappers/src/index.ts | 4 +- .../contract_wrappers_config_schema.ts | 4 +- packages/contract-wrappers/src/types.ts | 8 +-- .../src/utils/contract_addresses.ts | 14 ++-- .../contract-wrappers/src/utils/decorators.ts | 2 +- .../test/calldata_decoder_test.ts | 4 +- .../test/coordinator_wrapper_test.ts | 20 +++--- .../contract-wrappers/test/utils/constants.ts | 5 +- packages/ethereum-types/src/index.ts | 10 +-- ...ders_channel_subscribe_payload_schema.json | 2 +- .../schemas/request_opts_schema.json | 2 +- .../migrations/src/test_contract_configs.ts | 8 +-- packages/migrations/src/testnet_migrations.ts | 7 +- packages/migrations/src/utils/constants.ts | 4 +- packages/migrations/src/utils/token_info.ts | 4 +- packages/order-utils/src/constants.ts | 2 +- packages/order-utils/src/signature_utils.ts | 10 +-- .../order_provider/base_sra_order_provider.ts | 12 ++-- .../sra_polling_order_provider.ts | 2 +- .../sra_websocket_order_provider.ts | 2 +- packages/orderbook/src/types.ts | 8 +-- packages/sol-compiler/src/compiler.ts | 2 +- packages/sol-compiler/src/utils/compiler.ts | 4 +- packages/sol-compiler/test/util/constants.ts | 1 - packages/sra-spec/src/examples/errors.ts | 4 +- packages/sra-spec/src/md/introduction.md | 26 +++---- packages/sra-spec/src/parameters.ts | 8 +-- .../src/ts/dispense_asset_tasks.ts | 6 +- packages/testnet-faucets/src/ts/handler.ts | 60 ++++++++-------- .../src/ts/parameter_transformer.ts | 10 +-- packages/testnet-faucets/src/ts/tokens.ts | 6 +- packages/types/src/index.ts | 10 +-- packages/utils/src/types.ts | 2 +- .../contract_addresses/src/index.rst | 6 +- .../zero_ex/contract_addresses/__init__.py | 36 +++++----- .../src/zero_ex/contract_wrappers/__init__.py | 18 ++--- .../contract_wrappers/test/conftest.py | 12 ++-- .../test/test_base_contract_method.py | 4 +- .../test/test_erc20_wrapper.py | 4 +- .../test/test_exchange_wrapper.py | 8 +-- .../src/zero_ex/json_schemas/__init__.py | 6 +- .../test/test_local_message_signer.py | 4 +- .../src/zero_ex/order_utils/__init__.py | 12 ++-- .../order_utils/stubs/web3/__init__.pyi | 5 +- .../src/zero_ex/sra_client/__init__.py | 14 ++-- .../src/zero_ex/sra_client/api/default_api.py | 70 +++++++++---------- ...orders_channel_subscribe_payload_schema.py | 30 ++++---- 73 files changed, 368 insertions(+), 371 deletions(-) diff --git a/contracts/test-utils/src/constants.ts b/contracts/test-utils/src/constants.ts index 5e33b32295..eb93afbcf7 100644 --- a/contracts/test-utils/src/constants.ts +++ b/contracts/test-utils/src/constants.ts @@ -31,7 +31,6 @@ const MAX_UINT256 = new BigNumber(2).pow(256).minus(1); export const constants = { BASE_16: 16, INVALID_OPCODE: 'invalid opcode', - TESTRPC_NETWORK_ID: 50, TESTRPC_CHAIN_ID: 1337, // Note(albrow): In practice V8 and most other engines limit the minimum // interval for setInterval to 10ms. We still set it to 0 here in order to diff --git a/packages/0x.js/src/index.ts b/packages/0x.js/src/index.ts index 291ab39c5b..9b87cdb91f 100644 --- a/packages/0x.js/src/index.ts +++ b/packages/0x.js/src/index.ts @@ -1,4 +1,4 @@ -export { getContractAddressesForNetworkOrThrow, NetworkId, ContractAddresses } from '@0x/contract-addresses'; +export { getContractAddressesForChainOrThrow, ChainId, ContractAddresses } from '@0x/contract-addresses'; export { assetDataUtils, @@ -124,11 +124,11 @@ export { BlockParam, CompilerOpts, StandardContractOutput, - ContractNetworks, + ContractChains, TxDataPayable, BlockParamLiteral, CompilerSettings, - ContractNetworkData, + ContractChainData, DevdocOutput, EvmOutput, CompilerSettingsMetadata, diff --git a/packages/abi-gen/src/index.ts b/packages/abi-gen/src/index.ts index f9793aa5d6..ef65285cd8 100644 --- a/packages/abi-gen/src/index.ts +++ b/packages/abi-gen/src/index.ts @@ -28,7 +28,7 @@ import { utils } from './utils'; const ABI_TYPE_CONSTRUCTOR = 'constructor'; const ABI_TYPE_METHOD = 'function'; const ABI_TYPE_EVENT = 'event'; -const DEFAULT_NETWORK_ID = 50; +const DEFAULT_CHAIN_ID = 1337; const DEFAULT_BACKEND = 'web3'; const args = yargs @@ -65,10 +65,10 @@ const args = yargs choices: [ContractsBackend.Web3, ContractsBackend.Ethers], default: DEFAULT_BACKEND, }) - .option('network-id', { - describe: 'ID of the network where contract ABIs are nested in artifacts', + .option('chain-id', { + describe: 'ID of the chain where contract ABIs are nested in artifacts', type: 'number', - default: DEFAULT_NETWORK_ID, + default: DEFAULT_CHAIN_ID, }) .option('language', { describe: 'Language of output file to generate', diff --git a/packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json b/packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json index 2023f5685e..a59d9ef4d6 100644 --- a/packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json +++ b/packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json @@ -846,5 +846,5 @@ "remappings": [] } }, - "networks": {} + "chains": {} } \ No newline at end of file diff --git a/packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json b/packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json index 162cc32ce3..af6f5d5d56 100644 --- a/packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json +++ b/packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json @@ -60,5 +60,5 @@ "remappings": [] } }, - "networks": {} + "chains": {} } \ No newline at end of file diff --git a/packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json b/packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json index b2c6c86742..9edf4668cb 100644 --- a/packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json +++ b/packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json @@ -107,5 +107,5 @@ "remappings": [] } }, - "networks": {} + "chains": {} } \ No newline at end of file diff --git a/packages/asset-buyer/src/asset_buyer.ts b/packages/asset-buyer/src/asset_buyer.ts index fd30833756..ff595fe567 100644 --- a/packages/asset-buyer/src/asset_buyer.ts +++ b/packages/asset-buyer/src/asset_buyer.ts @@ -35,7 +35,7 @@ interface OrdersEntry { export class AssetBuyer { public readonly provider: ZeroExProvider; public readonly orderProvider: OrderProvider; - public readonly networkId: number; + public readonly chainId: number; public readonly orderRefreshIntervalMs: number; public readonly expiryBufferSeconds: number; private readonly _contractWrappers: ContractWrappers; @@ -76,8 +76,8 @@ export class AssetBuyer { ): AssetBuyer { const provider = providerUtils.standardizeOrThrow(supportedProvider); assert.isWebUri('sraApiUrl', sraApiUrl); - const networkId = options.networkId || constants.DEFAULT_ASSET_BUYER_OPTS.networkId; - const orderProvider = new StandardRelayerAPIOrderProvider(sraApiUrl, networkId); + const chainId = options.chainId || constants.DEFAULT_ASSET_BUYER_OPTS.chainId; + const orderProvider = new StandardRelayerAPIOrderProvider(sraApiUrl, chainId); const assetBuyer = new AssetBuyer(provider, orderProvider, options); return assetBuyer; } @@ -94,23 +94,23 @@ export class AssetBuyer { orderProvider: OrderProvider, options: Partial = {}, ) { - const { networkId, orderRefreshIntervalMs, expiryBufferSeconds } = _.merge( + const { chainId, orderRefreshIntervalMs, expiryBufferSeconds } = _.merge( {}, constants.DEFAULT_ASSET_BUYER_OPTS, options, ); const provider = providerUtils.standardizeOrThrow(supportedProvider); assert.isValidOrderProvider('orderProvider', orderProvider); - assert.isNumber('networkId', networkId); + assert.isNumber('chainId', chainId); assert.isNumber('orderRefreshIntervalMs', orderRefreshIntervalMs); assert.isNumber('expiryBufferSeconds', expiryBufferSeconds); this.provider = provider; this.orderProvider = orderProvider; - this.networkId = networkId; + this.chainId = chainId; this.orderRefreshIntervalMs = orderRefreshIntervalMs; this.expiryBufferSeconds = expiryBufferSeconds; this._contractWrappers = new ContractWrappers(this.provider, { - networkId, + chainId, }); } /** @@ -331,7 +331,7 @@ export class AssetBuyer { const orderProviderRequest = { makerAssetData: assetData, takerAssetData: etherTokenAssetData, - networkId: this.networkId, + chainId: this.chainId, }; const request = orderProviderRequest; // get provider response @@ -357,14 +357,14 @@ export class AssetBuyer { } /** * Get the assetData that represents the WETH token. - * Will throw if WETH does not exist for the current network. + * Will throw if WETH does not exist for the current chain. */ private _getEtherTokenAssetDataOrThrow(): string { return assetDataUtils.encodeERC20AssetData(this._contractWrappers.contractAddresses.etherToken); } /** * Get the assetData that represents the ZRX token. - * Will throw if ZRX does not exist for the current network. + * Will throw if ZRX does not exist for the current chain. */ private _getZrxTokenAssetDataOrThrow(): string { return assetDataUtils.encodeERC20AssetData(this._contractWrappers.contractAddresses.zrxToken); diff --git a/packages/asset-buyer/src/constants.ts b/packages/asset-buyer/src/constants.ts index c0e1bf27d6..224821ad3f 100644 --- a/packages/asset-buyer/src/constants.ts +++ b/packages/asset-buyer/src/constants.ts @@ -4,10 +4,10 @@ import { BigNumber } from '@0x/utils'; import { AssetBuyerOpts, BuyQuoteExecutionOpts, BuyQuoteRequestOpts, OrdersAndFillableAmounts } from './types'; const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; -const MAINNET_NETWORK_ID = 1; +const MAINNET_CHAIN_ID = 1; const DEFAULT_ASSET_BUYER_OPTS: AssetBuyerOpts = { - networkId: MAINNET_NETWORK_ID, + chainId: MAINNET_CHAIN_ID, orderRefreshIntervalMs: 10000, // 10 seconds expiryBufferSeconds: 120, // 2 minutes }; @@ -31,7 +31,7 @@ const EMPTY_ORDERS_AND_FILLABLE_AMOUNTS: OrdersAndFillableAmounts = { export const constants = { ZERO_AMOUNT: new BigNumber(0), NULL_ADDRESS, - MAINNET_NETWORK_ID, + MAINNET_CHAIN_ID, ETHER_TOKEN_DECIMALS: 18, DEFAULT_ASSET_BUYER_OPTS, DEFAULT_BUY_QUOTE_EXECUTION_OPTS, diff --git a/packages/asset-buyer/src/order_providers/standard_relayer_api_order_provider.ts b/packages/asset-buyer/src/order_providers/standard_relayer_api_order_provider.ts index abb9544e7e..43323b5735 100644 --- a/packages/asset-buyer/src/order_providers/standard_relayer_api_order_provider.ts +++ b/packages/asset-buyer/src/order_providers/standard_relayer_api_order_provider.ts @@ -15,7 +15,7 @@ import { assert } from '../utils/assert'; export class StandardRelayerAPIOrderProvider implements OrderProvider { public readonly apiUrl: string; - public readonly networkId: number; + public readonly chainId: number; private readonly _sraClient: HttpClient; /** * Given an array of APIOrder objects from a standard relayer api, return an array @@ -49,14 +49,14 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider { /** * Instantiates a new StandardRelayerAPIOrderProvider instance * @param apiUrl The standard relayer API base HTTP url you would like to source orders from. - * @param networkId The ethereum network id. + * @param chainId The ethereum chain id. * @return An instance of StandardRelayerAPIOrderProvider */ - constructor(apiUrl: string, networkId: number) { + constructor(apiUrl: string, chainId: number) { assert.isWebUri('apiUrl', apiUrl); - assert.isNumber('networkId', networkId); + assert.isNumber('chainId', chainId); this.apiUrl = apiUrl; - this.networkId = networkId; + this.chainId = chainId; this._sraClient = new HttpClient(apiUrl); } /** @@ -68,7 +68,7 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider { assert.isValidOrderProviderRequest('orderProviderRequest', orderProviderRequest); const { makerAssetData, takerAssetData } = orderProviderRequest; const orderbookRequest = { baseAssetData: makerAssetData, quoteAssetData: takerAssetData }; - const requestOpts = { networkId: this.networkId }; + const requestOpts = { chainId: this.chainId }; let orderbook: OrderbookResponse; try { orderbook = await this._sraClient.getOrderbookAsync(orderbookRequest, requestOpts); @@ -91,7 +91,7 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider { public async getAvailableMakerAssetDatasAsync(takerAssetData: string): Promise { // Return a maximum of 1000 asset datas const maxPerPage = 1000; - const requestOpts = { networkId: this.networkId, perPage: maxPerPage }; + const requestOpts = { chainId: this.chainId, perPage: maxPerPage }; const assetPairsRequest = { assetDataA: takerAssetData }; const fullRequest = { ...requestOpts, diff --git a/packages/asset-buyer/src/types.ts b/packages/asset-buyer/src/types.ts index 46a2338cea..eae698bd68 100644 --- a/packages/asset-buyer/src/types.ts +++ b/packages/asset-buyer/src/types.ts @@ -4,7 +4,7 @@ import { BigNumber } from '@0x/utils'; /** * makerAssetData: The assetData representing the desired makerAsset. * takerAssetData: The assetData representing the desired takerAsset. - * networkId: The networkId that the desired orders should be for. + * chainId: The chainId that the desired orders should be for. */ export interface OrderProviderRequest { makerAssetData: string; @@ -98,12 +98,12 @@ export interface BuyQuoteExecutionOpts { } /** - * networkId: The ethereum network id. Defaults to 1 (mainnet). + * chainId: The ethereum chain id. Defaults to 1 (mainnet). * orderRefreshIntervalMs: The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states. Defaults to 10000ms (10s). * expiryBufferSeconds: The number of seconds to add when calculating whether an order is expired or not. Defaults to 300s (5m). */ export interface AssetBuyerOpts { - networkId: number; + chainId: number; orderRefreshIntervalMs: number; expiryBufferSeconds: number; } diff --git a/packages/asset-swapper/src/constants.ts b/packages/asset-swapper/src/constants.ts index ead0d47624..97a7eba606 100644 --- a/packages/asset-swapper/src/constants.ts +++ b/packages/asset-swapper/src/constants.ts @@ -11,12 +11,12 @@ import { const NULL_BYTES = '0x'; const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; -const MAINNET_NETWORK_ID = 1; +const MAINNET_CHAIN_ID = 1; const ONE_SECOND_MS = 1000; const DEFAULT_PER_PAGE = 1000; const DEFAULT_SWAP_QUOTER_OPTS: SwapQuoterOpts = { - networkId: MAINNET_NETWORK_ID, + chainId: MAINNET_CHAIN_ID, orderRefreshIntervalMs: 10000, // 10 seconds expiryBufferMs: 120000, // 2 minutes }; @@ -42,7 +42,7 @@ export const constants = { NULL_BYTES, ZERO_AMOUNT: new BigNumber(0), NULL_ADDRESS, - MAINNET_NETWORK_ID, + MAINNET_CHAIN_ID, ETHER_TOKEN_DECIMALS: 18, ONE_AMOUNT: new BigNumber(1), ONE_SECOND_MS, diff --git a/packages/asset-swapper/src/quote_consumers/exchange_swap_quote_consumer.ts b/packages/asset-swapper/src/quote_consumers/exchange_swap_quote_consumer.ts index a81c2a2cc5..7e79b930c7 100644 --- a/packages/asset-swapper/src/quote_consumers/exchange_swap_quote_consumer.ts +++ b/packages/asset-swapper/src/quote_consumers/exchange_swap_quote_consumer.ts @@ -23,19 +23,19 @@ import { utils } from '../utils/utils'; export class ExchangeSwapQuoteConsumer implements SwapQuoteConsumerBase { public readonly provider: ZeroExProvider; - public readonly networkId: number; + public readonly chainId: number; private readonly _contractWrappers: ContractWrappers; constructor(supportedProvider: SupportedProvider, options: Partial = {}) { - const { networkId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options); - assert.isNumber('networkId', networkId); + const { chainId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options); + assert.isNumber('chainId', chainId); const provider = providerUtils.standardizeOrThrow(supportedProvider); this.provider = provider; - this.networkId = networkId; + this.chainId = chainId; this._contractWrappers = new ContractWrappers(this.provider, { - networkId, + chainId, }); } diff --git a/packages/asset-swapper/src/quote_consumers/forwarder_swap_quote_consumer.ts b/packages/asset-swapper/src/quote_consumers/forwarder_swap_quote_consumer.ts index f4553572df..427484dfd5 100644 --- a/packages/asset-swapper/src/quote_consumers/forwarder_swap_quote_consumer.ts +++ b/packages/asset-swapper/src/quote_consumers/forwarder_swap_quote_consumer.ts @@ -25,19 +25,19 @@ import { utils } from '../utils/utils'; export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumerBase { public readonly provider: ZeroExProvider; - public readonly networkId: number; + public readonly chainId: number; private readonly _contractWrappers: ContractWrappers; constructor(supportedProvider: SupportedProvider, options: Partial = {}) { - const { networkId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options); - assert.isNumber('networkId', networkId); + const { chainId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options); + assert.isNumber('chainId', chainId); const provider = providerUtils.standardizeOrThrow(supportedProvider); this.provider = provider; - this.networkId = networkId; + this.chainId = chainId; this._contractWrappers = new ContractWrappers(this.provider, { - networkId, + chainId, }); } diff --git a/packages/asset-swapper/src/quote_consumers/swap_quote_consumer.ts b/packages/asset-swapper/src/quote_consumers/swap_quote_consumer.ts index 1da8192ec6..a07b587e52 100644 --- a/packages/asset-swapper/src/quote_consumers/swap_quote_consumer.ts +++ b/packages/asset-swapper/src/quote_consumers/swap_quote_consumer.ts @@ -24,24 +24,24 @@ import { ForwarderSwapQuoteConsumer } from './forwarder_swap_quote_consumer'; export class SwapQuoteConsumer implements SwapQuoteConsumerBase { public readonly provider: ZeroExProvider; - public readonly networkId: number; + public readonly chainId: number; private readonly _exchangeConsumer: ExchangeSwapQuoteConsumer; private readonly _forwarderConsumer: ForwarderSwapQuoteConsumer; private readonly _contractWrappers: ContractWrappers; constructor(supportedProvider: SupportedProvider, options: Partial = {}) { - const { networkId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options); - assert.isNumber('networkId', networkId); + const { chainId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options); + assert.isNumber('chainId', chainId); const provider = providerUtils.standardizeOrThrow(supportedProvider); this.provider = provider; - this.networkId = networkId; + this.chainId = chainId; this._exchangeConsumer = new ExchangeSwapQuoteConsumer(supportedProvider, options); this._forwarderConsumer = new ForwarderSwapQuoteConsumer(supportedProvider, options); this._contractWrappers = new ContractWrappers(this.provider, { - networkId, + chainId, }); } diff --git a/packages/asset-swapper/src/swap_quoter.ts b/packages/asset-swapper/src/swap_quoter.ts index 0c5bb37366..89080c6760 100644 --- a/packages/asset-swapper/src/swap_quoter.ts +++ b/packages/asset-swapper/src/swap_quoter.ts @@ -69,7 +69,7 @@ export class SwapQuoter { httpEndpoint: sraApiUrl, pollingIntervalMs: options.orderRefreshIntervalMs || constants.DEFAULT_SWAP_QUOTER_OPTS.orderRefreshIntervalMs, - networkId: options.networkId || constants.DEFAULT_SWAP_QUOTER_OPTS.networkId, + chainId: options.chainId || constants.DEFAULT_SWAP_QUOTER_OPTS.chainId, perPage: options.perPage || constants.DEFAULT_PER_PAGE, }); const swapQuoter = new SwapQuoter(provider, orderbook, options); @@ -97,7 +97,7 @@ export class SwapQuoter { const orderbook = Orderbook.getOrderbookForWebsocketProvider({ httpEndpoint: sraApiUrl, websocketEndpoint: sraWebsocketAPIUrl, - networkId: options.networkId, + chainId: options.chainId, }); const swapQuoter = new SwapQuoter(provider, orderbook, options); return swapQuoter; @@ -134,16 +134,16 @@ export class SwapQuoter { * @return An instance of SwapQuoter */ constructor(supportedProvider: SupportedProvider, orderbook: Orderbook, options: Partial = {}) { - const { networkId, expiryBufferMs } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options); + const { chainId, expiryBufferMs } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options); const provider = providerUtils.standardizeOrThrow(supportedProvider); assert.isValidOrderbook('orderbook', orderbook); - assert.isNumber('networkId', networkId); + assert.isNumber('chainId', chainId); assert.isNumber('expiryBufferMs', expiryBufferMs); this.provider = provider; this.orderbook = orderbook; this.expiryBufferMs = expiryBufferMs; this._contractWrappers = new ContractWrappers(this.provider, { - networkId, + chainId, }); } /** @@ -394,7 +394,7 @@ export class SwapQuoter { /** * Get the assetData that represents the ZRX token. - * Will throw if ZRX does not exist for the current network. + * Will throw if ZRX does not exist for the current chain. */ private _getZrxTokenAssetDataOrThrow(): string { return assetDataUtils.encodeERC20AssetData(this._contractWrappers.contractAddresses.zrxToken); diff --git a/packages/asset-swapper/src/types.ts b/packages/asset-swapper/src/types.ts index e3291bc204..29ca05c272 100644 --- a/packages/asset-swapper/src/types.ts +++ b/packages/asset-swapper/src/types.ts @@ -5,12 +5,12 @@ import { MethodAbi } from 'ethereum-types'; /** * makerAssetData: The assetData representing the desired makerAsset. * takerAssetData: The assetData representing the desired takerAsset. - * networkId: The networkId that the desired orders should be for. + * chainId: The chainId that the desired orders should be for. */ export interface OrderProviderRequest { makerAssetData: string; takerAssetData: string; - networkId: number; + chainId: number; } /** @@ -148,10 +148,10 @@ export interface SwapQuoteConsumerBase { } /** - * networkId: The networkId that the desired orders should be for. + * chainId: The chainId that the desired orders should be for. */ export interface SwapQuoteConsumerOpts { - networkId: number; + chainId: number; } /** @@ -271,12 +271,12 @@ export interface SwapQuoteRequestOpts { } /** - * networkId: The ethereum network id. Defaults to 1 (mainnet). + * chainId: The ethereum chain id. Defaults to 1 (mainnet). * orderRefreshIntervalMs: The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states. Defaults to 10000ms (10s). * expiryBufferMs: The number of seconds to add when calculating whether an order is expired or not. Defaults to 300s (5m). */ export interface SwapQuoterOpts { - networkId: number; + chainId: number; orderRefreshIntervalMs: number; expiryBufferMs: number; } diff --git a/packages/asset-swapper/test/exchange_swap_quote_consumer_test.ts b/packages/asset-swapper/test/exchange_swap_quote_consumer_test.ts index 44a919d854..9bdd7b878c 100644 --- a/packages/asset-swapper/test/exchange_swap_quote_consumer_test.ts +++ b/packages/asset-swapper/test/exchange_swap_quote_consumer_test.ts @@ -27,7 +27,7 @@ const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); const ONE_ETH_IN_WEI = new BigNumber(1000000000000000000); -const TESTRPC_NETWORK_ID = 50; +const TESTRPC_CHAIN_ID = 1337; const FILLABLE_AMOUNTS = [new BigNumber(3), new BigNumber(2), new BigNumber(5)].map(value => value.multipliedBy(ONE_ETH_IN_WEI), ); @@ -48,7 +48,7 @@ describe('ExchangeSwapQuoteConsumer', () => { let wethAssetData: string; let contractAddresses: ContractAddresses; - const networkId = TESTRPC_NETWORK_ID; + const chainId = TESTRPC_CHAIN_ID; let orders: SignedOrder[]; let marketSellSwapQuote: SwapQuote; @@ -60,7 +60,7 @@ describe('ExchangeSwapQuoteConsumer', () => { await blockchainLifecycle.startAsync(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); const config = { - networkId, + chainId, contractAddresses, }; contractWrappers = new ContractWrappers(provider, config); @@ -83,7 +83,7 @@ describe('ExchangeSwapQuoteConsumer', () => { makerFeeAssetData: assetDataUtils.encodeERC20AssetData(contractAddresses.zrxToken), takerFeeAssetData: assetDataUtils.encodeERC20AssetData(contractAddresses.zrxToken), exchangeAddress: contractAddresses.exchange, - chainId: networkId, + chainId, }; const privateKey = devConstants.TESTRPC_PRIVATE_KEYS[userAddresses.indexOf(makerAddress)]; orderFactory = new OrderFactory(privateKey, defaultOrderParams); @@ -117,7 +117,7 @@ describe('ExchangeSwapQuoteConsumer', () => { ); swapQuoteConsumer = new ExchangeSwapQuoteConsumer(provider, { - networkId, + chainId, }); }); afterEach(async () => { diff --git a/packages/asset-swapper/test/forwarder_swap_quote_consumer_test.ts b/packages/asset-swapper/test/forwarder_swap_quote_consumer_test.ts index c4ed8f1bcd..4c80770ddc 100644 --- a/packages/asset-swapper/test/forwarder_swap_quote_consumer_test.ts +++ b/packages/asset-swapper/test/forwarder_swap_quote_consumer_test.ts @@ -25,7 +25,7 @@ const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); const ONE_ETH_IN_WEI = new BigNumber(1000000000000000000); -const TESTRPC_NETWORK_ID = 50; +const TESTRPC_CHAIN_ID = 1337; const MARKET_OPERATION = MarketOperation.Sell; const FILLABLE_AMOUNTS = [new BigNumber(2), new BigNumber(3), new BigNumber(5)].map(value => value.multipliedBy(ONE_ETH_IN_WEI), @@ -53,13 +53,13 @@ describe('ForwarderSwapQuoteConsumer', () => { let swapQuoteConsumer: ForwarderSwapQuoteConsumer; let erc20ProxyAddress: string; - const networkId = TESTRPC_NETWORK_ID; + const chainId = TESTRPC_CHAIN_ID; before(async () => { contractAddresses = await migrateOnceAsync(); await blockchainLifecycle.startAsync(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); const config = { - networkId, + chainId, contractAddresses, }; contractWrappers = new ContractWrappers(provider, config); @@ -117,7 +117,7 @@ describe('ForwarderSwapQuoteConsumer', () => { ); swapQuoteConsumer = new ForwarderSwapQuoteConsumer(provider, { - networkId, + chainId, }); }); afterEach(async () => { diff --git a/packages/asset-swapper/test/swap_quote_consumer_test.ts b/packages/asset-swapper/test/swap_quote_consumer_test.ts index 2fb10140ed..f1e59ad68c 100644 --- a/packages/asset-swapper/test/swap_quote_consumer_test.ts +++ b/packages/asset-swapper/test/swap_quote_consumer_test.ts @@ -19,7 +19,7 @@ const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); const ONE_ETH_IN_WEI = new BigNumber(1000000000000000000); -const TESTRPC_NETWORK_ID = 50; +const TESTRPC_CHAIN_ID = 1337; const FILLABLE_AMOUNTS = [new BigNumber(3), new BigNumber(2), new BigNumber(5)].map(value => value.multipliedBy(ONE_ETH_IN_WEI), ); @@ -41,7 +41,7 @@ describe('SwapQuoteConsumer', () => { let wethAssetData: string; let contractAddresses: ContractAddresses; - const networkId = TESTRPC_NETWORK_ID; + const chainId = TESTRPC_CHAIN_ID; let orders: SignedOrder[]; let marketSellSwapQuote: SwapQuote; @@ -53,7 +53,7 @@ describe('SwapQuoteConsumer', () => { await blockchainLifecycle.startAsync(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); const config = { - networkId, + chainId, contractAddresses, }; contractWrappers = new ContractWrappers(provider, config); @@ -104,7 +104,7 @@ describe('SwapQuoteConsumer', () => { ); swapQuoteConsumer = new SwapQuoteConsumer(provider, { - networkId, + chainId, }); }); afterEach(async () => { diff --git a/packages/asset-swapper/test/swap_quote_consumer_utils_test.ts b/packages/asset-swapper/test/swap_quote_consumer_utils_test.ts index ed22d2dc35..d0cbb26956 100644 --- a/packages/asset-swapper/test/swap_quote_consumer_utils_test.ts +++ b/packages/asset-swapper/test/swap_quote_consumer_utils_test.ts @@ -19,7 +19,7 @@ const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); const ONE_ETH_IN_WEI = new BigNumber(1000000000000000000); -const TESTRPC_NETWORK_ID = 50; +const TESTRPC_CHAIN_ID = 1337; const FILLABLE_AMOUNTS = [new BigNumber(2), new BigNumber(3), new BigNumber(5)].map(value => value.multipliedBy(ONE_ETH_IN_WEI), ); @@ -40,13 +40,13 @@ describe('swapQuoteConsumerUtils', () => { let contractAddresses: ContractAddresses; let swapQuoteConsumer: SwapQuoteConsumer; - const networkId = TESTRPC_NETWORK_ID; + const chainId = TESTRPC_CHAIN_ID; before(async () => { contractAddresses = await migrateOnceAsync(); await blockchainLifecycle.startAsync(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); const config = { - networkId, + chainId, contractAddresses, }; contractWrappers = new ContractWrappers(provider, config); @@ -59,7 +59,7 @@ describe('swapQuoteConsumerUtils', () => { ]; swapQuoteConsumer = new SwapQuoteConsumer(provider, { - networkId, + chainId, }); }); after(async () => { diff --git a/packages/connect/src/http_client.ts b/packages/connect/src/http_client.ts index 136bf72eb0..9281606fce 100644 --- a/packages/connect/src/http_client.ts +++ b/packages/connect/src/http_client.ts @@ -53,7 +53,7 @@ export class HttpClient { } /** * Retrieve assetData pair info from the API - * @param requestOpts Options specifying assetData information to retrieve, page information, and network id. + * @param requestOpts Options specifying assetData information to retrieve, page information, and chain id. * @return The resulting AssetPairsResponse that match the request */ public async getAssetPairsAsync( @@ -73,7 +73,7 @@ export class HttpClient { } /** * Retrieve orders from the API - * @param requestOpts Options specifying orders to retrieve and page information, page information, and network id. + * @param requestOpts Options specifying orders to retrieve and page information, page information, and chain id. * @return The resulting OrdersResponse that match the request */ public async getOrdersAsync( @@ -111,7 +111,7 @@ export class HttpClient { /** * Retrieve an orderbook from the API * @param request An OrderbookRequest instance describing the specific orderbook to retrieve - * @param requestOpts Options specifying page information, and network id. + * @param requestOpts Options specifying page information, and chain id. * @return The resulting OrderbookResponse that matches the request */ public async getOrderbookAsync( @@ -133,7 +133,7 @@ export class HttpClient { /** * Retrieve fee information from the API * @param request A OrderConfigRequest instance describing the specific fees to retrieve - * @param requestOpts Options specifying network id. + * @param requestOpts Options specifying chain id. * @return The resulting OrderConfigResponse that matches the request */ public async getOrderConfigAsync( @@ -154,7 +154,7 @@ export class HttpClient { } /** * Retrieve the list of fee recipient addresses used by the relayer. - * @param requestOpts Options specifying page information, and network id. + * @param requestOpts Options specifying page information, and chain id. * @return The resulting FeeRecipientsResponse */ public async getFeeRecipientsAsync(requestOpts?: RequestOpts & PagedRequestOpts): Promise { @@ -172,7 +172,7 @@ export class HttpClient { /** * Submit a signed order to the API * @param signedOrder A SignedOrder instance to submit - * @param requestOpts Options specifying network id. + * @param requestOpts Options specifying chain id. */ public async submitOrderAsync(signedOrder: SignedOrder, requestOpts?: RequestOpts): Promise { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); diff --git a/packages/connect/test/http_client_test.ts b/packages/connect/test/http_client_test.ts index 41955bc314..5fb6364eb8 100644 --- a/packages/connect/test/http_client_test.ts +++ b/packages/connect/test/http_client_test.ts @@ -53,9 +53,9 @@ describe('HttpClient', () => { assetDataA: assetData, page: 3, perPage: 50, - networkId: 42, + chainId: 42, }; - const urlWithQuery = `${url}?assetDataA=${assetData}&networkId=42&page=3&perPage=50`; + const urlWithQuery = `${url}?assetDataA=${assetData}&chainId=42&page=3&perPage=50`; fetchMock.get(urlWithQuery, assetDataPairsResponseJSON); const assetDataPairs = await relayerClient.getAssetPairsAsync(assetPairsRequestOpts); expect(assetDataPairs).to.be.deep.equal(assetDataPairsResponse); @@ -78,9 +78,9 @@ describe('HttpClient', () => { assetDataAddress, page: 3, perPage: 50, - networkId: 42, + chainId: 42, }; - const urlWithQuery = `${url}?assetDataAddress=${assetDataAddress}&networkId=42&page=3&perPage=50`; + const urlWithQuery = `${url}?assetDataAddress=${assetDataAddress}&chainId=42&page=3&perPage=50`; fetchMock.get(urlWithQuery, ordersResponseJSON); const orders = await relayerClient.getOrdersAsync(ordersRequest); expect(orders).to.be.deep.equal(ordersResponse); @@ -120,12 +120,12 @@ describe('HttpClient', () => { it('gets orderbook with specified page options', async () => { const urlWithQuery = `${url}?baseAssetData=${ request.baseAssetData - }&networkId=42&page=3&perPage=50"eAssetData=${request.quoteAssetData}`; + }&chainId=42&page=3&perPage=50"eAssetData=${request.quoteAssetData}`; fetchMock.get(urlWithQuery, orderbookJSON); const pagedRequestOptions = { page: 3, perPage: 50, - networkId: 42, + chainId: 42, }; const orderbook = await relayerClient.getOrderbookAsync(request, pagedRequestOptions); expect(orderbook).to.be.deep.equal(orderbookResponse); @@ -175,12 +175,12 @@ describe('HttpClient', () => { expect(feeRecipients).to.be.deep.equal(feeRecipientsResponse); }); it('gets fee recipient with specified page options', async () => { - const urlWithQuery = `${url}?networkId=42&page=3&perPage=50`; + const urlWithQuery = `${url}?chainId=42&page=3&perPage=50`; fetchMock.get(urlWithQuery, feeRecipientsResponseJSON); const pagedRequestOptions = { page: 3, perPage: 50, - networkId: 42, + chainId: 42, }; const feeRecipients = await relayerClient.getFeeRecipientsAsync(pagedRequestOptions); expect(feeRecipients).to.be.deep.equal(feeRecipientsResponse); diff --git a/packages/contract-addresses/addresses.json b/packages/contract-addresses/addresses.json index 9eeb90f921..6293ab8e0b 100644 --- a/packages/contract-addresses/addresses.json +++ b/packages/contract-addresses/addresses.json @@ -91,7 +91,7 @@ "stakingProxy": "0xbab9145f1d57cd4bb0c9aa2d1ece0a5b6e734d34", "erc20BridgeProxy": "0xfb2dd2a1366de37f7241c83d47da58fd503e2c64" }, - "50": { + "1337": { "erc20Proxy": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48", "erc721Proxy": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401", "erc1155Proxy": "0x6a4a62e5a7ed13c361b176a5f62c2ee620ac0df8", diff --git a/packages/contract-addresses/src/index.ts b/packages/contract-addresses/src/index.ts index f2c12e6458..3cc763ac3a 100644 --- a/packages/contract-addresses/src/index.ts +++ b/packages/contract-addresses/src/index.ts @@ -26,27 +26,27 @@ export interface ContractAddresses { erc20BridgeProxy: string; } -export enum NetworkId { +export enum ChainId { Mainnet = 1, Ropsten = 3, Rinkeby = 4, Kovan = 42, - Ganache = 50, + Ganache = 1337, } /** * Used to get addresses of contracts that have been deployed to either the * Ethereum mainnet or a supported testnet. Throws if there are no known - * contracts deployed on the corresponding network. - * @param networkId The desired networkId. + * contracts deployed on the corresponding chain. + * @param chainId The desired chainId. * @returns The set of addresses for contracts which have been deployed on the - * given networkId. + * given chainId. */ -export function getContractAddressesForNetworkOrThrow(networkId: NetworkId): ContractAddresses { - const networkToAddresses: { [networkId: number]: ContractAddresses } = addresses; +export function getContractAddressesForChainOrThrow(chainId: ChainId): ContractAddresses { + const chainToAddresses: { [chainId: number]: ContractAddresses } = addresses; - if (networkToAddresses[networkId] === undefined) { - throw new Error(`Unknown network id (${networkId}). No known 0x contracts have been deployed on this network.`); + if (chainToAddresses[chainId] === undefined) { + throw new Error(`Unknown chain id (${chainId}). No known 0x contracts have been deployed on this chain.`); } - return networkToAddresses[networkId]; + return chainToAddresses[chainId]; } diff --git a/packages/contract-wrappers/src/contract_wrappers.ts b/packages/contract-wrappers/src/contract_wrappers.ts index 986f212031..93b40fe761 100644 --- a/packages/contract-wrappers/src/contract_wrappers.ts +++ b/packages/contract-wrappers/src/contract_wrappers.ts @@ -38,7 +38,7 @@ import { _getDefaultContractAddresses } from './utils/contract_addresses'; */ export class ContractWrappers { /** - * An index of the default contract addresses for this network. + * An index of the default contract addresses for this chain. */ public contractAddresses: ContractAddresses; /** @@ -113,7 +113,7 @@ export class ContractWrappers { }); const contractAddresses = config.contractAddresses === undefined - ? _getDefaultContractAddresses(config.networkId) + ? _getDefaultContractAddresses(config.chainId) : config.contractAddresses; this.erc20Proxy = new ERC20ProxyContract(contractAddresses.erc20Proxy, this.getProvider()); this.erc721Proxy = new ERC721ProxyContract(contractAddresses.erc721Proxy, this.getProvider()); @@ -125,7 +125,7 @@ export class ContractWrappers { this.devUtils = new DevUtilsContract(contractAddresses.devUtils, this.getProvider()); this.coordinator = new CoordinatorWrapper( this.getProvider(), - config.networkId, + config.chainId, contractAddresses.coordinator, contractAddresses.exchange, contractAddresses.coordinatorRegistry, diff --git a/packages/contract-wrappers/src/coordinator_wrapper.ts b/packages/contract-wrappers/src/coordinator_wrapper.ts index 9b8a543e3c..40250ba9cb 100644 --- a/packages/contract-wrappers/src/coordinator_wrapper.ts +++ b/packages/contract-wrappers/src/coordinator_wrapper.ts @@ -1,4 +1,4 @@ -import { getContractAddressesForNetworkOrThrow } from '@0x/contract-addresses'; +import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses'; import { Coordinator } from '@0x/contract-artifacts'; import { schemas } from '@0x/json-schemas'; import { generatePseudoRandomSalt, signatureUtils } from '@0x/order-utils'; @@ -32,7 +32,7 @@ import { getAbiEncodedTransactionData } from './utils/getAbiEncodedTransactionDa */ export class CoordinatorWrapper { public abi: ContractAbi = Coordinator.compilerOutput.abi; - public networkId: number; + public chainId: number; public address: string; public exchangeAddress: string; public registryAddress: string; @@ -45,23 +45,23 @@ export class CoordinatorWrapper { /** * Instantiate CoordinatorWrapper * @param web3Wrapper Web3Wrapper instance to use. - * @param networkId Desired networkId. + * @param chainId Desired chainId. * @param address The address of the Coordinator contract. If undefined, will - * default to the known address corresponding to the networkId. + * default to the known address corresponding to the chainId. * @param exchangeAddress The address of the Exchange contract. If undefined, will - * default to the known address corresponding to the networkId. + * default to the known address corresponding to the chainId. * @param registryAddress The address of the CoordinatorRegistry contract. If undefined, will - * default to the known address corresponding to the networkId. + * default to the known address corresponding to the chainId. */ constructor( provider: SupportedProvider, - networkId: number, + chainId: number, address?: string, exchangeAddress?: string, registryAddress?: string, ) { - this.networkId = networkId; - const contractAddresses = getContractAddressesForNetworkOrThrow(networkId); + this.chainId = chainId; + const contractAddresses = getContractAddressesForChainOrThrow(chainId); this.address = address === undefined ? contractAddresses.coordinator : address; this.exchangeAddress = exchangeAddress === undefined ? contractAddresses.coordinator : exchangeAddress; this.registryAddress = registryAddress === undefined ? contractAddresses.coordinatorRegistry : registryAddress; @@ -711,7 +711,7 @@ export class CoordinatorWrapper { signedTransaction, txOrigin, }; - const response = await fetchAsync(`${endpoint}/v1/request_transaction?networkId=${this.networkId}`, { + const response = await fetchAsync(`${endpoint}/v1/request_transaction?chainId=${this.chainId}`, { body: JSON.stringify(requestPayload), method: 'POST', headers: { diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index 96d46327cd..e3576f9f49 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -103,7 +103,7 @@ export { LogWithDecodedArgs, CompilerOpts, StandardContractOutput, - ContractNetworks, + ContractChains, EventParameter, TupleDataItem, TxDataPayable, @@ -116,7 +116,7 @@ export { LogEntry, RawLog, CompilerSettings, - ContractNetworkData, + ContractChainData, EIP1193Event, JSONRPCRequestPayload, JSONRPCErrorCallback, diff --git a/packages/contract-wrappers/src/schemas/contract_wrappers_config_schema.ts b/packages/contract-wrappers/src/schemas/contract_wrappers_config_schema.ts index ae1ce668c9..b12d5123b1 100644 --- a/packages/contract-wrappers/src/schemas/contract_wrappers_config_schema.ts +++ b/packages/contract-wrappers/src/schemas/contract_wrappers_config_schema.ts @@ -1,7 +1,7 @@ export const ContractWrappersConfigSchema = { id: '/ContractWrappersConfig', properties: { - networkId: { + chainId: { type: 'number', }, gasPrice: { $ref: '/numberSchema' }, @@ -21,5 +21,5 @@ export const ContractWrappersConfigSchema = { blockPollingIntervalMs: { type: 'number' }, }, type: 'object', - required: ['networkId'], + required: ['chainId'], }; diff --git a/packages/contract-wrappers/src/types.ts b/packages/contract-wrappers/src/types.ts index 5ac052858c..699e27233e 100644 --- a/packages/contract-wrappers/src/types.ts +++ b/packages/contract-wrappers/src/types.ts @@ -13,7 +13,7 @@ export enum ForwarderError { } export enum ContractError { - ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK', + ContractNotDeployedOnChain = 'CONTRACT_NOT_DEPLOYED_ON_CHAIN', InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER', InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER', InsufficientEthBalanceForDeposit = 'INSUFFICIENT_ETH_BALANCE_FOR_DEPOSIT', @@ -28,13 +28,13 @@ export enum ContractError { } /** - * networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 3-ropsten, 4-rinkeby, 42-kovan, 50-testrpc) + * chainId: The id of the underlying ethereum chain your provider is connected to. (1-mainnet, 3-ropsten, 4-rinkeby, 42-kovan, 1337-testrpc) * gasPrice: Gas price to use with every transaction - * contractAddresses: The address of all contracts to use. Defaults to the known addresses based on networkId. + * contractAddresses: The address of all contracts to use. Defaults to the known addresses based on chainId. * blockPollingIntervalMs: The interval to use for block polling in event watching methods (defaults to 1000) */ export interface ContractWrappersConfig { - networkId: number; + chainId: number; gasPrice?: BigNumber; contractAddresses?: ContractAddresses; blockPollingIntervalMs?: number; diff --git a/packages/contract-wrappers/src/utils/contract_addresses.ts b/packages/contract-wrappers/src/utils/contract_addresses.ts index dc156e0171..443bbd3f0e 100644 --- a/packages/contract-wrappers/src/utils/contract_addresses.ts +++ b/packages/contract-wrappers/src/utils/contract_addresses.ts @@ -1,15 +1,15 @@ -import { ContractAddresses, getContractAddressesForNetworkOrThrow, NetworkId } from '@0x/contract-addresses'; +import { ChainId, ContractAddresses, getContractAddressesForChainOrThrow } from '@0x/contract-addresses'; import * as _ from 'lodash'; /** - * Returns the default contract addresses for the given networkId or throws with - * a context-specific error message if the networkId is not recognized. + * Returns the default contract addresses for the given chainId or throws with + * a context-specific error message if the chainId is not recognized. */ -export function _getDefaultContractAddresses(networkId: number): ContractAddresses { - if (!(networkId in NetworkId)) { +export function _getDefaultContractAddresses(chainId: number): ContractAddresses { + if (!(chainId in ChainId)) { throw new Error( - `No default contract addresses found for the given network id (${networkId}). If you want to use ContractWrappers on this network, you must manually pass in the contract address(es) to the constructor.`, + `No default contract addresses found for the given chain id (${chainId}). If you want to use ContractWrappers on this chain, you must manually pass in the contract address(es) to the constructor.`, ); } - return getContractAddressesForNetworkOrThrow(networkId); + return getContractAddressesForChainOrThrow(chainId); } diff --git a/packages/contract-wrappers/src/utils/decorators.ts b/packages/contract-wrappers/src/utils/decorators.ts index 5862f5017f..d3ddf8267d 100644 --- a/packages/contract-wrappers/src/utils/decorators.ts +++ b/packages/contract-wrappers/src/utils/decorators.ts @@ -1,7 +1,7 @@ import * as _ from 'lodash'; export enum ContractError { - ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK', + ContractNotDeployedOnChain = 'CONTRACT_NOT_DEPLOYED_ON_CHAIN', InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER', InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER', InsufficientEthBalanceForDeposit = 'INSUFFICIENT_ETH_BALANCE_FOR_DEPOSIT', diff --git a/packages/contract-wrappers/test/calldata_decoder_test.ts b/packages/contract-wrappers/test/calldata_decoder_test.ts index e9926d70a9..bdd5fc61be 100644 --- a/packages/contract-wrappers/test/calldata_decoder_test.ts +++ b/packages/contract-wrappers/test/calldata_decoder_test.ts @@ -23,7 +23,7 @@ describe('ABI Decoding Calldata', () => { const defaultERC20MakerAssetAddress = addressUtils.generatePseudoRandomAddress(); const matchOrdersSignature = 'matchOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),bytes,bytes)'; - const chainId: number = constants.TESTRPC_NETWORK_ID; + const chainId: number = constants.TESTRPC_CHAIN_ID; let signedOrderLeft: SignedOrder; let signedOrderRight: SignedOrder; let orderLeft = {}; @@ -85,7 +85,7 @@ describe('ABI Decoding Calldata', () => { contractAddresses = await migrateOnceAsync(); await blockchainLifecycle.startAsync(); const config = { - networkId: constants.TESTRPC_NETWORK_ID, + chainId: constants.TESTRPC_CHAIN_ID, contractAddresses, blockPollingIntervalMs: 10, }; diff --git a/packages/contract-wrappers/test/coordinator_wrapper_test.ts b/packages/contract-wrappers/test/coordinator_wrapper_test.ts index 66acc6bde2..66e4ac49b3 100644 --- a/packages/contract-wrappers/test/coordinator_wrapper_test.ts +++ b/packages/contract-wrappers/test/coordinator_wrapper_test.ts @@ -65,7 +65,7 @@ describe.skip('CoordinatorWrapper', () => { const contractAddresses = await migrateOnceAsync(); await blockchainLifecycle.startAsync(); const config = { - networkId: constants.TESTRPC_NETWORK_ID, + chainId: constants.TESTRPC_CHAIN_ID, contractAddresses, blockPollingIntervalMs: 10, }; @@ -112,7 +112,7 @@ describe.skip('CoordinatorWrapper', () => { HTTP_PORT: 3000, // Only used in default instantiation in 0x-coordinator-server/server.js; not used here NETWORK_ID_TO_SETTINGS: { // TODO: change to CHAIN_ID_TO_SETTINGS when @0x/coordinator-server is ready - [config.networkId]: { + [config.chainId]: { FEE_RECIPIENTS: [ { ADDRESS: feeRecipientAddressOne, @@ -140,7 +140,7 @@ describe.skip('CoordinatorWrapper', () => { }, NETWORK_ID_TO_CONTRACT_ADDRESSES: { // TODO: change to CHAIN_ID_TO_CONTRACT_ADDRESSES when @0x/coordinator-server is ready - [config.networkId]: contractAddresses, + [config.chainId]: contractAddresses, }, // Optional selective delay on fill requests SELECTIVE_DELAY_MS: 0, @@ -148,7 +148,7 @@ describe.skip('CoordinatorWrapper', () => { }; coordinatorServerApp = await getAppAsync( { - [config.networkId]: provider, + [config.chainId]: provider, }, coordinatorServerConfigs, { @@ -168,7 +168,7 @@ describe.skip('CoordinatorWrapper', () => { anotherCoordinatorServerApp = await getAppAsync( { - [config.networkId]: provider, + [config.chainId]: provider, }, coordinatorServerConfigs, { @@ -456,7 +456,7 @@ describe.skip('CoordinatorWrapper', () => { nock(`${coordinatorEndpoint}${coordinatorPort}`) .post('/v1/request_transaction', () => true) .query({ - networkId: 50, + chainId: 1337, }) .reply(400, serverValidationError); }); @@ -505,7 +505,7 @@ describe.skip('CoordinatorWrapper', () => { nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) .post('/v1/request_transaction', () => true) .query({ - networkId: 50, + chainId: 1337, }) .reply(200, serverCancellationSuccess); @@ -533,7 +533,7 @@ describe.skip('CoordinatorWrapper', () => { nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) .post('/v1/request_transaction', () => true) .query({ - networkId: 50, + chainId: 1337, }) .reply(400, serverValidationError); @@ -612,7 +612,7 @@ describe.skip('CoordinatorWrapper', () => { nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) .post('/v1/request_transaction', () => true) .query({ - networkId: 50, + chainId: 1337, }) .reply(200, serverApprovalSuccess); @@ -641,7 +641,7 @@ describe.skip('CoordinatorWrapper', () => { nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) .post('/v1/request_transaction', () => true) .query({ - networkId: 50, + chainId: 1337, }) .reply(400, serverValidationError); diff --git a/packages/contract-wrappers/test/utils/constants.ts b/packages/contract-wrappers/test/utils/constants.ts index ca6c574e4f..261c248b76 100644 --- a/packages/contract-wrappers/test/utils/constants.ts +++ b/packages/contract-wrappers/test/utils/constants.ts @@ -2,9 +2,8 @@ import { BigNumber } from '@0x/utils'; export const constants = { NULL_ADDRESS: '0x0000000000000000000000000000000000000000', - ROPSTEN_NETWORK_ID: 3, - KOVAN_NETWORK_ID: 42, - TESTRPC_NETWORK_ID: 50, + ROPSTEN_CHAIN_ID: 3, + KOVAN_CHAIN_ID: 42, AWAIT_TRANSACTION_MINED_MS: 0, KOVAN_RPC_URL: 'https://kovan.infura.io/', ROPSTEN_RPC_URL: 'https://ropsten.infura.io/', diff --git a/packages/ethereum-types/src/index.ts b/packages/ethereum-types/src/index.ts index 25096a81e7..82df4f3f9d 100644 --- a/packages/ethereum-types/src/index.ts +++ b/packages/ethereum-types/src/index.ts @@ -546,11 +546,11 @@ export type OutputField = | 'ewasm.wast' | 'ewasm.wasm'; -export interface ContractNetworks { - [networkId: number]: ContractNetworkData; +export interface ContractChains { + [chainId: number]: ContractChainData; } -export interface ContractNetworkData { +export interface ContractChainData { address: string; links: { [linkName: string]: string; @@ -661,7 +661,7 @@ export interface CompilerOpts { * This type defines the schema of the artifact.json file generated by Sol-compiler * schemaVersion: The version of the artifact schema * contractName: The contract name it represents - * networks: Network specific information by network (address, id, constructor args, etc...) + * chains: Chain specific information by chain (address, id, constructor args, etc...) * compilerOutput: The Solidity compiler output generated from the specified compiler input * description (http://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#compiler-input-and-output-json-description) * compiler: The compiler settings used @@ -673,7 +673,7 @@ export interface CompilerOpts { export interface ContractArtifact extends ContractVersionData { schemaVersion: string; contractName: string; - networks: ContractNetworks; + chains: ContractChains; } export interface GeneratedCompilerOptions { diff --git a/packages/json-schemas/schemas/relayer_api_orders_channel_subscribe_payload_schema.json b/packages/json-schemas/schemas/relayer_api_orders_channel_subscribe_payload_schema.json index 274ef1625a..120ec5ab25 100644 --- a/packages/json-schemas/schemas/relayer_api_orders_channel_subscribe_payload_schema.json +++ b/packages/json-schemas/schemas/relayer_api_orders_channel_subscribe_payload_schema.json @@ -4,7 +4,7 @@ "properties": { "makerAssetProxyId": { "$ref": "/hexSchema" }, "takerAssetProxyId": { "$ref": "/hexSchema" }, - "networkId": { "type": "number" }, + "chainId": { "type": "number" }, "makerAssetAddress": { "$ref": "/addressSchema" }, "takerAssetAddress": { "$ref": "/addressSchema" }, "makerAssetData": { "$ref": "/hexSchema" }, diff --git a/packages/json-schemas/schemas/request_opts_schema.json b/packages/json-schemas/schemas/request_opts_schema.json index 2206f5016f..54dba1d66b 100644 --- a/packages/json-schemas/schemas/request_opts_schema.json +++ b/packages/json-schemas/schemas/request_opts_schema.json @@ -2,6 +2,6 @@ "id": "/RequestOptsSchema", "type": "object", "properties": { - "networkId": { "type": "number" } + "chainId": { "type": "number" } } } diff --git a/packages/migrations/src/test_contract_configs.ts b/packages/migrations/src/test_contract_configs.ts index 25bf8782b5..9c56e584b7 100644 --- a/packages/migrations/src/test_contract_configs.ts +++ b/packages/migrations/src/test_contract_configs.ts @@ -1,6 +1,6 @@ #!/usr/bin/env node import * as wrappers from '@0x/abi-gen-wrappers'; -import { getContractAddressesForNetworkOrThrow } from '@0x/contract-addresses'; +import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses'; import { ExchangeContract } from '@0x/contracts-exchange'; import { ZeroExGovernorContract } from '@0x/contracts-multisig'; import { StakingContract, StakingProxyContract, ZrxVaultContract } from '@0x/contracts-staking'; @@ -23,12 +23,12 @@ const networkIdToRpcUrl = { // tslint:disable:custom-no-magic-numbers async function testContractConfigsAsync(provider: SupportedProvider): Promise { const web3Wrapper = new Web3Wrapper(provider); - const networkId = await web3Wrapper.getNetworkIdAsync(); - const addresses = getContractAddressesForNetworkOrThrow(networkId); + const chainId = await web3Wrapper.getChainIdAsync(); + const addresses = getContractAddressesForChainOrThrow(chainId); function warnIfMismatch(actual: any, expected: any, message: string): void { if (actual !== expected) { - logUtils.warn(`${message}: actual: ${actual}, expected: ${expected}, networkId: ${networkId}`); + logUtils.warn(`${message}: actual: ${actual}, expected: ${expected}, chainId: ${chainId}`); } } diff --git a/packages/migrations/src/testnet_migrations.ts b/packages/migrations/src/testnet_migrations.ts index d2327deb37..e5bf90c959 100644 --- a/packages/migrations/src/testnet_migrations.ts +++ b/packages/migrations/src/testnet_migrations.ts @@ -1,4 +1,4 @@ -import { getContractAddressesForNetworkOrThrow } from '@0x/contract-addresses'; +import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses'; import { artifacts as assetProxyArtifacts, ERC20BridgeProxyContract } from '@0x/contracts-asset-proxy'; import { artifacts as coordinatorArtifacts, CoordinatorContract } from '@0x/contracts-coordinator'; import { artifacts as devUtilsArtifacts, DevUtilsContract } from '@0x/contracts-dev-utils'; @@ -17,7 +17,6 @@ import { } from '@0x/contracts-staking'; import { IAuthorizableContract, IOwnableContract } from '@0x/contracts-utils'; import { AbiEncoder, BigNumber, logUtils, providerUtils } from '@0x/utils'; -import { Web3Wrapper } from '@0x/web3-wrapper'; import { LogWithDecodedArgs, SupportedProvider, TxData } from 'ethereum-types'; import { constants } from './utils/constants'; @@ -47,10 +46,8 @@ async function submitAndExecuteTransactionAsync( */ export async function runMigrationsAsync(supportedProvider: SupportedProvider, txDefaults: TxData): Promise { const provider = providerUtils.standardizeOrThrow(supportedProvider); - const web3Wrapper = new Web3Wrapper(provider); - const networkId = await web3Wrapper.getNetworkIdAsync(); const chainId = new BigNumber(await providerUtils.getChainIdAsync(provider)); - const deployedAddresses = getContractAddressesForNetworkOrThrow(networkId); + const deployedAddresses = getContractAddressesForChainOrThrow(chainId.toNumber()); // NOTE: This must be deployed before running these migrations, since its address is hard coded in the // staking logic contract. diff --git a/packages/migrations/src/utils/constants.ts b/packages/migrations/src/utils/constants.ts index 15629e870e..84928510fd 100644 --- a/packages/migrations/src/utils/constants.ts +++ b/packages/migrations/src/utils/constants.ts @@ -12,8 +12,8 @@ export const constants = { ERC721_PROXY_ID: '0x02571792', NULL_ADDRESS: '0x0000000000000000000000000000000000000000', KOVAN_RPC_URL: 'https://kovan.infura.io/', - KOVAN_NETWORK_ID: 42, + KOVAN_CHAIN_ID: 42, MAINNET_RPC_URL: 'https://mainnet.infura.io/', - MAINNET_NETWORK_ID: 1, + MAINNET_CHAIN_ID: 1, ZERO_AMOUNT: new BigNumber(0), }; diff --git a/packages/migrations/src/utils/token_info.ts b/packages/migrations/src/utils/token_info.ts index 6e0411f603..e99e10ac65 100644 --- a/packages/migrations/src/utils/token_info.ts +++ b/packages/migrations/src/utils/token_info.ts @@ -2,7 +2,7 @@ import { BigNumber, NULL_BYTES } from '@0x/utils'; import { ERC20Token, ERC721Token } from '../types'; -export const etherTokenByNetwork: { [networkId: number]: { address: string } } = { +export const etherTokenByChain: { [chainId: number]: { address: string } } = { 3: { address: '0xc778417e063141139fce010982780140aa0cd5ab', }, @@ -12,7 +12,7 @@ export const etherTokenByNetwork: { [networkId: number]: { address: string } } = 42: { address: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', }, - 50: { + 1337: { address: '', }, }; diff --git a/packages/order-utils/src/constants.ts b/packages/order-utils/src/constants.ts index b2768f4918..08f2e4d0a0 100644 --- a/packages/order-utils/src/constants.ts +++ b/packages/order-utils/src/constants.ts @@ -89,7 +89,7 @@ export const constants = { NULL_ERC20_ASSET_DATA: '0xf47261b00000000000000000000000000000000000000000000000000000000000000000', // tslint:disable-next-line:custom-no-magic-numbers UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1), - TESTRPC_NETWORK_ID: 50, + TESTRPC_CHAIN_ID: 1337, ADDRESS_LENGTH: 20, ERC20_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX: 74, // 36 bytes ERC721_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX: 138, // 68 bytes diff --git a/packages/order-utils/src/signature_utils.ts b/packages/order-utils/src/signature_utils.ts index daf4f5b14e..25e92e3457 100644 --- a/packages/order-utils/src/signature_utils.ts +++ b/packages/order-utils/src/signature_utils.ts @@ -1,5 +1,5 @@ import { ExchangeContract, IValidatorContract, IWalletContract } from '@0x/abi-gen-wrappers'; -import { getContractAddressesForNetworkOrThrow } from '@0x/contract-addresses'; +import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses'; import { schemas } from '@0x/json-schemas'; import { ECSignature, @@ -120,8 +120,8 @@ export const signatureUtils = { exchangeContract = new ExchangeContract(exchangeAddress, provider); } else { const web3Wrapper = new Web3Wrapper(provider); - const networkId = await web3Wrapper.getNetworkIdAsync(); - const addresses = getContractAddressesForNetworkOrThrow(networkId); + const chainId = await web3Wrapper.getChainIdAsync(); + const addresses = getContractAddressesForChainOrThrow(chainId); exchangeContract = new ExchangeContract(addresses.exchange, provider); } @@ -183,8 +183,8 @@ export const signatureUtils = { exchangeContract = new ExchangeContract(exchangeAddress, provider); } else { const web3Wrapper = new Web3Wrapper(provider); - const networkId = await web3Wrapper.getNetworkIdAsync(); - const addresses = getContractAddressesForNetworkOrThrow(networkId); + const chainId = await web3Wrapper.getChainIdAsync(); + const addresses = getContractAddressesForChainOrThrow(chainId); exchangeContract = new ExchangeContract(addresses.exchange, provider); } diff --git a/packages/orderbook/src/order_provider/base_sra_order_provider.ts b/packages/orderbook/src/order_provider/base_sra_order_provider.ts index 29678dfe47..16d0c68d84 100644 --- a/packages/orderbook/src/order_provider/base_sra_order_provider.ts +++ b/packages/orderbook/src/order_provider/base_sra_order_provider.ts @@ -10,17 +10,17 @@ export const PER_PAGE_DEFAULT = 100; export abstract class BaseSRAOrderProvider extends BaseOrderProvider { protected readonly _httpClient: HttpClient; - protected readonly _networkId?: number; + protected readonly _chainId?: number; protected readonly _perPage: number; /** * This is an internal class for Websocket and Polling Order Providers */ - constructor(orderStore: OrderStore, httpEndpoint: string, perPage: number = PER_PAGE_DEFAULT, networkId?: number) { + constructor(orderStore: OrderStore, httpEndpoint: string, perPage: number = PER_PAGE_DEFAULT, chainId?: number) { super(orderStore); this._httpClient = new HttpClient(httpEndpoint); this._perPage = perPage; - this._networkId = networkId; + this._chainId = chainId; } /** @@ -30,7 +30,7 @@ export abstract class BaseSRAOrderProvider extends BaseOrderProvider { public async getAvailableAssetDatasAsync(): Promise { const requestOpts = { perPage: this._perPage, - networkId: this._networkId, + chainId: this._chainId, }; let recordsToReturn: AssetPairsItem[] = []; @@ -60,7 +60,7 @@ export abstract class BaseSRAOrderProvider extends BaseOrderProvider { const rejected: RejectedOrder[] = []; for (const order of orders) { try { - await this._httpClient.submitOrderAsync(order, { networkId: this._networkId }); + await this._httpClient.submitOrderAsync(order, { chainId: this._chainId }); accepted.push(order); } catch (e) { rejected.push({ order, message: e.message }); @@ -83,7 +83,7 @@ export abstract class BaseSRAOrderProvider extends BaseOrderProvider { makerAssetData, takerAssetData, perPage: this._perPage, - networkId: this._networkId, + chainId: this._chainId, }; let hasMorePages = true; diff --git a/packages/orderbook/src/order_provider/sra_polling_order_provider.ts b/packages/orderbook/src/order_provider/sra_polling_order_provider.ts index 958d6d9a5f..c60fd78797 100644 --- a/packages/orderbook/src/order_provider/sra_polling_order_provider.ts +++ b/packages/orderbook/src/order_provider/sra_polling_order_provider.ts @@ -18,7 +18,7 @@ export class SRAPollingOrderProvider extends BaseSRAOrderProvider { * @param orderStore The `OrderStore` where orders are added and removed from */ constructor(opts: SRAPollingOrderProviderOpts, orderStore: OrderStore) { - super(orderStore, opts.httpEndpoint, opts.perPage, opts.networkId); + super(orderStore, opts.httpEndpoint, opts.perPage, opts.chainId); assert.isNumber('pollingIntervalMs', opts.pollingIntervalMs); this._pollingIntervalMs = opts.pollingIntervalMs; } diff --git a/packages/orderbook/src/order_provider/sra_websocket_order_provider.ts b/packages/orderbook/src/order_provider/sra_websocket_order_provider.ts index 2dbf5b33de..80fe81e02b 100644 --- a/packages/orderbook/src/order_provider/sra_websocket_order_provider.ts +++ b/packages/orderbook/src/order_provider/sra_websocket_order_provider.ts @@ -28,7 +28,7 @@ export class SRAWebsocketOrderProvider extends BaseSRAOrderProvider { * @param orderStore The `OrderStore` where orders are added and removed from */ constructor(opts: SRAWebsocketOrderProviderOpts, orderStore: OrderStore) { - super(orderStore, opts.httpEndpoint, PER_PAGE_DEFAULT, opts.networkId); + super(orderStore, opts.httpEndpoint, PER_PAGE_DEFAULT, opts.chainId); assert.isUri('websocketEndpoint', opts.websocketEndpoint); this._websocketEndpoint = opts.websocketEndpoint; } diff --git a/packages/orderbook/src/types.ts b/packages/orderbook/src/types.ts index ac9cde167c..b7e68bbfe1 100644 --- a/packages/orderbook/src/types.ts +++ b/packages/orderbook/src/types.ts @@ -26,8 +26,8 @@ export interface SRAWebsocketOrderProviderOpts { httpEndpoint: string; // The websocket endpoint to the SRA service, e.g wss://ws.sra.0x.org/ websocketEndpoint: string; - // The network Id - networkId?: number; + // The chain Id + chainId?: number; } /** @@ -40,8 +40,8 @@ export interface SRAPollingOrderProviderOpts { pollingIntervalMs: number; // The amount of records to request per request to the SRA endpoint perPage?: number; - // The network Id - networkId?: number; + // The chain Id + chainId?: number; } /** diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts index 1c16a72829..adb13415da 100644 --- a/packages/sol-compiler/src/compiler.ts +++ b/packages/sol-compiler/src/compiler.ts @@ -405,7 +405,7 @@ export class Compiler { schemaVersion: constants.LATEST_ARTIFACT_VERSION, contractName, ...contractVersion, - networks: {}, + chains: {}, }; } diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index c5d96ca0cc..9962b14195 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -14,10 +14,10 @@ import { fsWrapper } from './fs_wrapper'; import { BinaryPaths, CompilationError } from './types'; /** - * Gets contract data on network or returns if an artifact does not exist. + * Gets contract data or returns if an artifact does not exist. * @param artifactsDir Path to the artifacts directory. * @param contractName Name of contract. - * @return Contract data on network or undefined. + * @return Contract data or undefined. */ export async function getContractArtifactIfExistsAsync( artifactsDir: string, diff --git a/packages/sol-compiler/test/util/constants.ts b/packages/sol-compiler/test/util/constants.ts index a74ea1b68d..f408e99d43 100644 --- a/packages/sol-compiler/test/util/constants.ts +++ b/packages/sol-compiler/test/util/constants.ts @@ -1,7 +1,6 @@ import { BigNumber } from '@0x/utils'; export const constants = { - networkId: 0, optimizerEnabled: false, gasPrice: new BigNumber(20000000000), timeoutMs: 30000, diff --git a/packages/sra-spec/src/examples/errors.ts b/packages/sra-spec/src/examples/errors.ts index 81f29d81cb..525367ef3a 100644 --- a/packages/sra-spec/src/examples/errors.ts +++ b/packages/sra-spec/src/examples/errors.ts @@ -3,9 +3,9 @@ export const validationError = { reason: 'Validation failed', validationErrors: [ { - field: 'networkId', + field: 'chainId', code: 1006, - reason: 'Network id 42 is not supported', + reason: 'Chain id 42 is not supported', }, ], }; diff --git a/packages/sra-spec/src/md/introduction.md b/packages/sra-spec/src/md/introduction.md index f851f200dc..c735c44361 100644 --- a/packages/sra-spec/src/md/introduction.md +++ b/packages/sra-spec/src/md/introduction.md @@ -34,26 +34,26 @@ All endpoints that are paginated should return a `total`, `page`, `perPage` and These requests include the [`/v3/asset_pairs`](#operation/getAssetPairs), [`/v3/orders`](#operation/getOrders), [`/v3/fee_recipients`](#operation/getFeeRecipients) and [`/v3/orderbook`](#operation/getOrderbook) endpoints. -# Network Id +# Chain Id -All requests should be able to specify a **?networkId** query param for all supported networks. For example: +All requests should be able to specify a **?chainId** query param for all supported chains. For example: ```bash -$ curl https://api.example-relayer.com/v3/asset_pairs?networkId=1 +$ curl https://api.example-relayer.com/v3/asset_pairs?chainId=1 ``` If the query param is not provided, it should default to **1** (mainnet). -Networks and their Ids: +Chains and their Ids: -| Network Id | Network Name | -| ---------- | ------------ | -| 1 | Mainnet | -| 42 | Kovan | -| 3 | Ropsten | -| 4 | Rinkeby | +| Chain Id | Chain Name | +| -------- | ---------- | +| 1 | Mainnet | +| 42 | Kovan | +| 3 | Ropsten | +| 4 | Rinkeby | -If a certain network is not supported, the response should **400** as specified in the [error response](#section/Errors) section. For example: +If a certain chain is not supported, the response should **400** as specified in the [error response](#section/Errors) section. For example: ```json { @@ -61,9 +61,9 @@ If a certain network is not supported, the response should **400** as specified "reason": "Validation failed", "validationErrors": [ { - "field": "networkId", + "field": "chainId", "code": 1006, - "reason": "Network id 42 is not supported" + "reason": "Chain id 42 is not supported" } ] } diff --git a/packages/sra-spec/src/parameters.ts b/packages/sra-spec/src/parameters.ts index 60281b203d..496e9d05cb 100644 --- a/packages/sra-spec/src/parameters.ts +++ b/packages/sra-spec/src/parameters.ts @@ -22,10 +22,10 @@ export const paginationParameters: ParameterObject[] = [ }, ]; -export const networkIdParameter: ParameterObject = { - name: 'networkId', +export const chainIdParameter: ParameterObject = { + name: 'chainId', in: 'query', - description: 'The id of the Ethereum network', + description: 'The id of the Ethereum chain', example: 42, schema: { type: 'number', @@ -35,5 +35,5 @@ export const networkIdParameter: ParameterObject = { export const generateParameters = (parameters: ParameterObject[], isPaginated: boolean = false): ParameterObject[] => { const optionalParameters = isPaginated ? paginationParameters : []; - return [...parameters, networkIdParameter, ...optionalParameters]; + return [...parameters, chainIdParameter, ...optionalParameters]; }; diff --git a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts index e66e51fe74..afe1ceb0cc 100644 --- a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts +++ b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts @@ -4,7 +4,7 @@ import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import { configs } from './configs'; -import { TOKENS_BY_NETWORK } from './tokens'; +import { TOKENS_BY_CHAIN } from './tokens'; const DISPENSE_AMOUNT_ETHER = 0.1; const DISPENSE_AMOUNT_TOKEN = 1; @@ -36,13 +36,13 @@ export const dispenseAssetTasks = { dispenseTokenTask( recipientAddress: string, tokenSymbol: string, - networkId: number, + chainId: number, provider: SupportedProvider, ): AsyncTask { return async () => { logUtils.log(`Processing ${tokenSymbol} ${recipientAddress}`); const amountToDispense = new BigNumber(DISPENSE_AMOUNT_TOKEN); - const tokenIfExists = _.get(TOKENS_BY_NETWORK, [networkId, tokenSymbol]); + const tokenIfExists = _.get(TOKENS_BY_CHAIN, [chainId, tokenSymbol]); if (tokenIfExists === undefined) { throw new Error(`Unsupported asset type: ${tokenSymbol}`); } diff --git a/packages/testnet-faucets/src/ts/handler.ts b/packages/testnet-faucets/src/ts/handler.ts index fbd6e1fda4..e50e1b8656 100644 --- a/packages/testnet-faucets/src/ts/handler.ts +++ b/packages/testnet-faucets/src/ts/handler.ts @@ -9,7 +9,7 @@ import { SignedOrder, Web3ProviderEngine, } from '0x.js'; -import { getContractAddressesForNetworkOrThrow } from '@0x/contract-addresses'; +import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses'; import { NonceTrackerSubprovider, PrivateKeyWalletSubprovider } from '@0x/subproviders'; import { logUtils } from '@0x/utils'; import { SupportedProvider, Web3Wrapper } from '@0x/web3-wrapper'; @@ -21,17 +21,17 @@ import { constants } from './constants'; import { DispatchQueue } from './dispatch_queue'; import { dispenseAssetTasks } from './dispense_asset_tasks'; import { rpcUrls } from './rpc_urls'; -import { TOKENS_BY_NETWORK } from './tokens'; +import { TOKENS_BY_CHAIN } from './tokens'; -interface NetworkConfig { +interface ChainConfig { dispatchQueue: DispatchQueue; web3Wrapper: Web3Wrapper; provider: SupportedProvider; - networkId: number; + chainId: number; } -interface ItemByNetworkId { - [networkId: string]: T; +interface ItemByChainId { + [chainId: string]: T; } enum RequestedAssetType { @@ -46,7 +46,7 @@ const ZERO = new BigNumber(0); const ASSET_AMOUNT = new BigNumber(0.1); export class Handler { - private readonly _networkConfigByNetworkId: ItemByNetworkId = {}; + private readonly _chainConfigByChainId: ItemByChainId = {}; private static _createProviderEngine(rpcUrl: string): Web3ProviderEngine { if (configs.DISPENSER_PRIVATE_KEY === undefined) { throw new Error('Dispenser Private key not found'); @@ -59,24 +59,24 @@ export class Handler { return engine; } constructor() { - _.forIn(rpcUrls, (rpcUrl: string, networkIdString: string) => { + _.forIn(rpcUrls, (rpcUrl: string, chainIdString: string) => { const providerObj = Handler._createProviderEngine(rpcUrl); const web3Wrapper = new Web3Wrapper(providerObj); // tslint:disable-next-line:custom-no-magic-numbers - const networkId = parseInt(networkIdString, 10); + const chainId = parseInt(chainIdString, 10); const dispatchQueue = new DispatchQueue(); - this._networkConfigByNetworkId[networkId] = { + this._chainConfigByChainId[chainId] = { dispatchQueue, web3Wrapper, provider: providerObj, - networkId, + chainId, }; }); } public getQueueInfo(_req: express.Request, res: express.Response): void { res.setHeader('Content-Type', 'application/json'); - const queueInfo = _.mapValues(rpcUrls, (_rpcUrl: string, networkId: string) => { - const dispatchQueue = this._networkConfigByNetworkId[networkId].dispatchQueue; + const queueInfo = _.mapValues(rpcUrls, (_rpcUrl: string, chainId: string) => { + const dispatchQueue = this._chainConfigByChainId[chainId].dispatchQueue; return { full: dispatchQueue.isFull(), size: dispatchQueue.size(), @@ -102,36 +102,36 @@ export class Handler { await this._dispenseOrderAsync(req, res, RequestedAssetType.ZRX); } private _dispenseAsset(req: express.Request, res: express.Response, requestedAssetType: RequestedAssetType): void { - const networkId = req.params.networkId; + const chainId = req.params.chainId; const recipient = req.params.recipient; - const networkConfig = _.get(this._networkConfigByNetworkId, networkId); - if (networkConfig === undefined) { - res.status(constants.BAD_REQUEST_STATUS).send('UNSUPPORTED_NETWORK_ID'); + const chainConfig = _.get(this._chainConfigByChainId, chainId); + if (chainConfig === undefined) { + res.status(constants.BAD_REQUEST_STATUS).send('UNSUPPORTED_CHAIN_ID'); return; } let dispenserTask; switch (requestedAssetType) { case RequestedAssetType.ETH: - dispenserTask = dispenseAssetTasks.dispenseEtherTask(recipient, networkConfig.web3Wrapper); + dispenserTask = dispenseAssetTasks.dispenseEtherTask(recipient, chainConfig.web3Wrapper); break; case RequestedAssetType.WETH: case RequestedAssetType.ZRX: dispenserTask = dispenseAssetTasks.dispenseTokenTask( recipient, requestedAssetType, - networkConfig.networkId, - networkConfig.provider, + chainConfig.chainId, + chainConfig.provider, ); break; default: throw new Error(`Unsupported asset type: ${requestedAssetType}`); } - const didAddToQueue = networkConfig.dispatchQueue.add(dispenserTask); + const didAddToQueue = chainConfig.dispatchQueue.add(dispenserTask); if (!didAddToQueue) { res.status(constants.SERVICE_UNAVAILABLE_STATUS).send('QUEUE_IS_FULL'); return; } - logUtils.log(`Added ${recipient} to queue: ${requestedAssetType} networkId: ${networkId}`); + logUtils.log(`Added ${recipient} to queue: ${requestedAssetType} chainId: ${chainId}`); res.status(constants.SUCCESS_STATUS).end(); } private async _dispenseOrderAsync( @@ -139,19 +139,19 @@ export class Handler { res: express.Response, requestedAssetType: RequestedAssetType, ): Promise { - const networkConfig = _.get(this._networkConfigByNetworkId, req.params.networkId); - if (networkConfig === undefined) { - res.status(constants.BAD_REQUEST_STATUS).send('UNSUPPORTED_NETWORK_ID'); + const chainConfig = _.get(this._chainConfigByChainId, req.params.chainId); + if (chainConfig === undefined) { + res.status(constants.BAD_REQUEST_STATUS).send('UNSUPPORTED_CHAIN_ID'); return; } res.setHeader('Content-Type', 'application/json'); - const makerTokenIfExists = _.get(TOKENS_BY_NETWORK, [networkConfig.networkId, requestedAssetType]); + const makerTokenIfExists = _.get(TOKENS_BY_CHAIN, [chainConfig.chainId, requestedAssetType]); if (makerTokenIfExists === undefined) { throw new Error(`Unsupported asset type: ${requestedAssetType}`); } const takerTokenSymbol = requestedAssetType === RequestedAssetType.WETH ? RequestedAssetType.ZRX : RequestedAssetType.WETH; - const takerTokenIfExists = _.get(TOKENS_BY_NETWORK, [networkConfig.networkId, takerTokenSymbol]); + const takerTokenIfExists = _.get(TOKENS_BY_CHAIN, [chainConfig.chainId, takerTokenSymbol]); if (takerTokenIfExists === undefined) { throw new Error(`Unsupported asset type: ${takerTokenSymbol}`); } @@ -160,7 +160,7 @@ export class Handler { const takerAssetAmount = Web3Wrapper.toBaseUnitAmount(ASSET_AMOUNT, takerTokenIfExists.decimals); const makerAssetData = assetDataUtils.encodeERC20AssetData(makerTokenIfExists.address); const takerAssetData = assetDataUtils.encodeERC20AssetData(takerTokenIfExists.address); - const contractAddresses = getContractAddressesForNetworkOrThrow(networkConfig.networkId); + const contractAddresses = getContractAddressesForChainOrThrow(chainConfig.chainId); const order: Order = { makerAddress: configs.DISPENSER_ADDRESS, takerAddress: req.params.recipient as string, @@ -180,11 +180,11 @@ export class Handler { .div(1000) .integerValue(BigNumber.ROUND_FLOOR), exchangeAddress: contractAddresses.exchange, - chainId: networkConfig.networkId, + chainId: chainConfig.chainId, }; const orderHash = orderHashUtils.getOrderHashHex(order); const signature = await signatureUtils.ecSignHashAsync( - networkConfig.web3Wrapper.getProvider(), + chainConfig.web3Wrapper.getProvider(), orderHash, configs.DISPENSER_ADDRESS, ); diff --git a/packages/testnet-faucets/src/ts/parameter_transformer.ts b/packages/testnet-faucets/src/ts/parameter_transformer.ts index a08145797e..8c85a5cbf2 100644 --- a/packages/testnet-faucets/src/ts/parameter_transformer.ts +++ b/packages/testnet-faucets/src/ts/parameter_transformer.ts @@ -5,7 +5,7 @@ import * as _ from 'lodash'; import { constants } from './constants'; import { rpcUrls } from './rpc_urls'; -const DEFAULT_NETWORK_ID = 42; // kovan +const DEFAULT_CHAIN_ID = 42; // kovan export const parameterTransformer = { transform(req: Request, res: Response, next: NextFunction): void { @@ -16,13 +16,13 @@ export const parameterTransformer = { } const lowerCaseRecipientAddress = recipientAddress.toLowerCase(); req.params.recipient = lowerCaseRecipientAddress; - const networkId = _.get(req.query, 'networkId', DEFAULT_NETWORK_ID); - const rpcUrlIfExists = _.get(rpcUrls, networkId); + const chainId = _.get(req.query, 'chainId', DEFAULT_CHAIN_ID); + const rpcUrlIfExists = _.get(rpcUrls, chainId); if (rpcUrlIfExists === undefined) { - res.status(constants.BAD_REQUEST_STATUS).send('UNSUPPORTED_NETWORK_ID'); + res.status(constants.BAD_REQUEST_STATUS).send('UNSUPPORTED_CHAIN_ID'); return; } - req.params.networkId = networkId; + req.params.chainId = chainId; next(); }, }; diff --git a/packages/testnet-faucets/src/ts/tokens.ts b/packages/testnet-faucets/src/ts/tokens.ts index 4ffb03df44..a769aa8a2a 100644 --- a/packages/testnet-faucets/src/ts/tokens.ts +++ b/packages/testnet-faucets/src/ts/tokens.ts @@ -1,5 +1,5 @@ -interface TokensByNetwork { - [networkId: number]: { [tokenSymbol: string]: { address: string; decimals: number } }; +interface TokensByChain { + [chainId: number]: { [tokenSymbol: string]: { address: string; decimals: number } }; } export const tokens = { @@ -10,7 +10,7 @@ export const tokens = { decimals: 18, }, }; -export const TOKENS_BY_NETWORK: TokensByNetwork = { +export const TOKENS_BY_CHAIN: TokensByChain = { 3: { ZRX: { ...tokens.ZRX, diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index ceac35918c..12508b8302 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -3,8 +3,8 @@ import { BigNumber } from 'bignumber.js'; import { ContractAbi, + ContractChains, ContractEventArg, - ContractNetworks, DecodedLogArgs, DevdocOutput, LogWithDecodedArgs, @@ -103,8 +103,8 @@ export type ArtifactContractName = 'ZRX' | 'TokenTransferProxy' | 'TokenRegistry export interface Artifact { contract_name: ArtifactContractName; abi: ContractAbi; - networks: { - [networkId: number]: { + chains: { + [chainId: number]: { address: string; }; }; @@ -484,7 +484,7 @@ export interface OrderConfigResponse { export type FeeRecipientsResponse = PaginatedCollection; export interface RequestOpts { - networkId?: number; + chainId?: number; } export interface PagedRequestOpts { @@ -882,7 +882,7 @@ export interface SimpleContractArtifact { schemaVersion: string; contractName: string; compilerOutput: SimpleStandardContractOutput; - networks: ContractNetworks; + chains: ContractChains; } export interface SimpleStandardContractOutput { diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts index 32e11efa22..1235bfc476 100644 --- a/packages/utils/src/types.ts +++ b/packages/utils/src/types.ts @@ -4,7 +4,7 @@ export interface FunctionInfo { functionSignature: string; contractName?: string; contractAddress?: string; - networkId?: number; + chainId?: number; abiEncoder?: AbiEncoder.Method; } diff --git a/python-packages/contract_addresses/src/index.rst b/python-packages/contract_addresses/src/index.rst index 62a2f4bf0e..7b9ea29f02 100644 --- a/python-packages/contract_addresses/src/index.rst +++ b/python-packages/contract_addresses/src/index.rst @@ -10,7 +10,7 @@ Python zero_ex.contract_addresses .. automodule:: zero_ex.contract_addresses :no-members: -.. autoclass:: zero_ex.contract_addresses.NetworkId +.. autoclass:: zero_ex.contract_addresses.ChainId :members: :undoc-members: :show-inheritance: @@ -19,8 +19,8 @@ Python zero_ex.contract_addresses :members: :show-inheritance: -.. autodata:: zero_ex.contract_addresses.network_to_addresses - :annotation: : Dict[NetworkId, ContractAddresses] +.. autodata:: zero_ex.contract_addresses.chain_to_addresses + :annotation: : Dict[ChainId, ContractAddresses] Indices and tables ================== diff --git a/python-packages/contract_addresses/src/zero_ex/contract_addresses/__init__.py b/python-packages/contract_addresses/src/zero_ex/contract_addresses/__init__.py index 7e267485d0..506afd118f 100644 --- a/python-packages/contract_addresses/src/zero_ex/contract_addresses/__init__.py +++ b/python-packages/contract_addresses/src/zero_ex/contract_addresses/__init__.py @@ -83,13 +83,13 @@ class ContractAddresses(NamedTuple): """Address of the ERC20BridgeProxy contract.""" -class NetworkId(Enum): - """Network names correlated to their network identification numbers. +class ChainId(Enum): + """Chain names correlated to their chain identification numbers. - >>> NetworkId.MAINNET - + >>> ChainId.MAINNET + - >>> NetworkId.MAINNET.value + >>> ChainId.MAINNET.value 1 """ @@ -97,7 +97,7 @@ class NetworkId(Enum): ROPSTEN = 3 RINKEBY = 4 KOVAN = 42 - GANACHE = 50 + GANACHE = 1337 class _AddressCache: @@ -106,35 +106,35 @@ class _AddressCache: # pylint: disable=too-few-public-methods # class data, not instance: - _network_to_addresses: Dict[str, ContractAddresses] = {} + _chain_to_addresses: Dict[str, ContractAddresses] = {} @classmethod - def network_to_addresses(cls, network_id: NetworkId): - """Return the addresses for the given network ID. + def chain_to_addresses(cls, chain_id: ChainId): + """Return the addresses for the given chain ID. First tries to get data from the class level storage - `_network_to_addresses`. If it's not there, loads it from disk, stores + `_chain_to_addresses`. If it's not there, loads it from disk, stores it in the class data (for the next caller), and then returns it. """ try: - return cls._network_to_addresses[str(network_id.value)] + return cls._chain_to_addresses[str(chain_id.value)] except KeyError: - cls._network_to_addresses = json.loads( + cls._chain_to_addresses = json.loads( resource_string("zero_ex.contract_addresses", "addresses.json") ) - return cls._network_to_addresses[str(network_id.value)] + return cls._chain_to_addresses[str(chain_id.value)] -def network_to_addresses(network_id: NetworkId) -> ContractAddresses: - """Map a NetworkId to an instance of ContractAddresses. +def chain_to_addresses(chain_id: ChainId) -> ContractAddresses: + """Map a ChainId to an instance of ContractAddresses. - Addresses under NetworkId.Ganache are from our Ganache snapshot generated + Addresses under ChainId.Ganache are from our Ganache snapshot generated from npm package @0x/migrations. - >>> network_to_addresses(NetworkId.MAINNET).exchange + >>> chain_to_addresses(ChainId.MAINNET).exchange '0x...' """ - addresses = _AddressCache.network_to_addresses(network_id) + addresses = _AddressCache.chain_to_addresses(chain_id) return ContractAddresses( erc20_proxy=addresses["erc20Proxy"], diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py index 538607c6fa..67ecae8d48 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py @@ -48,14 +48,14 @@ The `0x-contract-addresses`:code: package (which is used by `0x-contract-wrappers`:code: and thus gets installed along with it) provides -the addresses of the 0x contracts on each network, including those that come +the addresses of the 0x contracts on each chain, including those that come pre-deployed deployed in the `0xorg/ganache-cli`:code: docker image. Let's capture the addresses we'll use throughout the examples below: ->>> from zero_ex.contract_addresses import network_to_addresses, NetworkId ->>> weth_address = network_to_addresses(NetworkId.GANACHE).ether_token ->>> zrx_address = network_to_addresses(NetworkId.GANACHE).zrx_token ->>> exchange_address = network_to_addresses(NetworkId.GANACHE).exchange +>>> from zero_ex.contract_addresses import chain_to_addresses, ChainId +>>> weth_address = chain_to_addresses(ChainId.GANACHE).ether_token +>>> zrx_address = chain_to_addresses(ChainId.GANACHE).zrx_token +>>> exchange_address = chain_to_addresses(ChainId.GANACHE).exchange Wrapping ETH ------------ @@ -93,14 +93,14 @@ >>> from zero_ex.contract_wrappers.erc20_token import ERC20Token >>> zrx_token = ERC20Token( ... web3_or_provider=ganache, -... contract_address=network_to_addresses(NetworkId.GANACHE).zrx_token, +... contract_address=chain_to_addresses(ChainId.GANACHE).zrx_token, ... ) >>> weth_token = ERC20Token( ... web3_or_provider=ganache, -... contract_address=network_to_addresses(NetworkId.GANACHE).ether_token, +... contract_address=chain_to_addresses(ChainId.GANACHE).ether_token, ... ) ->>> erc20_proxy_addr = network_to_addresses(NetworkId.GANACHE).erc20_proxy +>>> erc20_proxy_addr = chain_to_addresses(ChainId.GANACHE).erc20_proxy >>> tx = zrx_token.approve.send_transaction( ... erc20_proxy_addr, @@ -166,7 +166,7 @@ >>> from zero_ex.contract_wrappers.exchange import Exchange >>> exchange = Exchange( ... web3_or_provider=ganache, -... contract_address=network_to_addresses(NetworkId.GANACHE).exchange, +... contract_address=chain_to_addresses(ChainId.GANACHE).exchange, ... ) But before filling an order, one may wish to check that it's actually fillable: diff --git a/python-packages/contract_wrappers/test/conftest.py b/python-packages/contract_wrappers/test/conftest.py index 040593a373..a0c7c8aa8c 100644 --- a/python-packages/contract_wrappers/test/conftest.py +++ b/python-packages/contract_wrappers/test/conftest.py @@ -5,7 +5,7 @@ from web3 import Web3 from zero_ex.order_utils import asset_data_utils -from zero_ex.contract_addresses import network_to_addresses, NetworkId +from zero_ex.contract_addresses import chain_to_addresses, ChainId from zero_ex.contract_artifacts import abi_by_name @@ -36,14 +36,14 @@ def accounts(web3_eth): # pylint: disable=redefined-outer-name @pytest.fixture(scope="module") def erc20_proxy_address(): """Get the 0x ERC20 Proxy address.""" - return network_to_addresses(NetworkId.GANACHE).erc20_proxy + return chain_to_addresses(ChainId.GANACHE).erc20_proxy @pytest.fixture(scope="module") def weth_asset_data(): # pylint: disable=redefined-outer-name """Get 0x asset data for Wrapped Ether (WETH) token.""" return asset_data_utils.encode_erc20( - network_to_addresses(NetworkId.GANACHE).ether_token + chain_to_addresses(ChainId.GANACHE).ether_token ) @@ -52,7 +52,7 @@ def weth_instance(web3_eth): # pylint: disable=redefined-outer-name """Get an instance of the WrapperEther contract.""" return web3_eth.contract( address=to_checksum_address( - network_to_addresses(NetworkId.GANACHE).ether_token + chain_to_addresses(ChainId.GANACHE).ether_token ), abi=abi_by_name("WETH9"), ) @@ -60,8 +60,8 @@ def weth_instance(web3_eth): # pylint: disable=redefined-outer-name @pytest.fixture(scope="module") def zrx_address(): - """Get address of ZRX token for Ganache network.""" - return network_to_addresses(NetworkId.GANACHE).zrx_token + """Get address of ZRX token for Ganache chain.""" + return chain_to_addresses(ChainId.GANACHE).zrx_token @pytest.fixture(scope="module") diff --git a/python-packages/contract_wrappers/test/test_base_contract_method.py b/python-packages/contract_wrappers/test/test_base_contract_method.py index e437f55aec..78e7140950 100644 --- a/python-packages/contract_wrappers/test/test_base_contract_method.py +++ b/python-packages/contract_wrappers/test/test_base_contract_method.py @@ -2,7 +2,7 @@ import pytest -from zero_ex.contract_addresses import network_to_addresses, NetworkId +from zero_ex.contract_addresses import chain_to_addresses, ChainId from zero_ex.contract_wrappers.bases import ContractMethod @@ -11,5 +11,5 @@ def contract_wrapper(ganache_provider): """Get a ContractMethod instance for testing.""" return ContractMethod( web3_or_provider=ganache_provider, - contract_address=network_to_addresses(NetworkId.GANACHE).ether_token, + contract_address=chain_to_addresses(ChainId.GANACHE).ether_token, ) diff --git a/python-packages/contract_wrappers/test/test_erc20_wrapper.py b/python-packages/contract_wrappers/test/test_erc20_wrapper.py index 8e13528e50..01044322f6 100644 --- a/python-packages/contract_wrappers/test/test_erc20_wrapper.py +++ b/python-packages/contract_wrappers/test/test_erc20_wrapper.py @@ -4,7 +4,7 @@ import pytest -from zero_ex.contract_addresses import network_to_addresses, NetworkId +from zero_ex.contract_addresses import chain_to_addresses, ChainId from zero_ex.contract_wrappers import TxParams from zero_ex.contract_wrappers.erc20_token import ERC20Token @@ -16,7 +16,7 @@ def erc20_wrapper(ganache_provider): """Get an instance of ERC20Token wrapper class for testing.""" return ERC20Token( - ganache_provider, network_to_addresses(NetworkId.GANACHE).ether_token + ganache_provider, chain_to_addresses(ChainId.GANACHE).ether_token ) diff --git a/python-packages/contract_wrappers/test/test_exchange_wrapper.py b/python-packages/contract_wrappers/test/test_exchange_wrapper.py index c299eeac9d..1b5e101cde 100644 --- a/python-packages/contract_wrappers/test/test_exchange_wrapper.py +++ b/python-packages/contract_wrappers/test/test_exchange_wrapper.py @@ -5,7 +5,7 @@ import pytest from eth_utils import remove_0x_prefix -from zero_ex.contract_addresses import network_to_addresses, NetworkId +from zero_ex.contract_addresses import chain_to_addresses, ChainId from zero_ex.contract_wrappers import TxParams from zero_ex.contract_wrappers.exchange import Exchange from zero_ex.contract_wrappers.exchange.types import Order @@ -22,7 +22,7 @@ def exchange_wrapper(ganache_provider): """Get an Exchange wrapper instance.""" return Exchange( web3_or_provider=ganache_provider, - contract_address=network_to_addresses(NetworkId.GANACHE).exchange, + contract_address=chain_to_addresses(ChainId.GANACHE).exchange, ) @@ -161,8 +161,8 @@ def test_two_instantiations_with_web3_objects(web3_instance): again." Test that that bug isn't occurring. """ exchange = Exchange( # pylint: disable=unused-variable - web3_instance, network_to_addresses(NetworkId.GANACHE).exchange + web3_instance, chain_to_addresses(ChainId.GANACHE).exchange ) exchange2 = Exchange( # pylint: disable=unused-variable - web3_instance, network_to_addresses(NetworkId.GANACHE).exchange + web3_instance, chain_to_addresses(ChainId.GANACHE).exchange ) diff --git a/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py b/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py index 9314f4d194..fc98c6e0e9 100644 --- a/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py +++ b/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py @@ -60,7 +60,7 @@ def assert_valid(data: Mapping, schema_id: str) -> None: Raises an exception if validation fails. >>> from zero_ex.json_schemas import assert_valid - >>> from zero_ex.contract_addresses import network_to_addresses, NetworkId + >>> from zero_ex.contract_addresses import chain_to_addresses, ChainId >>> from zero_ex.order_utils import asset_data_utils >>> from eth_utils import remove_0x_prefix >>> import random @@ -74,10 +74,10 @@ def assert_valid(data: Mapping, schema_id: str) -> None: ... '0x0000000000000000000000000000000000000000' ... ), ... 'makerAssetData': ( - ... network_to_addresses(NetworkId.MAINNET).zrx_token + ... chain_to_addresses(ChainId.MAINNET).zrx_token ... ), ... 'takerAssetData': ( - ... network_to_addresses(NetworkId.MAINNET).ether_token + ... chain_to_addresses(ChainId.MAINNET).ether_token ... ), ... 'salt': random.randint(1, 100000000000000000), ... 'makerFee': 0, diff --git a/python-packages/middlewares/test/test_local_message_signer.py b/python-packages/middlewares/test/test_local_message_signer.py index 2eb87997a8..469bf38e31 100644 --- a/python-packages/middlewares/test/test_local_message_signer.py +++ b/python-packages/middlewares/test/test_local_message_signer.py @@ -3,7 +3,7 @@ from eth_utils import to_checksum_address from web3 import Web3, HTTPProvider -from zero_ex.contract_addresses import network_to_addresses, NetworkId +from zero_ex.contract_addresses import chain_to_addresses, ChainId from zero_ex.middlewares.local_message_signer import ( construct_local_message_signer, ) @@ -17,7 +17,7 @@ def test_local_message_signer__sign_order(): "d6db0157d9dfe9f9fadb8dedabb7786352843357f4ec8d0fbcbeeb619b1091f5803" ) address = "0x5409ED021D9299bf6814279A6A1411A7e866A631" - exchange = network_to_addresses(NetworkId.GANACHE).exchange + exchange = chain_to_addresses(ChainId.GANACHE).exchange private_key = ( "f2f48ee19680706196e2e339e5da3491186e0c4c5030670656b0e0164837257d" ) diff --git a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py index 7cc7ef277e..f5e7b0721f 100644 --- a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py +++ b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py @@ -29,7 +29,7 @@ from web3.providers.base import BaseProvider from web3.contract import Contract -from zero_ex.contract_addresses import network_to_addresses, NetworkId +from zero_ex.contract_addresses import chain_to_addresses, ChainId import zero_ex.contract_artifacts from zero_ex.contract_wrappers.exchange import Exchange from zero_ex.contract_wrappers.exchange.types import Order @@ -127,9 +127,9 @@ def generate_order_hash_hex( ... takerFeeAssetData=((0).to_bytes(1, byteorder='big') * 20), ... ), ... exchange_address="0x1dc4c1cefef38a777b15aa20260a54e584b16c48", - ... chain_id=50 + ... chain_id=1337 ... ) - '331cb7e07a757bae130702da6646c26531798c92bcfaf671817268fd2c188531' + 'cb36e4fedb36508fb707e2c05e21bffc7a72766ccae93f8ff096693fff7f1714' """ # noqa: E501 (line too long) assert_is_address(exchange_address, "exchange_address") assert_valid( @@ -211,9 +211,9 @@ def is_valid_signature( return Exchange( provider, - network_to_addresses( - NetworkId( - int(Web3(provider).net.version) # pylint: disable=no-member + chain_to_addresses( + ChainId( + int(Web3(provider).eth.chainId) # pylint: disable=no-member ) ).exchange, ).is_valid_hash_signature.call( diff --git a/python-packages/order_utils/stubs/web3/__init__.pyi b/python-packages/order_utils/stubs/web3/__init__.pyi index a23a5141a8..913a0431aa 100644 --- a/python-packages/order_utils/stubs/web3/__init__.pyi +++ b/python-packages/order_utils/stubs/web3/__init__.pyi @@ -21,11 +21,14 @@ class Web3: version: str ... - class eth: + class Eth: @staticmethod def contract(address: str, abi: Dict) -> Contract: ... + chainId: int ... + eth: Eth + class geth: class personal: @staticmethod diff --git a/python-packages/sra_client/src/zero_ex/sra_client/__init__.py b/python-packages/sra_client/src/zero_ex/sra_client/__init__.py index dd15ab7ffb..89ae2443aa 100644 --- a/python-packages/sra_client/src/zero_ex/sra_client/__init__.py +++ b/python-packages/sra_client/src/zero_ex/sra_client/__init__.py @@ -69,10 +69,10 @@ >>> from web3 import HTTPProvider, Web3 >>> eth_node = HTTPProvider("http://localhost:8545") -What network is it? +What chain are we on? ->>> from zero_ex.contract_addresses import NetworkId ->>> network_id = NetworkId.GANACHE # you might use .MAINNET or .KOVAN +>>> from zero_ex.contract_addresses import ChainId +>>> chain_id = ChainId.GANACHE # you might use .MAINNET or .KOVAN For our Maker role, we'll just use the first address available in the node: @@ -83,8 +83,8 @@ Before such an order can be valid, though, the maker must give the 0x contracts permission to trade their ZRX tokens: ->>> from zero_ex.contract_addresses import network_to_addresses ->>> contract_addresses = network_to_addresses(network_id) +>>> from zero_ex.contract_addresses import chain_to_addresses +>>> contract_addresses = chain_to_addresses(chain_id) >>> >>> from zero_ex.contract_artifacts import abi_by_name >>> zrx_token_contract = Web3(eth_node).eth.contract( @@ -141,7 +141,7 @@ ... order, contract_addresses.exchange, Web3(eth_node).eth.chainId ... ) >>> relayer.post_order_with_http_info( -... network_id=network_id.value, +... chain_id=chain_id.value, ... signed_order_schema=order_to_jsdict( ... order=order, ... exchange_address=contract_addresses.exchange, @@ -346,7 +346,7 @@ >>> from zero_ex.order_utils import Order >>> exchange = Exchange( ... web3_or_provider=eth_node, -... contract_address=network_to_addresses(NetworkId.GANACHE).exchange +... contract_address=chain_to_addresses(ChainId.GANACHE).exchange ... ) (Due to `an Issue with the Launch Kit Backend diff --git a/python-packages/sra_client/src/zero_ex/sra_client/api/default_api.py b/python-packages/sra_client/src/zero_ex/sra_client/api/default_api.py index 03e0316979..9fe92406f5 100644 --- a/python-packages/sra_client/src/zero_ex/sra_client/api/default_api.py +++ b/python-packages/sra_client/src/zero_ex/sra_client/api/default_api.py @@ -42,7 +42,7 @@ def get_asset_pairs(self, **kwargs): :param bool async_req: Whether request should be asynchronous. :param str asset_data_a: The assetData value for the first asset in the pair. :param str asset_data_b: The assetData value for the second asset in the pair. - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param int page: The number of the page to request in the collection. :param int per_page: The number of records to return per page. @@ -71,7 +71,7 @@ def get_asset_pairs_with_http_info(self, **kwargs): :param bool async_req: Whether request should be asynchronous. :param str asset_data_a: The assetData value for the first asset in the pair. :param str asset_data_b: The assetData value for the second asset in the pair. - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param int page: The number of the page to request in the collection. :param int per_page: The number of records to return per page. @@ -86,7 +86,7 @@ def get_asset_pairs_with_http_info(self, **kwargs): all_params = [ "asset_data_a", "asset_data_b", - "network_id", + "chain_id", "page", "per_page", ] @@ -117,8 +117,8 @@ def get_asset_pairs_with_http_info(self, **kwargs): query_params.append( ("assetDataB", local_var_params["asset_data_b"]) ) - if "network_id" in local_var_params: - query_params.append(("networkId", local_var_params["network_id"])) + if "chain_id" in local_var_params: + query_params.append(("chainId", local_var_params["chain_id"])) if "page" in local_var_params: query_params.append(("page", local_var_params["page"])) if "per_page" in local_var_params: @@ -170,7 +170,7 @@ def get_fee_recipients(self, **kwargs): >>> result = thread.get() # doctest: +SKIP :param bool async_req: Whether request should be asynchronous. - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param int page: The number of the page to request in the collection. :param int per_page: The number of records to return per page. @@ -196,7 +196,7 @@ def get_fee_recipients_with_http_info(self, **kwargs): >>> result = thread.get() # doctest: +SKIP :param bool async_req: Whether request should be asynchronous. - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param int page: The number of the page to request in the collection. :param int per_page: The number of records to return per page. @@ -208,7 +208,7 @@ def get_fee_recipients_with_http_info(self, **kwargs): local_var_params = locals() - all_params = ["network_id", "page", "per_page"] + all_params = ["chain_id", "page", "per_page"] all_params.append("async_req") all_params.append("_return_http_data_only") all_params.append("_preload_content") @@ -228,8 +228,8 @@ def get_fee_recipients_with_http_info(self, **kwargs): path_params = {} query_params = [] - if "network_id" in local_var_params: - query_params.append(("networkId", local_var_params["network_id"])) + if "chain_id" in local_var_params: + query_params.append(("chainId", local_var_params["chain_id"])) if "page" in local_var_params: query_params.append(("page", local_var_params["page"])) if "per_page" in local_var_params: @@ -281,7 +281,7 @@ def get_order(self, order_hash, **kwargs): :param bool async_req: Whether request should be asynchronous. :param str order_hash: The hash of the desired 0x order. (required) - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :return: :class:`RelayerApiOrderSchema`. If the method is called asynchronously, returns the request thread. @@ -305,7 +305,7 @@ def get_order_with_http_info(self, order_hash, **kwargs): :param bool async_req: Whether request should be asynchronous. :param str order_hash: The hash of the desired 0x order. (required) - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :return: A tuple consisting of a :class:`RelayerApiOrderSchema`, an HTTP status code integer, and a @@ -315,7 +315,7 @@ def get_order_with_http_info(self, order_hash, **kwargs): local_var_params = locals() - all_params = ["order_hash", "network_id"] + all_params = ["order_hash", "chain_id"] all_params.append("async_req") all_params.append("_return_http_data_only") all_params.append("_preload_content") @@ -345,8 +345,8 @@ def get_order_with_http_info(self, order_hash, **kwargs): path_params["orderHash"] = local_var_params["order_hash"] query_params = [] - if "network_id" in local_var_params: - query_params.append(("networkId", local_var_params["network_id"])) + if "chain_id" in local_var_params: + query_params.append(("chainId", local_var_params["chain_id"])) header_params = {} @@ -401,7 +401,7 @@ def get_order_config(self, **kwargs): >>> result = thread.get() # doctest: +SKIP :param bool async_req: Whether request should be asynchronous. - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param relayer_api_order_config_payload_schema: instance of :class:`RelayerApiOrderConfigPayloadSchema`. The fields of a 0x order the relayer may want to decide what configuration to send @@ -436,7 +436,7 @@ def get_order_config_with_http_info(self, **kwargs): >>> result = thread.get() # doctest: +SKIP :param bool async_req: Whether request should be asynchronous. - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param relayer_api_order_config_payload_schema: instance of :class: `RelayerApiOrderConfigPayloadSchema`. The fields of a 0x order the relayer may want to decide what configuration to send @@ -450,7 +450,7 @@ def get_order_config_with_http_info(self, **kwargs): local_var_params = locals() - all_params = ["network_id", "relayer_api_order_config_payload_schema"] + all_params = ["chain_id", "relayer_api_order_config_payload_schema"] all_params.append("async_req") all_params.append("_return_http_data_only") all_params.append("_preload_content") @@ -470,8 +470,8 @@ def get_order_config_with_http_info(self, **kwargs): path_params = {} query_params = [] - if "network_id" in local_var_params: - query_params.append(("networkId", local_var_params["network_id"])) + if "chain_id" in local_var_params: + query_params.append(("chainId", local_var_params["chain_id"])) header_params = {} @@ -545,7 +545,7 @@ def get_orderbook(self, base_asset_data, quote_asset_data, **kwargs): :param str quote_asset_data: assetData (makerAssetData or takerAssetData) designated as the quote currency in the currency pair calculation of price. (required) - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param int page: The number of the page to request in the collection. :param int per_page: The number of records to return per page. @@ -594,7 +594,7 @@ def get_orderbook_with_http_info( :param str quote_asset_data: assetData (makerAssetData or takerAssetData) designated as the quote currency in the currency pair calculation of price. (required) - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param int page: The number of the page to request in the collection. :param int per_page: The number of records to return per page. @@ -609,7 +609,7 @@ def get_orderbook_with_http_info( all_params = [ "base_asset_data", "quote_asset_data", - "network_id", + "chain_id", "page", "per_page", ] @@ -658,8 +658,8 @@ def get_orderbook_with_http_info( query_params.append( ("quoteAssetData", local_var_params["quote_asset_data"]) ) - if "network_id" in local_var_params: - query_params.append(("networkId", local_var_params["network_id"])) + if "chain_id" in local_var_params: + query_params.append(("chainId", local_var_params["chain_id"])) if "page" in local_var_params: query_params.append(("page", local_var_params["page"])) if "per_page" in local_var_params: @@ -760,7 +760,7 @@ def get_orders(self, **kwargs): `0x Protocol v3 Specification `__ - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param int page: The number of the page to request in the collection. :param int per_page: The number of records to return per page. @@ -837,7 +837,7 @@ def get_orders_with_http_info(self, **kwargs): `0x Protocol v3 Specification `__ - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param int page: The number of the page to request in the collection. :param int per_page: The number of records to return per page. @@ -863,7 +863,7 @@ def get_orders_with_http_info(self, **kwargs): "taker_address", "trader_address", "fee_recipient_address", - "network_id", + "chain_id", "page", "per_page", ] @@ -941,8 +941,8 @@ def get_orders_with_http_info(self, **kwargs): local_var_params["fee_recipient_address"], ) ) - if "network_id" in local_var_params: - query_params.append(("networkId", local_var_params["network_id"])) + if "chain_id" in local_var_params: + query_params.append(("chainId", local_var_params["chain_id"])) if "page" in local_var_params: query_params.append(("page", local_var_params["page"])) if "per_page" in local_var_params: @@ -993,7 +993,7 @@ def post_order(self, **kwargs): >>> result = thread.get() # doctest: +SKIP :param bool async_req: Whether request should be asynchronous. - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param signed_order_schema: Instance of :class:`SignedOrderSchema`. A valid signed 0x order based on the schema. @@ -1018,7 +1018,7 @@ def post_order_with_http_info(self, **kwargs): >>> result = thread.get() # doctest: +SKIP :param bool async_req: Whether request should be asynchronous. - :param int network_id: The id of the Ethereum network + :param int chain_id: The id of the Ethereum chain :param signed_order_schema: Instance of :class:`SignedOrderSchema` A valid signed 0x order based on the schema. @@ -1030,7 +1030,7 @@ def post_order_with_http_info(self, **kwargs): local_var_params = locals() - all_params = ["network_id", "signed_order_schema"] + all_params = ["chain_id", "signed_order_schema"] all_params.append("async_req") all_params.append("_return_http_data_only") all_params.append("_preload_content") @@ -1050,8 +1050,8 @@ def post_order_with_http_info(self, **kwargs): path_params = {} query_params = [] - if "network_id" in local_var_params: - query_params.append(("networkId", local_var_params["network_id"])) + if "chain_id" in local_var_params: + query_params.append(("chainId", local_var_params["chain_id"])) header_params = {} diff --git a/python-packages/sra_client/src/zero_ex/sra_client/models/relayer_api_orders_channel_subscribe_payload_schema.py b/python-packages/sra_client/src/zero_ex/sra_client/models/relayer_api_orders_channel_subscribe_payload_schema.py index f6bb758f9e..f7e1f5dbcc 100644 --- a/python-packages/sra_client/src/zero_ex/sra_client/models/relayer_api_orders_channel_subscribe_payload_schema.py +++ b/python-packages/sra_client/src/zero_ex/sra_client/models/relayer_api_orders_channel_subscribe_payload_schema.py @@ -24,7 +24,7 @@ class RelayerApiOrdersChannelSubscribePayloadSchema(object): openapi_types = { "maker_asset_proxy_id": "str", "taker_asset_proxy_id": "str", - "network_id": "float", + "chain_id": "float", "maker_asset_address": "str", "taker_asset_address": "str", "maker_asset_data": "str", @@ -35,7 +35,7 @@ class RelayerApiOrdersChannelSubscribePayloadSchema(object): attribute_map = { "maker_asset_proxy_id": "makerAssetProxyId", "taker_asset_proxy_id": "takerAssetProxyId", - "network_id": "networkId", + "chain_id": "chainId", "maker_asset_address": "makerAssetAddress", "taker_asset_address": "takerAssetAddress", "maker_asset_data": "makerAssetData", @@ -47,7 +47,7 @@ def __init__( self, maker_asset_proxy_id=None, taker_asset_proxy_id=None, - network_id=None, + chain_id=None, maker_asset_address=None, taker_asset_address=None, maker_asset_data=None, @@ -58,7 +58,7 @@ def __init__( self._maker_asset_proxy_id = None self._taker_asset_proxy_id = None - self._network_id = None + self._chain_id = None self._maker_asset_address = None self._taker_asset_address = None self._maker_asset_data = None @@ -70,8 +70,8 @@ def __init__( self.maker_asset_proxy_id = maker_asset_proxy_id if taker_asset_proxy_id is not None: self.taker_asset_proxy_id = taker_asset_proxy_id - if network_id is not None: - self.network_id = network_id + if chain_id is not None: + self.chain_id = chain_id if maker_asset_address is not None: self.maker_asset_address = maker_asset_address if taker_asset_address is not None: @@ -138,25 +138,25 @@ def taker_asset_proxy_id(self, taker_asset_proxy_id): self._taker_asset_proxy_id = taker_asset_proxy_id @property - def network_id(self): - """Gets the network_id of this RelayerApiOrdersChannelSubscribePayloadSchema. # noqa: E501 + def chain_id(self): + """Gets the chain_id of this RelayerApiOrdersChannelSubscribePayloadSchema. # noqa: E501 - :return: The network_id of this RelayerApiOrdersChannelSubscribePayloadSchema. # noqa: E501 + :return: The chain_id of this RelayerApiOrdersChannelSubscribePayloadSchema. # noqa: E501 :rtype: float """ - return self._network_id + return self._chain_id - @network_id.setter - def network_id(self, network_id): - """Sets the network_id of this RelayerApiOrdersChannelSubscribePayloadSchema. + @chain_id.setter + def chain_id(self, chain_id): + """Sets the chain_id of this RelayerApiOrdersChannelSubscribePayloadSchema. - :param network_id: The network_id of this RelayerApiOrdersChannelSubscribePayloadSchema. # noqa: E501 + :param chain_id: The chain_id of this RelayerApiOrdersChannelSubscribePayloadSchema. # noqa: E501 :type: float """ - self._network_id = network_id + self._chain_id = chain_id @property def maker_asset_address(self): From 86756633380c067f5589c6485fb045b88ce7b246 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 4 Nov 2019 21:18:59 -0500 Subject: [PATCH 29/35] abi-gen/templates/Py: clarify if/else logic In response to https://github.com/0xProject/0x-monorepo/pull/2284#discussion_r342200906 --- packages/abi-gen/templates/Python/contract.handlebars | 2 +- .../abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py | 2 +- packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py | 2 +- .../abi-gen/test-cli/output/python/test_lib_dummy/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/abi-gen/templates/Python/contract.handlebars b/packages/abi-gen/templates/Python/contract.handlebars index 5fa8dcfa51..ab6e9682da 100644 --- a/packages/abi-gen/templates/Python/contract.handlebars +++ b/packages/abi-gen/templates/Python/contract.handlebars @@ -88,7 +88,7 @@ class {{contractName}}: web3 = Web3(web3_or_provider) elif isinstance(web3_or_provider, Web3): web3 = web3_or_provider - if web3 is None: + else: raise TypeError( "Expected parameter 'web3_or_provider' to be an instance of either" + " Web3 or BaseProvider" diff --git a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py index 3982f02477..73d062aefc 100644 --- a/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/abi_gen_dummy/__init__.py @@ -1977,7 +1977,7 @@ def __init__( web3 = Web3(web3_or_provider) elif isinstance(web3_or_provider, Web3): web3 = web3_or_provider - if web3 is None: + else: raise TypeError( "Expected parameter 'web3_or_provider' to be an instance of either" + " Web3 or BaseProvider" diff --git a/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py index 11d4a39bef..6c1375710e 100644 --- a/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/lib_dummy/__init__.py @@ -75,7 +75,7 @@ def __init__( web3 = Web3(web3_or_provider) elif isinstance(web3_or_provider, Web3): web3 = web3_or_provider - if web3 is None: + else: raise TypeError( "Expected parameter 'web3_or_provider' to be an instance of either" + " Web3 or BaseProvider" diff --git a/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py b/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py index 321893ee3a..b49c62b7f2 100644 --- a/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py +++ b/packages/abi-gen/test-cli/output/python/test_lib_dummy/__init__.py @@ -197,7 +197,7 @@ def __init__( web3 = Web3(web3_or_provider) elif isinstance(web3_or_provider, Web3): web3 = web3_or_provider - if web3 is None: + else: raise TypeError( "Expected parameter 'web3_or_provider' to be an instance of either" + " Web3 or BaseProvider" From e472ceea49cb0d7f62d33807b66baa63d65605c0 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 4 Nov 2019 21:51:09 -0500 Subject: [PATCH 30/35] sra_client.py: Update CHANGELOG and bump version --- python-packages/sra_client/CHANGELOG.md | 4 ++++ python-packages/sra_client/setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/python-packages/sra_client/CHANGELOG.md b/python-packages/sra_client/CHANGELOG.md index 1220c1a349..2b68b91b91 100644 --- a/python-packages/sra_client/CHANGELOG.md +++ b/python-packages/sra_client/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 4.0.0 - TBD + +- Migrated from v2 to v3 of the 0x protocol. + ## 3.0.0 - 2019-08-08 - Migrated from v4 to v5 of Web3.py. diff --git a/python-packages/sra_client/setup.py b/python-packages/sra_client/setup.py index b143467009..4e2d6a78a8 100755 --- a/python-packages/sra_client/setup.py +++ b/python-packages/sra_client/setup.py @@ -19,7 +19,7 @@ from setuptools.command.test import test as TestCommand NAME = "0x-sra-client" -VERSION = "3.0.0" +VERSION = "4.0.0" # To install the library, run the following # # python setup.py install From 8d7f47f5df832d0f7cb3131d0d5f73386d0dded1 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 5 Nov 2019 12:35:56 -0500 Subject: [PATCH 31/35] contract_addresses/setup.py: rm unnecessary rm --- python-packages/contract_addresses/setup.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/python-packages/contract_addresses/setup.py b/python-packages/contract_addresses/setup.py index e5916386a0..0d4dee62c3 100755 --- a/python-packages/contract_addresses/setup.py +++ b/python-packages/contract_addresses/setup.py @@ -8,7 +8,7 @@ import subprocess # nosec from shutil import copyfile, rmtree -from os import environ, path, remove +from os import environ, path from sys import argv, exit # pylint: disable=redefined-builtin from distutils.command.clean import clean @@ -32,10 +32,6 @@ def run(self): pkgdir, "src", "zero_ex", "contract_addresses" ) - try: - remove(path.join(destination_path, "addresses.json")) - except FileNotFoundError: - pass copyfile( path.join( pkgdir, From 6d454d1cedc5d2cc737e67d9d35e30ff4e71dec6 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 5 Nov 2019 16:40:11 -0500 Subject: [PATCH 32/35] json_schemas.py: corrections to dev dependencies --- python-packages/json_schemas/setup.py | 1 + .../json_schemas/src/zero_ex/json_schemas/__init__.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/python-packages/json_schemas/setup.py b/python-packages/json_schemas/setup.py index f943260847..1a2d5d6836 100755 --- a/python-packages/json_schemas/setup.py +++ b/python-packages/json_schemas/setup.py @@ -170,6 +170,7 @@ def run(self): "black", "coverage", "coveralls", + "eth_utils", "mypy", "mypy_extensions", "pycodestyle", diff --git a/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py b/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py index 9314f4d194..5036b6fa38 100644 --- a/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py +++ b/python-packages/json_schemas/src/zero_ex/json_schemas/__init__.py @@ -61,7 +61,6 @@ def assert_valid(data: Mapping, schema_id: str) -> None: >>> from zero_ex.json_schemas import assert_valid >>> from zero_ex.contract_addresses import network_to_addresses, NetworkId - >>> from zero_ex.order_utils import asset_data_utils >>> from eth_utils import remove_0x_prefix >>> import random >>> from datetime import datetime, timedelta From a14a4d3d0762a49a17c016f53f97665b241cb7df Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 29 Oct 2019 17:23:32 -0400 Subject: [PATCH 33/35] In tests against deployment, also run doctests --- python-packages/contract_addresses/tox.ini | 6 ++++++ python-packages/contract_artifacts/tox.ini | 6 ++++++ python-packages/contract_wrappers/tox.ini | 5 +++-- python-packages/json_schemas/tox.ini | 5 +++-- python-packages/order_utils/tox.ini | 5 +++-- python-packages/sra_client/tox.ini | 6 +++--- 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/python-packages/contract_addresses/tox.ini b/python-packages/contract_addresses/tox.ini index 1cce32b5f0..944049af60 100644 --- a/python-packages/contract_addresses/tox.ini +++ b/python-packages/contract_addresses/tox.ini @@ -10,3 +10,9 @@ envlist = py37 commands = pip install -e .[dev] python setup.py test + +[testenv:run_tests_against_deployment] +setenv = PY_IGNORE_IMPORTMISMATCH = 1 +commands= + pip install 0x-contract-addresses[dev] + pytest --doctest-modules src diff --git a/python-packages/contract_artifacts/tox.ini b/python-packages/contract_artifacts/tox.ini index 1cce32b5f0..4fd5f65639 100644 --- a/python-packages/contract_artifacts/tox.ini +++ b/python-packages/contract_artifacts/tox.ini @@ -10,3 +10,9 @@ envlist = py37 commands = pip install -e .[dev] python setup.py test + +[testenv:run_tests_against_deployment] +setenv = PY_IGNORE_IMPORTMISMATCH = 1 +commands= + pip install 0x-contract-artifacts[dev] + pytest --doctest-modules src diff --git a/python-packages/contract_wrappers/tox.ini b/python-packages/contract_wrappers/tox.ini index cd847a5bb8..c3e7029329 100644 --- a/python-packages/contract_wrappers/tox.ini +++ b/python-packages/contract_wrappers/tox.ini @@ -20,6 +20,7 @@ commands = pytest test [testenv:run_tests_against_deployment] +setenv = PY_IGNORE_IMPORTMISMATCH = 1 commands = - pip install 0x-contract-wrappers - pytest test + pip install 0x-contract-wrappers[dev] + pytest --doctest-modules src test diff --git a/python-packages/json_schemas/tox.ini b/python-packages/json_schemas/tox.ini index 1d5de646ef..87ec5e8473 100644 --- a/python-packages/json_schemas/tox.ini +++ b/python-packages/json_schemas/tox.ini @@ -20,6 +20,7 @@ commands = pytest test [testenv:run_tests_against_deployment] +setenv = PY_IGNORE_IMPORTMISMATCH = 1 commands = - pip install 0x-json-schemas - pytest test + pip install 0x-json-schemas[dev] + pytest --doctest-modules src test diff --git a/python-packages/order_utils/tox.ini b/python-packages/order_utils/tox.ini index ba7d55b569..c51a7e14f0 100644 --- a/python-packages/order_utils/tox.ini +++ b/python-packages/order_utils/tox.ini @@ -20,6 +20,7 @@ commands = pytest test [testenv:run_tests_against_deployment] +setenv = PY_IGNORE_IMPORTMISMATCH = 1 commands = - pip install 0x-order-utils - pytest test + pip install 0x-order-utils[dev] + pytest --doctest-modules src test diff --git a/python-packages/sra_client/tox.ini b/python-packages/sra_client/tox.ini index 0d776c7b07..2f40a07c89 100644 --- a/python-packages/sra_client/tox.ini +++ b/python-packages/sra_client/tox.ini @@ -18,7 +18,7 @@ commands = pytest test [testenv:run_tests_against_deployment] -deps=pytest +setenv = PY_IGNORE_IMPORTMISMATCH = 1 commands = - pip install 0x-sra-client - pytest test + pip install 0x-sra-client[dev] + pytest --doctest-modules src test From 19fac9206cf760566d67b13a1d6ea2eeed7ee3b8 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 5 Nov 2019 17:02:00 -0500 Subject: [PATCH 34/35] contract_wrappers example: rm xtra Order attribute Thanks to @steveklebanoff for catching this. https://github.com/0xProject/0x-monorepo/pull/2284#pullrequestreview-312065368 --- .../contract_wrappers/src/zero_ex/contract_wrappers/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py index 538607c6fa..538d378689 100644 --- a/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py +++ b/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/__init__.py @@ -138,7 +138,6 @@ ... ), ... makerFeeAssetData='0x', ... takerFeeAssetData='0x', -... chain_id=Web3(ganache).eth.chainId, ... ) For this order to be valid, our Maker must sign a hash of it: From 004fcd926331a697ce2526d3e577a3c0bc64ee56 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 5 Nov 2019 18:13:27 -0500 Subject: [PATCH 35/35] Update CHANGELOGs --- packages/0x.js/CHANGELOG.json | 9 +++++++++ packages/abi-gen/CHANGELOG.json | 4 ++++ packages/asset-buyer/CHANGELOG.json | 9 +++++++++ packages/asset-swapper/CHANGELOG.json | 9 +++++++++ packages/connect/CHANGELOG.json | 9 +++++++++ packages/contract-addresses/CHANGELOG.json | 6 +++++- packages/contract-wrappers/CHANGELOG.json | 9 +++++++++ packages/ethereum-types/CHANGELOG.json | 9 +++++++++ packages/json-schemas/CHANGELOG.json | 9 +++++++++ packages/migrations/CHANGELOG.json | 6 +++++- packages/order-utils/CHANGELOG.json | 6 +++++- packages/orderbook/CHANGELOG.json | 9 +++++++++ packages/sol-compiler/CHANGELOG.json | 9 +++++++++ packages/sra-spec/CHANGELOG.json | 9 +++++++++ packages/types/CHANGELOG.json | 6 +++++- python-packages/contract_addresses/CHANGELOG.md | 4 ++++ python-packages/contract_wrappers/CHANGELOG.md | 1 + python-packages/json_schemas/CHANGELOG.md | 3 ++- python-packages/order_utils/CHANGELOG.md | 1 + 19 files changed, 122 insertions(+), 5 deletions(-) diff --git a/packages/0x.js/CHANGELOG.json b/packages/0x.js/CHANGELOG.json index e0e2540d12..a0f5cef38c 100644 --- a/packages/0x.js/CHANGELOG.json +++ b/packages/0x.js/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "8.0.0-beta.0", + "changes": [ + { + "note": "Exported intefaces changed: from getContractAddressesForNetworkOrThrow to getContractAddressesForChainOrThrow, from NetworkId to ChainId, from ContractNetworks to ContractChains, and from ContractNetworkData to ContractChainData.", + "pr": 2313 + } + ] + }, { "version": "7.1.0-beta.0", "changes": [ diff --git a/packages/abi-gen/CHANGELOG.json b/packages/abi-gen/CHANGELOG.json index 079e1f902b..567126e1e1 100644 --- a/packages/abi-gen/CHANGELOG.json +++ b/packages/abi-gen/CHANGELOG.json @@ -17,6 +17,10 @@ { "note": "In Python wrappers, fix bug with casting some bytes objects using bytes.fromhex()", "pr": 2284 + }, + { + "note": "Command-line argument network-id has changed to chain-id", + "pr": 2313 } ] }, diff --git a/packages/asset-buyer/CHANGELOG.json b/packages/asset-buyer/CHANGELOG.json index 9d121469fe..961c57eb03 100644 --- a/packages/asset-buyer/CHANGELOG.json +++ b/packages/asset-buyer/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "7.0.0-beta.0", + "changes": [ + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 + } + ] + }, { "version": "6.2.0-beta.0", "changes": [ diff --git a/packages/asset-swapper/CHANGELOG.json b/packages/asset-swapper/CHANGELOG.json index 96f2a7801f..2af31c6909 100644 --- a/packages/asset-swapper/CHANGELOG.json +++ b/packages/asset-swapper/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "3.0.0-beta.0", + "changes": [ + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 + } + ] + }, { "version": "2.1.0-beta.0", "changes": [ diff --git a/packages/connect/CHANGELOG.json b/packages/connect/CHANGELOG.json index 02b53e52f5..b467adf1ea 100644 --- a/packages/connect/CHANGELOG.json +++ b/packages/connect/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "6.0.0-beta.0", + "changes": [ + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 + } + ] + }, { "version": "5.1.0-beta.0", "changes": [ diff --git a/packages/contract-addresses/CHANGELOG.json b/packages/contract-addresses/CHANGELOG.json index 9e681b775d..54e1d91ab7 100644 --- a/packages/contract-addresses/CHANGELOG.json +++ b/packages/contract-addresses/CHANGELOG.json @@ -1,6 +1,6 @@ [ { - "version": "3.4.0-beta.0", + "version": "4.0.0-beta.0", "changes": [ { "note": "Remove `readOnlyProxy` from addresses interface", @@ -13,6 +13,10 @@ { "note": "Update `exchange`, `staking`, `stakingProxy`, `zeroExGovernor`, `assetProxyOwner`, and `erc20BridgeProxy` addresses for each tesnet", "pr": 2296 + }, + { + "note": "Contract addresses are no longer indexed by network ID. Now they're indexed by chain ID.", + "pr": 2313 } ] }, diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index 966692cae0..a2fffaed24 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "13.0.0-beta.0", + "changes": [ + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 + } + ] + }, { "version": "12.2.0-beta.0", "changes": [ diff --git a/packages/ethereum-types/CHANGELOG.json b/packages/ethereum-types/CHANGELOG.json index 7abc500967..cada85485e 100644 --- a/packages/ethereum-types/CHANGELOG.json +++ b/packages/ethereum-types/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "3.0.0-beta.0", + "changes": [ + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 + } + ] + }, { "version": "2.2.0-beta.0", "changes": [ diff --git a/packages/json-schemas/CHANGELOG.json b/packages/json-schemas/CHANGELOG.json index 9ae7381703..b328dbc6b2 100644 --- a/packages/json-schemas/CHANGELOG.json +++ b/packages/json-schemas/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "5.0.0-beta.0", + "changes": [ + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 + } + ] + }, { "version": "4.1.0-beta.0", "changes": [ diff --git a/packages/migrations/CHANGELOG.json b/packages/migrations/CHANGELOG.json index 04a5829780..0d82545df3 100644 --- a/packages/migrations/CHANGELOG.json +++ b/packages/migrations/CHANGELOG.json @@ -1,10 +1,14 @@ [ { - "version": "4.4.0-beta.1", + "version": "5.0.0-beta.0", "changes": [ { "note": "Update all contract deployments to pass the actual chain ID (rather than the network ID) via the newly modified @0x/utils/provider_utils", "pr": 2270 + }, + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 } ] }, diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index 9aaff69250..8d97c9288b 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -1,10 +1,14 @@ [ { - "version": "8.5.0-beta.1", + "version": "9.0.0-beta.0", "changes": [ { "note": "Remove `TransferFailedError` from `ForwarderRevertErrors`.", "pr": 2309 + }, + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 } ] }, diff --git a/packages/orderbook/CHANGELOG.json b/packages/orderbook/CHANGELOG.json index 15c662c579..adb8c546a0 100644 --- a/packages/orderbook/CHANGELOG.json +++ b/packages/orderbook/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "1.0.0-beta.0", + "changes": [ + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 + } + ] + }, { "version": "0.1.0-beta.0", "changes": [ diff --git a/packages/sol-compiler/CHANGELOG.json b/packages/sol-compiler/CHANGELOG.json index efa2c2c311..46563b5ec8 100644 --- a/packages/sol-compiler/CHANGELOG.json +++ b/packages/sol-compiler/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "4.0.0-beta.0", + "changes": [ + { + "note": "Output artifacts now include a 'chains' attribute rather than 'networks'", + "pr": 2313 + } + ] + }, { "version": "3.2.0-beta.0", "changes": [ diff --git a/packages/sra-spec/CHANGELOG.json b/packages/sra-spec/CHANGELOG.json index b6085d18d7..aaa3fa77b3 100644 --- a/packages/sra-spec/CHANGELOG.json +++ b/packages/sra-spec/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "3.0.0-beta.0", + "changes": [ + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 + } + ] + }, { "version": "2.1.0-beta.0", "changes": [ diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index 5c9a0722f3..7cba5c2e0f 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -1,10 +1,14 @@ [ { - "version": "2.5.0-beta.1", + "version": "3.0.0-beta.0", "changes": [ { "note": "Add `SendTransactionOpts` and `AwaitTransactionSuccessOpts` types for contract wrappers", "pr": 2243 + }, + { + "note": "All references to network ID have been removed, and references to chain ID have been introduced instead", + "pr": 2313 } ] }, diff --git a/python-packages/contract_addresses/CHANGELOG.md b/python-packages/contract_addresses/CHANGELOG.md index 7a5747ff25..23be511ff2 100644 --- a/python-packages/contract_addresses/CHANGELOG.md +++ b/python-packages/contract_addresses/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.0.0 - TBD + +- Addresses are now indexed by chain ID rather than by network ID. + ## 2.2.0 - 2019-08-08 - Added ERC1155Proxy address diff --git a/python-packages/contract_wrappers/CHANGELOG.md b/python-packages/contract_wrappers/CHANGELOG.md index 24161a8b93..83a085820e 100644 --- a/python-packages/contract_wrappers/CHANGELOG.md +++ b/python-packages/contract_wrappers/CHANGELOG.md @@ -8,6 +8,7 @@ - Expanded documentation examples. - Moved methods `jsdict_to_order()` and `order_to_jsdict()` from `zero_ex.contract_wrappers.exchange.types` to `zero_ex.contract_wrappers.order_conversions`. - Changed field name `zero_ex.contract_wrappers.tx_params.TxParams.gasPrice` to `.gas_price`. +- Migrated to new version of 0x-contract-addresses. ## 1.1.0 - 2019-08-14 diff --git a/python-packages/json_schemas/CHANGELOG.md b/python-packages/json_schemas/CHANGELOG.md index b06c98ec8c..987c1854e1 100644 --- a/python-packages/json_schemas/CHANGELOG.md +++ b/python-packages/json_schemas/CHANGELOG.md @@ -1,8 +1,9 @@ # Changelog -## 1.1.1 - TBD +## 1.2.0 - TBD - Removed dev dependency on package `0x-contract-wrappers` +- Migrated examples to using new version of `0x-contract-addresses`. ## 1.1.0 - 2019-08-09 diff --git a/python-packages/order_utils/CHANGELOG.md b/python-packages/order_utils/CHANGELOG.md index afa979ae92..1c44bdf2a7 100644 --- a/python-packages/order_utils/CHANGELOG.md +++ b/python-packages/order_utils/CHANGELOG.md @@ -5,6 +5,7 @@ - Upgraded to protocol version 3. - `is_valid_signature()` now returns just a boolean. (Formerly, it returned a tuple consisting of the boolean and a reason string.) - Allow `sign_hash()` to be called with EITHER a Web3.py `BaseProvider` OR an already-instantiated `Web3` client object. +- Migrated to new version of `0x-contract-addresses`. ## 3.0.1 - 2019-08-09