Merge pull request #158 from pipermerriam/piper/switch-to-use-ethereum-utils-library

Switch to use new ethereum-utils library
This commit is contained in:
Piper Merriam 2017-02-15 12:23:45 -07:00 committed by GitHub
commit d797a5769e
62 changed files with 271 additions and 1425 deletions

View File

@ -25,6 +25,7 @@ setup(
include_package_data=True,
install_requires=[
"ethereum-abi-utils>=0.3.1",
"ethereum-utils>=0.2.0",
"pylru>=1.0.9",
"pysha3>=0.3",
"requests>=2.12.4",

View File

@ -1,8 +1,10 @@
import pytest
from web3.utils.compat import subprocess
from eth_utils import (
force_text,
)
from web3.utils.string import force_text
from web3.utils.compat import subprocess
def test_admin_setSolc(web3, skip_if_testrpc):

View File

@ -1,56 +0,0 @@
import pytest
from flaky import flaky
from web3.utils.compat import socket
def get_open_port():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 0))
s.listen(1)
port = s.getsockname()[1]
s.close()
return port
@flaky(max_runs=3)
def test_admin_startRPC(web3_ipc_empty, skip_if_testrpc):
web3 = web3_ipc_empty
skip_if_testrpc(web3)
with pytest.raises(ValueError):
web3.admin.startRPC()
assert web3.admin.stopRPC()
assert web3.admin.startRPC(port=get_open_port())
@flaky(max_runs=3)
def test_admin_stopRPC(web3_ipc_empty, skip_if_testrpc):
web3 = web3_ipc_empty
skip_if_testrpc(web3)
assert web3.admin.stopRPC()
with pytest.raises(ValueError):
web3.admin.stopRPC()
@flaky(max_runs=3)
def test_admin_startWS(web3_ipc_empty, skip_if_testrpc):
web3 = web3_ipc_empty
skip_if_testrpc(web3)
with pytest.raises(ValueError):
web3.admin.startWS()
assert web3.admin.stopWS()
assert web3.admin.startWS(port=get_open_port())
@flaky(max_runs=3)
def test_admin_stopWS(web3_ipc_empty, skip_if_testrpc):
web3 = web3_ipc_empty
skip_if_testrpc(web3)
assert web3.admin.stopWS()
with pytest.raises(ValueError):
web3.admin.stopWS()

View File

