|
| 1 | +This is the Python core library of the Ethereum project. |
| 2 | + |
| 3 | +For the python based command line client see: |
| 4 | +https://github.com/ethereum/pyethapp |
| 5 | + |
| 6 | +Installation: |
| 7 | +------------- |
| 8 | + |
| 9 | +``git clone https://github.com/ethereum/pyethereum/`` |
| 10 | + |
| 11 | +``cd pyethereum`` |
| 12 | + |
| 13 | +``python setup.py install`` |
| 14 | + |
| 15 | +Components |
| 16 | +---------- |
| 17 | + |
| 18 | +ethereum.pow.chain |
| 19 | +~~~~~~~~~~~~~~~~~~ |
| 20 | + |
| 21 | +Contains the Chain class, which can be used to manage a blockchain. Main |
| 22 | +methods are: |
| 23 | + |
| 24 | +- ``__init__(genesis=None, env=None, new_head_cb=None, reset_genesis=False, localtime=None)`` |
| 25 | + - initializes with the given genesis. ``env`` specifies the |
| 26 | + *environment* (including chain config and database), ``new_head_cb`` |
| 27 | + is a callback called when a new head is added, and ``localtime`` is |
| 28 | + what the chain assumes is the current timestamp. The genesis can be: |
| 29 | + |
| 30 | + - None - in which case it assumes ``env`` is given, and creates a |
| 31 | + Chain object with the data saved in ``env.db``. If |
| 32 | + ``reset_genesis`` is set, it re-initializes the chain. |
| 33 | + - A ``State`` object |
| 34 | + - A genesis declaration |
| 35 | + - A state snapshot (``State.snapshot()``) |
| 36 | + - An allocation (ie. dict |
| 37 | + ``{address: {balance: 1, nonce: 2, code: b'\x03\x04\x05', storage: {"0x06": "0x07"}}}``) |
| 38 | + |
| 39 | +- ``add_block(block)`` - adds a block to the chain |
| 40 | +- ``process_time_queue(timestamp)`` - tells the chain that the current |
| 41 | + time has increased to the new timestamp. The chain will then process |
| 42 | + any blocks that were unprocessed because they appeared too "early" |
| 43 | +- ``get_blockhash_by_number(num)`` - get the block hash of a block at |
| 44 | + the given block number |
| 45 | +- ``get_block(hash)`` - gets the block with the given blockhash |
| 46 | +- ``get_block_by_number(num)`` - equivalent to |
| 47 | + ``get_block(get_blockhash_by_number(num))`` |
| 48 | +- ``get_parent(block)`` - gets the parent of a block |
| 49 | +- ``get_children(block)`` - gets the children of a block |
| 50 | +- ``head`` (property) - gets the block at the head of the chain |
| 51 | +- ``state`` (property) - gets the state at the head of the chain |
| 52 | +- ``mk_poststate_of_blockhash(hash)`` - creates a state object after a |
| 53 | + given block |
| 54 | +- ``has_block(block)`` - is that block in the chain? Returns True/False |
| 55 | +- ``get_chain(from, to)`` - roughly equivalent to |
| 56 | + ``[get_block_by_number(i) for i in range(from, to)]``, though |
| 57 | + automatically stops if it reaches the head. ``from`` can be elided to |
| 58 | + start from genesis, ``to`` can be elided to go up to the head. |
| 59 | +- ``get_tx_position(tx)`` - if the transaction is in the chain, returns |
| 60 | + ``(blknum, index)`` where ``blknum`` is the block number of the block |
| 61 | + that contains the transaction and ``index`` is its position in the |
| 62 | + block |
| 63 | + |
| 64 | +ethereum.state |
| 65 | +~~~~~~~~~~~~~~ |
| 66 | + |
| 67 | +Contains the State class, which is used to manage a state. Main methods |
| 68 | +are: |
| 69 | + |
| 70 | +- ``__init__(root_hash, env, **kwargs)`` - initializes a state with the |
| 71 | + given root hash, the given env (which includes a config and database) |
| 72 | + and the given auxiliary arguments. These include: |
| 73 | + |
| 74 | + - ``txindex`` - the transaction index |
| 75 | + - ``gas_used`` - amount of gas used |
| 76 | + - ``gas_limit`` - block gas limit |
| 77 | + - ``block_number`` - block number |
| 78 | + - ``block_coinbase`` - block coinbase address |
| 79 | + - ``block_difficulty`` - block difficulty |
| 80 | + - ``timestamp`` - timestamp |
| 81 | + - ``logs`` - logs created so far |
| 82 | + - ``receipts`` - receipts created so far (from previous transactions |
| 83 | + in the current block) |
| 84 | + - ``bloom`` - the bloom filter |
| 85 | + - ``suicides`` - suicides (or selfdestructs, the newer more |
| 86 | + politically correct synonym) |
| 87 | + - ``recent_uncles`` - recent uncle blocks in the chain |
| 88 | + - ``prev_headers`` - previous block headers |
| 89 | + - ``refunds`` - suicide/selfdestruct refund counter |
| 90 | + |
| 91 | +Pyethereum follows a **maximally state-centric model**; the ONLY |
| 92 | +information needed to process a transaction or a block is located within |
| 93 | +the state itself, allowing the actual state transition logic to be a |
| 94 | +very clean ``apply_transaction(state, tx)`` and |
| 95 | +``apply_block(state, block)``. |
| 96 | + |
| 97 | +- ``get_balance``- gets the balance of an account |
| 98 | +- ``get_code`` - gets the code of an account |
| 99 | +- ``get_storage_data(addr, k)`` - gets the storage at the given key of |
| 100 | + the given address. Expects a key in **numerical** form (eg. b"cow" or |
| 101 | + "0x636f77" is represented as 6516599). |
| 102 | +- ``to_snapshot(root_only=False, no_prevblocks=False)`` - creates a |
| 103 | + snapshot for the current state. If ``root_only`` is set, only adds |
| 104 | + the state root, not the entire state. If ``no_prevblocks`` is set, |
| 105 | + does not add previous headers and uncles. Setting either of those |
| 106 | + flags means that the same database would be required to recover from |
| 107 | + the snapshot. |
| 108 | +- ``from_snapshot(snapshot, env)`` (classmethod) - creates a state from |
| 109 | + the given snapshot with the given ``env``. |
| 110 | +- ``ephemeral_clone()`` - creates a clone of the state that you can |
| 111 | + work with without affecting the original |
| 112 | + |
| 113 | +There are also many methods that modify the state, eg. ``set_code``, |
| 114 | +``set_storage_data``, but it is generally recommended to avoid using |
| 115 | +these, and instead modify the state ONLY through ``apply_transaction`` |
| 116 | +and ``apply_block``. |
| 117 | + |
| 118 | +ethereum.meta |
| 119 | +~~~~~~~~~~~~~ |
| 120 | + |
| 121 | +This file contains two functions: |
| 122 | + |
| 123 | +- ``apply_block(state, block)`` - takes a state and processes a block |
| 124 | + onto that state |
| 125 | +- ``make_head_candidate(chain, txqueue=None, parent=None, timestamp, coinbase, extra_data, min_gasprice=0)`` |
| 126 | + - creates a candidate block for the chain on top of the given parent |
| 127 | + block (default: head of the chain). Gets transactions from the given |
| 128 | + ``txqueue`` object with the given ``mingasprice`` (otherwise does not |
| 129 | + add transactions). ``timestamp``, ``coinbase`` and ``extra_data`` can |
| 130 | + be used to specify those parameters in the block; otherwise defaults |
| 131 | + are used |
| 132 | + |
| 133 | +ethereum.messages |
| 134 | +~~~~~~~~~~~~~~~~~ |
| 135 | + |
| 136 | +The main function that should be called from here is |
| 137 | +``apply_transaction(state, tx)``. |
| 138 | + |
| 139 | +ethereum.utils |
| 140 | +~~~~~~~~~~~~~~ |
| 141 | + |
| 142 | +Contains a bunch of utility functions, including: |
| 143 | + |
| 144 | +Numerical and hex conversions |
| 145 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 146 | + |
| 147 | +- ``encode_int(i)`` - converts an integer into big-endian binary |
| 148 | + representation |
| 149 | +- ``zpad(data, length)`` - pads the data up to the desired length by |
| 150 | + adding zero bytes on the left |
| 151 | +- ``encode_int32(i)`` - equivalent to ``zpad(encode_int(i), 32)`` but |
| 152 | + faster |
| 153 | +- ``big_endian_to_int(d)`` - converts binary data into an integer |
| 154 | +- ``encode_hex(b)`` - converts bytes to hex |
| 155 | +- ``decode_hex(h)`` - converts hex to bytes |
| 156 | +- ``int_to_addr(i)`` - converts integer to address |
| 157 | +- ``is_numeric(i)`` - returns True if the value is int or long, |
| 158 | + otherwise False |
| 159 | + |
| 160 | +Cryptography |
| 161 | +^^^^^^^^^^^^ |
| 162 | + |
| 163 | +- ``sha3(data)`` - computes the SHA3 (or more precisely, keccak256) |
| 164 | + hash |
| 165 | +- ``ecrecover_to_pub(hash, v, r, s)`` - recovers the public key that |
| 166 | + made the signature as a 64-byte binary blob of |
| 167 | + ``encode_int32(x) + encode_int32(y)``. Hashing this and taking the |
| 168 | + last 20 bytes gives the *address* that signed a message. |
| 169 | +- ``ecsign(hash, key)`` - returns the v, r, s values of a signature |
| 170 | +- ``normalize_key(key)`` - converts a key from many formats into |
| 171 | + 32-byte binary |
| 172 | +- ``privtoaddr(key)`` - converts a key to an address |
| 173 | + |
| 174 | +Addresses |
| 175 | +^^^^^^^^^ |
| 176 | + |
| 177 | +- ``normalize_address(addr)`` - converts an address into 20-byte binary |
| 178 | + form |
| 179 | +- ``check_checksum(addr)`` - returns True if the address checksum |
| 180 | + passes, otherwise False |
| 181 | +- ``checksum_encode(addr)`` - converts an address into hex form with a |
| 182 | + checksum |
| 183 | +- ``mk_contract_address(addr, nonce)`` - creates the address of a |
| 184 | + contract created by the given address with the given nonce |
| 185 | + |
| 186 | +Miscellaneous |
| 187 | +^^^^^^^^^^^^^ |
| 188 | + |
| 189 | +- ``denoms`` - contains the denominations of ether, eg. |
| 190 | + ``denoms.finney = 10**15``, ``denoms.shannon = 10**9``, |
| 191 | + ``denoms.gwei = 10**9`` |
| 192 | + |
| 193 | +ethereum.block |
| 194 | +~~~~~~~~~~~~~~ |
| 195 | + |
| 196 | +Contains the ``Block`` and ``BlockHeader`` classes. Generally |
| 197 | +recommended to avoid creating blocks and block headers directly, instead |
| 198 | +using ``mk_head_candidate``. The member variables are straightforward: |
| 199 | + |
| 200 | +- ``block.transactions`` - transactions in a block |
| 201 | +- ``block.uncles`` - uncles in a block |
| 202 | +- ``block.header`` - header of a block |
| 203 | + |
| 204 | +And in the header: |
| 205 | + |
| 206 | +- ``header.hash`` - the hash (also the block hash) |
| 207 | +- ``header.mining_hash`` - the hash used for proof of work mining |
| 208 | +- ``header.to_dict()`` - serializes into a human-readable dict |
| 209 | +- ``header.prevhash`` - previous block hash |
| 210 | +- ``header.uncles_hash`` - hash of the uncle list |
| 211 | +- ``header.coinbase`` - coinbase (miner) address |
| 212 | +- ``header.state_root`` - root hash of the post-state |
| 213 | +- ``header.tx_list_root`` - hash of the transactions in the block |
| 214 | +- ``header.receipts_root`` - hash of the receipt trie |
| 215 | +- ``header.bloom`` - bloom filter |
| 216 | +- ``header.difficulty`` - block difficulty |
| 217 | +- ``header.number`` - block number |
| 218 | +- ``header.gas_limit`` - gas limit |
| 219 | +- ``header.gas_used`` - gas used |
| 220 | +- ``header.timestamp`` - timestamp |
| 221 | +- ``header.extra_data`` - block extra data |
| 222 | +- ``header.mixhash`` and ``header.nonce`` - Ethash proof of work values |
| 223 | + |
| 224 | +ethereum.transactions |
| 225 | +~~~~~~~~~~~~~~~~~~~~~ |
| 226 | + |
| 227 | +Contains the Transaction class, with the following methods and values: |
| 228 | + |
| 229 | +- ``__init__(nonce, gasprice, startgas, to, value, data, (v, r, s optional))`` |
| 230 | + - constructor |
| 231 | +- ``sign(key, network_id=None)`` - signs the transaction with the given |
| 232 | + key, and with the given EIP155 chain ID (leaving as None will create |
| 233 | + a pre-EIP155 tx, be warned of replay attacks if you do this!) |
| 234 | +- ``sender`` - the sender address of the transaction |
| 235 | +- ``network_id`` - the EIP155 chain ID of the transaction |
| 236 | +- ``hash`` - the hash of the transaction |
| 237 | +- ``to_dict()`` - serializes into a human-readable dict |
| 238 | +- ``intrinsic_gas_used`` - the amount of gas consumed by the |
| 239 | + transaction, including the cost of the tx data |
| 240 | +- ``creates`` - if the transaction creates a contract, returns the |
| 241 | + contract address |
| 242 | +- ``nonce``, ``gasprice``, ``startgas``, ``to``, ``value``, ``data``, |
| 243 | + ``v``, ``r``, ``s`` - parameters in the transaction |
| 244 | + |
| 245 | +ethereum.tools.keys |
| 246 | +~~~~~~~~~~~~~~~~~~~ |
| 247 | + |
| 248 | +Creates encrypted private key storaes |
| 249 | + |
| 250 | +- ``decode_keystore_json(jsondata, password)`` - returns the private |
| 251 | + key from an encrypted keystore object. NOTE: if you are loading from |
| 252 | + a file, the most convenient way to do this is |
| 253 | + ``import json; key = decode_keystore_json(json.load(open('filename.json')), 'password')`` |
| 254 | +- ``make_keystore_json(key, pw, kdf='pbkdf2', cipher='aes-128-ctr')`` - |
| 255 | + creates an encrypted keystore object for the key. Keeping ``kdf`` and |
| 256 | + ``cipher`` at their default values is recommended. |
| 257 | + |
| 258 | +ethereum.abi |
| 259 | +~~~~~~~~~~~~ |
| 260 | + |
| 261 | +Most compilers for HLLs (solidity, serpent, viper, etc) on top of |
| 262 | +Ethereum have the option to output an ABI declaration for a program. |
| 263 | +This is a json object that looks something like this: |
| 264 | + |
| 265 | +:: |
| 266 | + |
| 267 | + [{"name": "ecrecover(uint256,uint256,uint256,uint256)", "type": "function", "constant": false, |
| 268 | + "inputs": [{"name": "h", "type": "uint256"}, {"name": "v", "type": "uint256"}, {"name": "r", "type": "uint256"}, {"name": "s", "type": "uint256"}], |
| 269 | + "outputs": [{"name": "out", "type": "int256[]"}]}, |
| 270 | + {"name": "PubkeyTripleLogEvent(uint256,uint256,uint256)", "type": "event", |
| 271 | + "inputs": [{"name": "x", "type": "uint256", "indexed": false}, {"name": "y", "type": "uint256", "indexed": false}, {"name": "z", "type": "uint256", "indexed": false}]}] |
| 272 | + |
| 273 | +You can initialize an ``abi.ContractTranslator`` object to encode and |
| 274 | +decode data for contracts as follows: |
| 275 | + |
| 276 | +:: |
| 277 | + |
| 278 | + true, false = True, False |
| 279 | + ct = abi.ContractTranslator(<json here>) |
| 280 | + txdata = ct.encode('function_name', [arg1, arg2, arg3]) |
| 281 | + |
| 282 | +You can also call ``ct.decode_event([topic1, topic2...], logdata)`` to |
| 283 | +decode a log. |
| 284 | + |
| 285 | +RLP encoding and decoding |
| 286 | +~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 287 | + |
| 288 | +For any transaction or block, you can simply do: |
| 289 | + |
| 290 | +:: |
| 291 | + |
| 292 | + import rlp |
| 293 | + bindata = rlp.encode(<tx or block>) |
| 294 | + |
| 295 | +To decode: |
| 296 | + |
| 297 | +:: |
| 298 | + |
| 299 | + import rlp |
| 300 | + from ethereum.transactions import Transaction |
| 301 | + rlp.decode(blob, Transaction) |
| 302 | + |
| 303 | +Or: |
| 304 | + |
| 305 | +:: |
| 306 | + |
| 307 | + import rlp |
| 308 | + from ethereum.blocks import Block |
| 309 | + rlp.decode(blob, Block) |
| 310 | + |
| 311 | +Consensus abstraction |
| 312 | +~~~~~~~~~~~~~~~~~~~~~ |
| 313 | + |
| 314 | +The pyethereum codebase is designed to be maximally friendly for use |
| 315 | +across many different consensus algorithms. If you want to add a new |
| 316 | +consensus algo, you'll need to take the following steps: |
| 317 | + |
| 318 | +- Add a directory alongside ``pow``, and in it create a ``chain.py`` |
| 319 | + class that implements a ``Chain`` module. This may have a totally |
| 320 | + different fork choice rule for proof of work (GHOST, signature |
| 321 | + counting, Casper, etc). |
| 322 | +- Add an entry to ``consensus_strategy.py``. You will need to |
| 323 | + implement: |
| 324 | + |
| 325 | + - ``check_seal`` - check that a block is correctly "sealed" (mined, |
| 326 | + signed, etc) |
| 327 | + - ``validate_uncles(state, block)`` - check that uncles are valid |
| 328 | + - ``initialize(state, block)`` - called in ``apply_block`` before |
| 329 | + transactions are processed |
| 330 | + - ``finalize(state, block)`` - called in ``apply_block`` after |
| 331 | + transactions are processed |
| 332 | + - ``get_uncle_candidates(chain, state)`` - called in |
| 333 | + ``mk_head_candidate`` to include uncles in a block |
| 334 | + |
| 335 | +- Create a chain config with the ``CONSENSUS_STRATEGY`` set to whatever |
| 336 | + you named your new consensus strategy |
| 337 | + |
| 338 | +Tester module |
| 339 | +------------- |
| 340 | + |
| 341 | +See https://github.com/ethereum/pyethereum/wiki/Using-pyethereum.tester |
| 342 | + |
| 343 | +Tests |
| 344 | +----- |
| 345 | + |
| 346 | +Run ``python3.6 -m pytest ethereum/tests/<filename>`` for any .py file |
| 347 | +in that directory. Currently all tests are passing except for a few |
| 348 | +Metropolis-specific state tests and block tests. |
| 349 | + |
| 350 | +To make your own state tests, use the tester module as follows: |
| 351 | + |
| 352 | +:: |
| 353 | + |
| 354 | + from ethereum.tools import tester as t |
| 355 | + import json |
| 356 | + c = t.Chain() |
| 357 | + x = c.contract(<code>, language=<language>) |
| 358 | + pre = t.mk_state_test_prefill(c) |
| 359 | + x.foo(<args>) |
| 360 | + post = t.mk_state_test_postfill(c, pre) |
| 361 | + open('output.json', 'w').write(json.dumps(post, indent=4)) |
| 362 | + |
| 363 | +To make a test filler file instead, do |
| 364 | +``post = t.mk_state_test_postfill(c, pre, True)``. |
| 365 | + |
| 366 | +Licence |
| 367 | +------- |
| 368 | + |
| 369 | +See LICENCE |
0 commit comments