예제 #1
0
 def get_invoke_result(self, script, container=None):
     appengine = ApplicationEngine.Run(script=script, container=container)
     return {
         "script": script.decode('utf-8'),
         "state": VMStateStr(appengine.State),
         "gas_consumed": appengine.GasConsumed().ToString(),
         "stack": [ContractParameter.ToParameter(item).ToJson() for item in appengine.EvaluationStack.Items]
     }
예제 #2
0
    def get_invoke_result(self, script):

        appengine = ApplicationEngine.Run(script=script)
        return {
            "script": script.hex(),
            "state": appengine.State,
            "gas_consumed": appengine.GasConsumed().ToString(),
            "stack": [ContractParameter.ToParameter(item).ToJson() for item in appengine.EvaluationStack.Items]
        }
예제 #3
0
 def get_invoke_result(self, script):
     snapshot = GetBlockchain()._db.createSnapshot()
     appengine = ApplicationEngine.Run(snapshot, script=script)
     return {
         "script": script.decode('utf-8'),
         "state": VMStateStr(appengine.State),
         "gas_consumed": appengine.GasConsumed().ToString(),
         "stack": [ContractParameter.ToParameter(item).ToJson() for item in appengine.ResultStack.Items]
     }
예제 #4
0
    def ExecutionCompleted(self, engine, success, error=None):

        height = Blockchain.Default().Height + 1
        tx_hash = None

        if engine.ScriptContainer:
            tx_hash = engine.ScriptContainer.Hash

        if not tx_hash:
            tx_hash = UInt256(data=bytearray(32))

        entry_script = None
        try:
            # get the first script that was executed
            # this is usually the script that sets up the script to be executed
            entry_script = UInt160(data=engine.ExecutedScriptHashes[0])

            # ExecutedScriptHashes[1] will usually be the first contract executed
            if len(engine.ExecutedScriptHashes) > 1:
                entry_script = UInt160(data=engine.ExecutedScriptHashes[1])
        except Exception as e:
            logger.error("Could not get entry script: %s " % e)

        payload = ContractParameter(ContractParameterType.Array, value=[])
        for item in engine.EvaluationStack.Items:
            payload.Value.append(ContractParameter.ToParameter(item))

        if success:

            # dispatch all notify events, along with the success of the contract execution
            for notify_event_args in self.notifications:
                self.events_to_dispatch.append(NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, notify_event_args.State,
                                                           notify_event_args.ScriptHash, height, tx_hash,
                                                           success, engine.testMode))

            if engine.Trigger == Application:
                self.events_to_dispatch.append(SmartContractEvent(SmartContractEvent.EXECUTION_SUCCESS, payload, entry_script,
                                                                  height, tx_hash, success, engine.testMode))
            else:
                self.events_to_dispatch.append(SmartContractEvent(SmartContractEvent.VERIFICATION_SUCCESS, payload, entry_script,
                                                                  height, tx_hash, success, engine.testMode))

        else:
            payload.Value.append(ContractParameter(ContractParameterType.String, error))
            payload.Value.append(ContractParameter(ContractParameterType.String, engine._VMState))
            if engine.Trigger == Application:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.EXECUTION_FAIL, payload,
                                       entry_script, height, tx_hash, success, engine.testMode))
            else:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.VERIFICATION_FAIL, payload,
                                       entry_script, height, tx_hash, success, engine.testMode))

        self.notifications = []
