Skip to main content

Common utility functions for ethereum codebases.

Project description

# Ethereum Utils

[![Join the chat at https://gitter.im/pipermerriam/ethereum-utils](https://badges.gitter.im/pipermerriam/ethereum-utils.svg)](https://gitter.im/pipermerriam/ethereum-utils?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

[![Build Status](https://travis-ci.org/pipermerriam/ethereum-utils.png)](https://travis-ci.org/pipermerriam/ethereum-utils)

Common utility functions for codebases which interact with ethereum.

## Installation

`sh pip install ethereum-utils `

## Documentation

All functions can be imported directly from the eth_utils module

### ABI Utils

#### event_abi_to_log_topic(event_abi) -> bytes

Returns the 32 byte log topic for the given event abi.

`python >>> 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' `

#### event_signature_to_log_topic(event_signature) -> bytes

Returns the 32 byte log topic for the given event signature.

`python >>> 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' `

#### function_abi_to_4byte_selector(function_abi) -> bytes

Returns the 4 byte function selector for the given function abi.

`python >>> function_abi_to_4byte_selector({'type': 'function', 'name': 'myFunction', 'inputs': [], 'outputs': []}) b'\xc3x\n:' `

#### function_signature_to_4byte_selector(function_signature) -> bytes

Returns the 4 byte function selector for the given function signature.

`python >>> function_signature_to_4byte_selector('myFunction()') b'\xc3x\n:' `

### Address Utils

#### is_address(value) -> bool

Returns True if the value is one of the following accepted address formats.

  • 20 byte hexidecimal, upper/lower/mixed case, with or without 0x prefix:
    • ‘d3cda913deb6f67967b99d67acdfa1712c293601’

    • ‘0xd3cda913deb6f67967b99d67acdfa1712c293601’

    • ‘0xD3CDA913DEB6F67967B99D67ACDFA1712C293601’

    • ‘0xd3CdA913deB6f67967B99D67aCDFa1712C293601’

  • 20 byte hexidecimal 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:
    • ‘xd3xcdxa9x13xdexb6xf6ygxb9x9dgxacxdfxa1q,)6x01’

  • 20 text or bytes string padded to 32 bytes with null bytes.
    • ‘x00x00x00x00x00x00x00x00x00x00x00x00xd3xcdxa9x13xdexb6xf6ygxb9x9dgxacxdfxa1q,)6x01’

This function has one special case, which is that it will return false for a 32 byte value that is all null bytes.

`python >>> 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 `

#### is_canonical_address(value) -> bool

Returns True if the value is an address in it’s canonical form.

The canonical representation of an address according to ethereum-utils is a 20 byte long string of bytes, eg: b’xd3xcdxa9x13xdexb6xf6ygxb9x9dgxacxdfxa1q,)6x01’

`python >>> 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 `

#### is_checksum_address(value) -> bool

Returns True if the value is a checksummed address as specified by [ERC55](https://github.com/ethereum/EIPs/issues/55)

`python >>> 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 `

#### is_normalized_address(value) -> bool

Returns True if the value is an address in its normalized form.

The normalized representation of an address is the lowercased 20 byte hexidecimal format.

`python >>> 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 `

#### is_same_address(a, b) -> bool

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.

`python >>> 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 `

#### to_canonical_address(value) -> bytes

Given any valid representation of an address return it’s canonical form.

`python >>> 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' `

#### to_checksum_address(value) -> text

Given any valid representation of an address return the checksummed representation.

`python >>> 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' `

#### to_normalized_address(value) -> text

Given any valid representation of an address return the normalized representation.

`python >>> 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', `

### Crypto Utils

#### keccak(value) -> bytes

Given any string returns the sha3/keccak hash. If value is not a byte string it will be converted using the force_bytes function.

`python >>> keccak('') b"\xc5\xd2F\x01\x86\xf7#<\x92~}\xb2\xdc\xc7\x03\xc0\xe5\x00\xb6S\xca\x82';{\xfa\xd8\x04]\x85\xa4p" `

### Currency Utils

#### denoms

Object with property access to all of the various denominations for ether. Available denominations are:

denomination

amount in wei

wei kwei babbage femtoether mwei lovelace picoether gwei shannon nanoether nano szabo microether micro finney milliether milli ether kether grand mether gether tether

1 1000 1000 1000 1000000 1000000 1000000 1000000000 1000000000 1000000000 1000000000 1000000000000 1000000000000 1000000000000 1000000000000000 1000000000000000 1000000000000000 1000000000000000000 1000000000000000000000 1000000000000000000000 1000000000000000000000000 1000000000000000000000000000 1000000000000000000000000000000

`python >>> denoms.wei 1 >>> denoms.finney 1000000000000000 >>> denoms.ether 1000000000000000000 `

### Formatting Utils

#### pad_left(value, to_size, pad_with) -> string

Returns value padded to the length specified by to_size with the string pad_with.

`python >>> pad_left('test', 6, '0') '00test' >>> pad_left('testing', 6, '0') 'testing' >>> pad_left('test', 8, '123') '12312test' `

#### pad_right(value, to_size, pad_with) -> string

Returns value padded to the length specified by to_size with the string pad_with.

`python >>> pad_right('test', 6, '0') 'test00' >>> pad_right('testing', 6, '0') 'testing' >>> pad_right('test', 8, '123') 'test12312' `

### Functional Utils

#### compose(*callables) -> callable

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 `

#### flatten_return(callable) -> callable() -> tuple

Decorator which performs a non-recursive flattening of the return value from the given callable.

`python >>> flatten_return(lambda: [[1, 2, 3], [4, 5], [6]]) (1, 2, 3, 4, 5, 6) `

#### sort_return(callable) => callable() -> tuple

Decorator which sorts the return value from the given callable.

`python >>> flatten_return(lambda: [[1, 2, 3], [4, 5], [6]]) (1, 2, 3, 4, 5, 6) `

#### reversed_return(callable) => callable() -> tuple

Decorator which reverses the return value from the given callable.

`python >>> reversed_return(lambda: [1, 5, 2, 4, 3]) (3, 4, 2, 5, 1) `

#### to_dict(callable) => callable() -> dict

Decorator which casts the return value from the given callable to a dictionary.

`python >>> @to_dict ... def build_thing(): ... yield 'a', 1 ... yield 'b', 2 ... yield 'c', 3 ... >>> build_thing() {'a': 1, 'b': 2, 'c': 3} `

#### to_list(callable) => callable() -> list

Decorator which casts the return value from the given callable to a list.

`python >>> @to_list ... def build_thing(): ... yield 'a' ... yield 'b' ... yield 'c' ... >>> build_thing() ['a', 'b', 'c'] `

#### to_ordered_dict(callable) => callable() -> collections.OrderedDict

Decorator which casts the return value from the given callable to an ordered dictionary of type collections.OrderedDict.

`python >>> @to_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)]) `

#### to_tuple(callable) => callable() -> tuple

Decorator which casts the return value from the given callable to a tuple.

`python >>> @to_tuple ... def build_thing(): ... yield 'a' ... yield 'b' ... yield 'c' ... >>> build_thing() ('a', 'b', 'c') `

### Hexidecimal Utils

#### add_0x_prefix(value) -> string

Returns value with a 0x prefix. If the value is already prefixed it is returned as-is.

`python >>> add_0x_prefix('12345') '0x12345' >>> add_0x_prefix('0x12345') '0x12345' `

#### decode_hex(value) -> bytes

Returns value decoded into a byte string. Accepts any string with or without the 0x prefix.

`python >>> decode_hex('0x123456') b'\x124V' >>> decode_hex('123456') b'\x124V' `

#### encode_hex(value) -> string

Returns value encoded into a hexidecimal representation with a 0x prefix

`python >>> encode_hex('\x01\x02\x03') '0x010203' `

#### is_0x_prefixed(value) -> bool

Returns True if value has a 0x prefix.

`python >>> is_0x_prefixed('12345') False >>> is_0x_prefixed('0x12345') True >>> is_0x_prefixed(b'0x12345') True `

#### remove_0x_prefix(value) -> string

Returns value with the 0x prefix stripped. If the value does not have a 0x prefix it is returned as-is.

`python >>> remove_0x_prefix('12345') '12345' >>> remove_0x_prefix('0x12345') '12345' >>> remove_0x_prefix(b'0x12345') b'12345' `

### String Utils

#### coerce_args_to_bytes(callable) -> callable

Decorator which will convert any string arguments both positional or keyword into byte strings using the force_bytes function. This is a recursive operation which will reach down into mappings and list-like objects as well.

`python >>> @coerce_args_to_bytes ... def do_thing(*args): ... return args ... >>> do_thing('a', 1, b'a-byte-string', ['a', b'b', 1], {'a': 'a', 'b': ['x', b'y']}) (b'a', 1, b'a-byte-string', [b'a', b'b', 1], {'a': b'a', 'b': [b'x', b'y']}) `

#### coerce_args_to_text(callable) -> callable

Decorator which will convert any string arguments both positional or keyword into text strings using the force_text function. This is a recursive operation which will reach down into mappings and list-like objects as well.

`python >>> @coerce_args_to_text ... def do_thing(*args): ... return args ... >>> do_thing('a', 1, b'a-byte-string', ['a', b'b', 1], {'a': 'a', 'b': ['x', b'y']}) ('a', 1, 'a-byte-string', ['a', 'b', 1], {'a': 'a', 'b': ['x', 'y']}) `

#### coerce_return_to_bytes(callable) -> callable

Decorator which will convert any string return values into byte strings using the force_text function. This is a recursive operation which will reach down into mappings and list-like objects as well.

`python >>> @coerce_return_to_bytes ... def do_thing(*args): ... return args ... >>> do_thing('a', 1, b'a-byte-string', ['a', b'b', 1], {'a': 'a', 'b': ['x', b'y']}) (b'a', 1, b'a-byte-string', [b'a', b'b', 1], {'a': b'a', 'b': [b'x', b'y']}) `

#### coerce_return_to_text(callable) -> callable

Decorator which will convert any string return values into text strings using the force_text function. This is a recursive operation which will reach down into mappings and list-like objects as well.

`python >>> @coerce_return_to_bytes ... def do_thing(*args): ... return args ... >>> do_thing('a', 1, b'a-byte-string', ['a', b'b', 1], {'a': 'a', 'b': ['x', b'y']}) ('a', 1, 'a-byte-string', ['a', 'b', 1], {'a': 'a', 'b': ['x', 'y']}) `

#### force_bytes(value, encoding=’iso-8859-1’) -> text

Returns value encoded into a byte string using the provided encoding. By default this uses iso-8859-1 as it can handle all byte values between 0-255 (unlike utf8)

`python >>> force_bytes('abcd') b'abcd' >>> force_bytes(b'abcd') b'abcd' `

#### force_obj_to_bytes(value) -> value

Returns value with all string elements converted to byte strings by recursivly traversing mappings and list-like elements.

`python >>> force_obj_to_bytes(('a', 1, b'a-byte-string', ['a', b'b', 1], {'a': 'a', 'b': ['x', b'y']})) (b'a', 1, b'a-byte-string', [b'a', b'b', 1], {'a': b'a', 'b': [b'x', b'y']}) `

#### force_obj_to_text(value) -> value

Returns value with all string elements converted to text strings by recursivly traversing mappings and list-like elements.

`python >>> force_obj_to_text(('a', 1, b'a-byte-string', ['a', b'b', 1], {'a': 'a', 'b': ['x', b'y']})) ('a', 1, 'a-byte-string', ['a', 'b', 1], {'a': 'a', 'b': ['x', 'y']}) `

#### force_text(value, encoding=’iso-8859-1’) -> text

Returns value decoded into a text string using the provided encoding. By default this uses iso-8859-1 as it can handle all byte values between 0-255 (unlike utf8)

`python >>> force_text(b'abcd') 'abcd' >>> force_text('abcd') 'abcd' `

### Type Utils

#### is_boolean(value) -> bool

Returns True if value is of type bool

`python >>> is_boolean(True) True >>> is_boolean(False) False >>> is_boolean(1) False `

#### is_bytes(value) -> bool

Returns True if value is a byte string or a byte array.

`python >>> is_bytes('abcd') False >>> is_bytes(b'abcd') True >>> is_bytes(bytearray((1, 2, 3))) True `

#### is_dict(value) -> bool

Returns True if value is a mapping type.

`python >>> is_dict({'a': 1}) True >>> is_dict([1, 2, 3]) False `

#### is_integer(value) -> bool

Returns True if value is an integer

`python >>> is_integer(0) True >>> is_integer(1) True >>> is_integer('1') False >>> is_integer(1.1) False `

#### is_list_like(value) -> bool

Returns True if value is a non-string sequence such as a list or tuple.

`python >>> is_list_like('abcd') False >>> is_list_like([]) True >>> is_list_like(tuple()) True `

#### is_null(value) -> bool

Returns True if value is None

`python >>> is_null(None) True >>> is_null(False) False `

#### is_number(value) -> bool

Returns True if value is numeric

`python >>> is_number(1) True >>> is_number(1.1) True >>> is_number('1') False >>> is_number(decimal.Decimal('1')) True `

#### is_string(value) -> bool

Returns True if value is of any string type.

`python >>> is_string('abcd') True >>> is_string(b'abcd') True >>> is_string(bytearra((1, 2, 3))) True `

#### is_text(value) -> bool

Returns True if value is a text string.

`python >>> is_string('abcd') True >>> is_string(b'abcd') True >>> is_string(bytearra((1, 2, 3))) True `

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ethereum-utils-0.2.2.tar.gz (14.5 kB view details)

Uploaded Source

Built Distribution

ethereum_utils-0.2.2-py2-none-any.whl (16.1 kB view details)

Uploaded Python 2

File details

Details for the file ethereum-utils-0.2.2.tar.gz.

File metadata

File hashes

Hashes for ethereum-utils-0.2.2.tar.gz
Algorithm Hash digest
SHA256 0f77f10ea067c6624d5da01709f33b8ba241f49a273ca077811c0b6651e2c316
MD5 5b237988313cb010d87750ec77db636a
BLAKE2b-256 e84ca5b8632f2c66d774c7a6915097007246bb2b3b06764025034486116ddb7c

See more details on using hashes here.

File details

Details for the file ethereum_utils-0.2.2-py2-none-any.whl.

File metadata

File hashes

Hashes for ethereum_utils-0.2.2-py2-none-any.whl
Algorithm Hash digest
SHA256 0410db916b1449caffe09941b2c268fc3a7e566cec9928e1402d5b9950afeb82
MD5 03aa24647f6f6a9636d6989cc3571655
BLAKE2b-256 8bb977e8c8b1238be35b3dd7e39564ae7b5ab9339593d088024f856c9eb71fbe

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page