Ejemplo n.º 1
0
 def run_view(
     entrypoint,
     parameter,
     storage,
     context: ExecutionContext,
 ) -> Tuple[Any, List[str], Optional[Exception]]:
     ctx = ExecutionContext(
         shell=context.shell,
         key=context.key,
         block_id=context.block_id,
         script=context.script,
         address=context.address,
     )
     stack = MichelsonStack()
     stdout = []  # type: ignore
     try:
         program = MichelsonProgram.load(ctx, with_code=True)
         res = program.instantiate(entrypoint=entrypoint,
                                   parameter=parameter,
                                   storage=storage)
         res.begin(stack, stdout, context)
         res.execute(stack, stdout, context)
         _, _, _, pair = res.end(stack, stdout)
         operations = cast(List[OperationType], list(pair.items[0]))
         if not len(operations) == 1:
             raise Exception(
                 'Multiple internal operations, not sure which one to pick')
         return operations[0].to_python_object(), stdout, None
     except MichelsonRuntimeError as e:
         stdout.append(e.format_stdout())
         return None, stdout, e
Ejemplo n.º 2
0
    def from_run_operation(cls, operation_group: Dict[str, Any], context: ExecutionContext) -> List['ContractCallResult']:
        """Get a list of results from an operation group content with metadata.

        :param operation_group: {..., "contents": [{..., kind: "transaction", ...}]}
        :param context: execution context
        :rtype: ContractCallResult
        """
        results: List['OperationResult'] = list()
        for content in OperationResult.iter_contents(operation_group):
            if content['kind'] == 'transaction':
                if content['destination'] == context.address:
                    results.append(cls.from_transaction(content))
            elif content['kind'] == 'origination':
                result = cls.get_result(content)
                if context.address in result.get('originated_contracts', []):
                    results.append(cls.from_origination(content))

        program = MichelsonProgram.load(context)

        def decode_result(res: OperationResult) -> 'ContractCallResult':
            kwargs = {}  # type: ignore
            if hasattr(res, 'storage') and res.storage is not None:  # type: ignore
                storage = program.storage.from_micheline_value(res.storage)  # type: ignore
                if hasattr(res, 'lazy_diff'):
                    kwargs.update(lazy_diff=res.lazy_diff)  # type: ignore
                    storage = storage.merge_lazy_diff(res.lazy_diff)  # type: ignore
                kwargs.update(storage=storage.to_python_object())
            if hasattr(res, 'parameters'):
                parameters = program.parameter.from_parameters(res.parameters)  # type: ignore
                kwargs.update(parameters=parameters)
            if hasattr(res, 'operations'):
                kwargs.update(operations=res.operations)  # type: ignore
            return cls(**kwargs)

        return list(map(decode_result, results))
Ejemplo n.º 3
0
    def run_view(
        entrypoint: str,
        parameter,
        storage,
        context: ExecutionContext,
    ) -> Tuple[Any, Any, List[str], Optional[Exception]]:
        """Execute view of contract loaded in context

        :param entrypoint: contract entrypoint
        :param parameter: parameter section
        :param storage: storage section
        :param context: execution context
        :returns: [operations, storage, stdout, error]
        """
        ctx = ExecutionContext(
            shell=context.shell,
            key=context.key,
            block_id=context.block_id,
            script=context.script,
            address=context.address,
        )
        stack = MichelsonStack()
        stdout = []  # type: ignore
        try:
            program = MichelsonProgram.load(ctx, with_code=True)
            res = program.instantiate(entrypoint=entrypoint, parameter=parameter, storage=storage)
            res.begin(stack, stdout, context)
            res.execute(stack, stdout, context)
            _, _, _, pair = res.end(stack, stdout)
            operations = cast(List[OperationType], list(pair.items[0]))
            storage = pair.items[1]
            return [op.to_python_object() for op in operations], storage.to_python_object(), stdout, None
        except MichelsonRuntimeError as e:
            stdout.append(e.format_stdout())
            return None, None, stdout, e
Ejemplo n.º 4
0
    def from_context(context: ExecutionContext) -> 'ContractInterface':
        """Create contract from the previously loaded context data.

        :param context: execution context
        :return: ContractInterface
        """
        program = MichelsonProgram.load(context, with_code=True)
        cls = type(ContractInterface.__name__, (ContractInterface, ),
                   dict(program=program))
        return cls(context)
Ejemplo n.º 5
0
    def run_code(
        parameter,
        storage,
        script: str,
        entrypoint='default',
        output_mode='readable',
        amount=None,
        chain_id=None,
        source=None,
        sender=None,
        balance=None,
        block_id=None,
        **kwargs,
    ) -> Tuple[List[dict], Any, List[dict], List[str], Optional[Exception]]:
        """Execute contract in interpreter

        :param parameter: parameter expression
        :param storage: storage expression
        :param script: contract's Michelson code
        :param entrypoint: contract entrypoint
        :param output_mode: one of readable/optimized/legacy_optimized
        :param amount: patch AMOUNT
        :param chain_id: patch CHAIN_ID
        :param source: patch SOURCE
        :param sender: patch SENDER
        :param balance: patch BALANCE
        :param block_id: set block ID
        """
        context = ExecutionContext(
            amount=amount,
            chain_id=chain_id,
            source=source,
            sender=sender,
            balance=balance,
            block_id=block_id,
            script=dict(code=script),
            **kwargs,
        )
        stack = MichelsonStack()
        stdout = []  # type: ignore
        try:
            program = MichelsonProgram.load(context, with_code=True)
            res = program.instantiate(
                entrypoint=entrypoint,
                parameter=parameter,
                storage=storage,
            )
            res.begin(stack, stdout, context)
            res.execute(stack, stdout, context)
            operations, storage, lazy_diff, _ = res.end(
                stack, stdout, output_mode=output_mode)
            return operations, storage, lazy_diff, stdout, None
        except MichelsonRuntimeError as e:
            stdout.append(e.format_stdout())
            return [], None, [], stdout, e
