Example #1
0
    def test_mixed_inequality_operation(self):
        expected_output = (Opcode.INITSLOT + b'\x00' + b'\x02' +
                           Opcode.LDARG0 + Opcode.LDARG1 + Opcode.NOTEQUAL +
                           Opcode.RET)

        path = self.get_contract_path('MixedInequality.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)

        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'Main', 1, 'unit')
        self.assertEqual(True, result)
        result = self.run_smart_contract(engine, path, 'Main', 123, '123')
        self.assertEqual(True, result)
        result = self.run_smart_contract(engine, path, 'Main',
                                         Integer.from_bytes(b'123'), '123')
        self.assertEqual(True, result)
Example #2
0
    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 = self.get_contract_path('SetValue.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)

        engine = TestEngine()
        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)
Example #3
0
def deserialize_binary(reader: BinaryReader) -> Any:
    deserialized_items = []
    underserialized = 1

    while underserialized > 0:
        stack_type = reader.read_byte()
        if stack_type == StackItemType.Any:
            deserialized_items.append(None)
        elif stack_type == StackItemType.Boolean:
            deserialized_items.append(reader.read_bool())
        elif stack_type == StackItemType.Integer:
            value_in_bytes = reader.read_var_bytes()
            deserialized_items.append(Integer.from_bytes(value_in_bytes))
        elif stack_type in (StackItemType.ByteString, StackItemType.Buffer):
            deserialized_items.append(reader.read_var_bytes())
        elif stack_type in (StackItemType.Array, StackItemType.Struct):
            count = reader.read_var_int()
            deserialized_items.append(list(range(count)))
            underserialized += count
        elif stack_type == StackItemType.Map:
            count = reader.read_var_int()
            deserialized_items.append({key: None for key in range(count)})
            underserialized += count * 2
        else:
            raise ValueError

        underserialized -= 1

    stack_temp = []
    while len(deserialized_items) > 0:
        item = deserialized_items.pop()
        if isinstance(item, list):
            new_item = []
            for _ in range(len(item)):
                new_item.append(stack_temp.pop())
            item = new_item
        elif isinstance(item, dict):
            new_item = {}
            for _ in range(0, len(item), 2):
                key = stack_temp.pop()
                value = stack_temp.pop()
                new_item[key] = value
            item = new_item
        stack_temp.append(item)

    return stack_temp.pop()
Example #4
0
    def test_any_list_constant(self):
        input = [1, '2', False]
        byte_input1 = String(input[1]).to_bytes()

        expected_output = (
            Opcode.INITSSLOT + b'\x01' + Opcode.PUSH0  # False
            + Opcode.CONVERT + StackItemType.Boolean + Opcode.PUSHDATA1  # '2'
            + Integer(len(byte_input1)).to_byte_array() + byte_input1 +
            Opcode.PUSH1  # 1
            + Opcode.PUSH3  # list length
            + Opcode.PACK + Opcode.DROP + Opcode.RET)

        analyser = Analyser(ast.parse(str(input)))
        analyser.symbol_table['x'] = Variable(Type.any)
        output = CodeGenerator.generate_code(analyser)

        self.assertEqual(expected_output, output)
Example #5
0
    def test_if_constant_condition(self):
        expected_output = (
            Opcode.INITSLOT + b'\x01' + b'\x00' + Opcode.PUSH0  # a = 0
            + Opcode.STLOC0 + Opcode.PUSH1 + Opcode.CONVERT +
            StackItemType.Boolean + 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 = self.get_contract_path('ConstantCondition.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)

        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'Main')
        self.assertEqual(2, 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)
Example #7
0
    def opcode(self) -> List[Tuple[Opcode, bytes]]:
        from boa3.model.builtin.interop.interop import Interop
        from boa3.model.type.type import Type
        from boa3.neo.vm.type.Integer import Integer
        from boa3.neo.vm.type.String import String

        method = String(self._sys_call).to_bytes()
        method_opcode = [
            (Opcode.PUSHDATA1,
             Integer(len(method)).to_byte_array(min_length=1) + method)
        ]
        drop_if_void_opcode = [(Opcode.DROP,
                                b'')] if self.return_type is Type.none else []

        return (method_opcode +
                Interop.ManagementContractScriptHash.getter.opcode +
                Interop.CallContract.opcode + drop_if_void_opcode)
Example #8
0
    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
        )

        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)
