Exemple #1
0
    def execute(self, arguments):
        path = PromptUtils.get_arg(arguments, 0)

        if not path:
            print("Please specify a path")
            return

        if os.path.exists(path):
            print("File already exists")
            return

        if PromptData.Wallet:
            PromptData.close_wallet()

        try:
            passwd1 = prompt("[password]> ", is_password=True)
            passwd2 = prompt("[password again]> ", is_password=True)
        except KeyboardInterrupt:
            print("Wallet creation cancelled")
            return

        if passwd1 != passwd2 or len(passwd1) < 10:
            print(
                "Please provide matching passwords that are at least 10 characters long"
            )
            return

        password_key = to_aes_key(passwd1)

        try:
            PromptData.Wallet = UserWallet.Create(path=path,
                                                  password=password_key)
            contract = PromptData.Wallet.GetDefaultContract()
            key = PromptData.Wallet.GetKey(contract.PublicKeyHash)
            print("Wallet %s" %
                  json.dumps(PromptData.Wallet.ToJson(), indent=4))
            print("Pubkey %s" % key.PublicKey.encode_point(True))
        except Exception as e:
            print("Exception creating wallet: %s" % e)
            PromptData.Wallet = None
            if os.path.isfile(path):
                try:
                    os.remove(path)
                except Exception as e:
                    print("Could not remove {}: {}".format(path, e))
            return

        if PromptData.Wallet:
            asyncio.create_task(
                PromptData.Wallet.sync_wallet(
                    start_block=PromptData.Wallet._current_height))
            return PromptData.Wallet
Exemple #2
0
    def execute(self, arguments):
        if PromptData.Wallet:
            PromptData.close_wallet()

        path = PromptUtils.get_arg(arguments, 0)

        if not path:
            print("Please specify the required parameter")
            return

        if not os.path.exists(path):
            print("Wallet file not found")
            return

        try:
            passwd = prompt("[password]> ", is_password=True)
        except KeyboardInterrupt:
            print("Wallet opening cancelled")
            return
        password_key = to_aes_key(passwd)

        try:
            PromptData.Wallet = UserWallet.Open(path, password_key)
            print("Opened wallet at %s" % path)
            asyncio.create_task(
                PromptData.Wallet.sync_wallet(
                    start_block=PromptData.Wallet._current_height))
            return PromptData.Wallet
        except Exception as e:
            print("Could not open wallet: %s" % e)
Exemple #3
0
    def execute(self, arguments):
        wallet = PromptData.Wallet

        if len(arguments) != 1:
            print("Please specify the required parameter")
            return False

        nep2_key = arguments[0]
        passphrase = prompt("[key password] ", is_password=True)

        try:
            kp = KeyPair.PrivateKeyFromNEP2(nep2_key, passphrase)
        except ValueError as e:
            print(str(e))
            return False

        try:
            key = wallet.CreateKey(kp)
            print(f"Imported key: {nep2_key}")
            pub_key = key.PublicKey.encode_point(True).decode('utf-8')
            print(f"Pubkey: {pub_key}")
            print(f"Address: {key.GetAddress()}")

        except Exception as e:
            # couldn't find an exact call that throws this but it was in the old code. Leaving it in for now.
            print(f"Key creation error: {str(e)}")
            return False
Exemple #4
0
def do_token_transfer(token,
                      wallet,
                      from_address,
                      to_address,
                      amount,
                      fee=Fixed8.Zero(),
                      tx_attributes=None):
    if not tx_attributes:
        tx_attributes = []

    p_fee = fee

    # because we cannot differentiate between a normal and multisig from_addr, and because we want to make
    # sending NEP5 tokens straight forward even when sending from multisig addresses, we include the script_hash
    # for verification by default to the transaction attributes. See PR/Issue: https://github.com/CityOfZion/neo-python/pull/491
    from_script_hash = binascii.unhexlify(
        bytes(wallet.ToScriptHash(from_address).ToString2(), 'utf-8'))
    tx_attributes.append(
        TransactionAttribute(usage=TransactionAttributeUsage.Script,
                             data=from_script_hash))

    tx, fee, results = token.Transfer(wallet,
                                      from_address,
                                      to_address,
                                      amount,
                                      tx_attributes=tx_attributes)

    if tx is not None and results is not None and len(results) > 0:

        if results[0].GetBigInteger() == 1:
            print(
                "\n-----------------------------------------------------------"
            )
            print("Will transfer %s %s from %s to %s" % (string_from_amount(
                token, amount), token.symbol, from_address, to_address))
            print("Transfer fee: %s " % (fee.value / Fixed8.D))
            print(
                "-------------------------------------------------------------\n"
            )
            comb_fee = p_fee + fee
            if comb_fee != fee:
                print(
                    f"Priority Fee ({p_fee.value / Fixed8.D}) + Transfer Fee ({fee.value / Fixed8.D}) = {comb_fee.value / Fixed8.D}\n"
                )
            print("Enter your password to send to the network")

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

            return InvokeContract(wallet, tx, comb_fee)

    print("could not transfer tokens")
    return False