예제 #5
0
    def test_invoke_contract(self, args):
        if not self.Wallet:
            print("Please open a wallet")
            return
        args, from_addr = get_from_addr(args)
        args, invoke_attrs = get_tx_attr_from_args(args)
        args, owners = get_owners_from_params(args)
        if args and len(args) > 0:
            tx, fee, results, num_ops = TestInvokeContract(
                self.Wallet,
                args,
                from_addr=from_addr,
                invoke_attrs=invoke_attrs,
                owners=owners)

            if tx is not None and results is not None:

                parameterized_results = [
                    ContractParameter.ToParameter(item) for item in results
                ]

                print(
                    "\n-------------------------------------------------------------------------------------------------------------------------------------"
                )
                print("Test invoke successful")
                print("Total operations: %s" % num_ops)
                print("Results %s" %
                      [item.ToJson() for item in parameterized_results])
                print("Invoke TX GAS cost: %s" % (tx.Gas.value / Fixed8.D))
                print("Invoke TX fee: %s" % (fee.value / Fixed8.D))
                print(
                    "-------------------------------------------------------------------------------------------------------------------------------------\n"
                )
                print(
                    "Enter your password to continue and invoke on the network\n"
                )

                tx.Attributes = invoke_attrs

                passwd = prompt("[password]> ", is_password=True)
                if not self.Wallet.ValidatePassword(passwd):
                    return print("Incorrect password")

                InvokeContract(self.Wallet,
                               tx,
                               fee,
                               from_addr=from_addr,
                               owners=owners)
                return
            else:
                print("Error testing contract invoke")
                return

        print("Please specify a contract to invoke")
예제 #6
0
파일: SC.py 프로젝트: ilkericyuz/neo-python
    def execute(self, arguments):
        wallet = PromptData.Wallet
        if not wallet:
            print("Please open a wallet")
            return False

        arguments, from_addr = PromptUtils.get_from_addr(arguments)
        arguments, invoke_attrs = PromptUtils.get_tx_attr_from_args(arguments)
        arguments, owners = PromptUtils.get_owners_from_params(arguments)

        if len(arguments) < 1:
            print("Please specify the required parameters")
            return False

        hash_string = arguments[0]
        try:
            script_hash = UInt160.ParseString(hash_string)
        except Exception:
            # because UInt160 throws a generic exception. Should be fixed in the future
            print("Invalid script hash")
            return False

        tx, fee, results, num_ops, engine_success = TestInvokeContract(wallet, arguments, from_addr=from_addr, invoke_attrs=invoke_attrs, owners=owners)
        if tx and results:

            parameterized_results = [ContractParameter.ToParameter(item).ToJson() for item in results]

            print(
                "\n-------------------------------------------------------------------------------------------------------------------------------------")
            print("Test invoke successful")
            print(f"Total operations: {num_ops}")
            print(f"Results {str(parameterized_results)}")
            print(f"Invoke TX GAS cost: {tx.Gas.value / Fixed8.D}")
            print(f"Invoke TX fee: {fee.value / Fixed8.D}")
            print(
                "-------------------------------------------------------------------------------------------------------------------------------------\n")
            print("Enter your password to continue and invoke on the network\n")

            tx.Attributes = invoke_attrs

            passwd = prompt("[password]> ", is_password=True)
            if not wallet.ValidatePassword(passwd):
                return print("Incorrect password")

            return InvokeContract(wallet, tx, fee, from_addr=from_addr, owners=owners)
        else:
            print("Error testing contract invoke")
            return False
예제 #7
0
 def get_invoke_result_balance(self, script):
     appengine = ApplicationEngine.Run(script=script)
     val = appengine.EvaluationStack.Items[0].GetBigInteger()
     balance = Decimal(val)
     return {
         "script":
         script.decode('utf-8'),
         "state":
         VMStateStr(appengine.State),
         "gas_consumed":
         appengine.GasConsumed().ToString(),
         "stack": [
             ContractParameter.ToParameter(item).ToJson()
             for item in appengine.EvaluationStack.Items
         ],
         "balance":
         str(balance)
     }
예제 #8
0
    def Runtime_Notify(self, engine: ExecutionEngine):
        state = engine.CurrentContext.EvaluationStack.Pop()

        payload = ContractParameter.ToParameter(state)

        args = NotifyEventArgs(
            engine.ScriptContainer,
            UInt160(data=engine.CurrentContext.ScriptHash()), payload)

        self.notifications.append(args)

        if settings.emit_notify_events_on_sc_execution_error:
            # emit Notify events even if the SC execution might fail.
            tx_hash = engine.ScriptContainer.Hash
            height = GetBlockchain().Height + 1
            success = None
            self.events_to_dispatch.append(
                NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, payload,
                            args.ScriptHash, height, tx_hash, success,
                            engine.testMode))

        return True
