Skip to content

Commit

Permalink
Merge pull request #42 from HyperLink-Technology/develop
Browse files Browse the repository at this point in the history
0.9.4 release
  • Loading branch information
iamdefinitelyahuman authored Feb 24, 2019
2 parents 8b1e15b + ef65de8 commit da4418d
Show file tree
Hide file tree
Showing 14 changed files with 408 additions and 250 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
0.9.4
-----

- Improved console formatting for lists and dicts
- Run method returns list of scripts when no argument is given
- Do not keep mnemonics and private keys in readline history
- Use KwargTuple type for call return values
- Bugfixes

0.9.3
-----

Expand Down
2 changes: 1 addition & 1 deletion __main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from lib.services import color, git


__version__ = "0.9.3" # did you change this in docs/conf.py as well?
__version__ = "0.9.4" # did you change this in docs/conf.py as well?
if git.get_branch() != "master":
__version__+= "-"+git.get_branch()+"-"+git.get_commit()

Expand Down
6 changes: 5 additions & 1 deletion docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1096,12 +1096,16 @@ These methods are used in the console.
Brownie environment is ready.
>>>
.. py:method:: run(script)
.. py:method:: run(script=None)
Loads a script and runs the ``main`` method within it. See :ref:`deploy` for more information.
If no argument is given, returns a list of script names from the ``scripts/`` folder.
.. code-block:: python
>>> run()
['token']
>>> run('token')
Transaction sent: 0xe4bd74210e56d4da8d53774dc333a1122c26a72a86fbba82220fcf5d2648d634
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# The short X.Y version
version = ''
# The full version, including alpha/beta/rc tags
release = '0.9.3'
release = '0.9.4'


# -- General configuration ---------------------------------------------------
Expand Down
51 changes: 28 additions & 23 deletions lib/components/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import eth_keys
from hexbytes import HexBytes
import json
import os

from lib.components.transaction import TransactionReceipt, raise_or_return_tx
Expand All @@ -18,6 +17,9 @@ class Accounts:

def __init__(self, accounts):
self._accounts = [Account(i) for i in accounts]
# prevent mnemonics and private keys from being stored in read history
self.add.__dict__['_private'] = True
self.mnemonic.__dict__['_private'] = True

def __contains__(self, address):
try:
Expand All @@ -26,9 +28,9 @@ def __contains__(self, address):
except ValueError:
return False

def __repr__(self):
def _console_repr(self):
return str(self._accounts)

def __iter__(self):
return iter(self._accounts)

Expand All @@ -40,14 +42,14 @@ def __delitem__(self, key):

def __len__(self):
return len(self._accounts)

def _check_nonce(self):
for i in self._accounts:
i.nonce = web3.eth.getTransactionCount(str(i))

def add(self, priv_key = None):
def add(self, priv_key=None):
'''Creates a new ``LocalAccount`` instance and appends it to the container.
Args:
priv_key: Private key of the account. If none is given, one is
randomly generated.
Expand All @@ -56,7 +58,7 @@ def add(self, priv_key = None):
Account instance.
'''
if not priv_key:
priv_key=web3.sha3(os.urandom(8192)).hex()
priv_key = web3.sha3(os.urandom(8192)).hex()
w3account = web3.eth.account.privateKeyToAccount(priv_key)
if w3account.address in self._accounts:
return self.at(w3account.address)
Expand Down Expand Up @@ -112,14 +114,17 @@ def clear(self):
class _AccountBase:

'''Base class for Account and LocalAccount'''

def __init__(self, addr):
self.address = addr
self.nonce = web3.eth.getTransactionCount(self.address)

def __hash__(self):
return hash(self.address)

def __repr__(self):
return "'{0[string]}{1}{0}'".format(color, self.address)

def __str__(self):
return self.address

Expand Down Expand Up @@ -148,7 +153,7 @@ def deploy(self, contract, *args):
* Contract instance if the transaction confirms
* TransactionReceipt if the transaction is pending or reverts'''
return contract.deploy(self, *args)

def estimate_gas(self, to, amount, data=""):
'''Estimates the gas cost for a transaction. Raises VirtualMachineError
if the transaction would revert.
Expand All @@ -161,10 +166,10 @@ def estimate_gas(self, to, amount, data=""):
Returns:
Estimated gas value in wei.'''
return web3.eth.estimateGas({
'from':self.address,
'to':str(to),
'data':data,
'value':wei(amount)
'from': self.address,
'to': str(to),
'data': data,
'value': wei(amount)
})

def _gas_limit(self, to, amount, data=""):
Expand All @@ -179,17 +184,17 @@ def _gas_price(self):
class Account(_AccountBase):

'''Class for interacting with an Ethereum account.
Attributes:
address: Public address of the account.
nonce: Current nonce of the account.'''
def __repr__(self):

def _console_repr(self):
return "<Account object '{0[string]}{1}{0}'>".format(color, self.address)

def transfer(self, to, amount, gas_limit=None, gas_price=None):
'''Transfers ether from this account.
Args:
to: Account instance or address string to transfer to.
amount: Amount of ether to send, in wei.
Expand Down Expand Up @@ -228,7 +233,7 @@ def _contract_tx(self, fn, args, tx, name, callback=None):
class LocalAccount(_AccountBase):