Exemple #5
0
    def execute(self, arguments):
        wallet = PromptData.Wallet

        if len(arguments) != 1:
            print("Please specify the required parameter")
            return False

        address = arguments[0]

        try:
            passphrase = prompt("[key password] ", is_password=True)
            len_pass = len(passphrase)
            if len_pass < 10:
                print(
                    f"Passphrase is too short, length: {len_pass}. Minimum length is 10"
                )
                return False

            passphrase_confirm = prompt("[key password again] ",
                                        is_password=True)

            if passphrase != passphrase_confirm:
                print("Please provide matching passwords")
                return False

            keys = wallet.GetKeys()
            for key in keys:
                if key.GetAddress() == address:
                    passwd = prompt("[wallet password]> ", is_password=True)
                    if not wallet.ValidatePassword(passwd):
                        return print("Incorrect password")
                    print(f"NEP2: {key.ExportNEP2(passphrase)}")
                    return True
        except KeyboardInterrupt:
            return print("Export cancelled")

        else:
            print(f"Could not find address {address} in wallet")
            return False
Exemple #6
0
def GatherContractDetails(function_code):
    print("Please fill out the following contract details:")

    name = prompt("[Contract Name] > ")
    version = prompt("[Contract Version] > ")
    author = prompt("[Contract Author] > ")
    email = prompt("[Contract Email] > ")
    description = prompt("[Contract Description] > ")

    print("Creating smart contract....")
    print("                 Name: %s " % name)
    print("              Version: %s" % version)
    print("               Author: %s " % author)
    print("                Email: %s " % email)
    print("          Description: %s " % description)
    print("        Needs Storage: %s " % function_code.HasStorage)
    print(" Needs Dynamic Invoke: %s " % function_code.HasDynamicInvoke)
    print("           Is Payable: %s " % function_code.IsPayable)
    print(json.dumps(function_code.ToJson(), indent=4))

    return generate_deploy_script(function_code.Script, name, version, author, email, description,
                                  function_code.ContractProperties, function_code.ReturnTypeBigInteger,
                                  function_code.ParameterList)
Exemple #7
0
def token_mint(token,
               wallet,
               to_addr,
               asset_attachments=[],
               fee=Fixed8.Zero(),
               invoke_attrs=None):
    if not invoke_attrs:
        invoke_attrs = []

    p_fee = fee

    tx, fee, results = token.Mint(wallet,
                                  to_addr,
                                  asset_attachments,
                                  invoke_attrs=invoke_attrs)

    if tx is not None and results is not None:
        if len(results) > 0 and results[0] is not None:
            print(
                "\n-----------------------------------------------------------"
            )
            print(f"[{token.symbol}] Will mint tokens to address: {to_addr}")
            print(f"Invocation 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}) + Invocation Fee ({fee.value / Fixed8.D}) = {comb_fee.value / Fixed8.D}\n"
                )
            print("Enter your password to send to the network")

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

            return InvokeWithTokenVerificationScript(wallet,
                                                     tx,
                                                     token,
                                                     comb_fee,
                                                     invoke_attrs=invoke_attrs)

    print("Failed to mint tokens")
    return False
Exemple #8
0
def start_output_config():
    # temporarily mute stdout while we try to reconfigure our settings
    # components like `network` set at DEBUG level will spam through the console
    # making it impractical to configure output levels
    log_manager.mute_stdio()

    print("Select your desired configuration per component.")
    print("(1) DEBUG (2) INFO (3) ERROR (enter) keep current")
    print("")

    configurations = []
    level_conversion = {1: logging.DEBUG, 2: logging.INFO, 3: logging.ERROR}

    # cycle through all known components
    for component, logger in log_manager.loggers.items():
        component_name = component.replace(log_manager.root, "")
        current_level = logging.getLevelName(logger.handlers[0].level)
        line = "[{}] current: {} new: ".format(component_name, current_level)

        choice = None
        try:
            choice = int(prompt(line))
        except ValueError:
            pass

        # invalid choice or enter == keep current
        if not choice:
            continue

        new_log_level = level_conversion.get(choice, logging.NOTSET)
        if new_log_level != logging.NOTSET:
            configurations.append((component_name, new_log_level))

    # finally apply new settings
    if configurations:
        log_manager.config_stdio(configurations)

    # and re-enable stdio
    log_manager.unmute_stdio()

    # provide confirmation of new settings
    print("\nNew Output Levels:")
    new_settings = {}
    for component, logger in log_manager.loggers.items():
        component_name = component.replace(log_manager.root, "")
        current_level = logging.getLevelName(logger.handlers[0].level)
        new_settings["%s" % component_name] = current_level
        print("[{}] new: {}".format(component_name, current_level))
    return new_settings