Example #9
0
    def test_import_user_module_with_global_variables(self):
        expected_output = (
            Opcode.LDSFLD0  # b = a
            + Opcode.RET + Opcode.INITSSLOT + b'\x01' +
            Opcode.CALL  # a = UserModule.EmptyList()
            + Integer(4).to_byte_array(min_length=1, signed=True) +
            Opcode.STSFLD0 + Opcode.RET + Opcode.NEWARRAY0  # imported function
            + Opcode.RET  # return
        )

        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)
Example #10
0
    def test_call_function_written_before_caller(self):
        call_address = Integer(-9).to_byte_array(min_length=1, signed=True)

        expected_output = (
            Opcode.INITSLOT  # TestFunction
            + b'\x00' + b'\x02' + Opcode.LDARG0  # return a + b
            + Opcode.LDARG1 + Opcode.ADD + Opcode.RET +
            Opcode.PUSH2  # return TestAdd(a, b)
            + Opcode.PUSH1 + Opcode.CALL + call_address + Opcode.RET)

        path = self.get_contract_path('CallFunctionWrittenBefore.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)

        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'Main')
        self.assertEqual(3, result)
Example #11
0
    def _get_raw_data(self, opcode: VMCode) -> bytes:
        """
        Gets the Neo VM raw data of the code

        :return: the unformatted data in bytes of the code.
        """
        min_len = self._info.data_len // 2  # for try opcode, data_len adds catch and finally addresses
        if opcode is None:
            return bytes(min_len)
        else:
            from boa3.compiler.vmcodemapping import VMCodeMapping
            code_mapping = VMCodeMapping.instance()
            self_start = code_mapping.get_start_address(self)
            target_start = code_mapping.get_start_address(opcode)

            return (Integer(target_start - self_start).to_byte_array(
                signed=True, min_length=min_len))
def get_native_contract_data(
        token_script: bytes) -> Tuple[Optional[bytes], Optional[int]]:
    prefix: Optional[NativeContractPrefix] = None
    contract_id: NativeContractId = NativeContractId.NONE

    if token_script is constants.NEO_SCRIPT:
        prefix = NativeContractPrefix.NEO
        contract_id = NativeContractId.NEO
    elif token_script is constants.GAS_SCRIPT:
        prefix = NativeContractPrefix.GAS
        contract_id = NativeContractId.GAS
    elif token_script is constants.MANAGEMENT_SCRIPT:
        prefix = NativeContractPrefix.ContractManagement
        contract_id = NativeContractId.ContractManagement

    return (prefix if prefix is None else Integer(prefix).to_byte_array(
        min_length=1), contract_id.value)
Example #13
0
    def convert_store_variable(self, var_id: str):
        """
        Converts the assignment of a variable

        :param var_id: the value to be converted
        """
        index, local, is_arg = self._get_variable_info(var_id)
        if index >= 0:
            opcode = Opcode.get_store(index, local, is_arg)
            if opcode is not None:
                op_info = OpcodeInfo.get_info(opcode)

                if op_info.data_len > 0:
                    self.__insert1(op_info, Integer(index).to_byte_array())
                else:
                    self.__insert1(op_info)
                self._stack.pop()
