Skip to content

Commit

Permalink
Change to compositional instead of OO
Browse files Browse the repository at this point in the history
  • Loading branch information
kclowes committed Sep 20, 2019
1 parent 2ea34fe commit 6d323e4
Show file tree
Hide file tree
Showing 21 changed files with 574 additions and 494 deletions.
2 changes: 1 addition & 1 deletion conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def web3():


@pytest.fixture
def web3_strict_types():
def w3_strict_abi():
w3 = Web3(EthereumTesterProvider())
w3.enable_strict_bytes_type_checking()
return w3
Expand Down
4 changes: 4 additions & 0 deletions docs/abi_types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ All addresses must be supplied in one of three ways:
Strict Bytes Type Checking
--------------------------

.. note ::
In version 6, this will be the default behavior
There is a method on web3 that will enable stricter bytes type checking.
The default is to allow Python strings, and to allow bytestrings less
than the specified byte size. To enable stricter checks, use
Expand Down
134 changes: 68 additions & 66 deletions docs/contracts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -545,12 +545,12 @@ The following values will raise an error by default:
- String is not valid hex

However, you may want to be stricter with acceptable values for bytes types.
For this you can use the ``enable_strict_bytes_type_checking`` method,
For this you can use the :meth:`w3.enable_strict_bytes_type_checking()` method,
which is available on the web3 instance. A web3 instance which has had this method
invoked will enforce a stricter set of rules on which values are accepted.

- A Python string that is not prefixed with ``0x`` will throw an error.
- A bytestring that is less than (or greater than) the specified byte size
- A bytestring whose length not exactly the specified byte size
will raise an error.

.. list-table:: Valid byte and hex strings for a strict bytes4 type
Expand Down Expand Up @@ -586,13 +586,75 @@ invoked will enforce a stricter set of rules on which values are accepted.
- Needs to have exactly 4 bytes


For example, the following contract code will generate the abi below and some bytecode:
Taking the following contract code as an example:

.. testsetup::

from web3 import Web3
w3 = Web3(Web3.EthereumTesterProvider())
bytecode = "608060405234801561001057600080fd5b506040516106103803806106108339810180604052602081101561003357600080fd5b81019080805164010000000081111561004b57600080fd5b8281019050602081018481111561006157600080fd5b815185602082028301116401000000008211171561007e57600080fd5b5050929190505050806000908051906020019061009c9291906100a3565b505061019c565b82805482825590600052602060002090600f0160109004810192821561015a5791602002820160005b8382111561012a57835183826101000a81548161ffff02191690837e010000000000000000000000000000000000000000000000000000000000009004021790555092602001926002016020816001010492830192600103026100cc565b80156101585782816101000a81549061ffff021916905560020160208160010104928301926001030261012a565b505b509050610167919061016b565b5090565b61019991905b8082111561019557600081816101000a81549061ffff021916905550600101610171565b5090565b90565b610465806101ab6000396000f3fe608060405260043610610051576000357c0100000000000000000000000000000000000000000000000000000000900480633b3230ee14610056578063d7c8a410146100e7578063dfe3136814610153575b600080fd5b34801561006257600080fd5b5061008f6004803603602081101561007957600080fd5b8101908080359060200190929190505050610218565b60405180827dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b3480156100f357600080fd5b506100fc61026c565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561013f578082015181840152602081019050610124565b505050509050019250505060405180910390f35b34801561015f57600080fd5b506102166004803603602081101561017657600080fd5b810190808035906020019064010000000081111561019357600080fd5b8201836020820111156101a557600080fd5b803590602001918460208302840111640100000000831117156101c757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050610326565b005b60008181548110151561022757fe5b9060005260206000209060109182820401919006600202915054906101000a90047e010000000000000000000000000000000000000000000000000000000000000281565b6060600080548060200260200160405190810160405280929190818152602001828054801561031c57602002820191906000526020600020906000905b82829054906101000a90047e01000000000000000000000000000000000000000000000000000000000000027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600201906020826001010492830192600103820291508084116102a95790505b5050505050905090565b806000908051906020019061033c929190610340565b5050565b82805482825590600052602060002090600f016010900481019282156103f75791602002820160005b838211156103c757835183826101000a81548161ffff02191690837e01000000000000000000000000000000000000000000000000000000000000900402179055509260200192600201602081600101049283019260010302610369565b80156103f55782816101000a81549061ffff02191690556002016020816001010492830192600103026103c7565b505b5090506104049190610408565b5090565b61043691905b8082111561043257600081816101000a81549061ffff02191690555060010161040e565b5090565b9056fea165627a7a72305820a8f9f1f4815c1eedfb8df31298a5cd13b198895de878871328b5d96296b69b4e0029"
abi = '''
[
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "bytes2Value",
"outputs": [
{
"name": "",
"type": "bytes2"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getBytes2Value",
"outputs": [
{
"name": "",
"type": "bytes2[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_bytes2Value",
"type": "bytes2[]"
}
],
"name": "setBytes2Value",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"name": "_bytes2Value",
"type": "bytes2[]"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
}
]
'''.strip()