Exemple #9
0
def gather_signatures(context, itx, owners):
    do_exit = False
    print("\n\n*******************\n")
    print("Gather Signatures for Transaction:\n%s " % json.dumps(itx.ToJson(), indent=4))
    print("Please use a client to sign the following: %s " % itx.GetHashData())

    owner_index = 0
    while not context.Completed and not do_exit:

        next_script = owners[owner_index]
        next_addr = scripthash_to_address(next_script.Data)
        try:
            print("\n*******************\n")
            owner_input = prompt('Public Key and Signature for %s> ' % next_addr)
            items = owner_input.split(' ')
            pubkey = ECDSA.decode_secp256r1(items[0]).G
            sig = items[1]
            contract = Contract.CreateSignatureContract(pubkey)

            if contract.Address == next_addr:
                context.Add(contract, 0, sig)
                print("Adding signature %s " % sig)
                owner_index += 1
            else:
                print("Public Key does not match address %s " % next_addr)

        except ValueError:
            # expected from ECDSA if public key is invalid
            print(f"Invalid public key: {items[0]}")
            do_exit = True
        except EOFError:
            # Control-D pressed: quit
            do_exit = True
        except KeyboardInterrupt:
            # Control-C pressed: do nothing
            do_exit = True
        except Exception as e:
            print("Could not parse input %s " % e)

    if context.Completed:
        print("Signatures complete")
        itx.scripts = context.GetScripts()
        return True
    else:
        print("Could not finish signatures")
        return False
Exemple #10
0
    def execute(self, arguments):
        wallet = PromptData.Wallet

        if len(arguments) != 1:
            print("Please specify the required parameter")
            return False

        address = arguments[0]
        keys = wallet.GetKeys()
        for key in keys:
            if key.GetAddress() == address:
                try:
                    passwd = prompt("[wallet password]> ", is_password=True)
                    if not wallet.ValidatePassword(passwd):
                        return print("Incorrect password")
                except KeyboardInterrupt:
                    return print("Export cancelled.")

                print(f"WIF: {key.Export()}")
                return True
        else:
            print(f"Could not find address {address} in wallet")
            return False
Exemple #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 is not None and results is not None:

            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
Exemple #12
0
def get_input_prompt(message):
    return prompt(message)
