def test_reverse_mutable_sequence(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x01' + b'\x00' + Opcode.PUSH3 # a = [1, 2, 3] + Opcode.PUSH2 + Opcode.PUSH1 + Opcode.PUSH3 + Opcode.PACK + Opcode.STLOC0 + Opcode.LDLOC0 # a.reverse() + Opcode.REVERSEITEMS + Opcode.LDLOC0 # return a + Opcode.RET) path = self.get_contract_path('ReverseMutableSequence.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertEqual([3, 2, 1], result)
def test_modulo_operation(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.MOD + Opcode.RET) path = self.get_contract_path('Modulo.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'mod', 10, 3) self.assertEqual(1, result) result = self.run_smart_contract(engine, path, 'mod', -42, -9) self.assertEqual(-6, result) result = self.run_smart_contract(engine, path, 'mod', -100, 3) self.assertEqual(-1, result)
def test_string_function(self): expected_output = ( # functions without arguments and local variables don't need initslot Opcode.PUSHDATA1 # body + bytes([len('42')]) + bytes('42', constants.ENCODING) + Opcode.RET # return ) path = self.get_contract_path('StringFunction.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertEqual('42', result)
def test_logic_xor_with_int_operand(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.XOR + Opcode.RET) path = '%s/boa3_test/test_sc/logical_test/LogicXorInt.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'Main', 4, 6) self.assertEqual(4 ^ 6, result) result = self.run_smart_contract(engine, path, 'Main', 40, 6) self.assertEqual(40 ^ 6, result) result = self.run_smart_contract(engine, path, 'Main', -4, 32) self.assertEqual(-4 ^ 32, result)
def test_bytes_to_bool_with_builtin(self): path = self.get_contract_path('BytesToBoolWithBuiltin.py') output = Boa3.compile(path) engine = TestEngine() result = self.run_smart_contract(engine, path, 'bytes_to_bool', b'\x00') self.assertEqual(False, result) result = self.run_smart_contract(engine, path, 'bytes_to_bool', b'\x01') self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'bytes_to_bool', b'\x02') self.assertEqual(True, result)
def test_assign_local_with_arg_value(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x01' + b'\x01' + Opcode.LDARG0 + Opcode.STLOC0 + Opcode.LDLOC0 # variable address + Opcode.RET) path = self.get_contract_path('AssignLocalWithArgument.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() 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_integer_division_augmented_assignment(self): expected_output = ( Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.DIV + Opcode.STARG0 + Opcode.RET ) path = self.get_contract_path('IntegerDivisionAugmentedAssignment.py') output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_logic_xor_with_bool_operand(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.XOR + Opcode.RET) path = self.get_contract_path('LogicXorBool.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', True, True) self.assertEqual(False, result) result = self.run_smart_contract(engine, path, 'Main', True, False) self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'Main', False, False) self.assertEqual(False, result)
def test_sequence_addition(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.ADD + Opcode.PUSH4 + Opcode.ADD + Opcode.RET) path = self.get_contract_path('AdditionThreeElements.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'add_four', 1, 2) self.assertEqual(7, result) result = self.run_smart_contract(engine, path, 'add_four', -42, -24) self.assertEqual(-62, result) result = self.run_smart_contract(engine, path, 'add_four', -42, 24) self.assertEqual(-14, result)
def test_any_variable_assignments(self): two = String('2').to_bytes() path = '%s/boa3_test/test_sc/any_test/AnyVariableAssignments.py' % self.dirname expected_output = ( Opcode.INITSLOT # function signature + b'\x01' + b'\x00' + Opcode.PUSH1 # a = 1 + Opcode.STLOC0 + Opcode.PUSHDATA1 # a = '2' + Integer(len(two)).to_byte_array() + two + Opcode.STLOC0 + Opcode.PUSH1 # a = True + Opcode.STLOC0 + Opcode.PUSH3 # a = [1, 2, 3] + Opcode.PUSH2 + Opcode.PUSH1 + Opcode.PUSH3 + Opcode.PACK + Opcode.STLOC0 + Opcode.PUSHNULL + Opcode.RET # return ) output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_if_constant_condition(self): expected_output = ( Opcode.INITSLOT + b'\x01' + b'\x00' + Opcode.PUSH0 # a = 0 + Opcode.STLOC0 + Opcode.PUSH1 + Opcode.JMPIFNOT # if True + Integer(4).to_byte_array(min_length=1, signed=True) + Opcode.PUSH2 # a = a + 2 + Opcode.STLOC0 + Opcode.LDLOC0 # return a + Opcode.RET) path = '%s/boa3_test/test_sc/if_test/ConstantCondition.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(2, result)
def test_dict_variable_keys_and_values(self): expected_output = ( Opcode.INITSLOT + b'\x04' + b'\x00' + Opcode.PUSH1 # a = 1 + Opcode.STLOC0 + Opcode.PUSH2 # b = 2 + Opcode.STLOC1 + Opcode.PUSH3 # c = 3 + Opcode.STLOC2 + Opcode.NEWMAP # d = {a: c, b: a, c: b} + Opcode.DUP + Opcode.PUSH1 # map[a] = c + Opcode.PUSH3 + Opcode.SETITEM + Opcode.DUP + Opcode.PUSH2 # map[b] = a + Opcode.PUSH1 + Opcode.SETITEM + Opcode.DUP + Opcode.PUSH3 # map[c] = b + Opcode.PUSH2 + Opcode.SETITEM + Opcode.STLOC3 + Opcode.RET) path = self.get_contract_path('VariableDict.py') output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_string_greater_than_operation(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.GT + Opcode.RET) path = '%s/boa3_test/test_sc/relational_test/StrGreaterThan.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'Main', 'test', 'unit') self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'Main', 'unit', 'unit') self.assertEqual(False, result) result = self.run_smart_contract(engine, path, 'Main', 'unit', 'test') self.assertEqual(False, result)
def test_number_less_or_equal_than_operation(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.LE + Opcode.RET) path = self.get_contract_path('NumLessOrEqual.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', 1, 2) self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'Main', 2, 2) self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'Main', 2, 1) self.assertEqual(False, result)
def test_string_greater_or_equal_than_operation(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.GE + Opcode.RET) path = self.get_contract_path('StrGreaterOrEqual.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', 'test', 'unit') self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'Main', 'unit', 'unit') self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'Main', 'unit', 'test') self.assertEqual(False, result)
def test_subtraction_operation(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.SUB + Opcode.RET) path = self.get_contract_path('Subtraction.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'sub', 10, 3) self.assertEqual(7, result) result = self.run_smart_contract(engine, path, 'sub', -42, -24) self.assertEqual(-18, result) result = self.run_smart_contract(engine, path, 'sub', -42, 24) self.assertEqual(-66, result)
def test_integer_division_operation(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.DIV + Opcode.RET) path = self.get_contract_path('IntegerDivision.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'floor_div', 10, 3) self.assertEqual(3, result) result = self.run_smart_contract(engine, path, 'floor_div', -42, -9) self.assertEqual(4, result) result = self.run_smart_contract(engine, path, 'floor_div', -100, 3) self.assertEqual(-33, result)
def test_addition_variable_and_literal(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x01' + Opcode.LDARG0 + Opcode.PUSH1 + Opcode.ADD + Opcode.RET) path = self.get_contract_path('AdditionVariableAndLiteral.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'add_one', 1) self.assertEqual(2, result) result = self.run_smart_contract(engine, path, 'add_one', -10) self.assertEqual(-9, result) result = self.run_smart_contract(engine, path, 'add_one', -1) self.assertEqual(0, result)
def test_modulo_augmented_assignment(self): expected_output = ( Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.MOD + Opcode.STARG0 + Opcode.RET ) path = self.get_contract_path('ModuloAugmentedAssignment.py') output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_dict_get_value(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x01' + Opcode.LDARG0 + Opcode.PUSH0 + Opcode.PICKITEM + Opcode.RET) path = self.get_contract_path('GetValue.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', {0: 'zero'}) self.assertEqual('zero', result) with self.assertRaises(TestExecutionException, msg=self.MAP_KEY_NOT_FOUND_ERROR_MSG): self.run_smart_contract(engine, path, 'Main', {1: 'one'})
def test_str_multiplication_operation_augmented_assignment(self): expected_output = ( Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + BinaryOp.StrMul.bytecode + Opcode.STARG0 + Opcode.RET ) path = self.get_contract_path('StringMultiplicationAugmentedAssignment.py') output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_logic_or_with_bool_operand(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.OR + Opcode.RET) path = '%s/boa3_test/test_sc/logical_test/LogicOrBool.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'Main', True, True) self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'Main', True, False) self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'Main', False, False) self.assertEqual(False, result)
def test_number_greater_or_equal_than_operation(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.GE + Opcode.RET) path = '%s/boa3_test/test_sc/relational_test/NumGreaterOrEqual.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(False, result) result = self.run_smart_contract(engine, path, 'Main', 2, 2) self.assertEqual(True, result) result = self.run_smart_contract(engine, path, 'Main', 2, 1) self.assertEqual(True, result)
def test_no_return_hint_function_without_return_statement(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x00' # num local variables + b'\x01' # num arguments + Opcode.NOP # pass + Opcode.RET # return ) path = self.get_contract_path('NoReturnFunction.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', 5) self.assertIsVoid(result)
def test_reassign_variable_with_none(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x02' + b'\x00' + Opcode.PUSH2 # a = 2 + Opcode.STLOC0 + Opcode.PUSH4 # b = a * 2 + Opcode.STLOC1 + Opcode.PUSHNULL # a = None + Opcode.STLOC0 + Opcode.RET # return ) path = self.get_contract_path('ReassignVariableWithNone.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertIsVoid(result)
def test_multiple_assignments_mismatched_type(self): string = String('str').to_bytes() expected_output = ( Opcode.INITSLOT # function signature + b'\x03' + b'\x00' + Opcode.PUSHDATA1 # c = 'str' + Integer(len(string)).to_byte_array(min_length=1) + string + Opcode.STLOC0 + Opcode.PUSH1 # a = b = c = True + Opcode.DUP # c = True + Opcode.STLOC0 + Opcode.DUP # b = True + Opcode.STLOC2 + Opcode.STLOC1 # a = True + Opcode.RET # return ) path = self.get_contract_path('MismatchedTypeMultipleAssignments.py') output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_logic_or_with_int_operand(self): expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG0 + Opcode.LDARG1 + Opcode.OR + Opcode.RET) path = self.get_contract_path('LogicOrInt.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', 4, 6) self.assertEqual(4 | 6, result) result = self.run_smart_contract(engine, path, 'Main', 40, 6) self.assertEqual(40 | 6, result) result = self.run_smart_contract(engine, path, 'Main', -4, 32) self.assertEqual(-4 | 32, result)
def test_return_local_var_value(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x01' + b'\x01' + Opcode.PUSH1 + Opcode.STLOC0 + Opcode.PUSH1 # variable address + Opcode.RET) path = self.get_contract_path('ReturnLocalVariable.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', 10) self.assertEqual(1, result) result = self.run_smart_contract(engine, path, 'Main', -140) self.assertEqual(1, result)
def test_get_contract(self): from boa3.neo3.contracts import CallFlags call_flag = Integer(CallFlags.ALL).to_byte_array(signed=True, min_length=1) expected_output = ( Opcode.INITSLOT + b'\x00\x01' + Opcode.LDARG0 + Opcode.PUSH1 + Opcode.PACK + Opcode.PUSHDATA1 + Integer(len(Interop.GetContract.method_name)).to_byte_array(min_length=1) + String(Interop.GetContract.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('GetContract.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'main', bytes(20)) self.assertIsNone(result) call_contract_path = self.get_contract_path('test_sc/arithmetic_test', 'Addition.py') Boa3.compile_and_save(call_contract_path) script, manifest = self.get_output(call_contract_path) nef, manifest = self.get_bytes_output(call_contract_path) call_hash = hash160(script) call_contract_path = call_contract_path.replace('.py', '.nef') engine.add_contract(call_contract_path) arg_manifest = json.dumps(manifest, separators=(',', ':')) result = self.run_smart_contract(engine, path, 'main', call_hash) self.assertEqual(5, len(result)) self.assertEqual(call_hash, result[2]) self.assertEqual(nef, result[3])
def test_dict_set_value(self): ok = String('ok').to_bytes() expected_output = (Opcode.INITSLOT + b'\x00' + b'\x01' + Opcode.LDARG0 + Opcode.PUSH0 + Opcode.PUSHDATA1 + Integer(len(ok)).to_byte_array(min_length=1) + ok + Opcode.SETITEM + Opcode.LDARG0 + Opcode.RET) path = '%s/boa3_test/test_sc/dict_test/SetValue.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) result = self.run_smart_contract(engine, path, 'Main', {0: 'zero'}) self.assertEqual({0: 'ok'}, result) result = self.run_smart_contract(engine, path, 'Main', {1: 'one'}) self.assertEqual({0: 'ok', 1: 'one'}, result)