@ -11,21 +11,21 @@ from mythril.ether.ethcontract import ETHContract
# Per https://github.com/ethereum/go-ethereum/blob/master/core/database_util.go
# prefixes and suffixes for keys in geth
headerP refix = b ' h ' # headerP refix + num (uint64 big endian) + hash -> header
bodyP refix = b ' b ' # bodyP refix + num (uint64 big endian) + hash -> block body
numS uffix = b ' n ' # headerPrefix + num (uint64 big endian) + numS uffix -> hash
blockHashP refix = b ' H ' # blockHashP refix + hash -> num (uint64 big endian)
blockReceiptsP refix = b ' r ' # blockReceiptsP refix + num (uint64 big endian) + hash -> block receipts
header_p refix = b ' h ' # header_p refix + num (uint64 big endian) + hash -> header
body_p refix = b ' b ' # body_p refix + num (uint64 big endian) + hash -> block body
num_s uffix = b ' n ' # header_prefix + num (uint64 big endian) + num_s uffix -> hash
block_hash_p refix = b ' H ' # block_hash_p refix + hash -> num (uint64 big endian)
block_receipts_p refix = b ' r ' # block_receipts_p refix + num (uint64 big endian) + hash -> block receipts
# known geth keys
headHeaderK ey = b ' LastBlock ' # head (latest) header hash
head_header_k ey = b ' LastBlock ' # head (latest) header hash
# custom prefixes
addressP refix = b ' AM ' # addressP refix + hash -> address
address_p refix = b ' AM ' # address_p refix + hash -> address
# custom keys
addressMappingHeadK ey = b ' accountMapping ' # head (latest) number of indexed block
headHeaderK ey = b ' LastBlock ' # head (latest) header hash
address_mapping_head_k ey = b ' accountMapping ' # head (latest) number of indexed block
head_header_k ey = b ' LastBlock ' # head (latest) header hash
def _formatBlockN umber ( number ) :
def _format_block_n umber ( number ) :
'''
formats block number to uint64 big endian
'''
@ -46,87 +46,87 @@ class LevelDBReader(object):
def __init__ ( self , db ) :
self . db = db
self . headBlockH eader = None
self . headS tate = None
self . head_block_h eader = None
self . head_s tate = None
def _get_head_state ( self ) :
'''
gets head state
'''
if not self . headS tate :
if not self . head_s tate :
root = self . _get_head_block ( ) . state_root
self . headS tate = State ( self . db , root )
return self . headS tate
self . head_s tate = State ( self . db , root )
return self . head_s tate
def _get_account ( self , address ) :
'''
gets account by address
'''
state = self . _get_head_state ( )
accountA ddress = binascii . a2b_hex ( utils . remove_0x_head ( address ) )
return state . get_and_cache_account ( accountA ddress )
account_a ddress = binascii . a2b_hex ( utils . remove_0x_head ( address ) )
return state . get_and_cache_account ( account_a ddress )
def _get_block_hash ( self , number ) :
'''
gets block hash by block number
'''
num = _formatBlockN umber ( number )
hashKey = headerP refix + num + numS uffix
return self . db . get ( hashK ey )
num = _format_block_n umber ( number )
hash_key = header_p refix + num + num_s uffix
return self . db . get ( hash_k ey )
def _get_head_block ( self ) :
'''
gets head block header
'''
if not self . headBlockH eader :
hash = self . db . get ( headHeaderK ey )
if not self . head_block_h eader :
hash = self . db . get ( head_header_k ey )
num = self . _get_block_number ( hash )
self . headBlockH eader = self . _get_block_header ( hash , num )
self . head_block_h eader = self . _get_block_header ( hash , num )
# find header with valid state
while not self . db . get ( self . headBlockH eader . state_root ) and self . headBlockH eader . prevhash is not None :
hash = self . headBlockH eader . prevhash
while not self . db . get ( self . head_block_h eader . state_root ) and self . head_block_h eader . prevhash is not None :
hash = self . head_block_h eader . prevhash
num = self . _get_block_number ( hash )
self . headBlockH eader = self . _get_block_header ( hash , num )
self . head_block_h eader = self . _get_block_header ( hash , num )
return self . headBlockH eader
return self . head_block_h eader
def _get_block_number ( self , hash ) :
'''
gets block number by hash
'''
numberKey = blockHashP refix + hash
return self . db . get ( numberK ey )
number_key = block_hash_p refix + hash
return self . db . get ( number_k ey )
def _get_block_header ( self , hash , num ) :
'''
get block header by block header hash & number
'''
headerKey = headerP refix + num + hash
blockHeaderD ata = self . db . get ( headerK ey )
header = rlp . decode ( blockHeaderD ata , sedes = BlockHeader )
header_key = header_p refix + num + hash
block_header_d ata = self . db . get ( header_k ey )
header = rlp . decode ( block_header_d ata , sedes = BlockHeader )
return header
def _get_address_by_hash ( self , hash ) :
'''
get mapped address by its hash
'''
addressKey = addressP refix + hash
return self . db . get ( addressK ey )
address_key = address_p refix + hash
return self . db . get ( address_k ey )
def _get_last_indexed_number ( self ) :
'''
latest indexed block number
'''
return self . db . get ( addressMappingHeadK ey )
return self . db . get ( address_mapping_head_k ey )
def _get_block_receipts ( self , hash , num ) :
'''
get block transaction receipts by block header hash & number
'''
number = _formatBlockN umber ( num )
receiptsKey = blockReceiptsP refix + number + hash
receiptsD ata = self . db . get ( receiptsK ey )
receipts = rlp . decode ( receiptsD ata , sedes = CountableList ( ReceiptForStorage ) )
number = _format_block_n umber ( num )
receipts_key = block_receipts_p refix + number + hash
receipts_d ata = self . db . get ( receipts_k ey )
receipts = rlp . decode ( receipts_d ata , sedes = CountableList ( ReceiptForStorage ) )
return receipts
@ -143,7 +143,7 @@ class LevelDBWriter(object):
'''
sets latest indexed block number
'''
return self . db . put ( addressMappingHeadKey , _formatBlockN umber ( number ) )
return self . db . put ( address_mapping_head_key , _format_block_n umber ( number ) )
def _start_writing ( self ) :
'''
@ -161,8 +161,8 @@ class LevelDBWriter(object):
'''
get block transaction receipts by block header hash & number
'''
addressKey = addressP refix + utils . sha3 ( address )
self . wb . put ( addressK ey , address )
address_key = address_p refix + utils . sha3 ( address )
self . wb . put ( address_k ey , address )
class EthLevelDB ( object ) :
@ -211,8 +211,8 @@ class EthLevelDB(object):
tries to find corresponding account address
'''
indexer = AccountIndexer ( self )
addressH ash = binascii . a2b_hex ( utils . remove_0x_head ( hash ) )
address = indexer . get_contract_by_hash ( addressH ash )
address_h ash = binascii . a2b_hex ( utils . remove_0x_head ( hash ) )
address = indexer . get_contract_by_hash ( address_h ash )
if address :
return _encode_hex ( address )
else :
@ -223,18 +223,18 @@ class EthLevelDB(object):
gets block header by block number
'''
hash = self . reader . _get_block_hash ( number )
blockNumber = _formatBlockN umber ( number )
return self . reader . _get_block_header ( hash , blockN umber )
block_number = _format_block_n umber ( number )
return self . reader . _get_block_header ( hash , block_n umber )
def eth_getBlockByNumber ( self , number ) :
'''
gets block body by block number
'''
blockH ash = self . reader . _get_block_hash ( number )
blockNumber = _formatBlockN umber ( number )
bodyKey = bodyPrefix + blockNumber + blockH ash
blockD ata = self . db . get ( bodyK ey )
body = rlp . decode ( blockD ata , sedes = Block )
block_h ash = self . reader . _get_block_hash ( number )
block_number = _format_block_n umber ( number )
body_key = body_prefix + block_number + block_h ash
block_d ata = self . db . get ( body_k ey )
body = rlp . decode ( block_d ata , sedes = Block )
return body
def eth_getCode ( self , address ) :