Example #14
0
    def test_any_variable_assignments(self):
        two = String('2').to_bytes()
        path = self.get_contract_path('AnyVariableAssignments.py')

        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.CONVERT + StackItemType.Boolean + Opcode.STLOC0 +
            Opcode.PUSH3  # a = [1, 2, 3]
            + Opcode.PUSH2 + Opcode.PUSH1 + Opcode.PUSH3 + Opcode.PACK +
            Opcode.STLOC0 + Opcode.RET  # return
        )
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)
Example #15
0
    def test_nested_for(self):
        outer_jmpif_address = Integer(47).to_byte_array(min_length=1,
                                                        signed=True)
        outer_jmp_address = Integer(-50).to_byte_array(min_length=1,
                                                       signed=True)

        inner_jmpif_address = Integer(21).to_byte_array(min_length=1,
                                                        signed=True)
        inner_jmp_address = Integer(-24).to_byte_array(min_length=1,
                                                       signed=True)

        expected_output = (
            Opcode.INITSLOT + b'\x04' + 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  # outer_for_sequence = sequence
            + Opcode.PUSH0  # outer_for_index = 0
            + Opcode.JMP + outer_jmpif_address +
            Opcode.OVER  # x = outer_for_sequence[outer_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.LDLOC1  # inner_for_sequence = sequence
            + Opcode.PUSH0  # inner_for_index = 0
            + Opcode.JMP + inner_jmpif_address +
            Opcode.OVER  # y = inner_for_sequence[inner_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.STLOC3 +
            Opcode.LDLOC0  # a = a + x * y
            + Opcode.LDLOC2 + Opcode.LDLOC3 + Opcode.MUL + Opcode.ADD +
            Opcode.STLOC0 + Opcode.INC  # inner_for_index = inner_for_index + 1
            + Opcode.DUP  # if inner_for_index < len(inner_for_sequence)
            + Opcode.PUSH2 + Opcode.PICK + Opcode.SIZE + Opcode.LT +
            Opcode.JMPIF  # end inner_for
            + inner_jmp_address + Opcode.DROP + Opcode.DROP +
            Opcode.INC  # outer_for_index = outer_for_index + 1
            + Opcode.DUP  # if outer_for_index < len(outer_for_sequence)
            + Opcode.PUSH2 + Opcode.PICK + Opcode.SIZE + Opcode.LT +
            Opcode.JMPIF  # end outer_for
            + outer_jmp_address + Opcode.DROP + Opcode.DROP +
            Opcode.LDLOC0  # return a
            + Opcode.RET)

        path = self.get_contract_path('NestedFor.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)

        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'Main')
        self.assertEqual(529, result)