@ -6,15 +6,18 @@ from hypothesis import (
import random
from web3.utils.functional import (
cast_return_to_dict,
from eth_utils import (
force_bytes,
force_text,
to_dict,
)
from web3.utils.caching import (
generate_cache_key,
)
@cast_return_to_dict
@to_dict
def shuffle_dict(_dict):
keys = list(_dict.keys())
random.shuffle(keys)
@ -22,14 +25,17 @@ def shuffle_dict(_dict):
yield key, _dict[key]
encodable_text = st.text().map(lambda v: force_text(force_bytes(v, 'utf8')))
def extend_fn(children):
lists_st = st.lists(children)
dicts_st = st.dictionaries(st.text(), children)
dicts_st = st.dictionaries(encodable_text, children)
return lists_st | dicts_st
all_st = st.recursive(
st.none() | st.integers() | st.booleans() | st.floats() | st.text() | st.binary(),
st.none() | st.integers() | st.booleans() | st.floats() | encodable_text | st.binary(),
extend_fn,
)

View File

@ -2,7 +2,8 @@ import pytest
import json
import textwrap
from web3.utils.abi import (
from eth_utils import (
encode_hex,
event_signature_to_log_topic,
)
@ -430,21 +431,21 @@ def emitter_event_ids():
class LogTopics(object):
LogAnonymous = event_signature_to_log_topic("LogAnonymous()")
LogNoArguments = event_signature_to_log_topic("LogNoArguments()")
LogSingleArg = event_signature_to_log_topic("LogSingleArg(uint256)")
LogSingleAnonymous = event_signature_to_log_topic("LogSingleAnonymous(uint256)")
LogSingleWithIndex = event_signature_to_log_topic("LogSingleWithIndex(uint256)")
LogDoubleArg = event_signature_to_log_topic("LogDoubleArg(uint256,uint256)")
LogDoubleAnonymous = event_signature_to_log_topic("LogDoubleAnonymous(uint256,uint256)")
LogDoubleWithIndex = event_signature_to_log_topic("LogDoubleWithIndex(uint256,uint256)")
LogTripleArg = event_signature_to_log_topic("LogTripleArg(uint256,uint256,uint256)")
LogTripleWithIndex = event_signature_to_log_topic("LogTripleWithIndex(uint256,uint256,uint256)")
LogQuadrupleArg = event_signature_to_log_topic("LogQuadrupleArg(uint256,uint256,uint256,uint256)")
LogQuadrupleWithIndex = event_signature_to_log_topic("LogQuadrupleWithIndex(uint256,uint256,uint256,uint256)")
LogBytes = event_signature_to_log_topic("LogBytes(bytes)")
LogString = event_signature_to_log_topic("LogString(string)")
LogDynamicArgs = event_signature_to_log_topic("LogDynamicArgs(string,string)")
LogAnonymous = encode_hex(event_signature_to_log_topic("LogAnonymous()"))
LogNoArguments = encode_hex(event_signature_to_log_topic("LogNoArguments()"))
LogSingleArg = encode_hex(event_signature_to_log_topic("LogSingleArg(uint256)"))
LogSingleAnonymous = encode_hex(event_signature_to_log_topic("LogSingleAnonymous(uint256)"))
LogSingleWithIndex = encode_hex(event_signature_to_log_topic("LogSingleWithIndex(uint256)"))
LogDoubleArg = encode_hex(event_signature_to_log_topic("LogDoubleArg(uint256,uint256)"))
LogDoubleAnonymous = encode_hex(event_signature_to_log_topic("LogDoubleAnonymous(uint256,uint256)"))
LogDoubleWithIndex = encode_hex(event_signature_to_log_topic("LogDoubleWithIndex(uint256,uint256)"))
LogTripleArg = encode_hex(event_signature_to_log_topic("LogTripleArg(uint256,uint256,uint256)"))
LogTripleWithIndex = encode_hex(event_signature_to_log_topic("LogTripleWithIndex(uint256,uint256,uint256)"))
LogQuadrupleArg = encode_hex(event_signature_to_log_topic("LogQuadrupleArg(uint256,uint256,uint256,uint256)"))
LogQuadrupleWithIndex = encode_hex(event_signature_to_log_topic("LogQuadrupleWithIndex(uint256,uint256,uint256,uint256)"))
LogBytes = encode_hex(event_signature_to_log_topic("LogBytes(bytes)"))
LogString = encode_hex(event_signature_to_log_topic("LogString(string)"))
LogDynamicArgs = encode_hex(event_signature_to_log_topic("LogDynamicArgs(string,string)"))
@pytest.fixture()

View File

@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
import pytest
import codecs
from web3.utils.string import (
from eth_utils import (
force_bytes,
force_text,
)

View File

@ -1,12 +1,14 @@
import pytest
from eth_utils import (
encode_hex,
remove_0x_prefix,
)
from eth_abi import (
encode_abi,
)
from web3.utils.encoding import encode_hex
from web3.utils.formatting import remove_0x_prefix
def test_contract_constructor_abi_encoding_with_no_constructor_fn(MathContract, MATH_CODE):
deploy_data = MathContract._encode_constructor_data()

View File

@ -1,4 +1,6 @@
from web3.utils.string import force_bytes
from eth_utils import (
force_bytes,
)
def test_contract_deployment_no_constructor(web3, MathContract,

View File

@ -1,6 +1,6 @@
import pytest
from web3.utils.abi import (
from eth_utils import (
function_abi_to_4byte_selector,
)

View File

@ -2,14 +2,15 @@
import pytest
from web3.utils.transactions import (
wait_for_transaction_receipt,
)
from web3.utils.string import (
from eth_utils import (
force_text,
force_bytes,
)
from web3.utils.transactions import (
wait_for_transaction_receipt,
)
@pytest.fixture()
def math_contract(web3, MathContract):

View File

@ -1,14 +1,13 @@
import pytest
from eth_utils import (
force_text,
decode_hex,
)
from web3.utils.events import (
get_event_data,
)
from web3.utils.string import (
force_text,
)
from web3.utils.encoding import (
decode_hex,
)
@pytest.fixture()

View File

@ -1,4 +1,4 @@
from web3.utils.address import (
from eth_utils import (
is_address,
)

View File

@ -1,4 +1,4 @@
from web3.utils.types import (
from eth_utils import (
is_integer,
)

View File

@ -1,6 +1,6 @@
import pytest
from web3.utils.string import (
from eth_utils import (
force_bytes,
)

View File

@ -1,6 +1,7 @@
import pytest
from web3.utils.abi import (
from eth_utils import (
encode_hex,
function_abi_to_4byte_selector,
)
@ -32,7 +33,7 @@ def math_contract(web3, MATH_ABI, MATH_CODE, MATH_RUNTIME, MATH_SOURCE,
def test_eth_estimateGas(web3, math_contract):
increment_abi = math_contract._find_matching_fn_abi('increment', [])
call_data = function_abi_to_4byte_selector(increment_abi)
call_data = encode_hex(function_abi_to_4byte_selector(increment_abi))
gas_estimate = web3.eth.estimateGas({
'to': math_contract.address,
'from': web3.eth.coinbase,

View File

@ -1,6 +1,6 @@
import pytest
from web3.utils.encoding import is_string
from eth_utils import is_string
@pytest.fixture(autouse=True)

View File

@ -1,6 +1,8 @@
import pytest
from web3.utils.string import force_bytes
from eth_utils import (
force_bytes,
)
@pytest.fixture(autouse=True)

View File

@ -1,7 +1,5 @@
import pytest
from web3.utils.string import force_bytes
@pytest.fixture(autouse=True)
def wait_for_first_block(web3, wait_for_block):

View File

@ -1,7 +1,5 @@
import pytest
from web3.utils.string import force_bytes
@pytest.fixture(autouse=True)
def wait_for_first_block(web3, wait_for_block):

View File

@ -1,6 +1,6 @@
import pytest
from web3.utils.string import force_bytes
from eth_utils import force_bytes
@pytest.fixture(autouse=True)

View File

@ -6,23 +6,15 @@ from bitcoin import encode_pubkey
from ethereum.utils import privtoaddr
from web3.utils.crypto import (
sha3 as _sha3,
)
from web3.utils.string import (
from eth_utils import (
force_bytes,
force_text,
coerce_return_to_bytes,
coerce_return_to_text,
coerce_args_to_bytes,
)
from web3.utils.types import (
keccak,
is_string,
)
from web3.utils.formatting import (
add_0x_prefix,
)
from web3.utils.encoding import (
encode_hex,
decode_hex,
)
@ -30,7 +22,7 @@ from web3.utils.encoding import (
@coerce_return_to_bytes
def sha3(s):
return add_0x_prefix(_sha3(s))
return encode_hex(keccak(s))
assert sha3(b'') == b'0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'

View File

@ -2,7 +2,8 @@ import pytest
import json
import textwrap
from web3.utils.abi import (
from eth_utils import (
encode_hex,
event_signature_to_log_topic,
)
@ -168,20 +169,20 @@ def emitter_event_ids():
class LogTopics(object):
LogAnonymous = event_signature_to_log_topic("LogAnonymous()")
LogNoArguments = event_signature_to_log_topic("LogNoArguments()")
LogSingleArg = event_signature_to_log_topic("LogSingleArg(uint256)")
LogSingleAnonymous = event_signature_to_log_topic("LogSingleAnonymous(uint256)")
LogSingleWithIndex = event_signature_to_log_topic("LogSingleWithIndex(uint256)")
LogDoubleArg = event_signature_to_log_topic("LogDoubleArg(uint256,uint256)")
LogDoubleAnonymous = event_signature_to_log_topic("LogDoubleAnonymous(uint256,uint256)")
LogDoubleWithIndex = event_signature_to_log_topic("LogDoubleWithIndex(uint256,uint256)")
LogTripleArg = event_signature_to_log_topic("LogTripleArg(uint256,uint256,uint256)")
LogTripleWithIndex = event_signature_to_log_topic("LogTripleWithIndex(uint256,uint256,uint256)")
LogQuadrupleArg = event_signature_to_log_topic("LogQuadrupleArg(uint256,uint256,uint256,uint256)")
LogQuadrupleWithIndex = event_signature_to_log_topic("LogQuadrupleWithIndex(uint256,uint256,uint256,uint256)")
LogBytes = event_signature_to_log_topic("LogBytes(bytes)")
LogString = event_signature_to_log_topic("LogString(string)")
LogAnonymous = encode_hex(event_signature_to_log_topic("LogAnonymous()"))
LogNoArguments = encode_hex(event_signature_to_log_topic("LogNoArguments()"))
LogSingleArg = encode_hex(event_signature_to_log_topic("LogSingleArg(uint256)"))
LogSingleAnonymous = encode_hex(event_signature_to_log_topic("LogSingleAnonymous(uint256)"))
LogSingleWithIndex = encode_hex(event_signature_to_log_topic("LogSingleWithIndex(uint256)"))
LogDoubleArg = encode_hex(event_signature_to_log_topic("LogDoubleArg(uint256,uint256)"))
LogDoubleAnonymous = encode_hex(event_signature_to_log_topic("LogDoubleAnonymous(uint256,uint256)"))
LogDoubleWithIndex = encode_hex(event_signature_to_log_topic("LogDoubleWithIndex(uint256,uint256)"))
LogTripleArg = encode_hex(event_signature_to_log_topic("LogTripleArg(uint256,uint256,uint256)"))
LogTripleWithIndex = encode_hex(event_signature_to_log_topic("LogTripleWithIndex(uint256,uint256,uint256)"))
LogQuadrupleArg = encode_hex(event_signature_to_log_topic("LogQuadrupleArg(uint256,uint256,uint256,uint256)"))
LogQuadrupleWithIndex = encode_hex(event_signature_to_log_topic("LogQuadrupleWithIndex(uint256,uint256,uint256,uint256)"))
LogBytes = encode_hex(event_signature_to_log_topic("LogBytes(bytes)"))
LogString = encode_hex(event_signature_to_log_topic("LogString(string)"))
@pytest.fixture()

View File

@ -1,109 +0,0 @@
import pytest
from web3.providers.manager import (
DelegatedSigningManager,
)
from web3.utils.currency import denoms
from flaky import flaky
@pytest.fixture()
def web3_signer(web3_rpc_empty, wait_for_block):
wait_for_block(web3_rpc_empty)
web3_rpc_empty.miner.stop()
return web3_rpc_empty
@pytest.fixture()
def web3_sender(web3_signer, web3_ipc_empty, wait_for_transaction, wait_for_block):
wait_for_block(web3_ipc_empty)
signer_cb = web3_signer.eth.coinbase
sender_cb = web3_ipc_empty.eth.coinbase
assert signer_cb != sender_cb
# fund the account
fund_txn_hash = web3_ipc_empty.eth.sendTransaction({
'from': sender_cb,
'to': signer_cb,
'value': 10 * denoms.ether,
})
wait_for_transaction(web3_ipc_empty, fund_txn_hash)
with pytest.raises(ValueError):
web3_ipc_empty.eth.sendTransaction({
'from': signer_cb,
'to': sender_cb,
'value': 0,
})
web3_ipc_empty._requestManager = DelegatedSigningManager(
wrapped_manager=web3_ipc_empty._requestManager,
signature_manager=web3_signer._requestManager,
)
return web3_ipc_empty
@flaky(max_runs=3)
def test_delegated_signing_manager(web3_sender,
web3_signer,
wait_for_transaction):
sender_cb = web3_sender.eth.coinbase
signer_cb = web3_signer.eth.coinbase
assert sender_cb in web3_sender.eth.accounts
assert signer_cb not in web3_sender.eth.accounts
txn_hash = web3_sender.eth.sendTransaction({
'from': signer_cb,
'to': sender_cb,
'value': 12345,
})
txn_receipt = wait_for_transaction(web3_sender, txn_hash)
txn = web3_sender.eth.getTransaction(txn_hash)
assert txn['from'] == signer_cb
assert txn['to'] == sender_cb
assert txn['value'] == 12345
@flaky(max_runs=3)
def test_delegated_signing_manager_tracks_nonces_correctly(web3_sender,
web3_signer,
wait_for_transaction):
sender_cb = web3_sender.eth.coinbase
signer_cb = web3_signer.eth.coinbase
assert sender_cb in web3_sender.eth.accounts
assert signer_cb not in web3_sender.eth.accounts
num_to_send = web3_sender.eth.getBlock('latest')['gasLimit'] // 21000 + 10
all_txn_hashes = []
for i in range(num_to_send):
all_txn_hashes.append(web3_sender.eth.sendTransaction({
'from': signer_cb,
'to': sender_cb,
'value': i,
}))
all_txn_receipts = [
wait_for_transaction(web3_sender, txn_hash)
for txn_hash in all_txn_hashes
]
all_txns = [
web3_sender.eth.getTransaction(txn_hash)
for txn_hash in all_txn_hashes
]
assert all([
idx == txn['nonce']
for idx, txn in enumerate(all_txns)
])
block_numbers = {
txn_receipt['blockNumber'] for txn_receipt in all_txn_receipts
}
assert len(block_numbers) > 1

View File

@ -1,11 +1,14 @@
import pytest
from eth_utils import (
denoms,
to_normalized_address,
decode_hex,
)
from web3.providers.manager import (
PrivateKeySigningManager,
)
from web3.utils.address import to_address
from web3.utils.currency import denoms
from web3.utils.encoding import decode_hex
from testrpc.client.utils import (
mk_random_privkey,
@ -21,7 +24,7 @@ def account_private_key():
@pytest.fixture()
def account_public_key(account_private_key):
from ethereum.utils import privtoaddr
return to_address(encode_address(privtoaddr(account_private_key)))
return to_normalized_address(encode_address(privtoaddr(account_private_key)))
@pytest.fixture()

View File

@ -2,7 +2,10 @@ import random
from flaky import flaky
from web3.utils.encoding import decode_hex
from eth_utils import (
decode_hex,
)
from web3.utils.compat import (
Timeout,
)

View File

@ -4,12 +4,10 @@ from testrpc.client.utils import (
mk_random_privkey,
)
from web3.utils.string import (
from eth_utils import (
force_bytes,
)
from web3.utils.address import (
to_address,
is_same_address,
to_normalized_address,
)
@ -26,7 +24,7 @@ def account_private_key():
@pytest.fixture()
def account_public_key(account_private_key):
from ethereum.utils import privtoaddr
return to_address(privtoaddr(account_private_key))
return to_normalized_address(privtoaddr(account_private_key))
@pytest.fixture()

View File

@ -1,12 +1,10 @@
from testrpc.client.utils import (
encode_32bytes,
from eth_utils import (
is_same_address,
remove_0x_prefix,
)
from web3.utils.address import (
is_same_address,
)
from web3.utils.formatting import (
remove_0x_prefix,
from testrpc.client.utils import (
encode_32bytes,
)

View File

@ -1,186 +0,0 @@
from __future__ import unicode_literals
import pytest
from web3.utils.address import (
is_address,
is_strict_address,
is_checksum_address,
to_checksum_address,
to_address,
is_same_address,
)
@pytest.mark.parametrize(
"value,expected",
[
(lambda : None, False),
("function", False),
({}, False),
("0xc6d9d2cd449a754c494264e1809c50e34d64562b", True),
("c6d9d2cd449a754c494264e1809c50e34d64562b", True),
# malformed
("c6d9d2cd449a754c494264e1809c50e34d64562", False), # too short
("0xc6d9d2cd449a754c494264e1809c50e34d64562", False),
("c6d9d2cd449a754c494264e1809c50e34d64562bb", False), # too long
("0xc6d9d2cd449a754c494264e1809c50e34d64562bb", False),
("c6d9d2cd449a754c494264e1809c50e34d64562x", False), # non-hex-character
("0xc6d9d2cd449a754c494264e1809c50e34d6456x", False),
]
)
def test_is_address(value, expected):
assert is_address(value) == expected
@pytest.mark.parametrize(
"value,expected",
[
('0x52908400098527886E0F7030069857D2E4169EE7', True),
('0x8617E340B3D01FA5F11F306F4090FD50E238070D', True),
('0xde709f2102306220921060314715629080e2fb77', True),
('0x27b1fdb04752bbc536007a920d24acb045561c26', True),
('0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed', True),
('0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359', True),
('0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB', True),
('0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb', True),
('0XD1220A0CF47C7B9BE7A2E6BA89F429762E7B9ADB', False),
('0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb', False)
]
)
def test_is_checksum_address(value, expected):
assert is_checksum_address(value) == expected, (value, to_checksum_address(value))
@pytest.mark.parametrize(
"value,expected",
[
(lambda: None, False),
("function", False),
({}, False),
('0xc6d9d2cd449a754c494264e1809c50e34d64562b', True),
('c6d9d2cd449a754c494264e1809c50e34d64562b', False)
]
)
def test_is_strict_address(value, expected):
assert is_strict_address(value) == expected
@pytest.mark.parametrize(
"value,expected",
(
(
b'\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01',
'0xd3cda913deb6f67967b99d67acdfa1712c293601',
),
(
b'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
),
(
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
),
(
b'0XC6D9D2CD449A754C494264E1809C50E34D64562B',
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
),
(
'0XC6D9D2CD449A754C494264E1809C50E34D64562B',
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
),
(
'c6d9d2cd449a754c494264e1809c50e34d64562b',
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
),
(
'C6D9D2CD449A754C494264E1809C50E34D64562B',
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
),
(
'0x000000000000000000000000c305c901078781c232a2a521c2af7980f8385ee9',
'0xc305c901078781c232a2a521c2af7980f8385ee9',
),
(
b'0x000000000000000000000000c305c901078781c232a2a521c2af7980f8385ee9',
'0xc305c901078781c232a2a521c2af7980f8385ee9',
),
(
'000000000000000000000000c305c901078781c232a2a521c2af7980f8385ee9',
'0xc305c901078781c232a2a521c2af7980f8385ee9',
),
)
)
def test_to_address(value, expected):
assert to_address(value) == expected
@pytest.mark.parametrize(
"value,expected",
(
(
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
'0xc6d9d2cD449A754c494264e1809c50e34D64562b',
),
(
'c6d9d2cd449a754c494264e1809c50e34d64562b',
'0xc6d9d2cD449A754c494264e1809c50e34D64562b',
),
)
)
def test_to_checksum_address(value, expected):
assert to_checksum_address(value) == expected, (to_checksum_address(value), expected)
@pytest.mark.parametrize(
"address1,address2,expected",
(
(
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
'0xc6d9d2cD449A754c494264e1809c50e34D64562b',
True,
),
(
'c6d9d2cd449a754c494264e1809c50e34d64562b',
'0xc6d9d2cD449A754c494264e1809c50e34D64562b',
True,
),
(
b'\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01',
'0xd3cda913deb6f67967b99d67acdfa1712c293601',
True,
),
(
b'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
True,
),
(
b'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
'0xc305c901078781c232a2a521c2af7980f8385ee9',
False,
),
(
'c6d9d2cd449a754c494264e1809c50e34d64562b',
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
True,
),
(
'C6D9D2CD449A754C494264E1809C50E34D64562B',
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
True,
),
(
'0x000000000000000000000000c305c901078781c232a2a521c2af7980f8385ee9',
'0xc305c901078781c232a2a521c2af7980f8385ee9',
True,
),
(
b'0x000000000000000000000000c305c901078781c232a2a521c2af7980f8385ee9',
'0xc6d9d2cd449a754c494264e1809c50e34d64562b',
False,
),
)
)
def test_is_same_address(address1, address2, expected):
assert is_same_address(address1, address2) == expected

View File

@ -1,8 +1,9 @@
import pytest
from web3.utils.abi import (
from eth_utils import (
event_abi_to_log_topic,
)
from web3.utils.filters import (
construct_event_filter_params,
)

View File

@ -1,89 +0,0 @@
import decimal
import pytest
from hypothesis import (
given,
strategies as st,
)
from web3.utils.currency import (
units,
to_wei,
from_wei,
MIN_WEI,
MAX_WEI,
)
@given(
amount_in_wei=st.integers(min_value=MIN_WEI, max_value=MAX_WEI),
intermediate_unit=st.sampled_from(tuple(units.keys())),
)
def test_conversion_rount_trip(amount_in_wei, intermediate_unit):
intermediate_amount = from_wei(amount_in_wei, intermediate_unit)
result_amount = to_wei(intermediate_amount, intermediate_unit)
assert result_amount == amount_in_wei
@pytest.mark.parametrize(
"value,expected",
[
([1000000000000000000, 'wei'], '1000000000000000000'),
([1000000000000000000, 'kwei'], '1000000000000000'),
([1000000000000000000, 'mwei'], '1000000000000'),
([1000000000000000000, 'gwei'], '1000000000'),
([1000000000000000000, 'szabo'], '1000000'),
([1000000000000000000, 'finney'], '1000'),
([1000000000000000000, 'ether'], '1'),
([1000000000000000000, 'kether'], '0.001'),
([1000000000000000000, 'grand'], '0.001'),
([1000000000000000000, 'mether'], '0.000001'),
([1000000000000000000, 'gether'], '0.000000001'),
([1000000000000000000, 'tether'], '0.000000000001'),
]
)
def test_from_wei(value, expected):
assert from_wei(*value) == decimal.Decimal(expected)
@pytest.mark.parametrize(
"value,expected",
[
([1, 'wei'], '1'),
([1, 'kwei'], '1000'),
([1, 'Kwei'], '1000'),
([1, 'babbage'], '1000'),
([1, 'mwei'], '1000000'),
([1, 'Mwei'], '1000000'),
([1, 'lovelace'], '1000000'),
([1, 'gwei'], '1000000000'),
([1, 'Gwei'], '1000000000'),
([1, 'shannon'], '1000000000'),
([1, 'szabo'], '1000000000000'),
([1, 'finney'], '1000000000000000'),
([1, 'ether'], '1000000000000000000'),
([1, 'kether'], '1000000000000000000000'),
([1, 'grand'], '1000000000000000000000'),
([1, 'mether'], '1000000000000000000000000'),
([1, 'gether'], '1000000000000000000000000000'),
([1, 'tether'], '1000000000000000000000000000000')
]
)
def test_to_wei(value, expected):
assert to_wei(*value) == decimal.Decimal(expected)
@pytest.mark.parametrize(
'value,unit',
(
(1, 'wei1'),
(1, 'not-a-unit'),
(-1, 'ether'),
)
)
def test_invalid_to_wei_values(value, unit):
with pytest.raises(ValueError):
to_wei(value, unit)
with pytest.raises(ValueError):
from_wei(value, unit)

View File

@ -6,35 +6,11 @@ from hypothesis import (
)
from web3.utils.encoding import (
encode_hex,
decode_hex,
from_decimal,
to_decimal,
)
@pytest.mark.parametrize(
"value,expected",
[
('myString', '0x6d79537472696e67'),
('myString\x00', '0x6d79537472696e6700'),
(
b'\xd9e\x11\xbe\xdbj\x81Q\xea\xb5\x9et\xd6l\r\xa7\xdfc\x14c\xb8b\x1ap\x8e@\x93\xe6\xec\xd7P\x8a',
'0xd96511bedb6a8151eab59e74d66c0da7df631463b8621a708e4093e6ecd7508a',
)
]
)
def test_encode_hex(value, expected):
assert encode_hex(value) == expected
@given(value=st.binary(min_size=0, average_size=32, max_size=256))
def test_hex_encode_decode_round_trip(value):
intermediate_value = encode_hex(value)
result_value = decode_hex(intermediate_value)
assert result_value == value, "Expected: {0!r}, Result: {1!r}, Intermediate: {2!r}".format(value, result_value, intermediate_value)
@pytest.mark.parametrize(
"value,expected",
[

View File

@ -1,20 +0,0 @@
from web3.utils.functional import compose
def test_composition_no_functions():
fn = compose()
assert fn(5) == 5
def test_composition_single_function():
def fn(x):
return x * 2
assert compose(fn)(5) == 10
def test_composition_multiple_function():
def fn(x):
return x + 1
assert compose(fn, fn, fn)(5) == 8

View File

@ -1,43 +0,0 @@
from __future__ import unicode_literals
import pytest
@pytest.mark.parametrize(
'value,expected,encoding',
(
(
'',
'0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470',
None,
),
(
'test123',
'0xf81b517a242b218999ec8eec0ea6e2ddbef2a367a14e93f4a32a39e260f686ad',
None,
),
(
'test(int)',
'0xf4d03772bec1e62fbe8c5691e1a9101e520e8f8b5ca612123694632bf3cb51b1',
None,
),
(
'0x80',
'0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
'hex',
),
(
'0x80',
'0x6b03a5eef7706e3fb52a61c19ab1122fad7237726601ac665bd4def888f0e4a0',
None,
),
(
'0x3c9229289a6125f7fdf1885a77bb12c37a8d3b4962d936f7e3084dece32a3ca1',
'0x82ff40c0a986c6a5cfad4ddf4c3aa6996f1a7837f9c398e17e5de5cbd5a12b28',
'hex',
)
)
)
def test_sha3(web3, value, expected, encoding):
actual = web3.sha3(value, encoding=encoding)
assert expected == actual

View File

@ -2,13 +2,12 @@ import pytest
import rlp
from web3.utils.address import (
to_address,
)
from web3.utils.encoding import (
from eth_utils import (
encode_hex,
decode_hex,
is_same_address,
)
from web3.utils.transactions import (
Transaction,
UnsignedTransaction,
@ -35,7 +34,7 @@ def test_transaction_serialization():
serialized_txn = serialize_transaction(transaction)
unserialized_txn = rlp.decode(serialized_txn, UnsignedTransaction)
assert to_address(unserialized_txn.to) == transaction['to']
assert is_same_address(unserialized_txn.to, transaction['to'])
assert unserialized_txn.startgas == int(transaction['gas'], 16)
assert unserialized_txn.gasprice == int(transaction['gasPrice'], 16)
assert unserialized_txn.nonce == int(transaction['nonce'], 16)
@ -65,7 +64,7 @@ def test_adding_signature_to_transaction(wait_for_first_block,
decode_hex(signature_hex),
)
assert to_address(signed_transaction.to) == transaction['to']
assert is_same_address(signed_transaction.to, transaction['to'])
assert signed_transaction.startgas == int(transaction['gas'], 16)
assert signed_transaction.gasprice == int(transaction['gasPrice'], 16)
assert signed_transaction.nonce == int(transaction['nonce'], 16)

View File

@ -1,89 +0,0 @@
import pytest
from web3.utils.types import (
is_integer,
is_boolean,
is_string,
is_array,
is_object,
)
@pytest.mark.parametrize(
"value,expected",
[
(3, True),
(None, False),
("3", False),
("0x3", False),
(True, False),
(False, False),
]
)
def test_is_integer(value, expected):
assert is_integer(value) == expected
@pytest.mark.parametrize(
"value,expected",
[
("3", True),
(None, False),
(3, False),
({}, False),
]
)
def test_is_string(value, expected):
assert is_string(value) == expected
@pytest.mark.parametrize(
"value,expected",
[
(lambda : None, False),
(3, False),
(None, False),
("3", False),
("0x3", False),
({}, True),
({"test": 3}, True),
]
)
def test_is_object(value, expected):
assert is_object(value) == expected
@pytest.mark.parametrize(
"value,expected",
[
(lambda : None, False),
(3, False),
(None, False),
("3", False),
("0x3", False),
(True, True),
(False, True),
]
)
def test_is_boolean(value, expected):
assert is_boolean(value) == expected
@pytest.mark.parametrize(
"value,expected",
[
(lambda : None, False),
(3, False),
(None, False),
("3", False),
("0x3", False),
([], True),
([3], True),
([3, 3], True),
([None], True),
([tuple()], True),
([(1, 2)], True),
]
)
def test_is_array(value, expected):
assert is_array(value) == expected

View File

@ -1,33 +0,0 @@
# -*- coding: utf-8 -*-
import pytest
from web3.utils.formatting import (
pad_left,
pad_right,
)
@pytest.mark.parametrize(
"value,expected",
[
(["test", 3, ""], "test"),
(["test", 5, ""], "test"),
(["test", 8, ""], "test"),
(["test", 8, "0"], "0000test"),
]
)
def test_padLeft(value, expected):
assert pad_left(*value) == expected
@pytest.mark.parametrize(
"value,expected",
[
(["test", 3, ""], "test"),
(["test", 5, ""], "test"),
(["test", 8, ""], "test"),
(["test", 8, "0"], "test0000"),
]
)
def test_padRight(value, expected):
assert pad_right(*value) == expected

View File

@ -5,6 +5,19 @@ import functools
import warnings
import itertools
from eth_utils import (
is_address,
function_abi_to_4byte_selector,
encode_hex,
add_0x_prefix,
remove_0x_prefix,
compose,
force_bytes,
coerce_return_to_text,
force_obj_to_bytes,
is_list_like,
)
from eth_abi import (
encode_abi,
decode_abi,
@ -18,9 +31,6 @@ from web3.exceptions import (
BadFunctionCallOutput,
)
from web3.utils.address import (
is_address,
)
from web3.utils.abi import (
filter_by_type,
filter_by_name,
@ -30,7 +40,6 @@ from web3.utils.abi import (
get_abi_input_types,
get_abi_output_types,
get_constructor_abi,
function_abi_to_4byte_selector,
merge_args_and_kwargs,
normalize_return_type,
check_if_arguments_can_be_encoded,
@ -41,9 +50,6 @@ from web3.utils.decorators import (
from web3.utils.empty import (
empty,
)
from web3.utils.encoding import (
encode_hex,
)
from web3.utils.events import (
get_event_data,
)
@ -54,21 +60,6 @@ from web3.utils.filters import (
construct_event_filter_params,
PastLogFilter,
)
from web3.utils.formatting import (
add_0x_prefix,
remove_0x_prefix,
)
from web3.utils.functional import (
compose,
)
from web3.utils.string import (
force_bytes,
coerce_return_to_text,
force_obj_to_bytes,
)
from web3.utils.types import (
is_array,
)
DEPRECATED_SIGNATURE_MESSAGE = (
@ -143,7 +134,7 @@ class Contract(object):
itertools.repeat(empty, 5),
))[:5]
if is_array(arg_0):
if is_list_like(arg_0):
if abi:
raise TypeError("The 'abi' argument was found twice")
abi = arg_0
@ -650,7 +641,7 @@ class Contract(object):
kwargs = {}
fn_abi = cls._find_matching_fn_abi(fn_name, args, kwargs)
fn_selector = function_abi_to_4byte_selector(fn_abi)
fn_selector = encode_hex(function_abi_to_4byte_selector(fn_abi))
fn_arguments = merge_args_and_kwargs(fn_abi, args, kwargs)

View File

@ -1,3 +1,11 @@
from eth_utils import (
is_address,
is_integer,
is_string,
encode_hex,
coerce_return_to_text,
)
from web3 import formatters
from web3.iban import Iban
@ -8,12 +16,8 @@ from web3.contract import (
from web3.utils.blocks import (
is_predefined_block_number,
)
from web3.utils.address import (
is_address,
)
from web3.utils.encoding import (
to_decimal,
encode_hex,
)
from web3.utils.filters import (
BlockFilter,
@ -23,16 +27,9 @@ from web3.utils.filters import (
from web3.utils.functional import (
apply_formatters_to_return,
)
from web3.utils.string import (
coerce_return_to_text,
)
from web3.utils.transactions import (
get_buffered_gas_estimate,
)
from web3.utils.types import (
is_integer,
is_string,
)
class Eth(object):

View File

@ -3,43 +3,38 @@ from __future__ import absolute_import
import functools
import operator
from web3.iban import Iban
from web3.utils.string import (
from eth_utils import (
coerce_args_to_text,
coerce_return_to_text,
)
from web3.utils.address import (
is_address,
is_strict_address,
to_address,
)
from web3.utils.types import (
is_array,
is_string,
is_integer,
is_null,
is_object,
)
from web3.utils.formatting import (
is_dict,
is_0x_prefixed,
add_0x_prefix,
)
from web3.utils.encoding import (
encode_hex,
decode_hex,
compose,
is_list_like,
to_normalized_address,
)
from web3.iban import Iban
from web3.utils.encoding import (
from_decimal,
to_decimal,
)
from web3.utils.functional import (
identity,
compose,
)
from web3.utils.blocks import (
is_predefined_block_number,
)
def noop(value):
return value
def apply_if_passes_test(test_fn):
"""
Constructs a decorator that will cause the underlying function to only be
@ -57,8 +52,8 @@ def apply_if_passes_test(test_fn):
apply_if_not_null = apply_if_passes_test(compose(is_null, operator.not_))
apply_if_string = apply_if_passes_test(is_string)
apply_if_array = apply_if_passes_test(is_array)
apply_if_object = apply_if_passes_test(is_object)
apply_if_array = apply_if_passes_test(is_list_like)
apply_if_dict = apply_if_passes_test(is_dict)
apply_if_integer = apply_if_passes_test(is_integer)
@ -89,7 +84,7 @@ def input_filter_params_formatter(filter_params):
}
return {
key: formatters.get(key, identity)(value)
key: formatters.get(key, noop)(value)
for key, value in filter_params.items()
}
@ -109,7 +104,7 @@ def input_transaction_formatter(eth, txn):
'nonce': from_decimal,
}
return {
key: formatters.get(key, identity)(txn.get(key, defaults.get(key)))
key: formatters.get(key, noop)(txn.get(key, defaults.get(key)))
for key in set(tuple(txn.keys()) + tuple(defaults.keys()))
}
@ -128,7 +123,7 @@ def output_transaction_formatter(txn):
}
return {
key: formatters.get(key, identity)(value)
key: formatters.get(key, noop)(value)
for key, value in txn.items()
}
@ -142,16 +137,16 @@ def output_log_formatter(log):
'blockNumber': apply_if_not_null(to_decimal),
'transactionIndex': apply_if_not_null(to_decimal),
'logIndex': apply_if_not_null(to_decimal),
'address': to_address,
'address': to_normalized_address,
}
return {
key: formatters.get(key, identity)(value)
key: formatters.get(key, noop)(value)
for key, value in log.items()
}
log_array_formatter = apply_if_not_null(apply_to_array(apply_if_object(
log_array_formatter = apply_if_not_null(apply_to_array(apply_if_dict(
output_log_formatter
)))
@ -172,7 +167,7 @@ def output_transaction_receipt_formatter(receipt):
}
return {
key: formatters.get(key, identity)(value)
key: formatters.get(key, noop)(value)
for key, value in receipt.items()
}
@ -190,13 +185,13 @@ def output_block_formatter(block):
'number': apply_if_not_null(to_decimal),
'difficulty': to_decimal,
'totalDifficulty': to_decimal,
'transactions': apply_if_array(apply_to_array(apply_if_object(
'transactions': apply_if_array(apply_to_array(apply_if_dict(
output_transaction_formatter,
))),
}
return {
key: formatters.get(key, identity)(value)
key: formatters.get(key, noop)(value)
for key, value in block.items()
}
@ -211,7 +206,7 @@ def inputPostFormatter(post):
post["workToProve"] = from_decimal(post.get("workToProve", 0))
post["priority"] = from_decimal(post["priority"])
if not is_array(post.get("topics")):
if not is_list_like(post.get("topics")):
post["topics"] = [post["topics"]] if post.get("topics") else []
post["topics"] = [topic if is_0x_prefixed(topic) else encode_hex(topic)
@ -243,10 +238,8 @@ def input_address_formatter(addr):
iban = Iban(addr)
if iban.isValid() and iban.isDirect():
return add_0x_prefix(iban.address())
elif is_strict_address(addr):
return addr
elif is_address(addr):
return add_0x_prefix(addr)
return to_normalized_address(addr)
raise ValueError("invalid address")
@ -273,7 +266,7 @@ def transaction_pool_content_formatter(value):
def transaction_pool_inspect_formatter(value):
return transaction_pool_formatter(value, identity)
return transaction_pool_formatter(value, noop)
@apply_if_not_null
@ -290,6 +283,6 @@ def syncing_formatter(value):
}
return {
key: formatters.get(key, identity)(value)
key: formatters.get(key, noop)(value)
for key, value in value.items()
}

View File

@ -1,21 +1,18 @@
from __future__ import unicode_literals
import re
import functools
from web3.utils.types import (
from eth_utils import (
is_string,
)
from web3.utils.string import (
coerce_args_to_text,
)
from web3.utils.formatting import (
pad_left,
add_0x_prefix,
)
def pad_left_hex(value, num_bytes):
return pad_left(value, num_bytes * 2)
return pad_left(value, num_bytes * 2, '0')
def iso13616Prepare(iban):
@ -115,9 +112,9 @@ class Iban(object):
@param {String} address
@return {Iban} the IBAN object
"""
asInt = int(address, 16)
base36 = baseN(asInt, 36)
padded = pad_left_hex(base36, 15)
address_as_integer = int(address, 16)
address_as_base36 = baseN(address_as_integer, 36)
padded = pad_left_hex(address_as_base36, 15)
return Iban.fromBban(padded.upper())
@staticmethod

View File

@ -1,5 +1,18 @@
from __future__ import absolute_import
from eth_utils import (
to_wei,
from_wei,
is_address,
is_checksum_address,
to_checksum_address,
decode_hex,
encode_hex,
force_text,
coerce_return_to_text,
compose,
)
from web3.admin import Admin
from web3.db import Db
from web3.eth import Eth
@ -31,29 +44,11 @@ from web3.providers.manager import (
PrivateKeySigningManager,
)
from web3.utils.address import (
is_address,
is_checksum_address,
to_checksum_address,
)
from web3.utils.currency import (
to_wei,
from_wei,
)
from web3.utils.encoding import (
to_hex,
decode_hex,
encode_hex,
to_decimal,
from_decimal,
)
from web3.utils.functional import (
compose,
)
from web3.utils.string import (
force_text,
coerce_return_to_text,
)
class Web3(object):

View File

@ -1,10 +1,9 @@
from __future__ import absolute_import
import getpass
from web3.utils.string import (
from eth_utils import (
coerce_return_to_text,
)
from web3.utils.encoding import (
remove_0x_prefix,
encode_hex,
)

View File

@ -3,7 +3,7 @@ from __future__ import absolute_import
import json
import itertools
from web3.utils.string import (
from eth_utils import (
force_bytes,
force_obj_to_text,
force_text,

View File

@ -10,14 +10,15 @@ try:
except ImportError:
JSONDecodeError = ValueError
from eth_utils import (
force_text,
)
from web3.utils.compat import (
Timeout,
threading,
socket,
)
from web3.utils.string import (
force_text,
)
from .base import JSONBaseProvider

View File

@ -4,17 +4,18 @@ import collections
import rlp
from web3.utils.crypto import sha3
from web3.utils.string import force_text
from web3.utils.address import to_address
from web3.utils.types import (
from eth_utils import (
force_text,
to_normalized_address,
is_string,
is_object,
)
from web3.utils.encoding import (
to_decimal,
is_dict,
encode_hex,
decode_hex,
keccak,
)
from web3.utils.encoding import (
to_decimal,
)
from web3.utils.transactions import (
is_bitcoin_available,
@ -43,7 +44,7 @@ class RequestManager(object):
if is_string(response_raw):
response = json.loads(force_text(response_raw))
elif is_object(response_raw):
elif is_dict(response_raw):
response = response_raw
if "error" in response:
@ -208,13 +209,13 @@ class BaseSendRawTransactionMixin(ManagerWrapper):
if method in self.TXN_SENDING_METHODS:
if method == 'eth_sendRawTransaction':
txn = rlp.decode(decode_hex(params[0]), Transaction)
self._known_transactions[to_address(txn.sender)].add(result)
self._known_nonces[to_address(txn.sender)].add(txn.nonce)
self._known_transactions[to_normalized_address(txn.sender)].add(result)
self._known_nonces[to_normalized_address(txn.sender)].add(txn.nonce)
else:
txn = params[0]
self._known_transactions[to_address(txn['from'])].add(result)
self._known_transactions[to_normalized_address(txn['from'])].add(result)
if 'nonce' in txn:
self._known_nonces[to_address(txn['from'])].add(
self._known_nonces[to_normalized_address(txn['from'])].add(
to_decimal(txn['nonce'])
)
return result
@ -264,11 +265,11 @@ class PrivateKeySigningManager(BaseSendRawTransactionMixin):
def register_private_key(self, key):
from bitcoin import privtopub
address = to_address(sha3(privtopub(key)[1:])[-40:])
address = to_normalized_address(keccak(privtopub(key)[1:])[-20:])
self.keys[address] = key
def sign_and_serialize_transaction(self, transaction):
txn_from = to_address(transaction['from'])
txn_from = to_normalized_address(transaction['from'])
if txn_from not in self.keys:
raise KeyError("No signing key registered for from address: {0}".format(txn_from))
transaction = Transaction(
@ -280,5 +281,5 @@ class PrivateKeySigningManager(BaseSendRawTransactionMixin):
data=decode_hex(transaction['data']),
)
transaction.sign(self.keys[txn_from])
assert to_address(transaction.sender) == txn_from
assert to_normalized_address(transaction.sender) == txn_from
return rlp.encode(transaction, Transaction)

View File

@ -2,6 +2,10 @@ import logging
from .base import JSONBaseProvider # noqa: E402
from eth_utils import (
to_dict,
)
from web3.utils.six import (
urlunparse,
)
@ -9,7 +13,6 @@ from web3.utils.compat import (
make_post_request,
)
from web3.utils.http import construct_user_agent
from web3.utils.functional import cast_return_to_dict
logger = logging.getLogger(__name__)
@ -28,7 +31,7 @@ class HTTPProvider(JSONBaseProvider):
def __str__(self):
return "RPC connection {0}".format(self.endpoint_uri)
@cast_return_to_dict
@to_dict
def get_request_kwargs(self):
if 'headers' not in self._request_kwargs:
yield 'headers', self.get_request_headers()

View File

@ -1,32 +1,23 @@
import itertools
import re
from eth_abi.abi import (
process_type,
)
from .crypto import sha3
from .string import (
from eth_utils import (
coerce_args_to_bytes,
coerce_args_to_text,
coerce_return_to_text,
)
from .functional import (
cast_return_to_tuple,
)
from .formatting import (
to_tuple,
add_0x_prefix,
)
from .types import (
is_array,
is_list_like,
is_string,
is_integer,
is_boolean,
)
from .address import (
is_address,
)
from eth_abi.abi import (
process_type,
)
def filter_by_type(_type, contract_abi):
return [abi for abi in contract_abi if abi['type'] == _type]
@ -82,7 +73,7 @@ def is_encodable(_type, value):
base, sub, arrlist = process_type(_type)
if arrlist:
if not is_array(value):
if not is_list_like(value):
return False
if arrlist[-1] and len(value) != arrlist[-1][0]:
return False
@ -268,7 +259,7 @@ def is_probably_enum(abi_type):
return bool(re.match(ENUM_REGEX, abi_type))
@cast_return_to_tuple
@to_tuple
def normalize_event_input_types(abi_args):
for arg in abi_args:
if is_recognized_type(arg['type']):
@ -289,24 +280,6 @@ def abi_to_signature(abi):
return function_signature
def function_signature_to_4byte_selector(event_signature):
return add_0x_prefix(sha3(event_signature)[:8])
def function_abi_to_4byte_selector(function_abi):
function_signature = abi_to_signature(function_abi)
return function_signature_to_4byte_selector(function_signature)
def event_signature_to_log_topic(event_signature):
return add_0x_prefix(sha3(event_signature))
def event_abi_to_log_topic(event_abi):
event_signature = abi_to_signature(event_abi)
return event_signature_to_log_topic(event_signature)
@coerce_return_to_text
def normalize_return_type(data_type, data_value):
try:

View File

@ -1,122 +0,0 @@
# Address utilities
from __future__ import absolute_import
import re
from .crypto import (
sha3,
)
from .encoding import (
encode_hex,
)
from .string import (
force_text,
coerce_args_to_text,
coerce_return_to_text,
)
from .types import (
is_string,
)
from .formatting import (
add_0x_prefix,
remove_0x_prefix,
is_prefixed,
)
@coerce_args_to_text
def is_address(address):
"""
Checks if the given string is an address
"""
if not is_string(address):
return False
if not re.match(r"^(0x)?[0-9a-fA-F]{40}$", address):
return False
elif re.match(r"^(0x)?[0-9a-f]{40}", address) or re.match(r"(0x)?[0-9A-F]{40}$", address):
return True
else:
return is_checksum_address(address)
@coerce_args_to_text
def is_checksum_address(address):
"""
Checks if the given string is a checksummed address
"""
if not is_string(address):
return False
checksum_address = to_checksum_address(address)
return force_text(address) == force_text(checksum_address)
@coerce_args_to_text
def is_strict_address(address):
"""
Checks if the given string is strictly an address
"""
if not is_string(address):
return False
return re.match(r"^0x[0-9a-fA-F]{40}$", address) is not None
@coerce_args_to_text
@coerce_return_to_text
def to_checksum_address(address):
"""
Makes a checksum address
"""
if not is_string(address):
return False
address = remove_0x_prefix(address.lower())
addressHash = sha3(address)
checksumAddress = "0x"
for i in range(len(address)):
if int(addressHash[i], 16) > 7:
checksumAddress += address[i].upper()
else:
checksumAddress += address[i]
return checksumAddress
@coerce_args_to_text
@coerce_return_to_text
def to_address(address):
"""
Transforms given string to valid 20 bytes-length addres with 0x prefix
"""
if is_string(address):
if len(address) == 42:
return address.lower()
elif len(address) == 40:
return add_0x_prefix(address.lower())
elif len(address) == 20:
return encode_hex(address)
elif len(address) in {66, 64}:
long_address = remove_0x_prefix(address.lower())
if is_prefixed(long_address, '000000000000000000000000'):
return add_0x_prefix(address[-40:])
raise ValueError("Unknown address format")
@coerce_args_to_text
def is_same_address(addr1, addr2):
"""
Checks if both addresses are same or not
"""
if is_address(addr1) & is_address(addr2):
return to_checksum_address(addr1) == to_checksum_address(addr2)
else:
return to_checksum_address(to_address(addr1)) == to_checksum_address(to_address(addr2))

View File

@ -1,5 +1,7 @@
from .types import is_string
from .string import force_text
from eth_utils import (
is_string,
force_text,
)
def is_predefined_block_number(block_number):

View File

@ -1,17 +1,16 @@
import hashlib
from .types import (
from eth_utils import (
is_boolean,
is_null,
is_object,
is_array,
is_dict,
is_list_like,
is_number,
is_text,
is_bytes,
)
from .string import (
force_bytes,
)
from .six import (
Generator,
)
@ -27,13 +26,13 @@ def generate_cache_key(value):
return generate_cache_key(force_bytes(value))
elif is_boolean(value) or is_null(value) or is_number(value):
return generate_cache_key(repr(value))
elif is_object(value):
elif is_dict(value):
return generate_cache_key((
(key, value[key])
for key
in sorted(value.keys())
))
elif is_array(value) or isinstance(value, Generator):
elif is_list_like(value) or isinstance(value, Generator):
return generate_cache_key("".join((
generate_cache_key(item)
for item

View File

@ -1,26 +0,0 @@
from __future__ import absolute_import
import codecs
try:
from sha3 import keccak_256
except ImportError:
from sha3 import sha3_256 as keccak_256
def sha3(value, encoding=None):
from .formatting import (
remove_0x_prefix,
)
from .string import (
force_bytes,
)
if encoding:
value = codecs.decode(remove_0x_prefix(value), encoding)
return keccak_256(force_bytes(value)).hexdigest()
# ensure we have the *right* sha3 installed
assert sha3('') == 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'

View File

@ -1,84 +0,0 @@
import decimal
# Set the decimal precision
decimal.DefaultContext.prec = 999
units = {
'wei': decimal.Decimal('1'),
'kwei': decimal.Decimal('1000'),
'babbage': decimal.Decimal('1000'),
'femtoether': decimal.Decimal('1000'),
'mwei': decimal.Decimal('1000000'),
'lovelace': decimal.Decimal('1000000'),
'picoether': decimal.Decimal('1000000'),
'gwei': decimal.Decimal('1000000000'),
'shannon': decimal.Decimal('1000000000'),
'nanoether': decimal.Decimal('1000000000'),
'nano': decimal.Decimal('1000000000'),
'szabo': decimal.Decimal('1000000000000'),
'microether': decimal.Decimal('1000000000000'),
'micro': decimal.Decimal('1000000000000'),
'finney': decimal.Decimal('1000000000000000'),
'milliether': decimal.Decimal('1000000000000000'),
'milli': decimal.Decimal('1000000000000000'),
'ether': decimal.Decimal('1000000000000000000'),
'kether': decimal.Decimal('1000000000000000000000'),
'grand': decimal.Decimal('1000000000000000000000'),
'mether': decimal.Decimal('1000000000000000000000000'),
'gether': decimal.Decimal('1000000000000000000000000000'),
'tether': decimal.Decimal('1000000000000000000000000000000'),
}
denoms = type('denoms', (object,), {
key: int(value) for key, value in units.items()
})
MIN_WEI = 0
MAX_WEI = 2 ** 256 - 1
def from_wei(number, unit):
"""
Takes a number of wei and converts it to any other ether unit.
"""
if unit.lower() not in units:
raise ValueError(
"Unknown unit. Must be one of {0}".format('/'.join(units.keys()))
)
if number == 0:
return 0
if number < MIN_WEI or number > MAX_WEI:
raise ValueError("value must be between 1 and 2**256 - 1")
d_number = decimal.Decimal(number)
unit_value = units[unit.lower()]
return d_number / unit_value
def to_wei(number, unit):
"""
Takes a number of a unit and converts it to wei.
"""
if unit.lower() not in units:
raise ValueError(
"Unknown unit. Must be one of {0}".format('/'.join(units.keys()))
)
if number == 0:
return 0
d_number = decimal.Decimal(number)
unit_value = units[unit.lower()]
result_value = d_number * unit_value
if result_value < MIN_WEI or result_value > MAX_WEI:
raise ValueError("Resulting wei value must be between 1 and 2**256 - 1")
return int(result_value)

View File

@ -1,42 +1,22 @@
# String encodings and numeric representations
import json
import codecs
from rlp.sedes import big_endian_int
from .types import (
from eth_utils import (
is_string,
is_boolean,
is_object,
is_dict,
is_integer,
)
from .string import (
coerce_args_to_text,
coerce_args_to_bytes,
coerce_return_to_text,
coerce_return_to_bytes,
)
from .formatting import (
remove_0x_prefix,
add_0x_prefix,
is_prefixed,
is_0x_prefixed,
encode_hex,
)
@coerce_return_to_bytes
def decode_hex(value):
if not is_string(value):
raise TypeError('Value must be an instance of str or unicode')
return codecs.decode(remove_0x_prefix(value), 'hex')
@coerce_args_to_bytes
@coerce_return_to_text
def encode_hex(value):
if not is_string(value):
raise TypeError('Value must be an instance of str or unicode')
return add_0x_prefix(codecs.encode(value, 'hex'))
from .formatting import (
is_prefixed,
)
@coerce_args_to_text
@ -47,7 +27,7 @@ def to_hex(value):
if is_boolean(value):
return "0x1" if value else "0x0"
if is_object(value):
if is_dict(value):
return encode_hex(json.dumps(value, sort_keys=True))
if is_string(value):

View File

@ -1,5 +1,13 @@
import itertools
from eth_utils import (
encode_hex,
to_tuple,
is_list_like,
coerce_return_to_text,
event_abi_to_log_topic,
)
from eth_abi import (
decode_abi,
decode_single,
@ -9,21 +17,10 @@ from eth_abi.abi import (
process_type,
)
from .encoding import encode_hex
from .functional import (
cast_return_to_tuple,
)
from .types import (
is_array,
)
from .string import (
coerce_return_to_text,
)
from .abi import (
get_abi_input_names,
get_indexed_event_inputs,
exclude_indexed_event_inputs,
event_abi_to_log_topic,
normalize_return_type,
normalize_event_input_types,
)
@ -46,11 +43,11 @@ def construct_event_topic_set(event_abi, arguments=None):
}
normalized_args = {
key: value if is_array(value) else [value]
key: value if is_list_like(value) else [value]
for key, value in arguments.items()
}
event_topic = event_abi_to_log_topic(event_abi)
event_topic = encode_hex(event_abi_to_log_topic(event_abi))
indexed_args = get_indexed_event_inputs(event_abi)
zipped_abi_and_args = [
(arg, normalized_args.get(arg['name'], [None]))
@ -89,7 +86,7 @@ def construct_event_data_set(event_abi, arguments=None):
}
normalized_args = {
key: value if is_array(value) else [value]
key: value if is_list_like(value) else [value]
for key, value in arguments.items()
}
@ -125,7 +122,7 @@ def is_dynamic_sized_type(_type):
return False
@cast_return_to_tuple
@to_tuple
def get_event_abi_types_for_decoding(event_inputs):
"""
Event logs use the `sha3(value)` for indexed inputs of type `bytes` or

View File

@ -1,5 +1,6 @@
import sys
# raise MyException() from original_exception compatibility
if sys.version_info.major == 2:
from .exception_py2 import raise_from # noqa: F401

View File

@ -1,10 +1,11 @@
import re
import random
from .types import (
from eth_utils import (
is_string,
is_array,
is_list_like,
)
from .events import (
construct_event_topic_set,
construct_event_data_set,
@ -29,13 +30,13 @@ def construct_event_filter_params(event_abi,
else:
topic_set = [topics] + construct_event_topic_set(event_abi, argument_filters)
if len(topic_set) == 1 and is_array(topic_set[0]):
if len(topic_set) == 1 and is_list_like(topic_set[0]):
filter_params['topics'] = topic_set[0]
else:
filter_params['topics'] = topic_set
if address and contract_address:
if is_array(address):
if is_list_like(address):
filter_params['address'] = address + [contract_address]
elif is_string(address):
filter_params['address'] = [address, contract_address]

View File

@ -1,55 +1,11 @@
from .string import (
from eth_utils import (
force_bytes,
force_text,
)
from .types import (
is_bytes,
)
def pad_left(string, chars, filler="0"):
"""
Should be called to pad string to expected length
"""
numchars = chars - len(string)
head = b"" if is_bytes(string) else ""
filler_value = force_bytes(filler) if is_bytes(string) else force_text(filler)
if numchars > 0:
head = filler_value * numchars
return head + string
def pad_right(string, chars, filler="0"):
"""
Should be called to pad string to expected length
"""
numchars = chars - len(string)
tail = b"" if is_bytes(string) else ""
filler_value = force_bytes(filler) if is_bytes(string) else force_text(filler)
if numchars > 0:
tail = filler_value * numchars
return string + tail
def is_prefixed(value, prefix):
return value.startswith(
force_bytes(prefix) if is_bytes(value) else force_text(prefix)
)
def is_0x_prefixed(value):
return is_prefixed(value, '0x')
def remove_0x_prefix(value):
if is_0x_prefixed(value):
return value[2:]
return value
def add_0x_prefix(value):
if is_0x_prefixed(value):
return value
prefix = b'0x' if is_bytes(value) else '0x'
return prefix + value

View File

@ -1,16 +1,8 @@
import functools
def identity(value):
return value
def combine(f, g):
return lambda x: f(g(x))
def compose(*functions):
return functools.reduce(combine, reversed(functions), identity)
from eth_utils import (
compose,
)
def apply_formatters_to_return(*formatters):
@ -23,17 +15,3 @@ def apply_formatters_to_return(*formatters):
return formatter(value)
return inner
return outer
def cast_return(_type):
def outer(fn):
@functools.wraps(fn)
def inner(*args, **kwargs):
return _type(fn(*args, **kwargs))
return inner
return outer
cast_return_to_tuple = cast_return(tuple)
cast_return_to_dict = cast_return(dict)

View File

@ -1,87 +0,0 @@
import functools
import codecs
from .types import (
is_bytes,
is_text,
is_string,
)
def force_bytes(value):
if is_bytes(value):
return bytes(value)
elif is_text(value):
try:
return codecs.encode(value, "iso-8859-1")
except UnicodeEncodeError:
return codecs.encode(value, "utf8")
else:
raise TypeError("Unsupported type: {0}".format(type(value)))
def force_text(value):
if is_text(value):
return value
elif is_bytes(value):
return codecs.decode(value, "iso-8859-1")
else:
raise TypeError("Unsupported type: {0}".format(type(value)))
def force_obj_to_bytes(obj):
if is_string(obj):
return force_bytes(obj)
elif isinstance(obj, dict):
return {
k: force_obj_to_bytes(v) for k, v in obj.items()
}
elif isinstance(obj, (list, tuple)):
return type(obj)(force_obj_to_bytes(v) for v in obj)
else:
return obj
def force_obj_to_text(obj):
if is_string(obj):
return force_text(obj)
elif isinstance(obj, dict):
return {
k: force_obj_to_text(v) for k, v in obj.items()
}
elif isinstance(obj, (list, tuple)):
return type(obj)(force_obj_to_text(v) for v in obj)
else:
return obj
def coerce_args_to_bytes(fn):
@functools.wraps(fn)
def inner(*args, **kwargs):
bytes_args = force_obj_to_bytes(args)
bytes_kwargs = force_obj_to_bytes(kwargs)
return fn(*bytes_args, **bytes_kwargs)
return inner
def coerce_args_to_text(fn):
@functools.wraps(fn)
def inner(*args, **kwargs):
text_args = force_obj_to_text(args)
text_kwargs = force_obj_to_text(kwargs)
return fn(*text_args, **text_kwargs)
return inner
def coerce_return_to_bytes(fn):
@functools.wraps(fn)
def inner(*args, **kwargs):
return force_obj_to_bytes(fn(*args, **kwargs))
return inner
def coerce_return_to_text(fn):
@functools.wraps(fn)
def inner(*args, **kwargs):
return force_obj_to_text(fn(*args, **kwargs))
return inner

View File

@ -4,26 +4,20 @@ import rlp
from rlp.sedes import big_endian_int, binary, Binary
from rlp.utils import int_to_big_endian
from .encoding import (
to_decimal,
from eth_utils import (
decode_hex,
decode_big_endian_int,
)
from .string import (
force_bytes,
coerce_args_to_bytes,
)
from .types import (
is_string,
)
from .crypto import (
sha3,
)
from .address import (
to_address,
)
from .formatting import (
to_canonical_address,
to_normalized_address,
pad_left,
keccak,
)
from .encoding import (
to_decimal,
decode_big_endian_int,
)
from .compat import (
Timeout,
@ -128,7 +122,7 @@ class Transaction(rlp.Serializable):
def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0, s=0):
self.data = None
to = decode_hex(to_address(to))
to = to_canonical_address(to)
assert len(to) == 20 or len(to) == 0
super(Transaction, self).__init__(nonce, gasprice, startgas, to, value, data, v, r, s)
@ -160,7 +154,7 @@ class Transaction(rlp.Serializable):
if has_invalid_signature_values:
raise ValueError("Invalid signature values!")
rlpdata = rlp.encode(self, UnsignedTransaction)
rawhash = decode_hex(sha3(rlpdata))
rawhash = keccak(rlpdata)
pk = PublicKey(flags=ALL_FLAGS)
try:
@ -187,7 +181,7 @@ class Transaction(rlp.Serializable):
if pub[1:] == b"\x00" * (len(pub) - 1):
raise ValueError("Invalid signature (zero privkey cannot sign)")
self._sender = to_address(sha3(pub[1:])[-40:])
self._sender = to_normalized_address(keccak(pub[1:])[-20:])
assert self.sender == self._sender
else:
self._sender = 0
@ -214,7 +208,7 @@ class Transaction(rlp.Serializable):
if key in (0, b'', b'\x00' * 32, b'0' * 64):
raise ValueError("Zero privkey cannot sign")
rawhash = decode_hex(sha3(rlp.encode(self, UnsignedTransaction)))
rawhash = keccak(rlp.encode(self, UnsignedTransaction))
if len(key) in {64, 66}:
# we need a binary key
@ -229,7 +223,7 @@ class Transaction(rlp.Serializable):
self.r = decode_big_endian_int(signature[0:32])
self.s = decode_big_endian_int(signature[32:64])
self.sender = to_address(sha3(privtopub(key)[1:])[-40:])
self.sender = to_normalized_address(keccak(privtopub(key)[1:])[-20:])
return self

View File

@ -1,51 +0,0 @@
import sys
import numbers
import collections
if sys.version_info.major == 2:
integer_types = (int, long) # noqa: F821
bytes_types = (bytes, bytearray)
text_types = (unicode,) # noqa: F821
string_types = (basestring, bytearray) # noqa: F821
else:
integer_types = (int,)
bytes_types = (bytes, bytearray)
text_types = (str,)
string_types = (bytes, str, bytearray)
def is_integer(value):
return isinstance(value, integer_types) and not isinstance(value, bool)
def is_bytes(value):
return isinstance(value, bytes_types)
def is_text(value):
return isinstance(value, text_types)
def is_string(value):
return isinstance(value, string_types)
def is_boolean(value):
return isinstance(value, bool)
def is_object(obj):
return isinstance(obj, collections.Mapping)
def is_array(obj):
return not is_string(obj) and isinstance(obj, collections.Sequence)
def is_null(obj):
return obj is None
def is_number(obj):
return isinstance(obj, numbers.Number)

View File