Exemplo n.º 1
0
 def load(context: ExecutionContext, with_code=False):
     cls = type(
         MichelsonProgram.__name__,
         (MichelsonProgram, ),
         dict(
             parameter=ParameterSection.match(context.get_parameter_expr()),
             storage=StorageSection.match(context.get_storage_expr()),
             code=CodeSection.match(
                 context.get_code_expr() if with_code else []),
         ),
     )
     return cast(Type['MichelsonProgram'], cls)
Exemplo n.º 2
0
 def load(context: ExecutionContext, with_code=False):
     cls = type(
         TztMichelsonProgram.__name__,
         (TztMichelsonProgram, ),
         dict(
             input=InputSection.match(context.get_input_expr()),
             output=OutputSection.match(context.get_output_expr()),
             code=CodeSection.match(
                 context.get_code_expr() if with_code else []),
             big_maps=BigMapsSection.match(context.get_big_maps_expr())
             if context.get_big_maps_expr() else None,
         ),
     )
     return cast(Type['TztMichelsonProgram'], cls)
Exemplo n.º 3
0
    def test_sandboxed(self) -> None:
        # Arrange
        # TODO: Update with florencenet response
        public_version_response = {
            "version": {
                "major": 8,
                "minor": 2,
                "additional_info": "release"
            },
            "network_version": {
                "chain_name": "TEZOS_EDO2NET_2021-02-11T14:00:00Z",
                "distributed_db_version": 1,
                "p2p_version": 1
            },
            "commit_info": {
                "commit_hash": "6102c808a21b32e732ab9bb1825761cd056f3e86",
                "commit_date": "2021-02-10 22:57:06 +0100"
            },
        }
        sandboxed_version_response = {
            "version": {
                "major": 8,
                "minor": 2,
                "additional_info": "release"
            },
            "network_version": {
                "chain_name": "SANDBOXED_TEZOS",
                "distributed_db_version": 1,
                "p2p_version": 1
            },
            "commit_info": {
                "commit_hash": "6102c808a21b32e732ab9bb1825761cd056f3e86",
                "commit_date": "2021-02-10 22:57:06 +0100"
            },
        }

        # Act
        with patch("pytezos.rpc.query.RpcQuery.__call__") as rpc_mock:
            rpc_mock.return_value = public_version_response
            public_result = ExecutionContext(shell=ShellQuery(None)).sandboxed

        with patch("pytezos.rpc.query.RpcQuery.__call__") as rpc_mock:
            rpc_mock.return_value = sandboxed_version_response
            sandboxed_result = ExecutionContext(
                shell=ShellQuery(None)).sandboxed

        # Assert
        self.assertFalse(public_result)
        self.assertTrue(sandboxed_result)
Exemplo n.º 4
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
Exemplo n.º 5
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
Exemplo n.º 6
0
    def run_tzt(
        script,
        amount=None,
        chain_id=None,
        source=None,
        sender=None,
        balance=None,
        block_id=None,
        **kwargs,
    ) -> None:
        context = ExecutionContext(
            amount=amount,
            chain_id=chain_id,
            source=source,
            sender=sender,
            balance=balance,
            block_id=block_id,
            script=dict(code=script),
            tzt=True,
            **kwargs,
        )
        stack = MichelsonStack()
        stdout: List[str] = []

        program = TztMichelsonProgram.load(context, with_code=True)
        res = program.instantiate()
        res.fill_context(script, context)
        res.register_bigmaps(stack, stdout, context)
        res.begin(stack, stdout, context)
        res.execute(stack, stdout, context)
        res.end(stack, stdout, context)
Exemplo n.º 7
0
 def from_json(cls, metadata_json: Dict[str, Any], context: Optional[ExecutionContext] = None) -> 'ContractMetadata':
     metadata_json = cls.fix_metadata_json(metadata_json)
     cls.validate_metadata_json(metadata_json)
     res = Converter().structure(metadata_json, ContractMetadata)
     res.context = context if context else ExecutionContext()
     res.raw = metadata_json
     return res
Exemplo n.º 8
0
 def __init__(self, context: Optional[ExecutionContext] = None):
     super(ContextMixin, self).__init__()
     if context is None:
         context = ExecutionContext(
             shell=ShellQuery(RpcNode(nodes[default_network][0])),
             key=Key.from_encoded_key(default_key) if is_installed() else KeyHash(default_key_hash))
     self.context = context
Exemplo n.º 9
0
 def from_ipfs(
         cls,
         multihash: str,
         context: Optional[ExecutionContext] = None) -> 'ContractMetadata':
     context = context or ExecutionContext()
     metadata_json = requests.get(
         f'{context.ipfs_gateway}/{multihash}').json()
     return cls.from_json(metadata_json, context)
Exemplo n.º 10
0
 def from_ipfs(cls,
               multihash: str,
               context: Optional[ExecutionContext] = None
               ) -> 'ContractTokenMetadata':
     """Fetch token metadata from IPFS network by multihash"""
     context = context or ExecutionContext()
     token_metadata_json = requests.get(
         f'{context.ipfs_gateway}/{multihash}').json()
     return cls.from_json(token_metadata_json, context)
