Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permitted bytes addresses in web3 #893

Merged
merged 14 commits into from
Jul 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/conventions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ Hexadecimal Representations
Addresses
---------

All addresses must be supplied in one of two ways:
All addresses must be supplied in one of three ways:

* While connected to mainnet, an Ethereum Name Service name (often in the form ``myname.eth``)
* A 20-byte hexadecimal that is checksummed using the `EIP-55
<https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md>`_ spec.
* While connected to mainnet, an Ethereum Name Service name (often in the form ``myname.eth``)
* A 20-byte binary address.
5 changes: 5 additions & 0 deletions ens/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

from eth_utils import (
is_binary_address,
is_checksum_address,
to_checksum_address,
)
Expand Down Expand Up @@ -122,6 +123,8 @@ def setup_address(self, name, address=default, transact={}):
address = None
elif address is default:
address = owner
elif is_binary_address(address):
address = to_checksum_address(address)
elif not is_checksum_address(address):
raise ValueError("You must supply the address in checksum format")
if self.address(name) == address:
Expand Down Expand Up @@ -166,6 +169,8 @@ def setup_name(self, name, address=None, transact={}):
address = self.owner(name)
if not address:
raise UnownedName("claim subdomain using setup_address() first")
if is_binary_address(address):
address = to_checksum_address(address)
if not is_checksum_address(address):
raise ValueError("You must supply the address in checksum format")
self._assert_control(address, name)
Expand Down
14 changes: 14 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest

from eth_utils import (
to_bytes,
)

from web3.utils.toolz import (
identity,
)


@pytest.fixture(scope="module", params=[lambda x: to_bytes(hexstr=x), identity])
def address_conversion_func(request):
return request.param
12 changes: 7 additions & 5 deletions tests/core/contracts/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,17 +292,19 @@ def Emitter(web3_empty, EMITTER):


@pytest.fixture()
def emitter(web3_empty, Emitter, wait_for_transaction, wait_for_block):
def emitter(web3_empty, Emitter, wait_for_transaction, wait_for_block, address_conversion_func):
web3 = web3_empty

wait_for_block(web3)
deploy_txn_hash = Emitter.constructor().transact({'from': web3.eth.coinbase, 'gas': 1000000})
deploy_receipt = wait_for_transaction(web3, deploy_txn_hash)
contract_address = deploy_receipt['contractAddress']
contract_address = address_conversion_func(deploy_receipt['contractAddress'])

bytecode = web3.eth.getCode(contract_address)
assert bytecode == Emitter.bytecode_runtime
return Emitter(address=contract_address)
emitter_contract = Emitter(address=contract_address)
assert emitter_contract.address == contract_address
return emitter_contract