Ejemplo n.º 6
0
    def from_run_code(cls, response: Dict[str, Any], parameters, context: ExecutionContext) -> 'ContractCallResult':
        """Parse a result of :py:meth:`pytezos.contract.call.ContractCall.run_code` execution.

        :param response: RPC response (JSON)
        :param parameters: {"entrypoint": str, "value": $Micheline}
        :param context: execution context
        :rtype: ContractCallResult
        """
        program = MichelsonProgram.load(context)
        parameters = program.parameter.from_parameters(parameters)
        storage = program.storage.from_micheline_value(response['storage'])
        extended_storage = storage.merge_lazy_diff(response.get('lazy_diff', []))
        return cls(
            parameters=parameters.to_python_object(),
            storage=extended_storage.to_python_object(lazy_diff=True),
            lazy_diff=response.get('lazy_diff', []),
            operations=response.get('operations', []),
        )
Ejemplo n.º 7
0
    def execute(cls, stack: MichelsonStack, stdout: List[str],
                context: AbstractContext):
        from pytezos.michelson.program import MichelsonProgram

        stack.clear()
        entrypoint, parameter_literal, storage_literal = cls.args  # type: ignore
        entrypoint_str = entrypoint.get_string()  # type: ignore

        parameter = parameter_literal.as_micheline_expr()
        storage = storage_literal.as_micheline_expr()

        program = MichelsonProgram.load(context, with_code=True).instantiate(
            entrypoint_str, parameter, storage)  # type: ignore
        program.begin(stack, stdout, context)
        program.execute(stack, stdout, context)  # type: ignore
        operations, storage, lazy_diff, res = program.end(stack, stdout)

        return cls(lazy_diff=lazy_diff, result=res)
Ejemplo n.º 8
0
    def run_view(
        entrypoint: str,
        parameter,
        storage,
        context: ExecutionContext,
    ) -> Tuple[Any, Any, List[str], Optional[Exception]]:
        """Execute view of contract loaded in context

        :param entrypoint: contract entrypoint
        :param parameter: parameter section
        :param storage: storage section
        :param context: execution context
        :returns: [operations, storage, stdout, error]
        """
        ctx = ExecutionContext(
            shell=context.shell,
            key=context.key,
            block_id=context.block_id,
            script=context.script,
            address=context.address,
        )
        stack = MichelsonStack()
        stdout = []  # type: ignore
        try:
            program = MichelsonProgram.load(ctx, with_code=True)
            res = program.instantiate(entrypoint=entrypoint, parameter=parameter, storage=storage)
            res.begin(stack, stdout, context)
            res.execute(stack, stdout, context)
            _, _, _, pair = res.end(stack, stdout)
            operations = cast(List[OperationType], list(pair.items[0]))
            storage = pair.items[1]
            # Note: the `storage` returned by the Michelson interpreter above is not
            # required to include the full annotations specified in the contract's storage.
            # The lack of annotations affects calls to `to_python_object()`, causing the storage
            # you get back from the view to not always be converted to the same object
            # as if you called ContractInterface.storage() directly.
            # Re-parsing using the contract's storage section here to recover the annotations.
            storage = program.storage.from_micheline_value(storage.to_micheline_value())
            return [op.to_python_object() for op in operations], storage.to_python_object(), stdout, None
        except MichelsonRuntimeError as e:
            stdout.append(e.format_stdout())
            return None, None, stdout, e
Ejemplo n.º 9
0
 def run_code(
     parameter,
     storage,
     script,
     entrypoint='default',
     output_mode='readable',
     amount=None,
     chain_id=None,
     source=None,
     sender=None,
     balance=None,
     block_id=None,
     **kwargs,
 ) -> Tuple[List[dict], Any, List[dict], List[str], Optional[Exception]]:
     context = ExecutionContext(
         amount=amount,
         chain_id=chain_id,
         source=source,
         sender=sender,
         balance=balance,
         block_id=block_id,
         script=dict(code=script),
         **kwargs,
     )
     stack = MichelsonStack()
     stdout = []  # type: ignore
     try:
         program = MichelsonProgram.load(context, with_code=True)
         res = program.instantiate(
             entrypoint=entrypoint,
             parameter=parameter,
             storage=storage,
         )
         res.begin(stack, stdout, context)
         res.execute(stack, stdout, context)
         operations, storage, lazy_diff, _ = res.end(
             stack, stdout, output_mode=output_mode)
         return operations, storage, lazy_diff, stdout, None
     except MichelsonRuntimeError as e:
         stdout.append(e.format_stdout())
         return [], None, [], stdout, e