Exemple #13
0
async def setup_and_start(loop):
    parser = argparse.ArgumentParser()

    # Network options
    group_network_container = parser.add_argument_group(
        title="Network options")
    group_network = group_network_container.add_mutually_exclusive_group(
        required=True)
    group_network.add_argument("--mainnet",
                               action="store_true",
                               default=False,
                               help="Use MainNet")
    group_network.add_argument("--testnet",
                               action="store_true",
                               default=False,
                               help="Use TestNet")
    group_network.add_argument("--privnet",
                               action="store_true",
                               default=False,
                               help="Use PrivNet")
    group_network.add_argument("--coznet",
                               action="store_true",
                               default=False,
                               help="Use CozNet")
    group_network.add_argument("--config",
                               action="store",
                               help="Use a specific config file")

    # Ports for RPC and REST api
    group_modes = parser.add_argument_group(title="Mode(s)")
    group_modes.add_argument(
        "--port-rpc",
        type=int,
        help="port to use for the json-rpc api (eg. 10332)")
    group_modes.add_argument("--port-rest",
                             type=int,
                             help="port to use for the rest api (eg. 80)")

    # Advanced logging setup
    group_logging = parser.add_argument_group(title="Logging options")
    group_logging.add_argument("--logfile",
                               action="store",
                               type=str,
                               help="Logfile")
    group_logging.add_argument(
        "--syslog",
        action="store_true",
        help=
        "Log to syslog instead of to log file ('user' is the default facility)"
    )
    group_logging.add_argument(
        "--syslog-local",
        action="store",
        type=int,
        choices=range(0, 7 + 1),
        metavar="[0-7]",
        help=
        "Log to a local syslog facility instead of 'user'. Value must be between 0 and 7 (e.g. 0 for 'local0')."
    )
    group_logging.add_argument("--disable-stderr",
                               action="store_true",
                               help="Disable stderr logger")

    # Where to store stuff
    parser.add_argument("--datadir",
                        action="store",
                        help="Absolute path to use for database directories")
    # peers
    parser.add_argument("--minpeers",
                        action="store",
                        type=int,
                        choices=range(1, 10 + 1),
                        metavar="[1-10]",
                        help="Min peers to use for P2P Joining")

    parser.add_argument("--maxpeers",
                        action="store",
                        type=int,
                        choices=range(1, 10 + 1),
                        metavar="[1-10]",
                        help="Max peers to use for P2P Joining")

    # If a wallet should be opened
    parser.add_argument(
        "--wallet",
        action="store",
        help=
        "Open wallet. Will allow you to use methods that require an open wallet"
    )

    # host
    parser.add_argument("--host",
                        action="store",
                        type=str,
                        help="Hostname ( for example 127.0.0.1)",
                        default="0.0.0.0")

    # Now parse
    args = parser.parse_args()
    # print(args)

    if not args.port_rpc and not args.port_rest:
        print("Error: specify at least one of --port-rpc / --port-rest")
        parser.print_help()
        raise SystemExit

    if args.port_rpc == args.port_rest:
        print("Error: --port-rpc and --port-rest cannot be the same")
        parser.print_help()
        raise SystemExit

    if args.logfile and (args.syslog or args.syslog_local):
        print("Error: Cannot only use logfile or syslog at once")
        parser.print_help()
        raise SystemExit

    # Setting the datadir must come before setting the network, else the wrong path is checked at net setup.
    if args.datadir:
        settings.set_data_dir(args.datadir)

    # Network configuration depending on command line arguments. By default, the testnet settings are already loaded.
    if args.config:
        settings.setup(args.config)
    elif args.mainnet:
        settings.setup_mainnet()
    elif args.testnet:
        settings.setup_testnet()
    elif args.privnet:
        settings.setup_privnet()
    elif args.coznet:
        settings.setup_coznet()

    def set_min_peers(num_peers) -> bool:
        try:
            settings.set_min_peers(num_peers)
            print("Minpeers set to ", num_peers)
            return True
        except ValueError:
            print("Please supply a positive integer for minpeers")
            return False

    def set_max_peers(num_peers) -> bool:
        try:
            settings.set_max_peers(num_peers)
            print("Maxpeers set to ", num_peers)
            return True
        except ValueError:
            print("Please supply a positive integer for maxpeers")
            return False

    minpeers = args.minpeers
    maxpeers = args.maxpeers

    if minpeers and maxpeers:
        if minpeers > maxpeers:
            print("minpeers setting cannot be bigger than maxpeers setting")
            return
        if not set_min_peers(minpeers) or not set_max_peers(maxpeers):
            return
    elif minpeers:
        if not set_min_peers(minpeers):
            return
        if minpeers > settings.CONNECTED_PEER_MAX:
            if not set_max_peers(minpeers):
                return
    elif maxpeers:
        if not set_max_peers(maxpeers):
            return
        if maxpeers < settings.CONNECTED_PEER_MIN:
            if not set_min_peers(maxpeers):
                return

    if args.syslog or args.syslog_local is not None:
        # Setup the syslog facility
        if args.syslog_local is not None:
            print("Logging to syslog local%s facility" % args.syslog_local)
            syslog_facility = SysLogHandler.LOG_LOCAL0 + args.syslog_local
        else:
            print("Logging to syslog user facility")
            syslog_facility = SysLogHandler.LOG_USER

        # Setup logzero to only use the syslog handler
        logzero.syslog(facility=syslog_facility)
    else:
        # Setup file logging
        if args.logfile:
            logfile = os.path.abspath(args.logfile)
            if args.disable_stderr:
                print("Logging to logfile: %s" % logfile)
            else:
                print("Logging to stderr and logfile: %s" % logfile)
            logzero.logfile(logfile,
                            maxBytes=LOGFILE_MAX_BYTES,
                            backupCount=LOGFILE_BACKUP_COUNT,
                            disableStderrLogger=args.disable_stderr)

        else:
            print("Logging to stdout and stderr")

    if args.wallet:
        if not os.path.exists(args.wallet):
            print("Wallet file not found")
            return

        passwd = os.environ.get('NEO_PYTHON_JSONRPC_WALLET_PASSWORD', None)
        if not passwd:
            try:
                passwd = prompt("[password]> ", is_password=True)
            except KeyboardInterrupt:
                print("Wallet opening cancelled")
                return

        password_key = to_aes_key(passwd)
        try:
            wallet = UserWallet.Open(args.wallet, password_key)
            asyncio.create_task(
                wallet.sync_wallet(start_block=wallet._current_height))

        except Exception as e:
            print(f"Could not open wallet {e}")
            return
    else:
        wallet = None

    # Disable logging smart contract events
    settings.set_log_smart_contract_events(False)

    # Write a PID file to easily quit the service
    write_pid_file()

    # Instantiate the blockchain and subscribe to notifications
    blockchain = Blockchain(getBlockchainDB())
    Blockchain.RegisterBlockchain(blockchain)

    p2p = NetworkService()
    p2p_task = loop.create_task(p2p.start())
    loop.create_task(custom_background_code())

    NotificationDB.instance().start()

    if args.port_rpc:
        logger.info("Starting json-rpc api server on http://%s:%s" %
                    (args.host, args.port_rpc))
        try:
            rpc_class = load_class_from_path(settings.RPC_SERVER)
        except ValueError as err:
            logger.error(err)
            sys.exit()
        api_server_rpc = rpc_class(wallet=wallet)

        runner = web.AppRunner(api_server_rpc.app)
        await runner.setup()
        site = web.TCPSite(runner, args.host, args.port_rpc)
        await site.start()

    if args.port_rest:
        logger.info("Starting REST api server on http://%s:%s" %
                    (args.host, args.port_rest))
        try:
            rest_api = load_class_from_path(settings.REST_SERVER)
        except ValueError as err:
            logger.error(err)
            sys.exit()
        api_server_rest = rest_api()
        runner = web.AppRunner(api_server_rest.app)
        await runner.setup()
        site = web.TCPSite(runner, args.host, args.port_rpc)
        await site.start()

    return wallet