'''Class for interacting with an Ethereum account.
Attributes:
address: Public address of the account.
nonce: Current nonce of the account.
Expand All @@ -241,12 +246,12 @@ def __init__(self, address, account, priv_key):
self.public_key = eth_keys.keys.PrivateKey(HexBytes(priv_key)).public_key
super().__init__(address)

def __repr__(self):
def _console_repr(self):
return "<LocalAccount object '{0[string]}{1}{0}'>".format(color, self.address)

def transfer(self, to, amount, gas_limit=None, gas_price=None):
'''Transfers ether from this account.
Args:
to: Account instance or address string to transfer to.
amount: Amount of ether to send, in wei.
Expand Down Expand Up @@ -274,8 +279,8 @@ def transfer(self, to, amount, gas_limit=None, gas_price=None):
def _contract_tx(self, fn, args, tx, name, callback=None):
try:
tx.update({
'from':self.address,
'nonce':self.nonce,
'from': self.address,
'nonce': self.nonce,
'gasPrice': self._gas_price(),
'gas': (
CONFIG['active_network']['gas_limit'] or
Expand Down
44 changes: 24 additions & 20 deletions lib/components/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

def true(statement, fail_msg="Expected statement to be true"):
'''Expects an object or statement to evaluate True.
Args:
statement: The object or statement to check.
fail_msg: Message to show if the check fails.'''
Expand All @@ -18,7 +18,7 @@ def true(statement, fail_msg="Expected statement to be true"):

def false(statement, fail_msg="Expected statement to be False"):
'''Expects an object or statement to evaluate False.
Args:
statement: The object or statement to check.
fail_msg: Message to show if the check fails.'''
Expand All @@ -28,14 +28,14 @@ def false(statement, fail_msg="Expected statement to be False"):

def reverts(fn, args, revert_msg=None):
'''Expects a transaction to revert.
Args:
fn: ContractTx instance to call.
args: List or tuple of contract input args.
fail_msg: Message to show if the check fails.
revert_msg: If set, the check only passes if the returned
revert message matches the given one.'''
try:
try:
fn(*args)
except _VMError as e:
if not revert_msg or revert_msg == e.revert_msg:
Expand All @@ -49,12 +49,12 @@ def reverts(fn, args, revert_msg=None):

def confirms(fn, args, fail_msg="Expected transaction to confirm"):
'''Expects a transaction to confirm.
Args:
fn: ContractTx instance to call.
args: List or tuple of contract input args.
fail_msg: Message to show if the check fails.
Returns:
TransactionReceipt instance.'''
try:
Expand All @@ -66,7 +66,7 @@ def confirms(fn, args, fail_msg="Expected transaction to confirm"):

def event_fired(tx, name, count=None, values=None):
'''Expects a transaction to contain an event.
Args:
tx: A TransactionReceipt.
name: Name of the event expected to fire.
Expand All @@ -75,7 +75,7 @@ def event_fired(tx, name, count=None, values=None):
values: A dict or list of dicts of {key:value} that must match
against the fired events. The length of values must also
match the number of events that fire.'''
events = [i for i in tx.events if i['name']==name]
events = [i for i in tx.events if i['name'] == name]
if count is not None and count != len(events):
raise AssertionError(
"Event {} - expected {} events to fire, got {}".format(
Expand All @@ -94,12 +94,12 @@ def event_fired(tx, name, count=None, values=None):
)
)
for i in range(len(values)):
data = dict((x['name'],x['value']) for x in events[i]['data'])
for k,v in values[i].items():
data = dict((x['name'], x['value']) for x in events[i]['data'])
for k, v in values[i].items():
if k not in data:
print(data)
raise KeyError(
"Event {} - does not contain value '{}'".format(name,k)
"Event {} - does not contain value '{}'".format(name, k)
)
if data[k] != v:
raise AssertionError(
Expand All @@ -111,12 +111,12 @@ def event_fired(tx, name, count=None, values=None):

def event_not_fired(tx, name, fail_msg="Expected event not to fire"):
'''Expects a transaction not to contain an event.
Args:
tx: A TransactionReceipt.
name: Name of the event expected to fire.
fail_msg: Message to show if check fails.'''
if [i for i in tx.events if i['name']==name]:
if [i for i in tx.events if i['name'] == name]:
raise AssertionError(fail_msg)


Expand All @@ -129,7 +129,7 @@ def equal(a, b, fail_msg="Expected values to be equal"):
fail_msg: Message to show if check fails.'''
a, b = _convert(a, b)
if a != b:
raise AssertionError(fail_msg+": {} != {}".format(a,b))
raise AssertionError(fail_msg+": {} != {}".format(a, b))


def not_equal(a, b, fail_msg="Expected values to be not equal"):
Expand All @@ -141,15 +141,19 @@ def not_equal(a, b, fail_msg="Expected values to be not equal"):
fail_msg: Message to show if check fails.'''
a, b = _convert(a, b)
if a == b:
raise AssertionError(fail_msg+": {} == {}".format(a,b))
raise AssertionError(fail_msg+": {} == {}".format(a, b))


# attempt conversion with wei before comparing equality
def _convert(a, b):
if a not in (None, False, True):
try: a = wei(a)
except ValueError: pass
try:
a = wei(a)
except (ValueError, TypeError):
pass
if b not in (None, False, True):
try: b = wei(b)
except ValueError: pass
return a, b
try:
b = wei(b)
except (ValueError, TypeError):
pass
return a, b
Loading

0 comments on commit da4418d

Please sign in to comment.