diff --git a/eip_96_blockhash_getter.se.py b/eip96/eip_96_blockhash_getter.se.py similarity index 66% rename from eip_96_blockhash_getter.se.py rename to eip96/eip_96_blockhash_getter.se.py index adf0e71..cd822d4 100644 --- a/eip_96_blockhash_getter.se.py +++ b/eip96/eip_96_blockhash_getter.se.py @@ -5,19 +5,21 @@ if msg.sender == 2**160 - 2: ~sstore(prev_block_number % 256, ~calldataload(0)) # Use storage fields 256..511 to store the hashes of the last 256 # blocks with block.number % 256 == 0 - if not prev_block_number % 256: + if not (prev_block_number % 256): ~sstore(256 + (prev_block_number / 256) % 256, ~calldataload(0)) # Use storage fields 512..767 to store the hashes of the last 256 # blocks with block.number % 65536 == 0 - if not prev_block_number % 65536: + if not (prev_block_number % 65536): ~sstore(512 + (prev_block_number / 65536) % 256, ~calldataload(0)) # Getting the block hash else: - if block.number - ~calldataload(0) <= 256: + if ~calldataload(0) >= block.number: + return(0) + elif block.number - ~calldataload(0) <= 256: return(~sload(~calldataload(0) % 256)) - elif not block.number % 256 and block.number - ~calldataload(0) <= 65536: + elif (not (~calldataload(0) % 256) and block.number - ~calldataload(0) <= 65536): return(~sload(256 + (~calldataload(0) / 256) % 256)) - elif not block.number % 65536 and block.number - ~calldataload(0) <= 16777216: + elif (not (~calldataload(0) % 65536) and block.number - ~calldataload(0) <= 16777216): return(~sload(512 + (~calldataload(0) / 65536) % 256)) else: - ~invalid() + return(~calldataload(0) % 256 == 0) diff --git a/eip96/eip_96_test_script.py b/eip96/eip_96_test_script.py new file mode 100644 index 0000000..bffa21b --- /dev/null +++ b/eip96/eip_96_test_script.py @@ -0,0 +1,34 @@ +from ethereum import tester, vm +from ethereum.utils import sha3, encode_int32, safe_ord, encode_hex +from ethereum.state_transition import apply_message +s = tester.state() +c = s.contract('eip_96_blockhash_getter.se.py') +blockhash_addr = b'\x00' * 19 + b'\x10' +system_addr = b'\xff' * 19 + b'\xfe' +s.state.set_code(blockhash_addr, s.state.get_code(c)) + +def mk_hash_setting_message(data): + return vm.Message(sender=system_addr, to=blockhash_addr, value=0, gas=1000000, data=data) + +print("Setting block hashes") +for i in range(1, 1000): + s.state.block_number = i + 1 + o = apply_message(s.state, mk_hash_setting_message(sha3(str(i)))) + if i % 100 == 0: + print("Set %d" % i) + +print("Testing reads") +s.state.block_number = 1000 +assert s.send(tester.k0, blockhash_addr, 0, encode_int32(999)) == sha3(str(999)) +assert s.send(tester.k0, blockhash_addr, 0, encode_int32(998)) == sha3(str(998)) +assert s.send(tester.k0, blockhash_addr, 0, encode_int32(744)) == sha3(str(744)) +assert s.send(tester.k0, blockhash_addr, 0, encode_int32(743)) == b'\x00' * 32 +assert s.send(tester.k0, blockhash_addr, 0, encode_int32(1000)) == b'\x00' * 32 +assert s.send(tester.k0, blockhash_addr, 0, encode_int32(1001)) == b'\x00' * 32 +assert s.send(tester.k0, blockhash_addr, 0, encode_int32(513)) == b'\x00' * 32 +assert s.send(tester.k0, blockhash_addr, 0, encode_int32(512)) == sha3(str(512)) +assert s.send(tester.k0, blockhash_addr, 0, encode_int32(511)) == b'\x00' * 32 +assert s.send(tester.k0, blockhash_addr, 0, encode_int32(256)) == sha3(str(256)) +print("Tests passed!") + +print("EVM code: 0x%s" % encode_hex(s.state.get_code(blockhash_addr)))