Example #16
0
    def test_dict_any_value(self):
        nine = String('nine').to_bytes()

        expected_output = (
            Opcode.INITSLOT + b'\x01' + b'\x00' +
            Opcode.NEWMAP  # a = {1: True, 2: 4, 3: 'nine'}
            + Opcode.DUP + Opcode.PUSH1  # map[1] = True
            + Opcode.PUSH1 + Opcode.SETITEM + Opcode.DUP +
            Opcode.PUSH2  # map[2] = 4
            + Opcode.PUSH4 + Opcode.SETITEM + Opcode.DUP +
            Opcode.PUSH3  # map[3] = 'nine'
            + Opcode.PUSHDATA1 +
            Integer(len(nine)).to_byte_array(min_length=1) + nine +
            Opcode.SETITEM + Opcode.STLOC0 + Opcode.PUSHNULL + Opcode.RET)

        path = '%s/boa3_test/test_sc/dict_test/AnyValueDict.py' % self.dirname
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)
Example #17
0
    def test_dict_any_value(self):
        nine = String('nine').to_bytes()

        expected_output = (
            Opcode.INITSLOT + b'\x01' + b'\x00' +
            Opcode.NEWMAP  # a = {1: True, 2: 4, 3: 'nine'}
            + Opcode.DUP + Opcode.PUSH1  # map[1] = True
            + Opcode.PUSH1 + Opcode.CONVERT + StackItemType.Boolean +
            Opcode.SETITEM + Opcode.DUP + Opcode.PUSH2  # map[2] = 4
            + Opcode.PUSH4 + Opcode.SETITEM + Opcode.DUP +
            Opcode.PUSH3  # map[3] = 'nine'
            + Opcode.PUSHDATA1 +
            Integer(len(nine)).to_byte_array(min_length=1) + nine +
            Opcode.SETITEM + Opcode.STLOC0 + Opcode.RET)

        path = self.get_contract_path('AnyValueDict.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)
Example #18
0
    def test_multiple_assignments_set_sequence_last(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  # a[2] = c = b = 2
            + Opcode.DUP  # b = 2
            + Opcode.STLOC2 + Opcode.DUP  # c = 2
            + Opcode.STLOC1 + Opcode.PUSH2  # a[2] = 2
            + 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.LDLOC0 + Opcode.REVERSE3 +
            Opcode.SETITEM + Opcode.PUSHNULL  # return
            + Opcode.RET)

        path = '%s/boa3_test/test_sc/variable_test/MultipleAssignmentsSetSequenceLast.py' % self.dirname
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)
Example #19
0
    def test_if_variable_condition(self):
        expected_output = (
            Opcode.INITSLOT + b'\x01' + b'\x01' + Opcode.PUSH0  # a = 0
            + Opcode.STLOC0 + Opcode.LDARG0 + Opcode.JMPIFNOT  # if arg0
            + Integer(4).to_byte_array(min_length=1, signed=True) +
            Opcode.PUSH2  # a = a + 2
            + Opcode.STLOC0 + Opcode.LDLOC0  # return a
            + Opcode.RET)

        path = self.get_contract_path('VariableCondition.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(0, result)
Example #20
0
    def test_log_str(self):
        string = String('str').to_bytes()
        expected_output = (
            Opcode.PUSHDATA1
            + Integer(len(string)).to_byte_array(min_length=1)
            + string
            + Opcode.SYSCALL
            + Interop.Log.interop_method_hash
            + Opcode.RET
        )

        path = self.get_contract_path('LogStr.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)

        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'Main')
        self.assertIsVoid(result)
Example #21
0
    def test_get_gas_native_script_hash(self):
        value = GAS
        expected_output = (
            Opcode.PUSHDATA1
            + Integer(len(value)).to_byte_array()
            + value
            + Opcode.CONVERT
            + Type.bytes.stack_item
            + Opcode.RET
        )

        path = '%s/boa3_test/test_sc/interop_test/GasScriptHash.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(value, result)
Example #22
0
    def _filter_result(self, test_engine, expected_result_type, result) -> Any:
        if test_engine.vm_state is not VMState.HALT and test_engine.error is not None:
            raise TestExecutionException(test_engine.error)

        if expected_result_type is not None:
            if expected_result_type is not str and isinstance(result, str):
                result = String(result).to_bytes()

            if expected_result_type is bool:
                if isinstance(result, bytes):
                    result = Integer.from_bytes(result, signed=True)
                if isinstance(result, int) and result in (False, True):
                    result = bool(result)

            if expected_result_type is bytearray and isinstance(result, bytes):
                result = bytearray(result)

        return result
Example #23
0
 def opcode(self) -> List[Tuple[Opcode, bytes]]:
     from boa3.neo.vm.type.Integer import Integer
     return [
         (Opcode.DUP, b''),
         (Opcode.SIGN, b''),
         (Opcode.PUSHM1, b''),
         (Opcode.JMPNE, Integer(5).to_byte_array(min_length=1,
                                                 signed=True)),
         (Opcode.OVER, b''),
         (Opcode.SIZE, b''),
         (Opcode.ADD, b''),
         (Opcode.OVER, b''),
         (Opcode.OVER, b''),
         (Opcode.PICKITEM, b''),
         (Opcode.REVERSE3, b''),
         (Opcode.SWAP, b''),
         (Opcode.REMOVE, b''),
     ]
Example #24
0
    def test_cast_to_typed_dict(self):
        string = String('example').to_bytes()
        expected_output = (
            Opcode.INITSLOT
            + b'\x01'
            + b'\x01'
            + Opcode.LDARG0     # x = cast(Dict[str, int], value)
            + Opcode.STLOC0
            + Opcode.LDLOC0     # return x['example']
            + Opcode.PUSHDATA1
            + Integer(len(string)).to_byte_array(min_length=1)
            + string
            + Opcode.PICKITEM
            + Opcode.RET
        )

        path = self.get_contract_path('CastToTypedDict.py')
        output = self.assertCompilerLogs(CompilerWarning.TypeCasting, path)
        self.assertEqual(expected_output, output)
Example #25
0
    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_script_hash_variable_with_builtin(self):
        path = self.get_contract_path('ScriptHashVariableBuiltinCall.py')
        from boa3.neo import to_script_hash
        from base58 import b58encode
        engine = TestEngine()

        script_hash = to_script_hash('123')
        result = self.run_smart_contract(engine, path, 'Main', '123',
                                         expected_result_type=bytes)
        self.assertEqual(script_hash, result)

        value = b58encode('123')
        if isinstance(value, int):
            value = Integer(value).to_byte_array()

        script_hash = to_script_hash(value)
        result = self.run_smart_contract(engine, path, 'Main', value,
                                         expected_result_type=bytes)
        self.assertEqual(script_hash, result)
Example #27
0
    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.RET  # return
        )

        path = self.get_contract_path('MultipleAssignmentsSetSequence.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)
Example #28
0
    def run_smart_contract(self, test_engine: TestEngine, smart_contract_path: Union[str, bytes], method: str,
                           *arguments: Any, reset_engine: bool = False,
                           fake_storage: Dict[Tuple[str, str], Any] = None,
                           signer_accounts: Iterable[bytes] = (),
                           expected_result_type: Type = None,
                           rollback_on_fault: bool = True) -> Any:

        if isinstance(smart_contract_path, str) and smart_contract_path.endswith('.py'):
            if not (os.path.isfile(smart_contract_path.replace('.py', '.nef'))
                    and os.path.isfile(smart_contract_path.replace('.py', '.manifest.json'))):
                # both .nef and .manifest.json are required to execute the smart contract
                self.compile_and_save(smart_contract_path, log=False)
            smart_contract_path = smart_contract_path.replace('.py', '.nef')
        elif isinstance(smart_contract_path, bytes):
            from boa3.neo3.core.types import UInt160
            smart_contract_path = UInt160(smart_contract_path)

        if isinstance(fake_storage, dict):
            test_engine.set_storage(fake_storage)

        for account in signer_accounts:
            test_engine.add_signer_account(account)

        result = test_engine.run(smart_contract_path, method, *arguments,
                                 reset_engine=reset_engine, rollback_on_fault=rollback_on_fault)

        if test_engine.vm_state is not VMState.HALT and test_engine.error is not None:
            raise TestExecutionException(test_engine.error)

        if expected_result_type is not None:
            if expected_result_type is not str and isinstance(result, str):
                result = String(result).to_bytes()

            if expected_result_type is bool:
                if isinstance(result, bytes):
                    result = Integer.from_bytes(result, signed=True)
                if isinstance(result, int) and result in (False, True):
                    result = bool(result)

            if expected_result_type is bytearray and isinstance(result, bytes):
                result = bytearray(result)

        return result
Example #29
0
    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)
