def commit_state(self): if not len(self.journal): return for address in self.caches['all']: acct = rlp.decode(self.state.get(address.decode('hex'))) \ or self.mk_blank_acct() for i, (key, typ, default) in enumerate(acct_structure): if key == 'storage': t = trie.Trie(utils.get_db_path(), acct[i]) t.proof_mode = self.proof_mode t.proof_nodes = self.proof_nodes for k, v in self.caches.get('storage:' + address, {}).iteritems(): enckey = utils.zpad(utils.coerce_to_bytes(k), 32) val = rlp.encode(utils.int_to_big_endian(v)) if v: t.update(enckey, val) else: t.delete(enckey) acct[i] = t.root_hash if self.proof_mode == RECORDING: self.proof_nodes.extend(t.proof_nodes) else: if address in self.caches[key]: v = self.caches[key].get(address, default) acct[i] = utils.encoders[acct_structure[i][1]](v) self.state.update(address.decode('hex'), rlp.encode(acct)) if self.proof_mode == RECORDING: self.proof_nodes.extend(self.state.proof_nodes) self.state.proof_nodes = [] self.reset_cache()
def commit_state(self): changes = [] if not len(self.journal): # log_state.trace('delta', changes=[]) return for address in self.caches['all']: acct = rlp.decode(self.state.get(address.decode('hex'))) \ or self.mk_blank_acct() for i, (key, typ, default) in enumerate(acct_structure): if key == 'storage': t = trie.Trie(self.db, acct[i]) for k, v in self.caches.get('storage:' + address, {}).iteritems(): enckey = utils.zpad(utils.coerce_to_bytes(k), 32) val = rlp.encode(utils.int_to_big_endian(v)) changes.append(['storage', address, k, v]) if v: t.update(enckey, val) else: t.delete(enckey) acct[i] = t.root_hash else: if address in self.caches[key]: v = self.caches[key].get(address, default) changes.append([key, address, v]) acct[i] = self.encoders[acct_structure[i][1]](v) self.state.update(address.decode('hex'), rlp.encode(acct)) log_state.trace('delta', changes=changes) self.reset_cache()
def commit_state(self): if not len(self.journal): return for address in self.caches['all']: acct = rlp.decode(self.state.get(address.decode('hex'))) \ or self.mk_blank_acct() for i, (key, typ, default) in enumerate(acct_structure): if key == 'storage': t = trie.Trie(utils.get_db_path(), acct[i]) t.proof_mode = self.proof_mode t.proof_nodes = self.proof_nodes for k, v in self.caches.get('storage:'+address, {}).iteritems(): enckey = utils.zpad(utils.coerce_to_bytes(k), 32) val = rlp.encode(utils.int_to_big_endian(v)) if v: t.update(enckey, val) else: t.delete(enckey) acct[i] = t.root_hash if self.proof_mode == RECORDING: self.proof_nodes.extend(t.proof_nodes) else: if address in self.caches[key]: v = self.caches[key].get(address, default) acct[i] = utils.encoders[acct_structure[i][1]](v) self.state.update(address.decode('hex'), rlp.encode(acct)) if self.proof_mode == RECORDING: self.proof_nodes.extend(self.state.proof_nodes) self.state.proof_nodes = [] self.reset_cache()
def account_to_dict(self, address, with_storage_root=False, with_storage=True, for_vmtest=False): if with_storage_root: assert len(self.journal) == 0 med_dict = {} for i, val in enumerate(self.get_acct(address)): name, typ, default = acct_structure[i] key = acct_structure[i][0] if name == 'storage': strie = trie.Trie(self.db, val) if with_storage_root: med_dict['storage_root'] = strie.get_root_hash().encode('hex') else: med_dict[key] = utils.printers[typ](self.caches[key].get(address, val)) if with_storage: med_dict['storage'] = {} d = strie.to_dict() subcache = self.caches.get('storage:' + address, {}) subkeys = [utils.zpad(utils.coerce_to_bytes(kk), 32) for kk in subcache.keys()] for k in d.keys() + subkeys: v = d.get(k, None) v2 = subcache.get(utils.big_endian_to_int(k), None) hexkey = '0x' + utils.zunpad(k).encode('hex') if v2 is not None: if v2 != 0: med_dict['storage'][hexkey] = \ '0x' + utils.int_to_big_endian(v2).encode('hex') elif v is not None: med_dict['storage'][hexkey] = '0x' + rlp.decode(v).encode('hex') return med_dict
def listen(self, log, noprint=True): if not len(log.topics) or log.topics[0] not in self.event_data: return types = self.event_data[log.topics[0]]['types'] name = self.event_data[log.topics[0]]['name'] names = self.event_data[log.topics[0]]['names'] indexed = self.event_data[log.topics[0]]['indexed'] indexed_types = [types[i] for i in range(len(types)) if indexed[i]] unindexed_types = [ types[i] for i in range(len(types)) if not indexed[i] ] # print('listen', encode_hex(log.data), log.topics) deserialized_args = decode_abi(unindexed_types, log.data) o = {} c1, c2 = 0, 0 for i in range(len(names)): if indexed[i]: topic_bytes = utils.zpad(utils.encode_int(log.topics[c1 + 1]), 32) o[names[i]] = decode_single(process_type(indexed_types[c1]), topic_bytes) c1 += 1 else: o[names[i]] = deserialized_args[c2] c2 += 1 o["_event_type"] = utils.to_string(name) if not noprint: print(o) return o
def listen(self, log, noprint=True): if not len(log.topics) or log.topics[0] not in self.event_data: return types = self.event_data[log.topics[0]]['types'] name = self.event_data[log.topics[0]]['name'] names = self.event_data[log.topics[0]]['names'] indexed = self.event_data[log.topics[0]]['indexed'] indexed_types = [types[i] for i in range(len(types)) if indexed[i]] unindexed_types = [types[i] for i in range(len(types)) if not indexed[i]] # print('listen', encode_hex(log.data), log.topics) deserialized_args = decode_abi(unindexed_types, log.data) o = {} c1, c2 = 0, 0 for i in range(len(names)): if indexed[i]: topic_bytes = utils.zpad(utils.encode_int(log.topics[c1 + 1]), 32) o[names[i]] = decode_single(process_type(indexed_types[c1]), topic_bytes) c1 += 1 else: o[names[i]] = deserialized_args[c2] c2 += 1 o["_event_type"] = utils.to_string(name) if not noprint: print(o) return o
def serialize(self): return [ self.address.decode('hex'), [utils.zpad(utils.encode_int(x), 32) for x in self.topics], # why zpad? self.data ]
def to_dict(self): return dict(address=self.address, topics=[ utils.zpad(utils.int_to_big_endian(x), 32).encode('hex') for x in self.topics ], data='0x' + self.data.encode('hex'))
def account_to_dict(self, address, with_storage_root=False, with_storage=True): if with_storage_root: assert len(self.journal) == 0 med_dict = {} for i, val in enumerate(self.get_acct(address)): name, typ, default = acct_structure[i] key = acct_structure[i][0] if name == 'storage': strie = trie.Trie(utils.get_db_path(), val) if with_storage_root: med_dict['storage_root'] = strie.get_root_hash().encode('hex') else: med_dict[key] = self.caches[key].get(address, utils.printers[typ](val)) if with_storage: med_dict['storage'] = {} d = strie.to_dict() subcache = self.caches.get('storage:'+address, {}) subkeys = [utils.zpad(utils.coerce_to_bytes(kk), 32) for kk in subcache.keys()] for k in d.keys() + subkeys: v = d.get(k, None) v2 = subcache.get(utils.big_endian_to_int(k), None) hexkey = '0x'+k.encode('hex') if v2 is not None: if v2 != 0: med_dict['storage'][hexkey] = '0x'+utils.int_to_big_endian(v2).encode('hex') elif v is not None: med_dict['storage'][hexkey] = '0x'+rlp.decode(v).encode('hex') return med_dict
def load_state(env, alloc): db = env.db state = SecureTrie(Trie(db, BLANK_ROOT)) count = 0 databaseLog.debug("Loading state from snapshot") for addr in alloc: databaseLog.debug("[%d] loading account %s", count, addr) account = alloc[addr] acct = Account.blank_account(db, env.config['ACCOUNT_INITIAL_NONCE']) if len(account['storage']) > 0: t = SecureTrie(Trie(db, BLANK_ROOT)) c = 0 for k in account['storage']: v = account['storage'][k] enckey = zpad(decode_hex(k), 32) t.update(enckey, decode_hex(v)) c += 1 if c % 1000 and len(db.db_service.uncommitted) > 50000: databaseLog.debug("%d uncommitted. committing...", len(db.db_service.uncommitted)) db.commit() acct.storage = t.root_hash if account['nonce']: acct.nonce = int(account['nonce']) if account['balance']: acct.balance = int(account['balance']) state.update(decode_hex(addr), rlp.encode(acct)) count += 1 db.commit() return state
def get_storage_data(self, address, index): CACHE_KEY = 'storage:'+address if CACHE_KEY in self.caches: if index in self.caches[CACHE_KEY]: return self.caches[CACHE_KEY][index] key = utils.zpad(utils.coerce_to_bytes(index), 32) val = rlp.decode(self.get_storage(address).get(key)) return utils.big_endian_to_int(val) if val else 0
def get_storage_data(self, address, index): if address in self.caches['storage']: if index in self.caches['storage'][address]: return self.caches['storage'][address][index] t = self.get_storage(address) key = utils.zpad(utils.coerce_to_bytes(index), 32) val = rlp.decode(t.get(key)) return utils.big_endian_to_int(val) if val else 0
def get_storage_data(self, address, index): if 'storage:' + address in self.caches: if index in self.caches['storage:' + address]: return self.caches['storage:' + address][index] t = self.get_storage(address) t.proof_mode = self.proof_mode t.proof_nodes = self.proof_nodes key = utils.zpad(utils.coerce_to_bytes(index), 32) val = rlp.decode(t.get(key)) if self.proof_mode == RECORDING: self.proof_nodes.extend(t.proof_nodes) return utils.big_endian_to_int(val) if val else 0
def get_storage_data(self, address, index): if 'storage:'+address in self.caches: if index in self.caches['storage:'+address]: return self.caches['storage:'+address][index] t = self.get_storage(address) t.proof_mode = self.proof_mode t.proof_nodes = self.proof_nodes key = utils.zpad(utils.coerce_to_bytes(index), 32) val = rlp.decode(t.get(key)) if self.proof_mode == RECORDING: self.proof_nodes.extend(t.proof_nodes) return utils.big_endian_to_int(val) if val else 0
def mine(full_size, dataset, header, difficulty): from random import randint # computing difficulty target target = zpad(encode_int(2**256 // difficulty), 64)[::-1] # nonces are randomly generated nonce = randint(0, 2**64) while hashimoto_full(full_size, dataset, header, nonce) > target: nonce = (nonce + 1) % 2**64 return nonce
def commit_state(self): for address in self.caches['all']: acct = rlp.decode(self.state.get(address.decode('hex'))) \ or self.mk_blank_acct() for i, (key, typ, default) in enumerate(acct_structure): if key == 'storage': t = trie.Trie(utils.get_db_path(), acct[i]) for k, v in self.caches[key].get(address, {}).iteritems(): enckey = utils.zpad(utils.coerce_to_bytes(k), 32) val = rlp.encode(utils.int_to_big_endian(v)) if v: t.update(enckey, val) else: t.delete(enckey) acct[i] = t.root_hash else: if address in self.caches[key]: v = self.caches[key].get(address, default) acct[i] = utils.encoders[acct_structure[i][1]](v) self.state.update(address.decode('hex'), rlp.encode(acct)) self.reset_cache()
def encode_function_call(self, function_name, args): """ Return the encoded function call. Args: function_name (str): One of the existing functions described in the contract interface. args (List[object]): The function arguments that wll be encoded and used in the contract execution in the vm. Return: bin: The encoded function name and arguments so that it can be used with the evm to execute a funcion call, the binary string follows the Ethereum Contract ABI. """ if function_name not in self.function_data: raise ValueError('Unkown function {}'.format(function_name)) description = self.function_data[function_name] function_selector = zpad(encode_int(description['prefix']), 4) arguments = encode_abi(description['encode_types'], args) return function_selector + arguments
def b64(int_bloom): "returns b64" return utils.zpad(utils.int_to_big_endian(int_bloom), 64)
import utils from db import BaseDB, EphemDB default_config = dict( # Genesis block prevhash, coinbase, nonce GENESIS_PREVHASH=b'\x00' * 32, GENESIS_COINBASE=b'\x00' * 20, GENESIS_NONCE=utils.zpad(utils.encode_int(42), 8), GENESIS_MIXHASH=b'\x00' * 32, GENESIS_TIMESTAMP=0, GENESIS_EXTRA_DATA=b'', GENESIS_INITIAL_ALLOC={}, # Gas limit adjustment algo: # block.gas_limit=block.parent.gas_limit * 1023/1024 + # (block.gas_used * 6 / 5) / 1024 #SHA-256 hash of 'IPchain is a blockchain developed at the Broadband Communications Research Group, used to study the feasability of a Proof of Stake blockchain to store and exchange IP addresses' GENESIS_RANDOM_NO= 'a37172904aa905e74d00879fced7b721444ebdd2a598a1a5daf4726b66698782', GENESIS_GROUP_PUBLIC_KEY= '1 0x1449b385fbaed403e317430c8eced0d3b1f364ebfdd1ac9b1143e9a36def7651 0x181765270a148c0d455d20c1bbf78b6b2f9ed33f3ec8bbf96daff04bd4e88fde 0xf97fc07c06decd75f99a488d0731ef8117660b27a217df18a50c663b9b16b49 0x11c177b86813af3d9ea5bc38ba3107dc2cbc23675dc3c00c870b2eac4309181b', GENESIS_GROUP_SIGNATURE= '1 0xfd0d20db0a7f2f068fa57ad2ee40a3bb679fd3e24db0160eaf01e71b3358423 0x168a542a094ae73d8a1053abdde70bfa4b9969779bab2bab6548d1621ed33a6c', GASLIMIT_EMA_FACTOR=1024, GASLIMIT_ADJMAX_FACTOR=1024, BLOCK_GAS_LIMIT=4712388, BLKLIM_FACTOR_NOM=3, BLKLIM_FACTOR_DEN=2, # Network ID NETWORK_ID=1, ACCOUNT_INITIAL_NONCE=0, PREV_HEADER_DEPTH=256,
def bloomables(self): return [self.address.decode('hex')] + \ [utils.zpad(utils.encode_int(x), 32) for x in self.topics] # why zpad?
def encode_single(typ, arg): base, sub, _ = typ # Unsigned integers: uint<sz> if base == 'uint': sub = int(sub) i = decint(arg, False) if not 0 <= i < 2 ** sub: raise ValueOutOfBounds(repr(arg)) return zpad(encode_int(i), 32) # bool: int<sz> elif base == 'bool': assert isinstance(arg, bool) return zpad(encode_int(int(arg)), 32) # Signed integers: int<sz> elif base == 'int': sub = int(sub) i = decint(arg, True) if not -2 ** (sub - 1) <= i < 2 ** (sub - 1): raise ValueOutOfBounds(repr(arg)) return zpad(encode_int(i % 2 ** sub), 32) # Unsigned reals: ureal<high>x<low> elif base == 'ureal': high, low = [int(x) for x in sub.split('x')] if not 0 <= arg < 2 ** high: raise ValueOutOfBounds(repr(arg)) return zpad(encode_int(int(arg * 2 ** low)), 32) # Signed reals: real<high>x<low> elif base == 'real': high, low = [int(x) for x in sub.split('x')] if not -2 ** (high - 1) <= arg < 2 ** (high - 1): raise ValueOutOfBounds(repr(arg)) i = int(arg * 2 ** low) return zpad(encode_int(i % 2 ** (high + low)), 32) # Strings elif base == 'string' or base == 'bytes': if not is_string(arg): raise EncodingError("Expecting string: %r" % arg) # Fixed length: string<sz> if len(sub): assert int(sub) <= 32 assert len(arg) <= int(sub) return arg + b'\x00' * (32 - len(arg)) # Variable length: string else: return zpad(encode_int(len(arg)), 32) + \ arg + \ b'\x00' * (utils.ceil32(len(arg)) - len(arg)) # Hashes: hash<sz> elif base == 'hash': if not (int(sub) and int(sub) <= 32): raise EncodingError("too long: %r" % arg) if isnumeric(arg): return zpad(encode_int(arg), 32) elif len(arg) == int(sub): return zpad(arg, 32) elif len(arg) == int(sub) * 2: return zpad(decode_hex(arg), 32) else: raise EncodingError("Could not parse hash: %r" % arg) # Addresses: address (== hash160) elif base == 'address': assert sub == '' if isnumeric(arg): return zpad(encode_int(arg), 32) elif len(arg) == 20: return zpad(arg, 32) elif len(arg) == 40: return zpad(decode_hex(arg), 32) elif len(arg) == 42 and arg[:2] in {'0x', b'0x'}: return zpad(decode_hex(arg[2:]), 32) else: raise EncodingError("Could not parse address: %r" % arg) raise EncodingError("Unhandled type: %r %r" % (base, sub))
def sub1(b): v = utils.big_endian_to_int(b) return utils.zpad(utils.encode_int(v - 1), 4)
def encode_single(typ, arg): base, sub, _ = typ # Unsigned integers: uint<sz> if base == 'uint': sub = int(sub) i = decint(arg, False) if not 0 <= i < 2**sub: raise ValueOutOfBounds(repr(arg)) return zpad(encode_int(i), 32) # bool: int<sz> elif base == 'bool': assert isinstance(arg, bool) return zpad(encode_int(int(arg)), 32) # Signed integers: int<sz> elif base == 'int': sub = int(sub) i = decint(arg, True) if not -2**(sub - 1) <= i < 2**(sub - 1): raise ValueOutOfBounds(repr(arg)) return zpad(encode_int(i % 2**sub), 32) # Unsigned reals: ureal<high>x<low> elif base == 'ureal': high, low = [int(x) for x in sub.split('x')] if not 0 <= arg < 2**high: raise ValueOutOfBounds(repr(arg)) return zpad(encode_int(int(arg * 2**low)), 32) # Signed reals: real<high>x<low> elif base == 'real': high, low = [int(x) for x in sub.split('x')] if not -2**(high - 1) <= arg < 2**(high - 1): raise ValueOutOfBounds(repr(arg)) i = int(arg * 2**low) return zpad(encode_int(i % 2**(high + low)), 32) # Strings elif base == 'string' or base == 'bytes': if not is_string(arg): raise EncodingError("Expecting string: %r" % arg) # Fixed length: string<sz> if len(sub): assert int(sub) <= 32 assert len(arg) <= int(sub) return arg + b'\x00' * (32 - len(arg)) # Variable length: string else: return zpad(encode_int(len(arg)), 32) + \ arg + \ b'\x00' * (utils.ceil32(len(arg)) - len(arg)) # Hashes: hash<sz> elif base == 'hash': if not (int(sub) and int(sub) <= 32): raise EncodingError("too long: %r" % arg) if isnumeric(arg): return zpad(encode_int(arg), 32) elif len(arg) == int(sub): return zpad(arg, 32) elif len(arg) == int(sub) * 2: return zpad(decode_hex(arg), 32) else: raise EncodingError("Could not parse hash: %r" % arg) # Addresses: address (== hash160) elif base == 'address': assert sub == '' if isnumeric(arg): return zpad(encode_int(arg), 32) elif len(arg) == 20: return zpad(arg, 32) elif len(arg) == 40: return zpad(decode_hex(arg), 32) elif len(arg) == 42 and arg[:2] == '0x': return zpad(decode_hex(arg[2:]), 32) else: raise EncodingError("Could not parse address: %r" % arg) raise EncodingError("Unhandled type: %r %r" % (base, sub))
def to_dict(self): return dict(address=self.address, topics=[utils.zpad(utils.int_to_big_endian(x), 32).encode('hex') for x in self.topics], data='0x' + self.data.encode('hex'))
def add1(b): v = utils.big_endian_to_int(b) return utils.zpad(utils.encode_int(v + 1), 4)