.. code-block::
Expand All @@ -614,72 +676,12 @@ For example, the following contract code will generate the abi below and some by
... # }
... # }
.. doctest::
>>> abi = '''
... [
... {
... "constant": true,
... "inputs": [
... {
... "name": "",
... "type": "uint256"
... }
... ],
... "name": "bytes2Value",
... "outputs": [
... {
... "name": "",
... "type": "bytes2"
... }
... ],
... "payable": false,
... "stateMutability": "view",
... "type": "function"
... },
... {
... "constant": true,
... "inputs": [],
... "name": "getBytes2Value",
... "outputs": [
... {
... "name": "",
... "type": "bytes2[]"
... }
... ],
... "payable": false,
... "stateMutability": "view",
... "type": "function"
... },
... {
... "constant": false,
... "inputs": [
... {
... "name": "_bytes2Value",
... "type": "bytes2[]"
... }
... ],
... "name": "setBytes2Value",
... "outputs": [],
... "payable": false,
... "stateMutability": "nonpayable",
... "type": "function"
... },
... {
... "inputs": [
... {
... "name": "_bytes2Value",
... "type": "bytes2[]"
... }
... ],
... "payable": false,
... "stateMutability": "nonpayable",
... "type": "constructor"
... }
... ]
... '''.strip()
>>> # abi = "..."
>>> # bytecode = "6080..."
.. doctest::

>>> ArraysContract = w3.eth.contract(abi=abi, bytecode=bytecode)

>>> tx_hash = ArraysContract.constructor([b'b']).transact()
Expand Down
36 changes: 18 additions & 18 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -202,19 +202,19 @@ Given the following solidity source file stored at ``contract.sol``.
.. code-block:: javascript
contract StoreVar {
uint8 public _myVar;
event MyEvent(uint indexed _var);
function setVar(uint8 _var) public {
_myVar = _var;
MyEvent(_var);
}
function getVar() public view returns (uint8) {
return _myVar;
}
}
The following example demonstrates a few things:
Expand All @@ -229,45 +229,45 @@ The following example demonstrates a few things:
import sys
import time
import pprint
from web3.providers.eth_tester import EthereumTesterProvider
from web3 import Web3
from solc import compile_source
def compile_source_file(file_path):
with open(file_path, 'r') as f:
source = f.read()
return compile_source(source)
def deploy_contract(w3, contract_interface):
tx_hash = w3.eth.contract(
abi=contract_interface['abi'],
bytecode=contract_interface['bin']).deploy()
address = w3.eth.getTransactionReceipt(tx_hash)['contractAddress']
return address
w3 = Web3(EthereumTesterProvider())
contract_source_path = 'contract.sol'
compiled_sol = compile_source_file('contract.sol')
contract_id, contract_interface = compiled_sol.popitem()
address = deploy_contract(w3, contract_interface)
print("Deployed {0} to: {1}\n".format(contract_id, address))
store_var_contract = w3.eth.contract(
address=address,
abi=contract_interface['abi'])
gas_estimate = store_var_contract.functions.setVar(255).estimateGas()
print("Gas estimate to transact with setVar: {0}\n".format(gas_estimate))
if gas_estimate < 100000:
print("Sending transaction to setVar(255)\n")
tx_hash = store_var_contract.functions.setVar(255).transact()
Expand Down
32 changes: 32 additions & 0 deletions docs/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,38 @@ Cryptographic Hashing
>>> Web3.soliditySha3(['address'], ["ethereumfoundation.eth"])
HexBytes("0x913c99ea930c78868f1535d34cd705ab85929b2eaaf70fcd09677ecd6e5d75e9")
Check Encodability
~~~~~~~~~~~~~~~~~~~~

