diff --git a/.travis.yml b/.travis.yml index df43175c3..c47988be8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ before_install: - if [ -n "$SOLC_VERSION" ]; then sudo apt-get install -y tree unzip; fi install: - if [ -n "$SOLC_VERSION" ]; then /.$TRAVIS_BUILD_DIR/.travis/install_solc.sh; fi - - travis_retry pip install setuptools --upgrade + - travis_retry pip install pip setuptools --upgrade - travis_retry pip install tox - travis_retry pip install coverage - travis_retry pip install flake8 diff --git a/README.md b/README.md index 037bbe8a2..15091d989 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ Contains the Transaction class, with the following methods and values: ### ethereum.tools.keys -Creates encrypted private key storaes +Creates encrypted private key storages * `decode_keystore_json(jsondata, password)` - returns the private key from an encrypted keystore object. NOTE: if you are loading from a file, the most convenient way to do this is `import json; key = decode_keystore_json(json.load(open('filename.json')), 'password')` * `make_keystore_json(key, pw, kdf='pbkdf2', cipher='aes-128-ctr')` - creates an encrypted keystore object for the key. Keeping `kdf` and `cipher` at their default values is recommended. diff --git a/dev_requirements.txt b/dev_requirements.txt index 8bd463833..5d6a78a0d 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -3,4 +3,5 @@ coveralls pytest>=2.9.0 pytest-catchlog==1.2.2 pytest-timeout==1.0.0 +py-ecc https://github.com/ethereum/serpent/tarball/develop diff --git a/ethereum/pow/chain.py b/ethereum/pow/chain.py index 5db89f281..6afb2eb3a 100644 --- a/ethereum/pow/chain.py +++ b/ethereum/pow/chain.py @@ -365,8 +365,8 @@ def add_block(self, block): self.add_child(block) self.db.put('head_hash', self.head_hash) self.db.put(block.hash, rlp.encode(block)) - self.db.put(b'changed:'+block.hash, b''.join(list(changed.keys()))) - log.debug('Saved %d address change logs' % len(changed.keys())) + self.db.put(b'changed:'+block.hash, b''.join([k.encode() if isinstance(k, str) else k for k in list(changed.keys())])) + print('Saved %d address change logs' % len(changed.keys())) self.db.put(b'deletes:'+block.hash, b''.join(deletes)) log.debug('Saved %d trie node deletes for block %d (%s)' % (len(deletes), block.number, utils.encode_hex(block.hash))) # Delete old junk data diff --git a/ethereum/tools/_solidity.py b/ethereum/tools/_solidity.py index 8eb47f055..b1b1d979c 100644 --- a/ethereum/tools/_solidity.py +++ b/ethereum/tools/_solidity.py @@ -165,6 +165,13 @@ def solidity_names(code): # pylint: disable=too-many-branches if result: names.append(('contract', result.groups()[0])) + if char == 'i' and code[pos: pos + 9] == 'interface': + result = re.match('^interface[^_$a-zA-Z]+([_$a-zA-Z][_$a-zA-Z0-9]*)', code[pos:]) + + if result: + names.append(('contract', result.groups()[0])) + + if char == 'l' and code[pos: pos + 7] == 'library': result = re.match('^library[^_$a-zA-Z]+([_$a-zA-Z][_$a-zA-Z0-9]*)', code[pos:]) diff --git a/ethereum/tools/keys.py b/ethereum/tools/keys.py index d9b46232a..e9520c0f5 100644 --- a/ethereum/tools/keys.py +++ b/ethereum/tools/keys.py @@ -1,6 +1,6 @@ import os -import pbkdf2 import sys +from hashlib import pbkdf2_hmac from rlp.utils import decode_hex from ethereum.utils import encode_hex @@ -43,9 +43,8 @@ } PBKDF2_CONSTANTS = { - "prf": "hmac-sha256", "dklen": 32, - "c": 262144 + "rounds": 262144 } @@ -96,9 +95,8 @@ def mk_pbkdf2_params(): def pbkdf2_hash(val, params): - assert params["prf"] == "hmac-sha256" - return pbkdf2.PBKDF2(val, decode_hex(params["salt"]), params["c"], - SHA256).read(params["dklen"]) + return pbkdf2_hmac('sha256', val, decode_hex(params["salt"]), + params["rounds"], params["dklen"]) kdfs = { diff --git a/ethereum/tools/tester.py b/ethereum/tools/tester.py index 8edea6c37..02791a43e 100644 --- a/ethereum/tools/tester.py +++ b/ethereum/tools/tester.py @@ -157,7 +157,7 @@ def __init__(self, alloc=base_alloc, env=None, genesis=None): def direct_tx(self, transaction): self.last_tx = transaction - if self.last_sender and privtoaddr(self.last_sender) != transaction.sender: + if self.last_sender is not None and privtoaddr(self.last_sender) != transaction.sender: self.last_sender = None success, output = apply_transaction(self.head_state, transaction) self.block.transactions.append(transaction) diff --git a/ethereum/utils.py b/ethereum/utils.py index c54e4dd52..e82ab0c53 100644 --- a/ethereum/utils.py +++ b/ethereum/utils.py @@ -13,11 +13,11 @@ try: - import secp256k1 + import coincurve except ImportError: import warnings - warnings.warn('could not import secp256k1', ImportWarning) - secp256k1 = None + warnings.warn('could not import coincurve', ImportWarning) + coincurve = None big_endian_to_int = lambda x: big_endian_int.deserialize(str_to_bytes(x).lstrip(b'\x00')) int_to_big_endian = lambda x: big_endian_int.serialize(x) @@ -85,22 +85,15 @@ def bytes_to_int(value): def ecrecover_to_pub(rawhash, v, r, s): - if secp256k1 and hasattr(secp256k1, "PublicKey"): - # Legendre symbol check; the secp256k1 library does not seem to do this - pk = secp256k1.PublicKey(flags=secp256k1.ALL_FLAGS) - xc = r * r * r + 7 - assert pow(xc, (SECP256K1P - 1) // 2, SECP256K1P) == 1 + if coincurve and hasattr(coincurve, "PublicKey"): try: - pk.public_key = pk.ecdsa_recover( + pk = coincurve.PublicKey.from_signature_and_message( + zpad(utils.bytearray_to_bytestr(int_to_32bytearray(r)), 32) + zpad(utils.bytearray_to_bytestr(int_to_32bytearray(s)), 32) + + utils.ascii_chr(v - 27), rawhash, - pk.ecdsa_recoverable_deserialize( - zpad(bytearray_to_bytestr(int_to_32bytearray(r)), 32) + - zpad(bytearray_to_bytestr(int_to_32bytearray(s)), 32), - v - 27 - ), - raw=True + hasher=None, ) - pub = pk.serialize(compressed=False)[1:] + pub = pk.format(compressed=False)[1:] except: pub = b"\x00" * 64 else: @@ -111,12 +104,9 @@ def ecrecover_to_pub(rawhash, v, r, s): def ecsign(rawhash, key): - if secp256k1 and hasattr(secp256k1, 'PrivateKey'): - pk = secp256k1.PrivateKey(key, raw=True) - signature = pk.ecdsa_recoverable_serialize( - pk.ecdsa_sign_recoverable(rawhash, raw=True) - ) - signature = signature[0] + bytearray_to_bytestr([signature[1]]) + if coincurve and hasattr(coincurve, 'PrivateKey'): + pk = coincurve.PrivateKey(key) + signature = pk.sign_recoverable(msghash, hasher=None) v = safe_ord(signature[64]) + 27 r = big_endian_to_int(signature[0:32]) s = big_endian_to_int(signature[32:64]) diff --git a/requirements.txt b/requirements.txt index 5c22c1798..539243791 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,9 @@ pysha3>=1.0.1 PyYAML repoze.lru -pbkdf2 scrypt py_ecc rlp>=0.4.7 https://github.com/ethereum/ethash/tarball/master +pycryptodome==3.4.6 +coincurve>=5.0.1 diff --git a/setup.py b/setup.py index 2c07d55a9..c2b1c6220 100644 --- a/setup.py +++ b/setup.py @@ -41,7 +41,7 @@ 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', ], )