Example #30
0
    def test_sequence_of_int_sequence_fail(self):
        ok = String('ok').to_bytes()
        expected_output = (
            Opcode.INITSLOT + b'\x04' + b'\x00' +
            Opcode.PUSH3  # int_list = [1, 2, 3]
            + Opcode.PUSH2 + Opcode.PUSH1 + Opcode.PUSH3 + Opcode.PACK +
            Opcode.STLOC0 + Opcode.PUSHDATA1  # any_tuple = (True, 1, 'ok')
            + Integer(len(ok)).to_byte_array() + ok + Opcode.PUSH1 +
            Opcode.PUSH1 + Opcode.PUSH3 + Opcode.PACK + Opcode.STLOC1 +
            Opcode.PUSH8  # int_tuple = 10, 9, 8
            + Opcode.PUSH9 + Opcode.PUSH10 + Opcode.PUSH3 + Opcode.PACK +
            Opcode.STLOC2 +
            Opcode.LDLOC2  # a = [int_list, any_tuple, int_tuple]
            + Opcode.LDLOC1 + Opcode.LDLOC0 + Opcode.PUSH3 + Opcode.PACK +
            Opcode.STLOC3 + Opcode.RET)

        path = self.get_contract_path('SequenceOfAnyIntSequence.py')
        output = self.assertCompilerLogs(CompilerWarning.TypeCasting, path)
        self.assertEqual(expected_output, output)