def test_assert_binary_boolean_operation(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x00' + b'\x02' + Opcode.LDARG0 # assert a != b + Opcode.LDARG1 + Opcode.NUMNOTEQUAL + Opcode.ASSERT + Opcode.LDARG0 # return a + Opcode.RET) path = self.get_contract_path('AssertBinaryOperation.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', 10, 20) self.assertEqual(10, result) with self.assertRaises(TestExecutionException, msg=self.ASSERT_RESULTED_FALSE_MSG): self.run_smart_contract(engine, path, 'Main', 20, 20)
def test_multiple_arithmetic_expressions(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x03' + b'\x02' + Opcode.PUSH1 # d = 1 + Opcode.STLOC0 + Opcode.PUSH2 # e = 2 + Opcode.STLOC1 + Opcode.LDARG0 # c = a + b + Opcode.LDARG1 + Opcode.ADD + Opcode.STLOC2 + Opcode.LDLOC2 # return c + Opcode.RET) path = '%s/boa3_test/test_sc/arithmetic_test/MultipleExpressionsInLine.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'Main', 1, 2) self.assertEqual(3, result) result = self.run_smart_contract(engine, path, 'Main', 5, -7) self.assertEqual(-2, result)
def test_tuple_string_values(self): byte_input0 = String('1').to_bytes() byte_input1 = String('2').to_bytes() byte_input2 = String('3').to_bytes() expected_output = ( Opcode.INITSLOT # function signature + b'\x01' + b'\x00' + Opcode.PUSHDATA1 # a = ('1', '2', '3') + Integer(len(byte_input2)).to_byte_array() + byte_input2 + Opcode.PUSHDATA1 + Integer(len(byte_input1)).to_byte_array() + byte_input1 + Opcode.PUSHDATA1 + Integer(len(byte_input0)).to_byte_array() + byte_input0 + Opcode.PUSH3 # tuple length + Opcode.PACK + Opcode.STLOC0 + Opcode.RET # return ) path = self.get_contract_path('StrTuple.py') output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_multiple_comparisons(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x03' + Opcode.LDARG1 + Opcode.LDARG0 + Opcode.LE + Opcode.LDARG0 + Opcode.LDARG2 + Opcode.LE + Opcode.BOOLAND + Opcode.RET) path = '%s/boa3_test/test_sc/relational_test/NumRange.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'Main', 1, 2, 5) self.assertEqual(False, result) result = self.run_smart_contract(engine, path, 'Main', 2, 1, 5) self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'Main', 5, 1, 2) self.assertEqual(False, result) result = self.run_smart_contract(engine, path, 'Main', 2, 5, 1) self.assertEqual(False, result)
def test_list_clear(self): path = self.get_contract_path('ClearList.py') expected_output = ( Opcode.INITSLOT # function signature + b'\x01' + b'\x02' + Opcode.PUSH3 # a = [1, 2, 3] + Opcode.PUSH2 + Opcode.PUSH1 + Opcode.PUSH3 + Opcode.PACK + Opcode.STLOC0 + Opcode.LDLOC0 # a.clear() + Opcode.DUP + Opcode.ISTYPE + Type.bytearray.stack_item + Opcode.JMPIFNOT + Integer(9).to_byte_array(min_length=1) + Opcode.DROP + Opcode.PUSHDATA1 + Integer(0).to_byte_array(min_length=1) + Opcode.CONVERT + Type.bytearray.stack_item + Opcode.JMP + Integer(5).to_byte_array(min_length=1) + Opcode.CLEARITEMS + Opcode.JMP + Integer(3).to_byte_array(min_length=1) + Opcode.STLOC0 + Opcode.LDLOC0 # return a + Opcode.RET) output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_destroy_contract(self): call_flag = Integer(CallFlags.ALL).to_byte_array(signed=True, min_length=1) expected_output = ( Opcode.NEWARRAY0 + Opcode.PUSHDATA1 + Integer(len(Interop.DestroyContract.method_name)).to_byte_array( min_length=1) + String(Interop.DestroyContract.method_name).to_bytes() + Opcode.PUSHDATA1 + Integer(len( constants.MANAGEMENT_SCRIPT)).to_byte_array(min_length=1) + constants.MANAGEMENT_SCRIPT + Opcode.PUSHDATA1 + Integer(len(call_flag)).to_byte_array(min_length=1) + call_flag + Opcode.ROT + Opcode.ROT + Opcode.SYSCALL + Interop.CallContract.interop_method_hash + Opcode.DROP + Opcode.RET) path = self.get_contract_path('DestroyContract.py') output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_return_void_function(self): called_function_address = Integer(4).to_byte_array(min_length=1, signed=True) expected_output = ( Opcode.CALL # Main + called_function_address # return TestFunction() + Opcode.PUSHNULL + Opcode.RET + Opcode.INITSLOT # TestFunction + b'\x01' + b'\x00' + Opcode.PUSH1 # a = 1 + Opcode.STLOC0 + Opcode.RET # return ) path = self.get_contract_path('ReturnVoidFunction.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertIsNone(result)
def test_bytes_multiplication_operation_augmented_assignment(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + BinaryOp.StrBytesMul.build(Type.bytes).bytecode + Opcode.STARG0 + Opcode.LDARG0 + Opcode.RET) path = self.get_contract_path( 'BytesMultiplicationAugmentedAssignment.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', b'unit', 50, expected_result_type=bytes) self.assertEqual(b'unit' * 50, result)
def test_update_contract(self): call_flag = Integer(CallFlags.ALL).to_byte_array(signed=True, min_length=1) expected_output = ( Opcode.INITSLOT + b'\00' + b'\02' + Opcode.LDARG1 + Opcode.LDARG0 + Opcode.PUSH2 + Opcode.PACK + Opcode.PUSHDATA1 + Integer(len(Interop.UpdateContract.method_name)).to_byte_array( min_length=1) + String(Interop.UpdateContract.method_name).to_bytes() + Opcode.PUSHDATA1 + Integer(len( constants.MANAGEMENT_SCRIPT)).to_byte_array(min_length=1) + constants.MANAGEMENT_SCRIPT + Opcode.PUSHDATA1 + Integer(len(call_flag)).to_byte_array(min_length=1) + call_flag + Opcode.ROT + Opcode.ROT + Opcode.SYSCALL + Interop.CallContract.interop_method_hash + Opcode.RET) path = self.get_contract_path('UpdateContract.py') output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_power_operation(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.POW + Opcode.RET) path = self.get_contract_path('Power.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'pow', 10, 3) self.assertEqual(1000, result) result = self.run_smart_contract(engine, path, 'pow', 1, 15) self.assertEqual(1, result) result = self.run_smart_contract(engine, path, 'pow', -2, 2) self.assertEqual(4, result) result = self.run_smart_contract(engine, path, 'pow', 0, 20) self.assertEqual(0, result) with self.assertRaises(TestExecutionException): self.run_smart_contract(engine, path, 'pow', 1, -2)
def test_mixed_operations(self): expected_output = ( Opcode.INITSLOT + b'\x00' + b'\x05' + Opcode.LDARG0 + Opcode.LDARG2 + Opcode.LDARG4 + Opcode.MUL # multiplicative operations + Opcode.ADD # additive operations + Opcode.LDARG3 + Opcode.NEGATE # parentheses + Opcode.LDARG1 + Opcode.DIV # multiplicative + Opcode.SUB # additive + Opcode.RET) path = self.get_contract_path('MixedOperations.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'mixed', 10, 20, 30, 40, 50) self.assertEqual(10 + 30 * 50 + 40 // 20, result)
def test_storage_put_str_key_str_value(self): value = String('123').to_bytes() expected_output = ( Opcode.INITSLOT + b'\x01' + b'\x01' + Opcode.PUSHDATA1 + Integer(len(value)).to_byte_array(min_length=1, signed=True) + value + Opcode.STLOC0 + Opcode.PUSHDATA1 + Integer(len(value)).to_byte_array(min_length=1, signed=True) + value + Opcode.LDARG0 + Opcode.SYSCALL + Interop.StorageGetContext.interop_method_hash + Opcode.SYSCALL + Interop.StoragePut.interop_method_hash + Opcode.RET) path = self.get_contract_path('StoragePutStrKeyStrValue.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() stored_value = String('123').to_bytes() result = self.run_smart_contract(engine, path, 'Main', 'test1') self.assertIsVoid(result) storage_value = engine.storage_get(b'test1', path) self.assertIsNotNone(storage_value) self.assertEqual(stored_value, storage_value) result = self.run_smart_contract(engine, path, 'Main', 'test2') self.assertIsVoid(result) storage_value = engine.storage_get(b'test1', path) self.assertIsNotNone(storage_value) self.assertEqual(stored_value, storage_value) storage_value = engine.storage_get(b'test2', path) self.assertIsNotNone(storage_value) self.assertEqual(stored_value, storage_value) result = self.run_smart_contract(engine, path, 'Main', 'test2', fake_storage={}) self.assertIsVoid(result) storage_value = engine.storage_get(b'test1', path) self.assertIsNone(storage_value) storage_value = engine.storage_get(b'test2', path) self.assertIsNotNone(storage_value) self.assertEqual(stored_value, storage_value)
def test_assert_any(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x00' + b'\x01' + Opcode.LDARG0 # assert a + Opcode.DUP + Opcode.ISTYPE + StackItemType.Array + Opcode.JMPIF + Integer(12).to_byte_array(signed=True, min_length=1) + Opcode.DUP + Opcode.ISTYPE + StackItemType.Map + Opcode.JMPIF + Integer(7).to_byte_array(signed=True, min_length=1) + Opcode.DUP + Opcode.ISTYPE + StackItemType.Struct + Opcode.JMPIFNOT + Integer(3).to_byte_array(signed=True, min_length=1) + Opcode.SIZE + Opcode.ASSERT + Opcode.RET) path = self.get_contract_path('AssertAny.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', True) self.assertIsVoid(result)
def test_logic_right_shift(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.SHR + Opcode.RET) path = self.get_contract_path('LogicRightShift.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', int('10000', 2), 2) self.assertEqual(int('100', 2), result) result = self.run_smart_contract(engine, path, 'Main', int('110', 2), 1) self.assertEqual(int('11', 2), result) result = self.run_smart_contract(engine, path, 'Main', int('1010100000', 2), 4) self.assertEqual(int('101010', 2), result)
def test_assign_local_shadowing_global_with_arg_value(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x01' + b'\x01' + Opcode.LDARG0 # b = a // this b is not the global b + Opcode.STLOC0 + Opcode.LDLOC0 # variable address + Opcode.RET + Opcode.INITSSLOT # global variables + b'\x01' # number of globals + Opcode.PUSH0 # b = 0 + Opcode.STSFLD0 + Opcode.RET) path = '%s/boa3_test/test_sc/variable_test/AssignLocalWithArgumentShadowingGlobal.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'Main', 10) self.assertEqual(10, result) result = self.run_smart_contract(engine, path, 'Main', -140) self.assertEqual(-140, result)
def test_str_to_bytes_with_builtin(self): value = String('123').to_bytes() expected_output = ( Opcode.PUSHDATA1 # str.to_bytes('123') + Integer(len(value)).to_byte_array(min_length=1) + value + Opcode.CONVERT + Type.bytes.stack_item + Opcode.RET ) path = self.get_contract_path('StrToBytesWithBuiltin.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'str_to_bytes', expected_result_type=bytes) self.assertEqual(value, result)
def test_byte_array_reverse(self): data = b'\x01\x02\x03' expected_output = ( Opcode.INITSLOT # function signature + b'\x01' + b'\x00' + Opcode.PUSHDATA1 # a = bytearray(b'\x01\x02\x03') + Integer(len(data)).to_byte_array(min_length=1) + data + Opcode.CONVERT + Type.bytes.stack_item + Opcode.STLOC0 + Opcode.LDLOC0 # a.reverse() + Opcode.REVERSEITEMS + Opcode.LDLOC0 + Opcode.RET # return a ) path = '%s/boa3_test/test_sc/bytes_test/BytearrayReverse.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'Main') self.assertEqual(b'\x03\x02\x01', result)
def test_multiple_assignments_set_sequence(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x03' + b'\x00' + Opcode.PUSH3 # a = [1, 2, 3] + Opcode.PUSH2 + Opcode.PUSH1 + Opcode.PUSH3 + Opcode.PACK + Opcode.STLOC0 + Opcode.PUSH2 # c = a[2] = b = 2 + Opcode.DUP # b = 2 + Opcode.STLOC2 + Opcode.LDLOC0 # a[2] = 2 + Opcode.PUSH2 + Opcode.DUP + Opcode.SIGN + Opcode.PUSHM1 + Opcode.JMPNE + Integer(5).to_byte_array(signed=True, min_length=1) + Opcode.OVER + Opcode.SIZE + Opcode.ADD + Opcode.PUSH2 + Opcode.PICK + Opcode.SETITEM + Opcode.STLOC1 # c = 2 + Opcode.PUSHNULL # return + Opcode.RET) path = '%s/boa3_test/test_sc/variable_test/MultipleAssignmentsSetSequence.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_mixed_operations_with_parentheses(self): expected_output = ( Opcode.INITSLOT + b'\x00' + b'\x05' + Opcode.LDARG0 + Opcode.LDARG2 + Opcode.LDARG4 + Opcode.LDARG3 + Opcode.NEGATE # inside parentheses + Opcode.SUB # parentheses + Opcode.MUL # multiplicative operations + Opcode.LDARG1 + Opcode.DIV # multiplicative + Opcode.ADD # additive operations + Opcode.RET) path = '%s/boa3_test/test_sc/arithmetic_test/WithParentheses.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'mixed', 10, 20, 30, 40, 50) self.assertEqual(10 + 30 * (50 + 40) // 20, result)
def test_import_user_module_with_global_variables(self): expected_output = ( Opcode.LDSFLD0 # b = a + Opcode.RET + Opcode.NEWARRAY0 # imported function + Opcode.RET # return + Opcode.INITSSLOT + b'\x02' + Opcode.CALL # a = UserModule.EmptyList() + Integer(-4).to_byte_array(min_length=1, signed=True) + Opcode.STSFLD0 + Opcode.NEWARRAY0 # module variable empty_list from import + Opcode.STSFLD1 + Opcode.RET) path = self.get_contract_path('FromImportWithGlobalVariables.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertEqual([], result)
def test_from_import_user_module_with_alias(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x01' + b'\x00' + Opcode.CALL + Integer(5).to_byte_array(min_length=1, signed=True) + Opcode.STLOC0 + Opcode.LDLOC0 + Opcode.RET + Opcode.NEWARRAY0 # imported function + Opcode.RET # return + Opcode.INITSSLOT + b'\x01' + Opcode.NEWARRAY0 # module variable empty_list from import + Opcode.STSFLD0 + Opcode.RET) path = self.get_contract_path('FromImportUserModuleWithAlias.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertEqual([], result)
def test_for_break_else(self): jmpif_address = Integer(32).to_byte_array(min_length=1, signed=True) jmp_address = Integer(-35).to_byte_array(min_length=1, signed=True) expected_output = ( Opcode.INITSLOT + b'\x03' + b'\x00' + Opcode.PUSH0 # a = 0 + Opcode.STLOC0 + Opcode.PUSH15 # sequence = (3, 5, 15) + Opcode.PUSH5 + Opcode.PUSH3 + Opcode.PUSH3 + Opcode.PACK + Opcode.STLOC1 + Opcode.LDLOC1 # for_sequence = sequence + Opcode.PUSH0 # for_index = 0 + Opcode.JMP + jmpif_address + Opcode.OVER # x = for_sequence[for_index] + Opcode.OVER + Opcode.DUP + Opcode.SIGN + Opcode.PUSHM1 + Opcode.JMPNE + Integer(5).to_byte_array(min_length=1, signed=True) + Opcode.OVER + Opcode.SIZE + Opcode.ADD + Opcode.PICKITEM + Opcode.STLOC2 + Opcode.LDLOC2 # if x % 5 == 0 + Opcode.PUSH5 + Opcode.MOD + Opcode.PUSH0 + Opcode.NUMEQUAL + Opcode.JMPIFNOT + Integer(8).to_byte_array(min_length=1, signed=True) + Opcode.LDLOC0 # a += x + Opcode.LDLOC2 + Opcode.ADD + Opcode.STLOC0 + Opcode.JMP # break + Integer(20).to_byte_array(min_length=1, signed=True) + Opcode.LDLOC0 # a += 1 + Opcode.PUSH1 + Opcode.ADD + Opcode.STLOC0 + Opcode.INC # for_index = for_index + 1 + Opcode.DUP # if for_index < len(for_sequence) + Opcode.PUSH2 + Opcode.PICK + Opcode.SIZE + Opcode.LT + Opcode.JMPIF # end for + jmp_address + Opcode.DROP + Opcode.DROP + Opcode.PUSHM1 # a = -1 + Opcode.STLOC0 + Opcode.JMP # else + Integer(4).to_byte_array(signed=True, min_length=1) + Opcode.DROP + Opcode.DROP + Opcode.LDLOC0 # return a + Opcode.RET) path = '%s/boa3_test/test_sc/for_test/ForBreakElse.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'Main') self.assertEqual(6, result)
def test_storage_get_str_key(self): expected_output = ( Opcode.INITSLOT + b'\x00' + b'\x01' + Opcode.LDARG0 + Opcode.SYSCALL + Interop.StorageGetContext.interop_method_hash + Opcode.SYSCALL + Interop.StorageGet.interop_method_hash + Opcode.DUP + Opcode.ISNULL + Opcode.JMPIFNOT + Integer(7).to_byte_array(signed=True, min_length=1) + Opcode.DROP + Opcode.PUSHDATA1 + Integer(0).to_byte_array(signed=False, min_length=1) + Opcode.CONVERT + Type.bytes.stack_item + Opcode.RET ) path = self.get_contract_path('StorageGetStrKey.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', 'example', expected_result_type=bytes) self.assertEqual(b'', result) storage = {('example', path): 23} result = self.run_smart_contract(engine, path, 'Main', 'example', fake_storage=storage, expected_result_type=bytes) self.assertEqual(Integer(23).to_byte_array(), result) storage = {('test1', path): 23, ('test2', path): 42} result = self.run_smart_contract(engine, path, 'Main', 'test2', fake_storage=storage, expected_result_type=bytes) self.assertEqual(Integer(42).to_byte_array(), result)
def test_if_multiple_branches(self): twenty = Integer(20).to_byte_array() expected_output = ( Opcode.INITSLOT + b'\x01' + b'\x01' + Opcode.LDARG0 + Opcode.PUSH0 + Opcode.LT + Opcode.JMPIFNOT # if arg0 < 0 + Integer(6).to_byte_array(min_length=1) + Opcode.PUSH0 # a = 0 + Opcode.STLOC0 + Opcode.JMP + Integer(35).to_byte_array(min_length=1) + Opcode.LDARG0 + Opcode.PUSH5 + Opcode.LT + Opcode.JMPIFNOT # elif arg0 < 5 + Integer(6).to_byte_array(min_length=1) + Opcode.PUSH5 # a = 5 + Opcode.STLOC0 + Opcode.JMP + Integer(26).to_byte_array(min_length=1) + Opcode.LDARG0 + Opcode.PUSH10 + Opcode.LT + Opcode.JMPIFNOT # elif arg0 < 10 + Integer(6).to_byte_array(min_length=1) + Opcode.PUSH10 # a = 10 + Opcode.STLOC0 + Opcode.JMP + Integer(17).to_byte_array(min_length=1) + Opcode.LDARG0 + Opcode.PUSH15 + Opcode.LT + Opcode.JMPIFNOT # elif arg0 < 15 + Integer(6).to_byte_array(min_length=1) + Opcode.PUSH15 # a = 15 + Opcode.STLOC0 + Opcode.JMP # else + Integer(8).to_byte_array(min_length=1) + Opcode.PUSHDATA1 # a = 20 + Integer(len(twenty)).to_byte_array() + twenty + Opcode.CONVERT + Type.int.stack_item + Opcode.STLOC0 + Opcode.LDLOC0 # return a + Opcode.RET) path = self.get_contract_path('MultipleBranches.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', -10) self.assertEqual(0, result) result = self.run_smart_contract(engine, path, 'Main', 2) self.assertEqual(5, result) result = self.run_smart_contract(engine, path, 'Main', 7) self.assertEqual(10, result) result = self.run_smart_contract(engine, path, 'Main', 13) self.assertEqual(15, result) result = self.run_smart_contract(engine, path, 'Main', 17) self.assertEqual(20, result) result = self.run_smart_contract(engine, path, 'Main', 23) self.assertEqual(20, result)
def test_try_except_finally(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x01' + b'\x01' + Opcode.LDARG0 + Opcode.PUSH4 + Opcode.DIV + Opcode.STLOC0 + Opcode.TRY # try: + Integer(9).to_byte_array(signed=True, min_length=1) # jmp to exception + Integer(15).to_byte_array(signed=True, min_length=1) # jmp to finally if exists + Opcode.LDLOC0 # x += arg + Opcode.LDARG0 + Opcode.ADD + Opcode.STLOC0 + Opcode.JMP # except ValueError: + Integer(6).to_byte_array(signed=True, min_length=1) + Opcode.DROP + Opcode.LDLOC0 # x = -x + Opcode.NEGATE + Opcode.STLOC0 + Opcode.ENDTRY + Integer(7).to_byte_array(signed=True, min_length=1) + Opcode.LDLOC0 # finally + Opcode.PUSH2 # x *= 2 + Opcode.MUL + Opcode.STLOC0 + Opcode.ENDFINALLY + Opcode.LDLOC0 # return x + Opcode.RET ) path = '%s/boa3_test/test_sc/exception_test/TryExceptFinally.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'test_try_except', 10) self.assertEqual(24, result) result = self.run_smart_contract(engine, path, 'test_try_except', -110) self.assertEqual(-274, result)
def test_function_with_only_default_arguments(self): expected_output = ( Opcode.PUSH0 # defaults + Opcode.PUSH0 + Opcode.PUSH0 + Opcode.CALL # add() + Integer(20).to_byte_array(signed=True, min_length=1) + Opcode.PUSH0 # defaults + Opcode.PUSH6 # add(5, 6) + Opcode.PUSH5 + Opcode.CALL + Integer(15).to_byte_array(signed=True, min_length=1) + Opcode.PUSH0 # defaults + Opcode.PUSH0 + Opcode.PUSH9 # add(9) + Opcode.CALL + Integer(10).to_byte_array(signed=True, min_length=1) + Opcode.PUSH3 # add(1, 2, 3) + Opcode.PUSH2 + Opcode.PUSH1 + Opcode.CALL + Integer(5).to_byte_array(signed=True, min_length=1) + Opcode.PUSH4 + Opcode.PACK + Opcode.RET + Opcode.INITSLOT # def add(a: int, b: int, c: int) + b'\x00\x03' + Opcode.LDARG0 # return a + b + c + Opcode.LDARG1 + Opcode.ADD + Opcode.LDARG2 + Opcode.ADD + Opcode.RET ) path = self.get_contract_path('FunctionWithOnlyDefaultArguments.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertEqual([6, 9, 11, 0], result)
def test_bytes_get_value_negative_index(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x00' + b'\x01' + Opcode.LDARG0 # arg[0] + Opcode.PUSHM1 + Opcode.DUP + Opcode.SIGN + Opcode.PUSHM1 + Opcode.JMPNE + Integer(5).to_byte_array(min_length=1, signed=True) + Opcode.OVER + Opcode.SIZE + Opcode.ADD + Opcode.PICKITEM + Opcode.RET # return ) path = self.get_contract_path('BytesGetValueNegativeIndex.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', bytes([1, 2, 3])) self.assertEqual(3, result) result = self.run_smart_contract(engine, path, 'Main', b'0') self.assertEqual(48, result)
def test_if_expression_variable_condition(self): expected_output = ( Opcode.INITSLOT + b'\x01' + b'\x01' + Opcode.LDARG0 + Opcode.JMPIFNOT # a = 2 if arg0 else 3 + Integer(5).to_byte_array(min_length=1, signed=True) + Opcode.PUSH2 # 2 + Opcode.JMP # else + Integer(3).to_byte_array(min_length=1, signed=True) + Opcode.PUSH3 # 3 + Opcode.STLOC0 + Opcode.LDLOC0 # return a + Opcode.RET) path = self.get_contract_path('IfExpVariableCondition.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', True) self.assertEqual(2, result) result = self.run_smart_contract(engine, path, 'Main', False) self.assertEqual(3, result)
def test_byte_array_set_value(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x00' + b'\x01' + Opcode.LDARG0 # arg[0] = 0x01 + Opcode.PUSH0 + Opcode.DUP + Opcode.SIGN + Opcode.PUSHM1 + Opcode.JMPNE + Integer(5).to_byte_array(min_length=1, signed=True) + Opcode.OVER + Opcode.SIZE + Opcode.ADD + Opcode.PUSH1 + Opcode.SETITEM + Opcode.LDARG0 + Opcode.RET # return ) path = self.get_contract_path('BytearraySetValue.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', b'123') self.assertEqual(b'\x0123', result) result = self.run_smart_contract(engine, path, 'Main', b'0') self.assertEqual(b'\x01', result)
def test_if_else(self): expected_output = ( Opcode.INITSLOT + b'\x01' + b'\x01' + Opcode.PUSH0 # a = 0 + Opcode.STLOC0 + Opcode.LDARG0 + Opcode.JMPIFNOT # if arg0 + Integer(6).to_byte_array(min_length=1, signed=True) + Opcode.PUSH2 # a = a + 2 + Opcode.STLOC0 + Opcode.JMP # else + Integer(4).to_byte_array(min_length=1, signed=True) + Opcode.PUSH10 # a = 10 + Opcode.STLOC0 + Opcode.LDLOC0 # return a + Opcode.RET) path = self.get_contract_path('IfElse.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', True) self.assertEqual(2, result) result = self.run_smart_contract(engine, path, 'Main', False) self.assertEqual(10, result)