Exemplo n.º 11
0
 def __init__(
     self,
     extra_primitives: Optional[List[str]] = None,
     debug: bool = False,
 ) -> None:
     self.stack = MichelsonStack()
     self.context = ExecutionContext()
     self.context.debug = debug
     self.parser = MichelsonParser(debug=debug, extra_primitives=extra_primitives)
Exemplo n.º 12
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
Exemplo n.º 13
0
    def _spawn_context(
        self,
        shell: Optional[Union[ShellQuery, str]] = None,
        key: Optional[Union[Key, str, dict]] = None,
        address: Optional[str] = None,
        block_id: Optional[Union[str, int]] = None,
        mode: Optional[str] = None,
        script: Optional[dict] = None,
        ipfs_gateway: Optional[str] = None,
    ) -> ExecutionContext:
        if isinstance(shell, str):
            if shell.endswith('.pool'):
                shell = shell.split('.')[0]
                assert shell in nodes, f'unknown network {shell}'
                shell = ShellQuery(RpcMultiNode(nodes[shell]))
            elif shell in nodes:
                shell = ShellQuery(RpcNode(nodes[shell][0]))
            else:
                shell = ShellQuery(RpcNode(shell))
        else:
            assert shell is None or isinstance(
                shell, ShellQuery), f'unexpected shell {shell}'

        if isinstance(key, str):
            if key in keys:
                key = Key.from_encoded_key(keys[key])
            elif is_public_key(key):
                key = Key.from_encoded_key(key)
            elif is_pkh(key):
                key = KeyHash(key)
            elif exists(expanduser(key)):
                key = Key.from_faucet(key)
            else:
                key = Key.from_alias(key)
        elif isinstance(key, dict):
            key = Key.from_faucet(key)
        else:
            assert key is None or isinstance(key, Key), f'unexpected key {key}'

        if isinstance(address, str):
            try:
                script = self.shell.contracts[address].script()
            except RpcError as e:
                raise RpcError(f'Contract {address} not found', *e.args) from e

        return ExecutionContext(
            shell=shell or self.context.shell,
            key=key or self.context.key,
            address=address,
            block_id=block_id,
            script=script or self.context.script,
            mode=mode or self.context.mode,
            ipfs_gateway=ipfs_gateway,
        )
Exemplo n.º 14
0
    def from_json(
            cls,
            token_metadata_json: Dict[str, Any],
            context: Optional[ExecutionContext] = None
    ) -> 'ContractTokenMetadata':

        for key, value in token_metadata_json.items():
            if isinstance(value, bytes):
                token_metadata_json[key] = value.decode()
        if 'decimals' in token_metadata_json:
            token_metadata_json['decimals'] = int(
                token_metadata_json['decimals'])

        cls.validate_token_metadata_json(token_metadata_json)
        res = Converter().structure(token_metadata_json, ContractTokenMetadata)
        res.context = context if context else ExecutionContext()
        res.raw = token_metadata_json
        return res
Exemplo n.º 15
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
Exemplo n.º 16
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
Exemplo n.º 17
0
    def run_tzt(
        script: str,
        amount=None,
        chain_id=None,
        source=None,
        sender=None,
        balance=None,
        block_id=None,
        **kwargs,
    ) -> None:
        """Execute TZT test suite code

        :param script: test contract's Michelson code
        :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),
            tzt=True,
            **kwargs,
        )
        stack = MichelsonStack()
        stdout: List[str] = []

        program = TztMichelsonProgram.load(context, with_code=True)
        res = program.instantiate()
        res.fill_context(script, context)
        res.register_bigmaps(stack, stdout, context)
        res.begin(stack, stdout, context)
        res.execute(stack, stdout, context)
        res.end(stack, stdout, context)
Exemplo n.º 18
0
 def reset(self) -> None:
     self.stack = MichelsonStack()
     self.context = ExecutionContext()
Exemplo n.º 19
0
 def setUp(self):
     self.context = ExecutionContext()
     self.stack = MichelsonStack()
     self.stdout = []
Exemplo n.º 20
0
 def reset(self) -> None:
     """Reset interpreter's stack and context"""
     self.stack = MichelsonStack()
     self.context = ExecutionContext()
Exemplo n.º 21
0
 def fill_context(self, script, context: ExecutionContext) -> None:
     sender = context.get_sender_expr()
     if sender:
         context.sender = SenderSection.match(
             sender).args[0].get_string()  # type: ignore
     amount = context.get_amount_expr()
     if amount:
         context.amount = AmountSection.match(
             amount).args[0].get_int()  # type: ignore
     balance = context.get_balance_expr()
     if balance:
         context.balance = BalanceSection.match(
             balance).args[0].get_int()  # type: ignore
     _self = context.get_self_expr()
     if _self:
         context.address = SelfSection.match(
             _self).args[0].get_string()  # type: ignore
     now = context.get_now_expr()
     if now:
         context.now = NowSection.match(
             now).args[0].get_int()  # type: ignore
     source = context.get_source_expr()
     if source:
         context.source = SourceSection.match(
             source).args[0].get_string()  # type: ignore
     chain_id = context.get_chain_id_expr()
     if chain_id:
         # FIXME: Move to some common place
         context.chain_id = base58_encode(
             cast(bytes,
                  ChainIdSection.match(chain_id).args[0].literal),
             prefix=b'Net',
         ).decode()