Exemple #14
0
def ClaimGas(wallet, from_addr_str=None, to_addr_str=None):
    """
    Args:
        wallet:
        from_addr_str:
    Returns:
        (claim transaction, relayed status)
            if successful: (tx, True)
            if unsuccessful: (None, False)
    """
    if not wallet:
        print("Please open a wallet")
        return None, False

    unclaimed_coins = wallet.GetUnclaimedCoins()

    unclaimed_count = len(unclaimed_coins)
    if unclaimed_count == 0:
        print("No claims to process")
        return None, False

    unclaimed_coin_refs = [coin.Reference for coin in unclaimed_coins]

    available_bonus = Blockchain.Default().CalculateBonusIgnoreClaimed(
        unclaimed_coin_refs)

    if available_bonus == Fixed8.Zero():
        print("No gas to claim")
        return None, False

    claim_tx = ClaimTransaction()
    claim_tx.Claims = unclaimed_coin_refs
    claim_tx.Attributes = []
    claim_tx.inputs = []

    script_hash = wallet.GetChangeAddress()

    # the following can be used to claim gas that is in an imported contract_addr
    # example, wallet claim --from-addr={smart contract addr}
    if from_addr_str:
        script_hash = None
        script_hash = PromptUtils.lookup_addr_str(wallet, from_addr_str)
        if script_hash is None:
            logger.debug("invalid source address")
            return None, False
        standard_contract = wallet.GetStandardAddress()
        claim_tx.Attributes = [
            TransactionAttribute(usage=TransactionAttributeUsage.Script,
                                 data=standard_contract.Data)
        ]

    if to_addr_str:
        script_hash = None
        script_hash = PromptUtils.lookup_addr_str(wallet, to_addr_str)
        if script_hash is None:
            logger.debug("invalid destination address")
            return None, False

    claim_tx.outputs = [
        TransactionOutput(AssetId=Blockchain.SystemCoin().Hash,
                          Value=available_bonus,
                          script_hash=script_hash)
    ]

    context = ContractParametersContext(claim_tx)
    wallet.Sign(context)

    print("\n---------------------------------------------------------------")
    print(f"Will make claim for {available_bonus.ToString()} GAS")
    print(
        "------------------------------------------------------------------\n")

    print("Enter your password to complete this claim")

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

    if context.Completed:

        claim_tx.scripts = context.GetScripts()

        print("claim tx: %s " % json.dumps(claim_tx.ToJson(), indent=4))

        nodemgr = NodeManager()
        relayed = nodemgr.relay(claim_tx)

        if relayed:
            print("Relayed Tx: %s " % claim_tx.Hash.ToString())
            wallet.SaveTransaction(claim_tx)
        else:
            print("Could not relay tx %s " % claim_tx.Hash.ToString())
        return claim_tx, relayed

    else:
        print("could not sign tx")

    return None, False
Exemple #15
0
    def __init__(self, db, skip_version_check=False, skip_header_check=False):
        self._db = db
        self._header_index = []

        self._header_index.append(
            Blockchain.GenesisBlock().Header.Hash.ToBytes())

        self.TXProcessed = 0
        version = self._db.get(DBPrefix.SYS_Version)

        if skip_version_check:
            self._db.write(DBPrefix.SYS_Version, self._sysversion)
            version = self._sysversion

        if version == self._sysversion:  # or in the future, if version doesn't equal the current version...
            ba = bytearray(self._db.get(DBPrefix.SYS_CurrentBlock, 0))
            self._current_block_height = int.from_bytes(ba[-4:], 'little')

            if not skip_header_check:
                ba = bytearray(self._db.get(DBPrefix.SYS_CurrentHeader, 0))
                current_header_height = int.from_bytes(ba[-4:], 'little')
                current_header_hash = bytes(ba[:64].decode('utf-8'),
                                            encoding='utf-8')

                hashes = []
                try:
                    with self._db.openIter(
                            DBProperties(DBPrefix.IX_HeaderHashList)) as it:
                        for key, value in it:
                            ms = StreamManager.GetStream(value)
                            reader = BinaryReader(ms)
                            hlist = reader.Read2000256List()
                            key = int.from_bytes(key[-4:], 'little')
                            hashes.append({'k': key, 'v': hlist})
                            StreamManager.ReleaseStream(ms)
                except Exception as e:
                    logger.info("Could not get stored header hash list: %s " %
                                e)

                if len(hashes):
                    hashes.sort(key=lambda x: x['k'])
                    genstr = Blockchain.GenesisBlock().Hash.ToBytes()
                    for hlist in hashes:

                        for hash in hlist['v']:
                            if hash != genstr:
                                self._header_index.append(hash)
                            self._stored_header_count += 1

                if self._stored_header_count == 0:
                    logger.info(
                        "Current stored headers empty, re-creating from stored blocks..."
                    )
                    headers = []
                    logger.info('Recreate headers')
                    with self._db.openIter(DBProperties(
                            DBPrefix.DATA_Block)) as it:
                        for key, value in it:
                            dbhash = bytearray(value)[8:]
                            headers.append(
                                Header.FromTrimmedData(
                                    binascii.unhexlify(dbhash), 0))

                    headers.sort(key=lambda h: h.Index)
                    for h in headers:
                        if h.Index > 0:
                            self._header_index.append(h.Hash.ToBytes())

                    if len(headers):
                        self.OnAddHeader(headers[-1])

                elif current_header_height > self._stored_header_count:
                    try:
                        hash = current_header_hash
                        targethash = self._header_index[-1]

                        newhashes = []
                        while hash != targethash:
                            header = self.GetHeader(hash)
                            newhashes.insert(0, header)
                            hash = header.PrevHash.ToBytes()

                        self.AddHeaders(newhashes)
                    except Exception as e:
                        pass

        elif version is None:
            wait_for(self.Persist(Blockchain.GenesisBlock()))
            self._db.write(DBPrefix.SYS_Version, self._sysversion)
        else:
            logger.error("\n\n")
            logger.warning("Database schema has changed from %s to %s.\n" %
                           (version, self._sysversion))
            logger.warning(
                "You must either resync from scratch, or use the np-bootstrap command to bootstrap the chain."
            )

            res = prompt(
                "Type 'continue' to erase your current database and sync from new. Otherwise this program will exit:\n> "
            )
            if res == 'continue':

                with self._db.getBatch() as wb:
                    with self._db.openIter(
                            DBProperties(include_value=False)) as it:
                        for key in it:
                            wb.delete(key)

                wait_for(self.Persist(Blockchain.GenesisBlock()))
                self._db.write(DBPrefix.SYS_Version, self._sysversion)

            else:
                raise Exception("Database schema changed")
