mirror of
https://github.com/FlipsideCrypto/web3.py.git
synced 2026-02-06 10:56:47 +00:00
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:
commit
d797a5769e
1
setup.py
1
setup.py
@ -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",
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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()
|
||||
@ -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,
|
||||
)
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
import codecs
|
||||
|
||||
from web3.utils.string import (
|
||||
from eth_utils import (
|
||||
force_bytes,
|
||||
force_text,
|
||||
)
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
|
||||
from web3.utils.abi import (
|
||||
from eth_utils import (
|
||||
function_abi_to_4byte_selector,
|
||||
)
|
||||
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from web3.utils.address import (
|
||||
from eth_utils import (
|
||||
is_address,
|
||||
)
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from web3.utils.types import (
|
||||
from eth_utils import (
|
||||
is_integer,
|
||||
)
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
|
||||
from web3.utils.string import (
|
||||
from eth_utils import (
|
||||
force_bytes,
|
||||
)
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
|
||||
from web3.utils.encoding import is_string
|
||||
from eth_utils import is_string
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import pytest
|
||||
|
||||
from web3.utils.string import force_bytes
|
||||
from eth_utils import (
|
||||
force_bytes,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
|
||||
from web3.utils.string import force_bytes
|
||||
from eth_utils import force_bytes
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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
|
||||
@ -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()
|
||||
|
||||
@ -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,
|
||||
)
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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,
|
||||
)
|
||||
|
||||
@ -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)
|
||||
@ -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",
|
||||
[
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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)
|
||||
|
||||
|
||||
19
web3/eth.py
19
web3/eth.py
@ -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):
|
||||
|
||||
@ -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()
|
||||
}
|
||||
|
||||
15
web3/iban.py
15
web3/iban.py
@ -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
|
||||
|
||||
31
web3/main.py
31
web3/main.py
@ -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):
|
||||
|
||||
@ -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,
|
||||
)
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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))
|
||||
@ -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):
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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'
|
||||
@ -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)
|
||||
@ -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):
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
@ -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)
|
||||
Loading…
Reference in New Issue
Block a user