Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
This is the Python core library of the Ethereum project.
For the python based command line client see: https://github.com/ethereum/pyethapp
sudo apt-get install libssl-dev build-essential automake pkg-config libtool libffi-dev libgmp-dev
git clone https://github.com/ethereum/pyethereum/
cd pyethereum
python setup.py install
ethereum.pow.chain
Contains the Chain class, which can be used to manage a blockchain. Main
methods are:
- ``__init__(genesis=None, env=None, new_head_cb=None, reset_genesis=False, localtime=None)``
- initializes with the given genesis. ``env`` specifies the
*environment* (including chain config and database), ``new_head_cb``
is a callback called when a new head is added, and ``localtime`` is
what the chain assumes is the current timestamp. The genesis can be:
- None - in which case it assumes ``env`` is given, and creates a
Chain object with the data saved in ``env.db``. If
``reset_genesis`` is set, it re-initializes the chain.
- A ``State`` object
- A genesis declaration
- A state snapshot (``State.snapshot()``)
- An allocation (ie. dict
``{address: {balance: 1, nonce: 2, code: b'\x03\x04\x05', storage: {"0x06": "0x07"}}}``)
- ``add_block(block)`` - adds a block to the chain
- ``process_time_queue(timestamp)`` - tells the chain that the current
time has increased to the new timestamp. The chain will then process
any blocks that were unprocessed because they appeared too "early"
- ``get_blockhash_by_number(num)`` - get the block hash of a block at
the given block number
- ``get_block(hash)`` - gets the block with the given blockhash
- ``get_block_by_number(num)`` - equivalent to
``get_block(get_blockhash_by_number(num))``
- ``get_parent(block)`` - gets the parent of a block
- ``get_children(block)`` - gets the children of a block
- ``head`` (property) - gets the block at the head of the chain
- ``state`` (property) - gets the state at the head of the chain
- ``mk_poststate_of_blockhash(hash)`` - creates a state object after a
given block
- ``has_block(block)`` - is that block in the chain? Returns True/False
- ``get_chain(from, to)`` - roughly equivalent to
``[get_block_by_number(i) for i in range(from, to)]``, though
automatically stops if it reaches the head. ``from`` can be elided to
start from genesis, ``to`` can be elided to go up to the head.
- ``get_tx_position(tx)`` - if the transaction is in the chain, returns
``(blknum, index)`` where ``blknum`` is the block number of the block
that contains the transaction and ``index`` is its position in the
block
ethereum.state
~~~~~~~~~~~~~~
Contains the State class, which is used to manage a state. Main methods
are:
- ``__init__(root_hash, env, **kwargs)`` - initializes a state with the
given root hash, the given env (which includes a config and database)
and the given auxiliary arguments. These include:
- ``txindex`` - the transaction index
- ``gas_used`` - amount of gas used
- ``gas_limit`` - block gas limit
- ``block_number`` - block number
- ``block_coinbase`` - block coinbase address
- ``block_difficulty`` - block difficulty
- ``timestamp`` - timestamp
- ``logs`` - logs created so far
- ``receipts`` - receipts created so far (from previous transactions
in the current block)
- ``bloom`` - the bloom filter
- ``suicides`` - suicides (or selfdestructs, the newer more
politically correct synonym)
- ``recent_uncles`` - recent uncle blocks in the chain
- ``prev_headers`` - previous block headers
- ``refunds`` - suicide/selfdestruct refund counter
Pyethereum follows a **maximally state-centric model**; the ONLY
information needed to process a transaction or a block is located within
the state itself, allowing the actual state transition logic to be a
very clean ``apply_transaction(state, tx)`` and
``apply_block(state, block)``.
- ``get_balance``- gets the balance of an account
- ``get_code`` - gets the code of an account
- ``get_storage_data(addr, k)`` - gets the storage at the given key of
the given address. Expects a key in **numerical** form (eg. b"cow" or
"0x636f77" is represented as 6516599).
- ``to_snapshot(root_only=False, no_prevblocks=False)`` - creates a
snapshot for the current state. If ``root_only`` is set, only adds
the state root, not the entire state. If ``no_prevblocks`` is set,
does not add previous headers and uncles. Setting either of those
flags means that the same database would be required to recover from
the snapshot.
- ``from_snapshot(snapshot, env)`` (classmethod) - creates a state from
the given snapshot with the given ``env``.
- ``ephemeral_clone()`` - creates a clone of the state that you can
work with without affecting the original
There are also many methods that modify the state, eg. ``set_code``,
``set_storage_data``, but it is generally recommended to avoid using
these, and instead modify the state ONLY through ``apply_transaction``
and ``apply_block``.
ethereum.meta
~~~~~~~~~~~~~
This file contains two functions:
- ``apply_block(state, block)`` - takes a state and processes a block
onto that state
- ``make_head_candidate(chain, txqueue=None, parent=None, timestamp, coinbase, extra_data, min_gasprice=0)``
- creates a candidate block for the chain on top of the given parent
block (default: head of the chain). Gets transactions from the given
``txqueue`` object with the given ``mingasprice`` (otherwise does not
add transactions). ``timestamp``, ``coinbase`` and ``extra_data`` can
be used to specify those parameters in the block; otherwise defaults
are used
ethereum.messages
~~~~~~~~~~~~~~~~~
The main function that should be called from here is
``apply_transaction(state, tx)``.
ethereum.utils
~~~~~~~~~~~~~~
Contains a bunch of utility functions, including:
Numerical and hex conversions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- ``encode_int(i)`` - converts an integer into big-endian binary
representation
- ``zpad(data, length)`` - pads the data up to the desired length by
adding zero bytes on the left
- ``encode_int32(i)`` - equivalent to ``zpad(encode_int(i), 32)`` but
faster
- ``big_endian_to_int(d)`` - converts binary data into an integer
- ``encode_hex(b)`` - converts bytes to hex
- ``decode_hex(h)`` - converts hex to bytes
- ``int_to_addr(i)`` - converts integer to address
- ``is_numeric(i)`` - returns True if the value is int or long,
otherwise False
Cryptography
^^^^^^^^^^^^
- ``sha3(data)`` - computes the SHA3 (or more precisely, keccak256)
hash
- ``ecrecover_to_pub(hash, v, r, s)`` - recovers the public key that
made the signature as a 64-byte binary blob of
``encode_int32(x) + encode_int32(y)``. Hashing this and taking the
last 20 bytes gives the *address* that signed a message.
- ``ecsign(hash, key)`` - returns the v, r, s values of a signature
- ``normalize_key(key)`` - converts a key from many formats into
32-byte binary
- ``privtoaddr(key)`` - converts a key to an address
Addresses
^^^^^^^^^
- ``normalize_address(addr)`` - converts an address into 20-byte binary
form
- ``check_checksum(addr)`` - returns True if the address checksum
passes, otherwise False
- ``checksum_encode(addr)`` - converts an address into hex form with a
checksum
- ``mk_contract_address(addr, nonce)`` - creates the address of a
contract created by the given address with the given nonce
Miscellaneous
^^^^^^^^^^^^^
- ``denoms`` - contains the denominations of ether, eg.
``denoms.finney = 10**15``, ``denoms.shannon = 10**9``,
``denoms.gwei = 10**9``
ethereum.block
~~~~~~~~~~~~~~
Contains the ``Block`` and ``BlockHeader`` classes. Generally
recommended to avoid creating blocks and block headers directly, instead
using ``mk_head_candidate``. The member variables are straightforward:
- ``block.transactions`` - transactions in a block
- ``block.uncles`` - uncles in a block
- ``block.header`` - header of a block
And in the header:
- ``header.hash`` - the hash (also the block hash)
- ``header.mining_hash`` - the hash used for proof of work mining
- ``header.to_dict()`` - serializes into a human-readable dict
- ``header.prevhash`` - previous block hash
- ``header.uncles_hash`` - hash of the uncle list
- ``header.coinbase`` - coinbase (miner) address
- ``header.state_root`` - root hash of the post-state
- ``header.tx_list_root`` - hash of the transactions in the block
- ``header.receipts_root`` - hash of the receipt trie
- ``header.bloom`` - bloom filter
- ``header.difficulty`` - block difficulty
- ``header.number`` - block number
- ``header.gas_limit`` - gas limit
- ``header.gas_used`` - gas used
- ``header.timestamp`` - timestamp
- ``header.extra_data`` - block extra data
- ``header.mixhash`` and ``header.nonce`` - Ethash proof of work values
ethereum.transactions
Contains the Transaction class, with the following methods and values:
__init__(nonce, gasprice, startgas, to, value, data, (v, r, s optional))
sign(key, network_id=None)
- signs the transaction with the given
key, and with the given EIP155 chain ID (leaving as None will create
a pre-EIP155 tx, be warned of replay attacks if you do this!)sender
- the sender address of the transactionnetwork_id
- the EIP155 chain ID of the transactionhash
- the hash of the transactionto_dict()
- serializes into a human-readable dictintrinsic_gas_used
- the amount of gas consumed by the
transaction, including the cost of the tx datacreates
- if the transaction creates a contract, returns the
contract addressnonce
, gasprice
, startgas
, to
, value
, data
,
v
, r
, s
- parameters in the transactionethereum.tools.keys
Creates encrypted private key storaes
- ``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.
ethereum.abi
~~~~~~~~~~~~
Most compilers for HLLs (solidity, serpent, viper, etc) on top of
Ethereum have the option to output an ABI declaration for a program.
This is a json object that looks something like this:
::
[{"name": "ecrecover(uint256,uint256,uint256,uint256)", "type": "function", "constant": false,
"inputs": [{"name": "h", "type": "uint256"}, {"name": "v", "type": "uint256"}, {"name": "r", "type": "uint256"}, {"name": "s", "type": "uint256"}],
"outputs": [{"name": "out", "type": "int256[]"}]},
{"name": "PubkeyTripleLogEvent(uint256,uint256,uint256)", "type": "event",
"inputs": [{"name": "x", "type": "uint256", "indexed": false}, {"name": "y", "type": "uint256", "indexed": false}, {"name": "z", "type": "uint256", "indexed": false}]}]
You can initialize an ``abi.ContractTranslator`` object to encode and
decode data for contracts as follows:
::
true, false = True, False
ct = abi.ContractTranslator(<json here>)
txdata = ct.encode('function_name', [arg1, arg2, arg3])
You can also call ``ct.decode_event([topic1, topic2...], logdata)`` to
decode a log.
RLP encoding and decoding
For any transaction or block, you can simply do:
::
import rlp
bindata = rlp.encode(<tx or block>)
To decode:
::
import rlp
from ethereum.transactions import Transaction
rlp.decode(blob, Transaction)
Or:
::
import rlp
from ethereum.blocks import Block
rlp.decode(blob, Block)
Consensus abstraction
The pyethereum codebase is designed to be maximally friendly for use
across many different consensus algorithms. If you want to add a new
consensus algo, you'll need to take the following steps:
- Add a directory alongside ``pow``, and in it create a ``chain.py``
class that implements a ``Chain`` module. This may have a totally
different fork choice rule for proof of work (GHOST, signature
counting, Casper, etc).
- Add an entry to ``consensus_strategy.py``. You will need to
implement:
- ``check_seal`` - check that a block is correctly "sealed" (mined,
signed, etc)
- ``validate_uncles(state, block)`` - check that uncles are valid
- ``initialize(state, block)`` - called in ``apply_block`` before
transactions are processed
- ``finalize(state, block)`` - called in ``apply_block`` after
transactions are processed
- ``get_uncle_candidates(chain, state)`` - called in
``mk_head_candidate`` to include uncles in a block
- Create a chain config with the ``CONSENSUS_STRATEGY`` set to whatever
you named your new consensus strategy
Tester module
-------------
See https://github.com/ethereum/pyethereum/wiki/Using-pyethereum.tester
Tests
-----
Run ``python3.6 -m pytest ethereum/tests/<filename>`` for any .py file
in that directory. Currently all tests are passing except for a few
Metropolis-specific state tests and block tests.
To make your own state tests, use the tester module as follows:
::
from ethereum.tools import tester as t
import json
c = t.Chain()
x = c.contract(<code>, language=<language>)
pre = t.mk_state_test_prefill(c)
x.foo(<args>)
post = t.mk_state_test_postfill(c, pre)
open('output.json', 'w').write(json.dumps(post, indent=4))
To make a test filler file instead, do
``post = t.mk_state_test_postfill(c, pre, True)``.
License
-------
See `LICENSE <LICENSE>`_
FAQs
Next generation cryptocurrency network
We found that ethereum demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.