예제 #9
0
    def start(self):

        self.continue_debug = True
        #        pprint.pprint(self.debug_map)

        dbg_title = self.debug_map['avm']['name']
        print("\n")
        print("======= debug engine enter =======")

        ctx = self.get_context()
        ctx.print()

        while self.continue_debug:
            try:
                result = prompt("[%s debug]> " % dbg_title)
            except EOFError:
                # Control-D pressed: quit
                self.continue_debug = False
            except KeyboardInterrupt:
                # Control-C pressed: do nothing
                self.continue_debug = False

            command, arguments = self.parser.parse_input(result)

            if command is not None and len(command) > 0:
                command = command.lower()

                if command in ['quit', 'exit', 'cont']:
                    self.continue_debug = False

                elif command == 'estack':
                    if self.engine._InvocationStack.Count > 0:  # eval stack now only available via ExecutionContext objects in the istack
                        if len(self.engine.CurrentContext.EvaluationStack.Items
                               ):
                            for item in self.engine.CurrentContext.EvaluationStack.Items:
                                print(
                                    ContractParameter.ToParameter(
                                        item).ToJson())
                        else:
                            print("Evaluation stack empty")
                    else:
                        print("Evaluation stack empty")

                elif command == 'istack':
                    print("Invocation Stack:")
                    for item in self.engine.InvocationStack.Items:
                        pprint.pprint(item)
                        print(vars(item))

                elif command == 'astack':
                    if len(self.engine.AltStack.Items):
                        for item in self.engine.AltStack.Items:
                            print(ContractParameter.ToParameter(item).ToJson())
                    else:
                        print("Alt Stack Empty")

                elif command == 'rstack':
                    items = self.engine.ResultStack.Items
                    if len(items):
                        for item in items:
                            pprint.pprint(item)
                    else:
                        print("Result stack empty")

                elif command == 'ctx':
                    ctx.print()

                elif command == 'file':
                    ctx.print_file()

                elif command == 'ops':
                    ctx.print_method_ops()

                elif command == 'pdb':
                    pdb.set_trace()

                elif command == 'help':
                    print(
                        "Use one of [estack, istack, astack, exit, quit, ctx, file, ops, pdb, or any local variable]"
                    )

                elif command in ctx.method.scope:
                    try:
                        idx = ctx.method.scope[command]
                        value = self.engine.AltStack.Items[-1].GetArray()[idx]
                        param = ContractParameter.ToParameter(value)
                        print("\n")
                        print(
                            '%s = %s [%s]' %
                            (command, json.dumps(param.Value.ToJson(),
                                                 indent=4) if param.Type
                             == ContractParameterType.InteropInterface else
                             param.Value, param.Type))
                        print("\n")
                    except Exception as e:
                        logger.error("Could not lookup item %s: %s " %
                                     (command, e))
                else:
                    print("unknown command: %s " % command)

        print("======= debug engine exit =======")
        print("\n")
