Common utility functions for codebases which interact with ethereum.
This library and repository was previously located at https://github.com/pipermerriam/ethereum-utils. It was transferred to the Ethereum foundation github in November 2017 and renamed to
eth-utils
. The PyPi package was also renamed fromethereum-utils
to `eth-utils.
pip install eth-utils
Clone the repository and then run:
pip install -e .[dev] eth-hash[pycryptodome]
You can run the tests with:
py.test tests
Or you can install tox
to run the full test suite.
Pandoc is required for transforming the markdown README to the proper format to render correctly on pypi.
For Debian-like systems:
apt install pandoc
Or on OSX:
brew install pandoc
To release a new version:
make release bump=$$VERSION_PART_TO_BUMP$$
The version format for this repo is {major}.{minor}.{patch}
for stable, and
{major}.{minor}.{patch}-{stage}.{devnum}
for unstable (stage
can be alpha or beta).
To issue the next version in line, specify which part to bump,
like make release bump=minor
or make release bump=devnum
.
If you are in a beta version, make release bump=stage
will switch to a stable.
To issue an unstable version when the current version is stable, specify the
new version explicitly, like make release bump="--new-version 4.0.0-alpha.1 devnum"
All functions can be imported directly from the eth_utils
module
Alternatively, you can get the curried version of the functions by importing them
through the curried
module like so:
from eth_utils.curried import hexstr_if_str
Returns the 32 byte log topic for the given event abi.
>>> event_abi_to_log_topic({'type': 'event', 'anonymous': False, 'name': 'MyEvent', 'inputs': []})
b'M\xbf\xb6\x8bC\xdd\xdf\xa1+Q\xeb\xe9\x9a\xb8\xfd\xedb\x0f\x9a\n\xc21B\x87\x9aO\x19*\x1byR\xd2'
Returns the 32 byte log topic for the given event signature.
>>> event_signature_to_log_topic('MyEvent()')
b'M\xbf\xb6\x8bC\xdd\xdf\xa1+Q\xeb\xe9\x9a\xb8\xfd\xedb\x0f\x9a\n\xc21B\x87\x9aO\x19*\x1byR\xd2'
Returns the 4 byte function selector for the given function abi.
>>> function_abi_to_4byte_selector({'type': 'function', 'name': 'myFunction', 'inputs': [], 'outputs': []})
b'\xc3x\n:'
Returns the 4 byte function selector for the given function signature.
>>> function_signature_to_4byte_selector('myFunction()')
b'\xc3x\n:'
Applicators help you apply "formatters" in various ways, most notably:
- apply formatters to values by key
- apply formatters to lists by index
- conditionally applying a formatter
- conditionally applying one of several formatters.
Here we define a "formatter" as any callable
that may be called with a single positional argument.
It returns the "formatted" result. For example int()
could be used as a formatter.
Defining your own formatter is easy:
def i_put_my_thing_down_flip_it_and_reverse_it(lyric):
return ''.join(reversed(lyric))
These tools often work nicely when curried. Import them from the curried
module to get that
capability built in, like from eth_utils.curried import apply_formatter_if
.
This function will apply the formatter only if bool(condition()) is True
.
>>> from eth_utils.curried import apply_formatter_if, is_string
>>> bool_if_string = apply_formatter_if(is_string, bool)
>>> bool_if_string(1)
1
>>> bool_if_string('1')
True
>>> bool_if_string('')
False
This function will iterate through condition_formatter_pairs
, and
apply the first formatter which has a truthy condition. One of the formatters
must match, or this function will raise a ValueError
.
>>> from eth_utils.curried import apply_one_of_formatters, is_string, is_list_like
>>> multi_formatter = apply_one_of_formatters((
(is_list_like, tuple),
(is_string, i_put_my_thing_down_flip_it_and_reverse_it),
)
>>> multi_formatter('my thing')
'gniht ym'
>>> multi_formatter([1, 2])
(1, 2)
>>> multi_formatter(54)
ValueError("The provided value did not satisfy any of the formatter conditions")
This function will apply the formatter to one element of list_like
,
at position at_index
, and return a new iterable with that element replaced.
The returned value will be the same type as the one passed into the third argument.
>>> from eth_utils.curried import apply_formatter_at_index
>>> targetted_formatter = apply_formatter_at_index(bool, 1)
>>> targetted_formatter((1, 2, 3))
(1, True, 3)
>>> targetted_formatter([1, 2, 3])
[1, True, 3]
This function will apply the formatter to each element of list_like
.
It returns the same type as the list_like
argument
>>> from eth_utils.curried import apply_formatter_to_array
>>> map_int = apply_formatter_to_array(int)
>>> map_int((1.2, 3.4, 5.6))
(1, 3, 5)
>>> map_int([1.2, 3.4, 5.6])
[1, 3, 5]
This function will apply each formatter at to the list-like value, at the
position it was supplied. It returns the same time as the list_like
argument.
For example:
>>> from eth_utils.curried import apply_formatters_to_sequence
>>> list_formatter = apply_formatters_to_sequence([bool, int, str])
>>> list_formatter([1.2, 3.4, 5.6])
[True, 3, '5.6']
>>> list_formatter((1.2, 3.4, 5.6))
(True, 3, '5.6')
# Formatters and list-like value must be the same length
>>> list_formatter((1.2, 3.4, 5.6, 7.8))
IndexError: Too few formatters for sequence: 3 formatters for (1.2, 3.4, 5.6, 7.8)
>>> list_formatter((1.2, 3.4))
IndexError: Too many formatters for sequence: 3 formatters for (1.2, 3.4)
DEPRECATED
You can replace all current versions of:
>>> from eth_utils import combine_argument_formatters
>>> list_formatter = combine_argument_formatters(bool, int, str)
With the newer, preferred:
>>> from eth_utils.curried import apply_formatters_to_sequence
>>> list_formatter = apply_formatters_to_sequence((bool, int, str))
The old usage works like:
Combine several formatters to be applied to a list-like value, each formatter at the position it was supplied. The new formatter will return the same type as it was supplied. For example:
>>> from eth_utils import combine_argument_formatters
>>> list_formatter = combine_argument_formatters(bool, int, str)
>>> list_formatter([1.2, 3.4, 5.6])
[True, 3, '5.6']
>>> list_formatter((1.2, 3.4, 5.6))
(True, 3, '5.6')
# it will pass through items longer than the number of formatters supplied
>>> list_formatter((1.2, 3.4, 5.6, 7.8))
[True, 3, '5.6', 7.8]
This function will apply the formatter to the element with
the matching key in dict_like
, passing through values with keys that
have no matching formatter.
>>> from eth_utils.curried import apply_formatters_to_dict
>>> dict_formatter = apply_formatters_to_dict({
'should_be_int': int,
'should_be_bool': bool,
})
>>> dict_formatter({
'should_be_int': 1.2,
'should_be_bool': 3.4,
'pass_through': 5.6,
})
{
'should_be_int': 1,
'should_be_bool': True,
'pass_through': 5.6,
}
This function will rename keys from <dict_like> using the
lookups provided in formatter_dict
. It will pass through any unspecified keys.
>>> from eth_utils.curried import apply_key_map
>>> dict_key_map = apply_key_map({
'black': 'orange',
'Internet': 'Ethereum',
})
>>> dict_key_map({
'black': 1.2,
'Internet': 3.4,
'pass_through': 5.6,
})
{
'orange': 1.2,
'Ethereum': 3.4,
'pass_through': 5.6,
}
Returns True
if the value
is one of the following accepted address formats.
- 20 byte hexadecimal, upper/lower/mixed case, with or without
0x
prefix:'d3cda913deb6f67967b99d67acdfa1712c293601'
'0xd3cda913deb6f67967b99d67acdfa1712c293601'
'0xD3CDA913DEB6F67967B99D67ACDFA1712C293601'
'0xd3CdA913deB6f67967B99D67aCDFa1712C293601'
- 20 byte hexadecimal padded to 32 bytes with null bytes, upper/lower/mixed case, with or without
0x
prefix:'000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601'
'000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601'
'0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601'
'0x000000000000000000000000D3CDA913DEB6F67967B99D67ACDFA1712C293601'
'0x000000000000000000000000d3CdA913deB6f67967B99D67aCDFa1712C293601'
- 20 text or bytes string:
'\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01'
- 20 text or bytes string padded to 32 bytes with null bytes.
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01'
This function has two special cases when it will return False:
- a 20-byte hex string that has mixed case, with an invalid checksum
- a 32-byte value that is all null bytes
>>> is_address('d3cda913deb6f67967b99d67acdfa1712c293601')
True
>>> is_address('0xd3cda913deb6f67967b99d67acdfa1712c293601')
True
>>> is_address('0xD3CDA913DEB6F67967B99D67ACDFA1712C293601')
True
>>> is_address('0xd3CdA913deB6f67967B99D67aCDFa1712C293601')
True
>>> is_address('000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601')
True
>>> is_address('000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601')
True
>>> is_address('0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601')
True
>>> is_address('0x000000000000000000000000D3CDA913DEB6F67967B99D67ACDFA1712C293601')
True
>>> is_address('0x000000000000000000000000d3CdA913deB6f67967B99D67aCDFa1712C293601')
True
>>> is_address('\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01')
True
>>> is_address('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01')
True
>>> is_address('0x0000000000000000000000000000000000000000000000000000000000000000')
False
>>> is_address('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
False
Return True
if the value is a 20 byte hexadecimal encoded string in any of
upper/lower/mixed casing, with or without the 0x
prefix. Otherwise return
False
'd3cda913deb6f67967b99d67acdfa1712c293601'
'0xd3cda913deb6f67967b99d67acdfa1712c293601'
'0xD3CDA913DEB6F67967B99D67ACDFA1712C293601'
'0xd3CdA913deB6f67967B99D67aCDFa1712C293601'
>>> is_hex_address('d3cda913deb6f67967b99d67acdfa1712c293601')
True
>>> is_hex_address('0xd3cda913deb6f67967b99d67acdfa1712c293601')
True
>>> is_hex_address('0xD3CDA913DEB6F67967B99D67ACDFA1712C293601')
True
>>> is_hex_address('0xd3CdA913deB6f67967B99D67aCDFa1712C293601')
True
>>> is_hex_address('000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_hex_address('000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_hex_address('0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_hex_address('0x000000000000000000000000D3CDA913DEB6F67967B99D67ACDFA1712C293601')
False
>>> is_hex_address('0x000000000000000000000000d3CdA913deB6f67967B99D67aCDFa1712C293601')
False
>>> is_hex_address('\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01')
False
>>> is_hex_address('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01')
False
>>> is_hex_address('0x0000000000000000000000000000000000000000000000000000000000000000')
False
>>> is_hex_address('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
False
Return True
if the value is a 20 byte string.
>>> is_binary_address('d3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_binary_address('0xd3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_binary_address('0xD3CDA913DEB6F67967B99D67ACDFA1712C293601')
False
>>> is_binary_address('0xd3CdA913deB6f67967B99D67aCDFa1712C293601')
False
>>> is_binary_address('000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_binary_address('000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_binary_address('0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_binary_address('0x000000000000000000000000D3CDA913DEB6F67967B99D67ACDFA1712C293601')
False
>>> is_binary_address('0x000000000000000000000000d3CdA913deB6f67967B99D67aCDFa1712C293601')
False
>>> is_binary_address('\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01')
True
>>> is_binary_address('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01')
False
>>> is_binary_address('0x0000000000000000000000000000000000000000000000000000000000000000')
False
>>> is_binary_address('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
False
Returns True
if the value
is an address in its canonical form.
The canonical representation of an address according to eth_utils
is a
20 byte long string of bytes, eg:
b'\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01'
>>> is_canonical_address('0xd3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_canonical_address(b'\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01xd')
True
>>> is_canonical_address('\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01xd')
False
Returns True
if the value
is a checksummed address as specified by
ERC55
>>> is_checksum_address('0xd3CdA913deB6f67967B99D67aCDFa1712C293601')
True
>>> is_checksum_address('0xd3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_checksum_address('0xD3CDA913DEB6F67967B99D67ACDFA1712C293601')
False
>>> is_checksum_address('0x52908400098527886E0F7030069857D2E4169EE7')
True
>>> is_checksum_address('0xde709f2102306220921060314715629080e2fb77')
True
Returns True
if the value
is formatted as an
ERC55 checksum address.
>>> is_checksum_formatted_address('0xd3CdA913deB6f67967B99D67aCDFa1712C293601')
True
>>> is_checksum_formatted_address('0xd3cda913deb6f67967b99d67acdfa1712c293601')
False
>>> is_checksum_formatted_address('0xD3CDA913DEB6F67967B99D67ACDFA1712C293601')
False
>>> is_checksum_formatted_address('0x52908400098527886E0F7030069857D2E4169EE7')
False
>>> is_checksum_formatted_address('0xde709f2102306220921060314715629080e2fb77')
False
Returns True
if the value
is an address in its normalized form.
The normalized representation of an address is the lowercased 20 byte hexadecimal format.
>>> is_normalized_address('0xd3CdA913deB6f67967B99D67aCDFa1712C293601')
False
>>> is_normalized_address('0xd3cda913deb6f67967b99d67acdfa1712c293601')
True
>>> is_normalized_address('0xD3CDA913DEB6F67967B99D67ACDFA1712C293601')
False
>>> is_normalized_address('0x52908400098527886E0F7030069857D2E4169EE7')
False
>>> is_normalized_address('0xde709f2102306220921060314715629080e2fb77')
True
Returns True
if both a
and b
are valid addresses according to the
is_address
function and that they are both representations of the same
address.
>>> is_same_address('0xd3cda913deb6f67967b99d67acdfa1712c293601', '0xD3CDA913DEB6F67967B99D67ACDFA1712C293601')
True
>>> is_same_address('0xd3cda913deb6f67967b99d67acdfa1712c293601', '0xd3CdA913deB6f67967B99D67aCDFa1712C293601')
True
>>> is_same_address('0xd3cda913deb6f67967b99d67acdfa1712c293601', '\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01xd')
True
Given any valid representation of an address return its canonical form.
>>> to_canonical_address('0xd3cda913deb6f67967b99d67acdfa1712c293601')
b'\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01xd'
>>> to_canonical_address('0xD3CDA913DEB6F67967B99D67ACDFA1712C293601')
b'\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01xd'
>>> to_canonical_address('0xd3CdA913deB6f67967B99D67aCDFa1712C293601')
b'\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01xd'
>>> to_canonical_address('\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01xd')
b'\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01xd'
Given any valid representation of an address return the checksummed representation.
>>> to_checksum_address('0xd3cda913deb6f67967b99d67acdfa1712c293601')
'0xd3CdA913deB6f67967B99D67aCDFa1712C293601'
>>> to_checksum_address('0xD3CDA913DEB6F67967B99D67ACDFA1712C293601')
'0xd3CdA913deB6f67967B99D67aCDFa1712C293601'
>>> to_checksum_address('0xd3CdA913deB6f67967B99D67aCDFa1712C293601')
'0xd3CdA913deB6f67967B99D67aCDFa1712C293601'
>>> to_checksum_address('\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01xd')
'0xd3CdA913deB6f67967B99D67aCDFa1712C293601'
Given any valid representation of an address return the normalized representation.
>>> to_normalized_address('\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01') # raw bytes
'0xd3cda913deb6f67967b99d67acdfa1712c293601'
>>> to_normalized_address(b'0xc6d9d2cd449a754c494264e1809c50e34d64562b') # hex encoded (as byte string)
'0xc6d9d2cd449a754c494264e1809c50e34d64562b'
>>> to_normalized_address('0xc6d9d2cd449a754c494264e1809c50e34d64562b') # hex encoded
'0xc6d9d2cd449a754c494264e1809c50e34d64562b'
>>> to_normalized_address('0XC6D9D2CD449A754C494264E1809C50E34D64562B') # cap-cased
'0xc6d9d2cd449a754c494264e1809c50e34d64562b'
>>> to_normalized_address('0x000000000000000000000000c305c901078781c232a2a521c2af7980f8385ee9') # padded to 32 bytes
'0xc305c901078781c232a2a521c2af7980f8385ee9',
These methods convert values using standard practices in the Ethereum ecosystem. For example, strings are encoded to binary using UTF-8.
Because there is no reliable way to distinguish between text and a hex-encoded
bytestring, you must explicitly specify which of the two is being supplied when
passing in a str
.
Only supply one of the arguments:
Takes a variety of inputs and returns its bytes equivalent. Text gets encoded as UTF-8.
>>> to_bytes(0)
b'\x00'
>>> to_bytes(0x000F)
b'\x0f'
>>> to_bytes(b'')
b''
>>> to_bytes(b'\x00\x0F')
b'\x00\x0f'
>>> to_bytes(False)
b'\x00'
>>> to_bytes(True)
b'\x01'
>>> to_bytes(hexstr='0x000F')
b'\x00\x0f'
>>> to_bytes(hexstr='000F')
b'\x00\x0f'
>>> to_bytes(text='')
b''
>>> to_bytes(text='cowmö')
b'cowm\xc3\xb6'
Takes a variety of inputs and returns it in its hexadecimal representation. It follows the rules for converting to hex in the JSON-RPC spec. Roughly, it leaves leading 0s on bytes input, and trims leading zeros on int input.
>>> to_hex(0)
'0x0'
>>> to_hex(1)
'0x1'
>>> to_hex(0x0)
'0x0'
>>> to_hex(0x000F)
'0xf'
>>> to_hex(b'')
'0x'
>>> to_hex(b'\x00\x0F')
'0x000f'
>>> to_hex(False)
'0x0'
>>> to_hex(True)
'0x1'
>>> to_hex(hexstr='0x000F')
'0x000f'
>>> to_hex(hexstr='000F')
'0x000f'
>>> to_hex(text='')
'0x'
>>> to_hex(text='cowmö')
'0x636f776dc3b6'
Takes a variety of inputs and returns its integer equivalent.
>>> to_int(0)
0
>>> to_int(0x000F)
15
>>> to_int(b'\x00\x0F')
15
>>> to_int(False)
0
>>> to_int(True)
1
>>> to_int(hexstr='0x000F')
15
>>> to_int(hexstr='000F')
15
Takes a variety of inputs and returns its string equivalent. Text gets decoded as UTF-8.
>>> Web3.toText(0x636f776dc3b6)
'cowmö'
>>> Web3.toText(b'cowm\xc3\xb6')
'cowmö'
>>> Web3.toText(hexstr='0x636f776dc3b6')
'cowmö'
>>> Web3.toText(hexstr='636f776dc3b6')
'cowmö'
>>> Web3.toText(text='cowmö')
'cowmö'
Because there is no reliable way to distinguish between text and a hex-encoded
bytestring, you must explicitly specify which of the two is being supplied when
passing in a str
.
Only supply one of the arguments:
>>> keccak(text='')
b"\xc5\xd2F\x01\x86\xf7#<\x92~}\xb2\xdc\xc7\x03\xc0\xe5\x00\xb6S\xca\x82';{\xfa\xd8\x04]\x85\xa4p"
# A series of equivalent hash inputs:
>>> keccak(text='☢')
b'\x85\xe8\x07"\xeb\x93\r\xe9;\xcc\xa8{\xa5\xdf\xda\x89\n\xa12\x95\xae\xad.\xec\xc9\x0b\xb2\xd9z\x14\x93\x16'
>>> keccak(0xe298a2)
b'\x85\xe8\x07"\xeb\x93\r\xe9;\xcc\xa8{\xa5\xdf\xda\x89\n\xa12\x95\xae\xad.\xec\xc9\x0b\xb2\xd9z\x14\x93\x16'
>>> keccak(b'\xe2\x98\xa2')
b'\x85\xe8\x07"\xeb\x93\r\xe9;\xcc\xa8{\xa5\xdf\xda\x89\n\xa12\x95\xae\xad.\xec\xc9\x0b\xb2\xd9z\x14\x93\x16'
>>> keccak(hexstr='0xe298a2')
b'\x85\xe8\x07"\xeb\x93\r\xe9;\xcc\xa8{\xa5\xdf\xda\x89\n\xa12\x95\xae\xad.\xec\xc9\x0b\xb2\xd9z\x14\x93\x16'
Please Note - When using Python's native hex literals, python converts the hex to an int, so leading 0 bytes are truncated. But all other formats maintain zeros on the left. Hex literals are only padded until a whole number of bytes are provided to keccak. For example:
>>> keccak(0xe298a2)
b'\x85\xe8\x07"\xeb\x93\r\xe9;\xcc\xa8{\xa5\xdf\xda\x89\n\xa12\x95\xae\xad.\xec\xc9\x0b\xb2\xd9z\x14\x93\x16'
>>> keccak(0x0e298a2)
b'\x85\xe8\x07"\xeb\x93\r\xe9;\xcc\xa8{\xa5\xdf\xda\x89\n\xa12\x95\xae\xad.\xec\xc9\x0b\xb2\xd9z\x14\x93\x16'
>>> keccak(0x00e298a2)
b'\x85\xe8\x07"\xeb\x93\r\xe9;\xcc\xa8{\xa5\xdf\xda\x89\n\xa12\x95\xae\xad.\xec\xc9\x0b\xb2\xd9z\x14\x93\x16'
>>> keccak(0x000e298a2)
b'\x85\xe8\x07"\xeb\x93\r\xe9;\xcc\xa8{\xa5\xdf\xda\x89\n\xa12\x95\xae\xad.\xec\xc9\x0b\xb2\xd9z\x14\x93\x16'
>>> keccak(hexstr='0x0e298a2')
b'i\x0f$\xbd\xbe\xf7c\xbb\xb9M\xd9\x12H"\x9f\x1f\x87\\E\xa36\xc2\xea,\x8f.\r\xf5\x95\xdc\x19\x9b'
>>> keccak(hexstr='0x00e298a2')
b'i\x0f$\xbd\xbe\xf7c\xbb\xb9M\xd9\x12H"\x9f\x1f\x87\\E\xa36\xc2\xea,\x8f.\r\xf5\x95\xdc\x19\x9b'
>>> keccak(hexstr='0x000e298a2')
b'!$Ezy\xdeU<\xec\x1f\xd1\x10\x05\xff\x11\xfc=J\xcf\xd5H\x0f\xb3c\xcc\xb5\xae\xb1\x1eA\x8b\xd3'
Object with property access to all of the various denominations for ether. Available denominations are:
+--------------+---------------------------------+ | denomination | amount in wei | +--------------+---------------------------------+ | wei | 1 | | kwei | 1000 | | babbage | 1000 | | femtoether | 1000 | | mwei | 1000000 | | lovelace | 1000000 | | picoether | 1000000 | | gwei | 1000000000 | | shannon | 1000000000 | | nanoether | 1000000000 | | nano | 1000000000 | | szabo | 1000000000000 | | microether | 1000000000000 | | micro | 1000000000000 | | finney | 1000000000000000 | | milliether | 1000000000000000 | | milli | 1000000000000000 | | ether | 1000000000000000000 | | kether | 1000000000000000000000 | | grand | 1000000000000000000000 | | mether | 1000000000000000000000000 | | gether | 1000000000000000000000000000 | | tether | 1000000000000000000000000000000 | +--------------+---------------------------------+
>>> denoms.wei
1
>>> denoms.finney
1000000000000000
>>> denoms.ether
1000000000000000000
Converts value
in the given denomination
to its equivalent in the wei denomination.
>>> to_wei(1, 'ether')
1000000000000000000
Converts the value
in the wei denomination to its equivalent in the given
denomination
. Return value is a decimal.Decimal
with the appropriate
precision to be a lossless conversion.
>>> from_wei(1000000000000000000, 'ether')
Decimal('1')
>>> from_wei(123456789, 'ether')
Decimal('1.23456789E-10')
At the shell:
$ python -m eth_utils
Python version:
3.5.3 (default, Nov 23 2017, 11:34:05)
[GCC 6.3.0 20170406]
Operating System: Linux-4.10.0-42-generic-x86_64-with-Ubuntu-17.04-zesty
pip freeze result:
bumpversion==0.5.3
cytoolz==0.9.0
flake8==3.4.1
ipython==6.2.1
pytest==3.3.2
virtualenv==15.1.0
... etc
Decorates methods in a class that can be called as both an instance method
or a @classmethod
.
Use the decorator like so:
from eth_utils import combomethod
class Storage:
val = 1
@combomethod
def get(combo):
if isinstance(combo, type):
print("classmethod call")
elif isinstance(combo, Storage):
print("instance method call")
else:
raise TypeError("Unreachable, unless you really monkey around")
return combo.val
As usual, instances create their own copy on assignment.
>>> store = Storage()
>>> store.val = 2
>>> store.get()
instance method call
2
>>> Storage.get()
classmethod call
1
Returns value
converted to an integer (from a big endian representation).
>>> big_endian_to_int(b'\x00')
0
>>> big_endian_to_int(b'\x01')
1
>>> big_endian_to_int(b'\x01\x00')
256
Returns value
converted to the big endian representation.
>>> int_to_big_endian(0)
b'\x00'
>>> int_to_big_endian(1)
b'\x01'
>>> int_to_big_endian(256)
b'\x01\x00'
DEPRECATED in 0.3.0.
Returns a single function which is the composition of the given callables.
>>> def f(v):
... return v * 3
...
>>> def g(v):
... return v + 2
...
>>> def h(v):
... return v % 5
...
>>> compose(f, g, h)(1)
0
>>> h(g(f(1)))
0
>>> compose(f, g, h)(2)
3
>>> h(g(f(1)))
3
>>> compose(f, g, h)(3)
1
>>> h(g(f(1)))
1
>>> compose(f, g, h)(4)
4
>>> h(g(f(1)))
4
Decorator which performs a non-recursive flattening of the return value from
the given callable
.
>>> flatten_return(lambda: [[1, 2, 3], [4, 5], [6]])
(1, 2, 3, 4, 5, 6)
Decorator which sorts the return value from the given callable
.
>>> flatten_return(lambda: [[1, 2, 3], [4, 5], [6]])
(1, 2, 3, 4, 5, 6)
Decorator which reverses the return value from the given callable
.
>>> reversed_return(lambda: [1, 5, 2, 4, 3])
(3, 4, 2, 5, 1)
Decorator which casts the return value from the given callable
to a dictionary.
>>> @to_dict
... def build_thing():
... yield 'a', 1
... yield 'b', 2
... yield 'c', 3
...
>>> build_thing()
{'a': 1, 'b': 2, 'c': 3}
Decorator which casts the return value from the given callable
to a list.
>>> @to_list
... def build_thing():
... yield 'a'
... yield 'b'
... yield 'c'
...
>>> build_thing()
['a', 'b', 'c']
Decorator which casts the return value from the given callable
to an ordered dictionary of type collections.OrderedDict
.
>>> @to_ordered_dict
... def build_thing():
... yield 'd', 4
... yield 'a', 1
... yield 'b', 2
... yield 'c', 3
...
>>> build_thing()
OrderedDict([('d', 4), ('a', 1), ('b', 2), ('c', 3)])
Decorator which casts the return value from the given callable
to a tuple.
>>> @to_tuple
... def build_thing():
... yield 'a'
... yield 'b'
... yield 'c'
...
>>> build_thing()
('a', 'b', 'c')
Decorator which casts the return value from the given callable
to a set.
>>> @to_set
... def build_thing():
... yield 'a'
... yield 'b'
... yield 'a' # duplicate
... yield 'c'
...
>>> build_thing()
{'a', 'b', 'c'}
This function takes a single callable and returns a decorator. The returned decorator, when applied to a function, will incercept the function's return value, pass it to the callable, and return the value returned by the callable.
>>> double = apply_to_return_value(lambda v: v * 2)
>>> @double
... def f(v):
... return v
...
>>> f(2)
4
>>> f(3)
6
Returns value
with a 0x
prefix. If the value is already prefixed it is returned as-is. Value must be a string literal.
>>> add_0x_prefix('12345')
'0x12345'
>>> add_0x_prefix('0x12345')
'0x12345'
Returns value
decoded into a byte string. Accepts any string with or without the 0x
prefix.
>>> decode_hex('0x123456')
b'\x124V'
>>> decode_hex('123456')
b'\x124V'
Returns value
encoded into a hexadecimal representation with a 0x
prefix
>>> encode_hex('\x01\x02\x03')
'0x010203'
Returns True
if value
has a 0x
prefix. Value must be a string literal.
>>> is_0x_prefixed('12345')
False
>>> is_0x_prefixed('0x12345')
True
Returns True
if value
is a hexadecimal encoded string of text type.
>>> is_hex('')
False
>>> is_hex('0x')
True
>>> is_hex('0X')
True
>>> is_hex('1234567890abcdef')
True
>>> is_hex('0x1234567890abcdef')
True
>>> is_hex('0x1234567890ABCDEF')
True
>>> is_hex('0x1234567890AbCdEf')
True
>>> is_hex('12345') # odd length is ok
True
>>> is_hex('0x12345') # odd length is ok
True
>>> is_hex('123456__abcdef') # non hex characters
False
# invalid, will raise TypeError:
>>> is_hex(b'')
>>> is_hex(b'0x')
>>> is_hex(b'0X')
Returns value
with the 0x
prefix stripped. If the value does not have a
0x
prefix it is returned as-is. Value must be string literal.
>>> remove_0x_prefix('12345')
'12345'
>>> remove_0x_prefix('0x12345')
'12345'
Returns True
if value
is of type bool
>>> is_boolean(True)
True
>>> is_boolean(False)
False
>>> is_boolean(1)
False
Returns True
if value
is a byte string or a byte array.
>>> is_bytes('abcd')
False
>>> is_bytes(b'abcd')
True
>>> is_bytes(bytearray((1, 2, 3)))
True
Returns True
if value
is a mapping type.
>>> is_dict({'a': 1})
True
>>> is_dict([1, 2, 3])
False
Returns True
if value
is an integer
>>> is_integer(0)
True
>>> is_integer(1)
True
>>> is_integer('1')
False
>>> is_integer(1.1)
False
Returns True
if value
is a non-string sequence such as a sequence (such as a list or tuple).
>>> is_list_like('abcd')
False
>>> is_list_like([])
True
>>> is_list_like(tuple())
True
Returns True
if value
is a non-string sequence such as a list.
>>> is_list('abcd')
False
>>> is_list([])
True
>>> is_list(tuple())
False
Returns True
if value
is a non-string sequence such as a tuple.
>>> is_tuple('abcd')
False
>>> is_tuple([])
False
>>> is_tuple(tuple())
True
Returns True
if value
is None
>>> is_null(None)
True
>>> is_null(False)
False
Returns True
if value
is numeric
>>> is_number(1)
True
>>> is_number(1.1)
True
>>> is_number('1')
False
>>> is_number(decimal.Decimal('1'))
True
Returns True
if value
is of any string type.
>>> is_string('abcd')
True
>>> is_string(b'abcd')
True
>>> is_string(bytearray((1, 2, 3)))
True
Returns True
if value
is a text string.
>>> is_text(u'abcd')
True
>>> is_text(b'abcd')
False
>>> is_text(bytearray((1, 2, 3)))
False
The version format for this repo is {major}.{minor}.{patch}
for stable, and
{major}.{minor}.{patch}-{stage}.{devnum}
for unstable (stage
can be alpha or beta).
To issue the next version in line, use bumpversion and specify which part to bump,
like bumpversion minor
or bumpversion devnum
.
If you are in a beta version, bumpversion stage
will switch to a stable.
To issue an unstable version when the current version is stable, specify the
new version explicitly, like bumpversion --new-version 4.0.0-alpha.1 devnum