Exemple #16
0
def SplitUnspentCoin(wallet,
                     asset_id,
                     from_addr,
                     index,
                     divisions,
                     fee=Fixed8.Zero()):
    """
    Split unspent asset vins into several vouts

    Args:
        wallet (neo.Wallet): wallet to show unspent coins from.
        asset_id (UInt256): a bytearray (len 32) representing an asset on the blockchain.
        from_addr (UInt160): a bytearray (len 20) representing an address.
        index (int): index of the unspent vin to split
        divisions (int): number of vouts to create
        fee (Fixed8): A fee to be attached to the Transaction for network processing purposes.

    Returns:
        neo.Core.TX.Transaction.ContractTransaction: contract transaction created
    """

    if wallet is None:
        print("Please open a wallet.")
        return

    unspent_items = wallet.FindUnspentCoinsByAsset(asset_id,
                                                   from_addr=from_addr)
    if not unspent_items:
        print(f"No unspent assets matching the arguments.")
        return

    if index < len(unspent_items):
        unspent_item = unspent_items[index]
    else:
        print(f"unspent-items: {unspent_items}")
        print(
            f"Could not find unspent item for asset {asset_id} with index {index}"
        )
        return

    outputs = split_to_vouts(asset_id, from_addr, unspent_item.Output.Value,
                             divisions)

    # subtract a fee from the first vout
    if outputs[0].Value > fee:
        outputs[0].Value -= fee
    else:
        print("Fee could not be subtracted from outputs.")
        return

    contract_tx = ContractTransaction(outputs=outputs,
                                      inputs=[unspent_item.Reference])

    ctx = ContractParametersContext(contract_tx)
    wallet.Sign(ctx)

    print("Splitting: %s " % json.dumps(contract_tx.ToJson(), indent=4))
    try:
        passwd = prompt("[Password]> ", is_password=True)
    except KeyboardInterrupt:
        print("Splitting cancelled")
        return
    if not wallet.ValidatePassword(passwd):
        print("incorrect password")
        return

    if ctx.Completed:
        contract_tx.scripts = ctx.GetScripts()

        nodemgr = NodeManager()
        # this blocks, consider moving this wallet function to async instead
        relayed = nodemgr.relay(contract_tx)

        if relayed:
            wallet.SaveTransaction(contract_tx)
            print("Relayed Tx: %s " % contract_tx.Hash.ToString())
            return contract_tx
        else:
            print("Could not relay tx %s " % contract_tx.Hash.ToString())
Exemple #17
0
    def execute(self, arguments):
        wallet = PromptData.Wallet

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

        arguments, priority_fee = PromptUtils.get_fee(arguments)

        token_str = arguments[0]
        from_addr = arguments[1]
        to_addr = arguments[2]

        try:
            amount = float(arguments[3])
        except ValueError:
            print(f"{arguments[3]} is not a valid amount")
            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

        try:
            token = _validate_nep5_args(wallet, token_str, from_addr, to_addr,
                                        amount)
        except ValueError as e:
            print(str(e))
            return False

        decimal_amount = amount_from_string(token, amount)

        tx, fee, results = token.Approve(wallet, from_addr, to_addr,
                                         decimal_amount)

        if tx is not None and results is not None:
            if results[0].GetBigInteger() == 1:
                print(
                    "\n-----------------------------------------------------------"
                )
                print(
                    f"Approve allowance of {amount} {token.symbol} from {from_addr} to {to_addr}"
                )
                print(f"Invocation 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}) + Invocation Fee ({fee.value / Fixed8.D}) = {comb_fee.value / Fixed8.D}\n"
                    )
                print("Enter your password to send to the network")

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

                return InvokeContract(wallet, tx, comb_fee)

        print(
            "Failed to approve tokens. Make sure you are entitled for approving."
        )
        return False
