Added impurity checker code
This commit is contained in:
parent
00db6345e5
commit
5335845163
|
@ -0,0 +1,61 @@
|
|||
macro calldatachar($x):
|
||||
div(calldataload($x), 2**248)
|
||||
|
||||
# sum([2**x for x in [0x31, 0x32, 0x33, 0x3a, 0x3b, 0x3c, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x54, 0x55, 0xf0, 0xff])
|
||||
mask = 57897811465722876096115075801844696845150819816717215668290421542284681019392
|
||||
|
||||
data approved_addrs[]
|
||||
|
||||
def submit(addr: address):
|
||||
# Copy external contract code
|
||||
extcode = string(~extcodesize(addr))
|
||||
~extcodecopy(addr, extcode, 0, ~extcodesize(addr))
|
||||
ops = array(~extcodesize(addr))
|
||||
pushargs = array(~extcodesize(addr))
|
||||
# Loop through the code
|
||||
with i = 0:
|
||||
with op = 0:
|
||||
while i < len(extcode):
|
||||
with c = ~mod(~mload(extcode + i - 31), 256):
|
||||
# Banned opcode
|
||||
if ~and(2**c, mask):
|
||||
~invalid()
|
||||
# PUSH
|
||||
if 0x60 <= c and c <= 0x7f:
|
||||
pushargs[op] = ~div(~mload(extcode + i + 1), 256 ** (0x7f - c))
|
||||
i += c - 0x5e
|
||||
# Call, callcode, delegatecall
|
||||
elif c == 0xf1 or c == 0xf2 or c == 0xf4:
|
||||
# Pattern-match two ways of setting the gas parameter:
|
||||
#
|
||||
# 1. PUSH<value>
|
||||
# 2. sub(gas, PUSH<value>)
|
||||
if op >= 2 and ops[op - 1] >= 0x60 and ops[op - 1] <= 0x7f:
|
||||
address_entry = op - 2
|
||||
elif op >= 4 and ops[op - 1] == 0x03 and ops[op - 2] == 0x5a and ops[op - 3] >= 0x60 and ops[op - 3] <= 0x7f:
|
||||
address_entry = op - 4
|
||||
else:
|
||||
~invalid()
|
||||
# Operation before the gas parameter must satisfy one of three conditions:
|
||||
#
|
||||
# 1. It is a PUSH of an already approved address
|
||||
# 2. It is the address itself, through the ADDRESS opcode (ie. self-calling is permitted)
|
||||
# 3. It is a PUSH1, ie. less than 256 (ie. a present or future precompile)
|
||||
if self.approved_addrs[pushargs[address_entry]]:
|
||||
success = 1
|
||||
elif ops[address_entry] == 0x30:
|
||||
success = 1
|
||||
elif ops[address_entry] == 0x60:
|
||||
success = 1
|
||||
if not success:
|
||||
~invalid()
|
||||
i += 1
|
||||
else:
|
||||
i += 1
|
||||
ops[op] = c
|
||||
op += 1
|
||||
self.approved_addrs[addr] = 1
|
||||
return(1: bool)
|
||||
|
||||
def check(addr: address):
|
||||
return(self.approved_addrs[addr]:bool)
|
|
@ -0,0 +1,122 @@
|
|||
from ethereum import tester as t
|
||||
from ethereum import utils
|
||||
from ethereum import transactions
|
||||
import rlp
|
||||
import serpent
|
||||
s = t.state()
|
||||
c = s.abi_contract('check_for_impurity.se')
|
||||
|
||||
#from ethereum.slogging import LogRecorder, configure_logging, set_level
|
||||
#config_string = ':info,eth.vm.log:trace,eth.vm.op:trace,eth.vm.stack:trace,eth.vm.exit:trace,eth.pb.msg:trace,eth.pb.tx:debug'
|
||||
#configure_logging(config_string=config_string)
|
||||
|
||||
test1 = s.abi_contract("""
|
||||
|
||||
data horse
|
||||
|
||||
def foo():
|
||||
return self.horse
|
||||
|
||||
""")
|
||||
|
||||
try:
|
||||
c.submit(test1.address)
|
||||
success = True
|
||||
except:
|
||||
success = False
|
||||
assert not success
|
||||
|
||||
failedtest_addr = "0x"+utils.encode_hex(test1.address)
|
||||
|
||||
test2 = s.abi_contract("""
|
||||
|
||||
def foo():
|
||||
return block.number
|
||||
|
||||
""")
|
||||
|
||||
try:
|
||||
c.submit(test2.address)
|
||||
success = True
|
||||
except:
|
||||
success = False
|
||||
assert not success
|
||||
|
||||
test3 = s.abi_contract("""
|
||||
|
||||
def foo(x):
|
||||
return x * 2
|
||||
""")
|
||||
|
||||
c.submit(test3.address)
|
||||
|
||||
|
||||
|
||||
test4 = s.abi_contract("""
|
||||
|
||||
def modexp(b: uint256, e: uint256, m: uint256):
|
||||
if e == 0:
|
||||
return 1
|
||||
elif e == 1:
|
||||
return b
|
||||
elif e % 2 == 0:
|
||||
return self.modexp(~mulmod(b, b, m), ~div(e, 2), m)
|
||||
elif e % 2 == 1:
|
||||
return ~mulmod(self.modexp(~mulmod(b, b, m), ~div(e, 2), m), b, m)
|
||||
|
||||
""")
|
||||
|
||||
c.submit(test4.address)
|
||||
modexp_addr = "0x"+utils.encode_hex(test4.address)
|
||||
|
||||
test5 = s.abi_contract("""
|
||||
|
||||
def modinv(b, m):
|
||||
inpdata = [0xa7d4bbe6, b, m-2, m]
|
||||
outdata = [0]
|
||||
~call(100000, %s, 0, inpdata + 28, 100, outdata, 32)
|
||||
return outdata[0]
|
||||
|
||||
""" % modexp_addr)
|
||||
|
||||
c.submit(test5.address)
|
||||
|
||||
test6 = s.abi_contract("""
|
||||
def phooey(h, v, r, s):
|
||||
return ecrecover(h, v, r, s)
|
||||
""")
|
||||
|
||||
c.submit(test6.address)
|
||||
|
||||
test7 = s.abi_contract("""
|
||||
|
||||
def modinv(b, m):
|
||||
inpdata = [0xa7d4bbe6, b, m-2, m]
|
||||
outdata = [0]
|
||||
~call(msg.gas - 10000, %s, 0, inpdata + 28, 100, outdata, 32)
|
||||
return outdata[0]
|
||||
|
||||
""" % failedtest_addr)
|
||||
|
||||
try:
|
||||
c.submit(test7.address)
|
||||
success = True
|
||||
except:
|
||||
success = False
|
||||
assert not success
|
||||
|
||||
print('All tests passed')
|
||||
|
||||
kode = serpent.compile('check_for_impurity.se')
|
||||
|
||||
# Create transaction
|
||||
t = transactions.Transaction(0, 30 * 10**9, 2999999, '', 0, kode)
|
||||
t.startgas = t.intrinsic_gas_used + 50000 + 200 * len(kode)
|
||||
t.v = 27
|
||||
t.r = 45
|
||||
t.s = 79
|
||||
print('Send %d wei to %s' % (t.startgas * t.gasprice,
|
||||
'0x'+utils.encode_hex(t.sender)))
|
||||
|
||||
print('Contract address: 0x'+utils.encode_hex(utils.mk_contract_address(t.sender, 0)))
|
||||
print('Code: 0x'+utils.encode_hex(rlp.encode(t)))
|
Loading…
Reference in New Issue