def test_event_logging_with_multiple_logs_topics_and_data(): loggy_code = """ MyLog: __log__({arg1: indexed(num), arg2: bytes <= 3}) YourLog: __log__({arg1: indexed(address), arg2: bytes <= 5}) def foo(): log.MyLog(1, 'bar') log.YourLog(self, 'house') """ c = get_contract_with_gas_estimation(loggy_code) c.foo() logs1 = s.head_state.receipts[-1].logs[-2] logs2 = s.head_state.receipts[-1].logs[-1] event_id1 = u.bytes_to_int(u.sha3(bytes('MyLog(int128,bytes3)', 'utf-8'))) event_id2 = u.bytes_to_int( u.sha3(bytes('YourLog(address,bytes5)', 'utf-8'))) # Event id is always the first topic assert logs1.topics[0] == event_id1 assert logs2.topics[0] == event_id2 # Event ids are calculated correctly assert c.translator.event_data[event_id1] assert c.translator.event_data[event_id2] # Event abi is created correctly assert c.translator.event_data[event_id1] == { 'types': ['int128', 'bytes3'], 'name': 'MyLog', 'names': ['arg1', 'arg2'], 'indexed': [True, False], 'anonymous': False } assert c.translator.event_data[event_id2] == { 'types': ['address', 'bytes5'], 'name': 'YourLog', 'names': ['arg1', 'arg2'], 'indexed': [True, False], 'anonymous': False } # Event is decoded correctly assert c.translator.decode_event(logs1.topics, logs1.data) == { 'arg1': 1, 'arg2': b'bar', '_event_type': b'MyLog' } assert c.translator.decode_event(logs2.topics, logs2.data) == { 'arg1': '0x' + c.address.hex(), 'arg2': b'house', '_event_type': b'YourLog' }
def test_modmul(): modexper = """ @public def exp(base: num256, exponent: num256, modulus: num256) -> num256: o = as_num256(1) for i in range(256): o = num256_mulmod(o, o, modulus) if bitwise_and(exponent, shift(as_num256(1), 255 - i)) != as_num256(0): o = num256_mulmod(o, base, modulus) return o """ c = get_contract_with_gas_estimation(modexper) assert c.exp(3, 5, 100) == 43 assert c.exp(2, 997, 997) == 2
def test_two_d_array_accessor(): two_d_array_accessor = """ @public def test_array(x: num, y: num, z: num, w: num) -> num: a: num[2][2] a[0][0] = x a[0][1] = y a[1][0] = z a[1][1] = w return a[0][0] * 1000 + a[0][1] * 100 + a[1][0] * 10 + a[1][1] """ c = get_contract_with_gas_estimation(two_d_array_accessor) assert c.test_array(2, 7, 1, 8) == 2718 print('Passed complex array accessor test')
def test_test_slice2(): test_slice2 = """ @public def slice_tower_test(inp1: bytes <= 50) -> bytes <= 50: inp = inp1 for i in range(1, 11): inp = slice(inp, start=1, len=30 - i * 2) return inp """ c = get_contract_with_gas_estimation(test_slice2) x = c.slice_tower_test(b"abcdefghijklmnopqrstuvwxyz1234") assert x == b"klmnopqrst", x print('Passed advanced slice test')
def test_is_contract(): contract_1 = """ @public def foo(arg1: address) -> bool: result = arg1.is_contract return result """ contract_2 = """ @public def foo(arg1: address) -> bool: return arg1.is_contract """ c1 = get_contract_with_gas_estimation(contract_1) c2 = get_contract_with_gas_estimation(contract_2) assert c1.foo(c1.address) is True assert c1.foo(c2.address) is True assert c1.foo(t.a1) is False assert c1.foo(t.a3) is False assert c2.foo(c1.address) is True assert c2.foo(c2.address) is True assert c2.foo(t.a1) is False assert c2.foo(t.a3) is False
def test_private_test(): private_test_code = """ @private def a() -> num: return 5 @public def returnten() -> num: return self.a() * 2 """ c = get_contract_with_gas_estimation(private_test_code) assert c.returnten() == 10 print("Passed private function test")
def test_internal_test(): internal_test = """ @internal def a() -> num: return 5 @public def returnten() -> num: return self.a() * 2 """ c = get_contract_with_gas_estimation(internal_test) assert c.returnten() == 10 print("Passed internal function test")
def test_negative_nums(assert_tx_failed): negative_nums_code = """ @public def _negative_num() -> num: return -1 @public def _negative_exp() -> num: return -(1+2) """ c = get_contract_with_gas_estimation(negative_nums_code) t.s = s assert c._negative_num() == -1 assert c._negative_exp() == -3
def test_array_accessor(): array_accessor = """ @public def test_array(x: num, y: num, z: num, w: num) -> num: a: num[4] a[0] = x a[1] = y a[2] = z a[3] = w return a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3] """ c = get_contract_with_gas_estimation(array_accessor) assert c.test_array(2, 7, 1, 8) == 2718 print('Passed basic array accessor test')
def test_large_input_code(): large_input_code = """ @public def foo(x: num) -> num: return 3 """ c = get_contract_with_gas_estimation(large_input_code) c.foo(1274124) c.foo(2**120) try: c.foo(2**130) success = True except: success = False assert not success
def test_init_argument_test(): init_argument_test = """ moose: num @public def __init__(_moose: num): self.moose = _moose @public def returnMoose() -> num: return self.moose """ c = get_contract_with_gas_estimation(init_argument_test, args=[5]) assert c.returnMoose() == 5 print('Passed init argument test')
def test_constructor_advanced_code2(): constructor_advanced_code2 = """ comb: num @public def __init__(x: num[2], y: bytes <= 3, z: num): self.comb = x[0] * 1000 + x[1] * 100 + len(y) * 10 + z @public def get_comb() -> num: return self.comb """ c = get_contract_with_gas_estimation(constructor_advanced_code2, args=[[5, 7], "dog", 8]) assert c.get_comb() == 5738 print("Passed advanced init argument tests")
def test_num256_with_exponents(assert_tx_failed): exp_code = """ @public def _num256_exp(x: num256, y: num256) -> num256: return num256_exp(x,y) """ c = get_contract_with_gas_estimation(exp_code) t.s = s assert c._num256_exp(2, 0) == 1 assert c._num256_exp(2, 1) == 2 assert c._num256_exp(2, 3) == 8 assert_tx_failed(lambda: c._num256_exp(2**128, 2)) assert c._num256_exp(2**64, 2) == 2**128 assert c._num256_exp(7**23, 3) == 7**69
def test_offset_repeater_2(): offset_repeater_2 = """ def sum(frm: num, to: num) -> num: out = 0 for i in range(frm, frm + 101): if i == to: break out = out + i return(out) """ c = get_contract_with_gas_estimation(offset_repeater_2) assert c.sum(100, 99999) == 15150 assert c.sum(70, 131) == 6100 print('Passed more complex repeater with offset test')
def test_crazy_concat_code(): crazy_concat_code = """ y: bytes <= 10 @public def krazykonkat(z: bytes <= 10) -> bytes <= 25: x = "cow" self.y = "horse" return concat(x, " ", self.y, " ", z) """ c = get_contract_with_gas_estimation(crazy_concat_code) assert c.krazykonkat(b"moose") == b'cow horse moose' print('Passed third concat test')
def test_cmp_in_list(): code = """ @public def in_test(x: num) -> bool: if x in [9, 7, 6, 5]: return True return False """ c = get_contract_with_gas_estimation(code) assert c.in_test(1) is False assert c.in_test(-7) is False assert c.in_test(-9) is False assert c.in_test(5) is True assert c.in_test(7) is True
def test_altering_list_within_for_loop(assert_compile_failed): code = """ @public def data() -> num: s = [1, 2, 3, 4, 5, 6] count = 0 for i in s: s[count] = 1 # this should not be allowed. if i >= 3: return i count += 1 return -1 """ assert_compile_failed(lambda: get_contract_with_gas_estimation(code), StructureException)
def test_test_bytes2(): test_bytes2 = """ @public def foo(x: bytes <= 100) -> bytes <= 100: y = x return y """ c = get_contract_with_gas_estimation(test_bytes2) assert c.foo(b'cow') == b'cow' assert c.foo(b'') == b'' assert c.foo(b'\x35' * 63) == b'\x35' * 63 assert c.foo(b'\x35' * 64) == b'\x35' * 64 assert c.foo(b'\x35' * 65) == b'\x35' * 65 print('Passed string copying test')
def test_conditional_return_code(): conditional_return_code = """ def foo(i: bool) -> num: if i: return 5 else: assert 2 return 7 return 11 """ c = get_contract_with_gas_estimation(conditional_return_code) assert c.foo(True) == 5 assert c.foo(False) == 7 print('Passed conditional return tests')
def test_minmax(): minmax_test = """ @public def foo() -> decimal: return min(3, 5) + max(10, 20) + min(200.1, 400) + max(3000, 8000.02) + min(50000.003, 70000.004) @public def goo() -> num256: return num256_add(min(as_num256(3), as_num256(5)), max(as_num256(40), as_num256(80))) """ c = get_contract_with_gas_estimation(minmax_test) assert c.foo() == 58223.123 assert c.goo() == 83 print("Passed min/max test")
def test_hash_code(): hash_code = """ @public def foo(inp: bytes <= 100) -> bytes32: return sha3(inp) @public def bar() -> bytes32: return sha3("inp") """ c = get_contract_with_gas_estimation(hash_code) for inp in (b"", b"cow", b"s" * 31, b"\xff" * 32, b"\n" * 33, b"g" * 64, b"h" * 65): assert c.foo(inp) == u.sha3(inp) assert c.bar() == u.sha3("inp")
def test_packing_test(): packing_test = """ x: num y: num[5] z: {foo: num[3], bar: {a: num, b: num}[2]} a: num @public def foo() -> num: self.x = 1 self.y[0] = 2 self.y[4] = 4 self.z.foo[0] = 8 self.z.foo[2] = 16 self.z.bar[0].a = 32 self.z.bar[0].b = 64 self.z.bar[1].a = 128 self.z.bar[1].b = 256 self.a = 512 return self.x + self.y[0] + self.y[4] + self.z.foo[0] + self.z.foo[2] + \ self.z.bar[0].a + self.z.bar[0].b + self.z.bar[1].a + self.z.bar[1].b + self.a @public def fop() -> num: _x: num _y: num[5] _z: {foo: num[3], bar: {a: num, b: num}[2]} _a: num _x = 1 _y[0] = 2 _y[4] = 4 _z.foo[0] = 8 _z.foo[2] = 16 _z.bar[0].a = 32 _z.bar[0].b = 64 _z.bar[1].a = 128 _z.bar[1].b = 256 _a = 512 return _x + _y[0] + _y[4] + _z.foo[0] + _z.foo[2] + \ _z.bar[0].a + _z.bar[0].b + _z.bar[1].a + _z.bar[1].b + _a """ c = get_contract_with_gas_estimation(packing_test) assert c.foo() == 1023, c.foo() assert c.fop() == 1023, c.fop() print('Passed packing test')
def test_permanent_variables_test(): permanent_variables_test = """ var: {a: num, b: num} @public def __init__(a: num, b: num): self.var.a = a self.var.b = b @public def returnMoose() -> num: return self.var.a * 10 + self.var.b """ c = get_contract_with_gas_estimation(permanent_variables_test, args=[5, 7]) assert c.returnMoose() == 57 print('Passed init argument and variable member test')
def test_num_bound(assert_tx_failed): num_bound_code = """ @public def _num(x: num) -> num: return x @public def _num_add(x: num, y: num) -> num: return x + y @public def _num_sub(x: num, y: num) -> num: return x - y @public def _num_add3(x: num, y: num, z: num) -> num: return x + y + z @public def _num_max() -> num: return 170141183460469231731687303715884105727 # 2**127 - 1 @public def _num_min() -> num: return -170141183460469231731687303715884105728 # -2**127 """ c = get_contract_with_gas_estimation(num_bound_code) t.s = s NUM_MAX = 2**127 - 1 NUM_MIN = -2**127 assert c._num_add(NUM_MAX, 0) == NUM_MAX assert c._num_sub(NUM_MIN, 0) == NUM_MIN assert c._num_add(NUM_MAX - 1, 1) == NUM_MAX assert c._num_sub(NUM_MIN + 1, 1) == NUM_MIN assert_tx_failed(lambda: c._num_add(NUM_MAX, 1)) assert_tx_failed(lambda: c._num_sub(NUM_MIN, 1)) assert_tx_failed(lambda: c._num_add(NUM_MAX - 1, 2)) assert_tx_failed(lambda: c._num_sub(NUM_MIN + 1, 2)) assert c._num_max() == NUM_MAX assert c._num_min() == NUM_MIN assert_tx_failed(lambda: c._num_add3(NUM_MAX, 1, -1)) assert c._num_add3(NUM_MAX, -1, 1) == NUM_MAX
def test_extract32_code(): extract32_code = """ @public def foo(inp: bytes <= 32) -> num: return extract32(inp, 0, type=num128) @public def bar(inp: bytes <= 32) -> num256: return extract32(inp, 0, type=num256) @public def baz(inp: bytes <= 32) -> bytes32: return extract32(inp, 0, type=bytes32) @public def fop(inp: bytes <= 32) -> bytes32: return extract32(inp, 0) @public def foq(inp: bytes <= 32) -> address: return extract32(inp, 0, type=address) """ c = get_contract_with_gas_estimation(extract32_code) assert c.foo(b"\x00" * 30 + b"\x01\x01") == 257 assert c.bar(b"\x00" * 30 + b"\x01\x01") == 257 try: c.foo(b"\x80" + b"\x00" * 30) success = True except: success = False assert not success assert c.bar(b"\x80" + b"\x00" * 31) == 2**255 assert c.baz(b"crow" * 8) == b"crow" * 8 assert c.fop(b"crow" * 8) == b"crow" * 8 assert c.foq(b"\x00" * 12 + b"3" * 20) == "0x" + "3" * 40 try: c.foq(b"crow" * 8) success = True except: success = False assert not success print('Passed extract32 test')
def test_list_tester_code(): list_tester_code = """ z: num[3] z2: num[2][2] z3: num[2] @public def foo(x: num[3]) -> num: return x[0] + x[1] + x[2] @public def goo(x: num[2][2]) -> num: return x[0][0] + x[0][1] + x[1][0] * 10 + x[1][1] * 10 @public def hoo(x: num[3]) -> num: y = x return y[0] + x[1] + y[2] @public def joo(x: num[2][2]) -> num: y = x y2 = x[1] return y[0][0] + y[0][1] + y2[0] * 10 + y2[1] * 10 @public def koo(x: num[3]) -> num: self.z = x return self.z[0] + x[1] + self.z[2] @public def loo(x: num[2][2]) -> num: self.z2 = x self.z3 = x[1] return self.z2[0][0] + self.z2[0][1] + self.z3[0] * 10 + self.z3[1] * 10 """ c = get_contract_with_gas_estimation(list_tester_code) assert c.foo([3, 4, 5]) == 12 assert c.goo([[1, 2], [3, 4]]) == 73 assert c.hoo([3, 4, 5]) == 12 assert c.joo([[1, 2], [3, 4]]) == 73 assert c.koo([3, 4, 5]) == 12 assert c.loo([[1, 2], [3, 4]]) == 73 print("Passed list tests")
def test_clamper_test_code(): clamper_test_code = """ @public def foo(s: bytes <= 3) -> bytes <= 3: return s """ c = get_contract_with_gas_estimation(clamper_test_code, value=1) assert c.foo(b"ca") == b"ca" assert c.foo(b"cat") == b"cat" try: c.foo(b"cate") success = True except t.TransactionFailed: success = False assert not success print("Passed bytearray clamping test")
def test_digit_reverser(): digit_reverser = """ def reverse_digits(x: num) -> num: dig: num[6] z = x for i in range(6): dig[i] = z % 10 z = z / 10 o = 0 for i in range(6): o = o * 10 + dig[i] return o """ c = get_contract_with_gas_estimation(digit_reverser) assert c.reverse_digits(123456) == 654321 print('Passed digit reverser test')
def test_in_storage_list(): code = """ allowed: num[10] @public def in_test(x: num) -> bool: self.allowed = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] if x in self.allowed: return True return False """ c = get_contract_with_gas_estimation(code) assert c.in_test(1) is True assert c.in_test(9) is True assert c.in_test(11) is False assert c.in_test(-1) is False assert c.in_test(32000) is False
def test_break_test(): break_test = """ def log(n: num) -> num: c = n * 1.0 output = 0 for i in range(400): c = c / 1.2589 if c < 1.0: output = i break return output """ c = get_contract_with_gas_estimation(break_test) assert c.log(1) == 0 assert c.log(2) == 3 assert c.log(10) == 10 assert c.log(200) == 23 print('Passed for-loop break test')