CONTRACT_ARRAYS_SOURCE = """
Expand Down Expand Up @@ -527,8 +529,8 @@ def emitter_log_topics():


@pytest.fixture()
def some_address():
return '0x5B2063246F2191f18F2675ceDB8b28102e957458'
def some_address(address_conversion_func):
return address_conversion_func('0x5B2063246F2191f18F2675ceDB8b28102e957458')


def invoke_contract(api_style=None,
Expand Down
5 changes: 3 additions & 2 deletions tests/core/contracts/test_concise_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ def deploy(web3, Contract, args=None):


@pytest.fixture()
def EMPTY_ADDR():
return '0x' + '00' * 20
def EMPTY_ADDR(address_conversion_func):
addr = '0x' + '00' * 20
return address_conversion_func(addr)


@pytest.fixture()
Expand Down
6 changes: 4 additions & 2 deletions tests/core/contracts/test_contract_ambiguous_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@


@pytest.fixture()
def string_contract(web3, StringContract):
def string_contract(web3, StringContract, address_conversion_func):
deploy_txn = StringContract.constructor("Caqalai").transact()
deploy_receipt = web3.eth.waitForTransactionReceipt(deploy_txn)
assert deploy_receipt is not None
contract = StringContract(address=deploy_receipt['contractAddress'])
contract_address = address_conversion_func(deploy_receipt['contractAddress'])
contract = StringContract(address=contract_address)
assert contract.address == contract_address
assert len(web3.eth.getCode(contract.address)) > 0
return contract

Expand Down
12 changes: 8 additions & 4 deletions tests/core/contracts/test_contract_buildTransaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,24 @@


@pytest.fixture()
def math_contract(web3, MathContract):
def math_contract(web3, MathContract, address_conversion_func):
deploy_txn = MathContract.constructor().transact()
deploy_receipt = web3.eth.waitForTransactionReceipt(deploy_txn)
assert deploy_receipt is not None
_math_contract = MathContract(address=deploy_receipt['contractAddress'])
math_contract_address = address_conversion_func(deploy_receipt['contractAddress'])
_math_contract = MathContract(address=math_contract_address)
assert _math_contract.address == math_contract_address
return _math_contract


@pytest.fixture()
def fallback_function_contract(web3, FallballFunctionContract):
def fallback_function_contract(web3, FallballFunctionContract, address_conversion_func):
deploy_txn = FallballFunctionContract.constructor().transact()
deploy_receipt = web3.eth.waitForTransactionReceipt(deploy_txn)
assert deploy_receipt is not None
_fallback_contract = FallballFunctionContract(address=deploy_receipt['contractAddress'])
fallback_contract_address = address_conversion_func(deploy_receipt['contractAddress'])
_fallback_contract = FallballFunctionContract(address=fallback_contract_address)
assert _fallback_contract.address == fallback_contract_address
return _fallback_contract


Expand Down
62 changes: 35 additions & 27 deletions tests/core/contracts/test_contract_call_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,62 +20,70 @@
from web3.utils.ens import (
contract_ens_addresses,
)
from web3.utils.toolz import (
identity,
)

# Ignore warning in pyethereum 1.6 - will go away with the upgrade
pytestmark = pytest.mark.filterwarnings("ignore:implicit cast from 'char *'")


def deploy(web3, Contract, args=None):
def deploy(web3, Contract, apply_func=identity, args=None):
args = args or []
deploy_txn = Contract.constructor(*args).transact()
deploy_receipt = web3.eth.waitForTransactionReceipt(deploy_txn)
assert deploy_receipt is not None
contract = Contract(address=deploy_receipt['contractAddress'])
address = apply_func(deploy_receipt['contractAddress'])
contract = Contract(address=address)
assert contract.address == address
assert len(web3.eth.getCode(contract.address)) > 0
return contract


@pytest.fixture()
def address_reflector_contract(web3, AddressReflectorContract):
return deploy(web3, AddressReflectorContract)
def address_reflector_contract(web3, AddressReflectorContract, address_conversion_func):
return deploy(web3, AddressReflectorContract, address_conversion_func)


@pytest.fixture()
def math_contract(web3, MathContract):
return deploy(web3, MathContract)
def math_contract(web3, MathContract, address_conversion_func):
return deploy(web3, MathContract, address_conversion_func)


@pytest.fixture()
def string_contract(web3, StringContract):
return deploy(web3, StringContract, args=["Caqalai"])
def string_contract(web3, StringContract, address_conversion_func):
return deploy(web3, StringContract, address_conversion_func, args=["Caqalai"])


@pytest.fixture()
def arrays_contract(web3, ArraysContract):
def arrays_contract(web3, ArraysContract, address_conversion_func):
# bytes_32 = [keccak('0'), keccak('1')]
bytes32_array = [
b'\x04HR\xb2\xa6p\xad\xe5@~x\xfb(c\xc5\x1d\xe9\xfc\xb9eB\xa0q\x86\xfe:\xed\xa6\xbb\x8a\x11m', # noqa: E501
b'\xc8\x9e\xfd\xaaT\xc0\xf2\x0cz\xdfa(\x82\xdf\tP\xf5\xa9Qc~\x03\x07\xcd\xcbLg/)\x8b\x8b\xc6', # noqa: E501
]
byte_arr = [b'\xff', b'\xff', b'\xff', b'\xff']
return deploy(web3, ArraysContract, args=[bytes32_array, byte_arr])
return deploy(web3, ArraysContract, address_conversion_func, args=[bytes32_array, byte_arr])


@pytest.fixture()
def address_contract(web3, WithConstructorAddressArgumentsContract):
return deploy(web3, WithConstructorAddressArgumentsContract, args=[
"0xd3CdA913deB6f67967B99D67aCDFa1712C293601",
])
def address_contract(web3, WithConstructorAddressArgumentsContract, address_conversion_func):
return deploy(
web3,
WithConstructorAddressArgumentsContract,
address_conversion_func,
args=["0xd3CdA913deB6f67967B99D67aCDFa1712C293601"]
)


@pytest.fixture(params=[b'\x04\x06', '0x0406', '0406'])
def bytes_contract(web3, BytesContract, request):
return deploy(web3, BytesContract, args=[request.param])
def bytes_contract(web3, BytesContract, request, address_conversion_func):
return deploy(web3, BytesContract, address_conversion_func, args=[request.param])


@pytest.fixture()
def fixed_reflection_contract(web3, FixedReflectionContract):
return deploy(web3, FixedReflectionContract)
def fixed_reflection_contract(web3, FixedReflectionContract, address_conversion_func):
return deploy(web3, FixedReflectionContract, address_conversion_func)


@pytest.fixture()
Expand All @@ -91,30 +99,30 @@ def call_transaction():
'0406040604060406040604060406040604060406040604060406040604060406',
HexBytes('0406040604060406040604060406040604060406040604060406040604060406'),
])
def bytes32_contract(web3, Bytes32Contract, request):
return deploy(web3, Bytes32Contract, args=[request.param])
def bytes32_contract(web3, Bytes32Contract, request, address_conversion_func):
return deploy(web3, Bytes32Contract, address_conversion_func, args=[request.param])


@pytest.fixture()
def undeployed_math_contract(web3, MathContract):
empty_address = "0x000000000000000000000000000000000000dEaD"
def undeployed_math_contract(web3, MathContract, address_conversion_func):
empty_address = address_conversion_func("0x000000000000000000000000000000000000dEaD")
_undeployed_math_contract = MathContract(address=empty_address)
return _undeployed_math_contract


@pytest.fixture()
def mismatched_math_contract(web3, StringContract, MathContract):
def mismatched_math_contract(web3, StringContract, MathContract, address_conversion_func):
deploy_txn = StringContract.constructor("Caqalai").transact()
deploy_receipt = web3.eth.waitForTransactionReceipt(deploy_txn)
assert deploy_receipt is not None

_mismatched_math_contract = MathContract(address=deploy_receipt['contractAddress'])
address = address_conversion_func(deploy_receipt['contractAddress'])
_mismatched_math_contract = MathContract(address=address)
return _mismatched_math_contract


@pytest.fixture()
def fallback_function_contract(web3, FallballFunctionContract):
return deploy(web3, FallballFunctionContract)
def fallback_function_contract(web3, FallballFunctionContract, address_conversion_func):
return deploy(web3, FallballFunctionContract, address_conversion_func)


def test_invalid_address_in_deploy_arg(web3, WithConstructorAddressArgumentsContract):
Expand Down
Loading