.. py:method:: w3.is_encodable(_type, value)
Returns ``True`` if a value can be encoded as the given type. Otherwise returns ``False``.

.. code-block:: python
>>> from web3.auto.gethdev import w3
>>> w3.is_encodable('bytes2', b'12')
True
>>> w3.is_encodable('bytes2', b'1')
True
>>> w3.is_encodable('bytes2', '0x1234')
True
>>> w3.is_encodable('bytes2', b'123')
False
.. py:method:: w3.enable_strict_bytes_type_checking()
Enables stricter bytes type checking. For more examples see :ref:`enable-strict-byte-check`

.. doctest::

>>> from web3.auto.gethdev import w3
>>> w3.enable_strict_bytes_type_checking()
>>> w3.is_encodable('bytes2', b'12')
True
>>> w3.is_encodable('bytes2', b'1')
False

Modules
-------

Expand Down
26 changes: 13 additions & 13 deletions tests/core/contracts/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,11 @@ def WithConstructorArgumentsContract(web3,


@pytest.fixture()
def WithConstructorArgumentsContractStrict(web3_strict_types,
def WithConstructorArgumentsContractStrict(w3_strict_abi,
WITH_CONSTRUCTOR_ARGUMENTS_CODE,
WITH_CONSTRUCTOR_ARGUMENTS_RUNTIME,
WITH_CONSTRUCTOR_ARGUMENTS_ABI):
return web3_strict_types.eth.contract(
return w3_strict_abi.eth.contract(
abi=WITH_CONSTRUCTOR_ARGUMENTS_ABI,
bytecode=WITH_CONSTRUCTOR_ARGUMENTS_CODE,
bytecode_runtime=WITH_CONSTRUCTOR_ARGUMENTS_RUNTIME,
Expand Down Expand Up @@ -402,27 +402,27 @@ def EMITTER(EMITTER_CODE,


@pytest.fixture()
def StrictEmitter(web3_strict_types, EMITTER):
web3 = web3_strict_types
return web3.eth.contract(**EMITTER)
def StrictEmitter(w3_strict_abi, EMITTER):
w3 = w3_strict_abi
return w3.eth.contract(**EMITTER)


@pytest.fixture()
def strict_emitter(web3_strict_types,
def strict_emitter(w3_strict_abi,
StrictEmitter,
wait_for_transaction,
wait_for_block,
address_conversion_func):
web3 = web3_strict_types
w3 = w3_strict_abi

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

bytecode = web3.eth.getCode(contract_address)
bytecode = w3.eth.getCode(contract_address)
assert bytecode == StrictEmitter.bytecode_runtime
emitter_contract = StrictEmitter(address=contract_address)
assert emitter_contract.address == contract_address
Expand Down Expand Up @@ -625,8 +625,8 @@ def ArraysContract(web3, ARRAYS_CONTRACT):


@pytest.fixture()
def StrictArraysContract(web3_strict_types, ARRAYS_CONTRACT):
return web3_strict_types.eth.contract(**ARRAYS_CONTRACT)
def StrictArraysContract(w3_strict_abi, ARRAYS_CONTRACT):
return w3_strict_abi.eth.contract(**ARRAYS_CONTRACT)


CONTRACT_PAYABLE_TESTER_SOURCE = """
Expand Down
4 changes: 2 additions & 2 deletions tests/core/contracts/test_contract_call_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ def arrays_contract(web3, ArraysContract, address_conversion_func):


@pytest.fixture()
def strict_arrays_contract(web3_strict_types, StrictArraysContract, address_conversion_func):
def strict_arrays_contract(w3_strict_abi, StrictArraysContract, 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_strict_types,
w3_strict_abi,
StrictArraysContract,
address_conversion_func,
args=[bytes32_array, byte_arr]
Expand Down
Loading

0 comments on commit 6d323e4

Please sign in to comment.