예제 #10
0
    def ExecutionCompleted(self, engine, success, error=None):
        height = Blockchain.Default().Height + 1
        tx_hash = None

        if engine.ScriptContainer:
            tx_hash = engine.ScriptContainer.Hash

        if not tx_hash:
            tx_hash = UInt256(data=bytearray(32))

        entry_script = None
        try:
            # get the first script that was executed
            # this is usually the script that sets up the script to be executed
            entry_script = UInt160(data=engine.ExecutedScriptHashes[0])

            # ExecutedScriptHashes[1] will usually be the first contract executed
            if len(engine.ExecutedScriptHashes) > 1:
                entry_script = UInt160(data=engine.ExecutedScriptHashes[1])
        except Exception as e:
            logger.error("Could not get entry script: %s " % e)

        payload = ContractParameter(ContractParameterType.Array, value=[])
        for item in engine.ResultStack.Items:
            payload.Value.append(ContractParameter.ToParameter(item))

        if success:

            # dispatch all notify events, along with the success of the contract execution
            for notify_event_args in self.notifications:
                self.events_to_dispatch.append(NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, notify_event_args.State,
                                                           notify_event_args.ScriptHash, height, tx_hash,
                                                           success, engine.testMode))

            if engine.Trigger == Application:
                self.events_to_dispatch.append(SmartContractEvent(SmartContractEvent.EXECUTION_SUCCESS, payload, entry_script,
                                                                  height, tx_hash, success, engine.testMode))
            else:
                self.events_to_dispatch.append(SmartContractEvent(SmartContractEvent.VERIFICATION_SUCCESS, payload, entry_script,
                                                                  height, tx_hash, success, engine.testMode))

        else:
            # when a contract exits in a faulted state
            # we should display that in the notification
            if not error:
                error = 'Execution exited in a faulted state. Any payload besides this message contained in this event is the contents of the EvaluationStack of the current script context.'

            payload.Value.append(ContractParameter(ContractParameterType.String, error))

            # If we do not add the eval stack, then exceptions that are raised in a contract
            # are not displayed to the event consumer
            [payload.Value.append(ContractParameter.ToParameter(item)) for item in engine.CurrentContext.EvaluationStack.Items]

            if engine.Trigger == Application:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.EXECUTION_FAIL, payload,
                                       entry_script, height, tx_hash, success, engine.testMode))
            else:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.VERIFICATION_FAIL, payload,
                                       entry_script, height, tx_hash, success, engine.testMode))

        self.notifications = []
예제 #11
0
    def execute(self, arguments):
        wallet = PromptData.Wallet
        if not wallet:
            print("Please open a wallet")
            return False

        arguments, from_addr = PromptUtils.get_from_addr(arguments)
        arguments, priority_fee = PromptUtils.get_fee(arguments)
        arguments, invoke_attrs = PromptUtils.get_tx_attr_from_args(arguments)
        arguments, owners = PromptUtils.get_owners_from_params(arguments)
        arguments, return_type = PromptUtils.get_return_type_from_args(arguments)

        if len(arguments) < 1:
            print("Please specify the required parameters")
            return False

        hash_string = arguments[0]
        try:
            script_hash = UInt160.ParseString(hash_string)
        except Exception:
            # because UInt160 throws a generic exception. Should be fixed in the future
            print("Invalid script hash")
            return False

        p_fee = Fixed8.Zero()
        if priority_fee is not None:
            p_fee = priority_fee
            if p_fee is False:
                logger.debug("invalid fee")
                return False

        tx, fee, results, num_ops, engine_success = TestInvokeContract(wallet, arguments, from_addr=from_addr, invoke_attrs=invoke_attrs, owners=owners)
        if tx and results:

            if return_type is not None:
                try:
                    parameterized_results = [ContractParameter.AsParameterType(ContractParameterType.FromString(return_type), item).ToJson() for item in results]
                except ValueError:
                    logger.debug("invalid return type")
                    return False
            else:
                parameterized_results = [ContractParameter.ToParameter(item).ToJson() for item in results]

            print(
                "\n-------------------------------------------------------------------------------------------------------------------------------------")
            print("Test invoke successful")
            print(f"Total operations: {num_ops}")
            print(f"Results {str(parameterized_results)}")
            print(f"Invoke TX GAS cost: {tx.Gas.value / Fixed8.D}")
            print(f"Invoke TX fee: {fee.value / Fixed8.D}")
            print(
                "-------------------------------------------------------------------------------------------------------------------------------------\n")
            comb_fee = p_fee + fee
            if comb_fee != fee:
                print(f"Priority Fee ({p_fee.value / Fixed8.D}) + Invoke TX Fee ({fee.value / Fixed8.D}) = {comb_fee.value / Fixed8.D}\n")
            print("Enter your password to send this invocation to the network")

            tx.Attributes = invoke_attrs

            try:
                passwd = prompt("[password]> ", is_password=True)
            except KeyboardInterrupt:
                print("Invocation cancelled")
                return False
            if not wallet.ValidatePassword(passwd):
                return print("Incorrect password")

            return InvokeContract(wallet, tx, comb_fee, from_addr=from_addr, owners=owners)
        else:
            print("Error testing contract invoke")
            return False