Exemple #18
0
    def execute(self, arguments):
        wallet = PromptData.Wallet

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

        arguments, priority_fee = PromptUtils.get_fee(arguments)

        token_str = arguments[0]
        from_addr = arguments[1]
        to_addr = arguments[2]

        try:
            amount = float(arguments[3])
        except ValueError:
            print(f"{arguments[3]} is not a valid amount")
            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

        try:
            token, tx, fee, results = test_token_send_from(
                wallet, token_str, from_addr, to_addr, amount)
        except ValueError as e:
            # invalid arguments or bad allowance
            print(str(e))
            return False
        except Exception as e:
            # we act as the final capturing place
            print("Something really unexpected happened")
            logger.error(traceback.format_exc())
            return False

        if tx is not None and results is not None:
            vm_result = results[0].GetBigInteger()
            if vm_result == 1:
                print(
                    "\n-----------------------------------------------------------"
                )
                print("Transfer of %s %s from %s to %s" % (string_from_amount(
                    token, amount), token.symbol, from_addr, to_addr))
                print("Transfer fee: %s " % (fee.value / Fixed8.D))
                print(
                    "-------------------------------------------------------------\n"
                )
                comb_fee = p_fee + fee
                if comb_fee != fee:
                    print(
                        f"Priority Fee ({p_fee.value / Fixed8.D}) + Transfer Fee ({fee.value / Fixed8.D}) = {comb_fee.value / Fixed8.D}\n"
                    )
                print("Enter your password to send to the network")

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

                return InvokeContract(wallet, tx, comb_fee)

            print(
                f"Could not transfer tokens. Virtual machine returned: {vm_result}"
            )
            return False

        print(
            f"Could not transfer tokens. An unknown error occurred resulting in no Transaction object or VM output."
        )
        return False
Exemple #19
0
    def execute(self, arguments):
        wallet = PromptData.Wallet
        if not wallet:
            print("Please open a wallet")
            return False

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

        args, from_addr = PromptUtils.get_from_addr(arguments)
        arguments, priority_fee = PromptUtils.get_fee(arguments)

        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

        path = args[0]

        try:
            needs_storage = bool(util.strtobool(args[1]))
            needs_dynamic_invoke = bool(util.strtobool(args[2]))
            is_payable = bool(util.strtobool(args[3]))

        except ValueError:
            print("Invalid boolean option")
            return False

        params = args[4]
        return_type = args[5]

        try:
            function_code = LoadContract(path, needs_storage,
                                         needs_dynamic_invoke, is_payable,
                                         params, return_type)
        except (ValueError, Exception) as e:
            print(str(e))
            return False

        try:
            contract_script = GatherContractDetails(function_code)
        except KeyboardInterrupt:
            print("Deployment cancelled")
            return False
        if not contract_script:
            print("Failed to generate deploy script")
            return False

        tx, fee, results, num_ops, engine_success = test_invoke(
            contract_script, wallet, [], from_addr=from_addr)
        if tx is not None and results is not None:
            print(
                "\n-------------------------------------------------------------------------------------------------------------------------------------"
            )
            print("Test deploy invoke successful")
            print(f"Total operations executed: {num_ops}")
            print("Results:")
            print([item.GetInterface() for item in results])
            print(f"Deploy Invoke TX GAS cost: {tx.Gas.value / Fixed8.D}")
            print(f"Deploy 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}) + Deploy Invoke TX Fee ({fee.value / Fixed8.D}) = {comb_fee.value / Fixed8.D}\n"
                )
            print(
                "Enter your password to deploy this contract on the blockchain"
            )

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

            return InvokeContract(wallet, tx, comb_fee, from_addr=from_addr)
        else:
            print("Test invoke failed")
            print(f"TX is {tx}, results are {results}")
            return False
Exemple #20
0
    def execute(self, arguments):
        wallet = PromptData.Wallet

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

        arguments, priority_fee = PromptUtils.get_fee(arguments)

        token_str = arguments[0]
        try:
            token = PromptUtils.get_token(wallet, token_str)
        except ValueError as e:
            print(str(e))
            return False

        register_addr = arguments[1:]
        addr_list = []
        for addr in register_addr:
            if isValidPublicAddress(addr):
                addr_list.append(addr)
            else:
                print(f"{addr} is not a valid address")
                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 = token.CrowdsaleRegister(wallet, addr_list)

        if tx is not None and results is not None:
            if len(results) > 0 and results[0].GetBigInteger() > 0:
                print(
                    "\n-----------------------------------------------------------"
                )
                print("[%s] Will register addresses for crowdsale: %s " %
                      (token.symbol, register_addr))
                print("Invocation Fee: %s " % (fee.value / Fixed8.D))
                print(
                    "-------------------------------------------------------------\n"
                )
                comb_fee = p_fee + fee
                if comb_fee != fee:
                    print(
                        f"Priority Fee ({p_fee.value / Fixed8.D}) + Invocation Fee ({fee.value / Fixed8.D}) = {comb_fee.value / Fixed8.D}\n"
                    )
                print("Enter your password to send to the network")

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

                return InvokeContract(wallet, tx, comb_fee)

        print("Could not register address(es)")
        return False
Exemple #21
0
def construct_send_many(wallet, arguments):
    if len(arguments) is 0:
        print("Please specify the required parameter")
        return

    outgoing = get_arg(arguments, convert_to_int=True)
    if outgoing is None:
        print("Invalid outgoing number")
        return
    if outgoing < 1:
        print("Outgoing number must be >= 1")
        return

    arguments, from_address = get_from_addr(arguments)
    arguments, change_address = get_change_addr(arguments)
    arguments, priority_fee = get_fee(arguments)
    arguments, owners = get_owners_from_params(arguments)
    arguments, user_tx_attributes = get_tx_attr_from_args(arguments)

    output = []
    for i in range(outgoing):
        try:
            print('Outgoing Number ', i + 1)
            to_send = prompt("Asset to send: ")
            assetId = get_asset_id(wallet, to_send)
            if assetId is None:
                print("Asset id not found")
                return
            if type(assetId) is NEP5Token:
                print('sendmany does not support NEP5 tokens')
                return
            address_to = prompt("Address to: ")
            scripthash_to = lookup_addr_str(wallet, address_to)
            if scripthash_to is None:
                logger.debug("invalid destination address")
                return
            amount = prompt("Amount to send: ")
            f8amount = get_asset_amount(amount, assetId)
            if f8amount is False:
                logger.debug("invalid amount")
                return
            if float(amount) == 0:
                print("Amount cannot be 0")
                return
            tx_output = TransactionOutput(AssetId=assetId,
                                          Value=f8amount,
                                          script_hash=scripthash_to)
            output.append(tx_output)
        except KeyboardInterrupt:
            print('Transaction cancelled')
            return
    contract_tx = ContractTransaction(outputs=output)

    scripthash_from = None

    if from_address is not None:
        scripthash_from = lookup_addr_str(wallet, from_address)
        if scripthash_from is None:
            logger.debug("invalid source address")
            return

    scripthash_change = None

    if change_address is not None:
        scripthash_change = lookup_addr_str(wallet, change_address)
        if scripthash_change is None:
            logger.debug("invalid change address")
            return

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

    print(f"Sending with fee: {fee.ToString()}")
    return [
        contract_tx, scripthash_from, scripthash_change, fee, owners,
        user_tx_attributes
    ]
Exemple #22
0
def process_transaction(wallet,
                        contract_tx,
                        scripthash_from=None,
                        scripthash_change=None,
                        fee=None,
                        owners=None,
                        user_tx_attributes=None):
    try:
        tx = wallet.MakeTransaction(tx=contract_tx,
                                    change_address=scripthash_change,
                                    fee=fee,
                                    from_addr=scripthash_from)
    except ValueError:
        print(
            "Insufficient funds. No unspent outputs available for building the transaction.\n"
            "If you are trying to sent multiple transactions in 1 block, then make sure you have enough 'vouts'\n."
            "Use `wallet unspent` and `wallet address split`, or wait until the first transaction is processed before sending another."
        )
        return

    if tx is None:
        logger.debug("insufficient funds")
        return

    try:
        print("Validate your transaction details")
        print("-" * 33)
        input_coinref = wallet.FindCoinsByVins(tx.inputs)[0]
        source_addr = input_coinref.Address
        for order in tx.outputs:
            dest_addr = order.Address
            value = order.Value.ToString()  # fixed8
            if order.AssetId == Blockchain.Default().SystemShare().Hash:
                asset_name = 'NEO'
            else:
                asset_name = 'GAS'

            if source_addr != dest_addr:
                print(
                    f"Sending {value} {asset_name} from {source_addr} to {dest_addr}"
                )
            else:
                print(
                    f"Returning {value} {asset_name} as change to {dest_addr}")
        print(" ")
        print("Enter your password to send to the network")

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

        standard_contract = wallet.GetStandardAddress()

        if scripthash_from is not None:
            signer_contract = wallet.GetContract(scripthash_from)
        else:
            signer_contract = wallet.GetContract(standard_contract)

        if not signer_contract.IsMultiSigContract and owners is None:
            data = standard_contract.Data
            tx.Attributes = [
                TransactionAttribute(usage=TransactionAttributeUsage.Script,
                                     data=data)
            ]

        # insert any additional user specified tx attributes
        tx.Attributes = tx.Attributes + user_tx_attributes

        if owners:
            owners = list(owners)
            for owner in owners:
                tx.Attributes.append(
                    TransactionAttribute(
                        usage=TransactionAttributeUsage.Script, data=owner))

        context = ContractParametersContext(
            tx, isMultiSig=signer_contract.IsMultiSigContract)
        wallet.Sign(context)

        if owners:
            owners = list(owners)
            gather_signatures(context, tx, owners)

        if context.Completed:

            tx.scripts = context.GetScripts()

            passed, reason = validate_simple_policy(tx)
            if not passed:
                print(reason)
                return

            nodemgr = NodeManager()
            relayed = nodemgr.relay(tx)

            if relayed:
                wallet.SaveTransaction(tx)

                print("Relayed Tx: %s " % tx.Hash.ToString())
                return tx
            else:

                print("Could not relay tx %s " % tx.Hash.ToString())

        else:
            print(
                "Transaction initiated, but the signature is incomplete. Use the `sign` command with the information below to complete signing."
            )
            print(json.dumps(context.ToJson(), separators=(',', ':')))
            return

    except Exception as e:
        print("Could not send: %s " % e)
        traceback.print_stack()
        traceback.print_exc()

    return
Exemple #23
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")

                        if param.Type == ContractParameterType.InteropInterface:
                            cmd_value = json.dumps(param.Value.ToJson(), indent=4)
                        else:
                            cmd_value = param.Value
                        print(f"{command} = {cmd_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")