示例#1
0
    def node_private_helios_key(self):
        if self._node_private_helios_key is None:
            # if self.is_dev_test_node:
            #     if "INSTANCE_NUMBER" in os.environ:
            #         self._node_private_helios_key = get_primary_node_private_helios_key(int(os.environ["INSTANCE_NUMBER"]))
            #
            # else:

            if (self.keystore_path is None and KEYSTORE_FILENAME_TO_USE is None
                ) or self.keystore_password is None:
                raise ValueError(
                    "You must provide a keystore file containing a private key for this node, and a password to open it."
                )
            else:
                try:
                    if self.keystore_path is not None:
                        self._node_private_helios_key = keys.PrivateKey(
                            eth_keyfile.extract_key_from_keyfile(
                                self.keystore_path, self.keystore_password))
                    else:
                        absolute_keystore_path = self.keystore_dir / KEYSTORE_FILENAME_TO_USE
                        self._node_private_helios_key = keys.PrivateKey(
                            eth_keyfile.extract_key_from_keyfile(
                                str(absolute_keystore_path),
                                self.keystore_password))
                except ValueError:
                    raise ValueError(
                        "An error occured when decoding your keyfile. This can be caused by an incorrect password, or damaged keyfile."
                    )

        return self._node_private_helios_key
示例#2
0
    def load(file_path: str, password: str) -> 'KeyWallet':
        """Loads a wallet from a keystore file with your password and generates an instance of Wallet.

        :param file_path: File path of the keystore file. type(str)
        :param password:
            Password for the keystore file.
            It must include alphabet character, number, and special character.
        :return: An instance of Wallet class.
        """
        try:
            with open(file_path, 'rb') as file:
                private_key: bytes = extract_key_from_keyfile(
                    file, bytes(password, 'utf-8'))
                private_key_object = PrivateKey(private_key)
                wallet = KeyWallet(private_key_object)
                logger.info(
                    f"Loaded Wallet by the keystore file. Address: {wallet.get_address()}, File path: {file_path}"
                )
                return wallet
        except FileNotFoundError:
            logger.exception(
                f"Raised KeyStoreException while loading the wallet by the keystore file because the file is not found."
            )
            raise KeyStoreException("File is not found.")
        except ValueError:
            logger.exception(
                f"Raised KeyStoreException while loading the wallet by the keystore file because the password is wrong."
            )
            raise KeyStoreException("Password is wrong.")
        except Exception as e:
            logger.exception(
                f"Raised KeyStoreException while loading the wallet by the keystore file. Error message: {e}"
            )
            raise KeyStoreException(f'keystore file error.{e}')
示例#3
0
def get_private_key(key_path, password_path=None):
    """Open a JSON-encoded private key and return it

    If a password file is provided, uses it to decrypt the key. If not, the
    password is asked interactively. Raw hex-encoded private keys are supported,
    but deprecated."""

    assert key_path, key_path
    if not os.path.exists(key_path):
        log.fatal("%s: no such file", key_path)
        return None
    #  if not check_permission_safety(key_path):
    #      log.fatal("Private key file %s must be readable only by its owner.", key_path)
    #      return None
    #
    #  if password_path and not check_permission_safety(password_path):
    #      log.fatal("Password file %s must be readable only by its owner.", password_path)
    #      return None

    with open(key_path) as keyfile:
        private_key = keyfile.readline().strip()

        if is_hex(private_key) and len(decode_hex(private_key)) == 32:
            log.warning(
                "Private key in raw format. Consider switching to JSON-encoded"
            )
        else:
            if password_path:
                with open(password_path) as password_file:
                    password = password_file.readline().strip()
            else:
                password = getpass.getpass("Enter the private key password: ")
            private_key = eth_keyfile.extract_key_from_keyfile(
                key_path, password).hex()
    return private_key
示例#4
0
def load_pk(pk_file, pw_file=None):
    assert pk_file, pk_file
    if not os.path.exists(pk_file):
        logger.fatal("%s: no such file", pk_file)
        return None
    #  if not check_permission_safety(pk_file):
    #      logger.fatal("Private key file %s must be readable only by its owner.", pk_file)
    #      return None
    #
    #  if pw_file and not check_permission_safety(pw_file):
    #      logger.fatal("Password file %s must be readable only by its owner.", pw_file)
    #      return None

    with open(pk_file) as keyfile:
        private_key = keyfile.readline().strip()

        if is_hex(private_key) and len(decode_hex(private_key)) == 32:
            logger.warning(
                "Private key in raw format. Consider switching to JSON-encoded"
            )
        else:
            if pw_file:
                with open(pw_file) as password_file:
                    password = password_file.readline().strip()
            else:
                password = getpass.getpass("Enter the private key password: ")
            private_key = eth_keyfile.extract_key_from_keyfile(
                pk_file, password).hex()
    return private_key
示例#5
0
文件: relay.py 项目: JTpku/relay
    def _install_w3_middleware(self):
        """install signing middleware if an account is configured"""
        if "account" not in self.config:
            logger.warning("No account configured")
            return

        keystore_path = self.config["account"]["keystore_path"]
        keystore_password_path = self.config["account"][
            "keystore_password_path"]
        with open(keystore_password_path, "r") as password_file:
            password = password_file.readline().strip()

        try:
            private_key = eth_keyfile.extract_key_from_keyfile(
                keystore_path, password.encode("utf-8"))
        except ValueError:
            raise ValueError(
                "Could not decrypt keystore. Please make sure the password is correct."
            )

        account = eth_account.Account.from_key(private_key)
        signing_middleware.install_signing_middleware(self._web3, account)
        logger.info(
            f"private key for address {account.address} loaded for signing transactions"
        )
示例#6
0
def key_from_key_store(file_path, password):
    """

    :param file_path:
    :return:
    """
    with open(file_path, 'rb') as file:
        private_key = extract_key_from_keyfile(file, password)
    return private_key
示例#7
0
def get_authorized_private_key(password: str) -> str:
    """
    Returns the private key associated with stored keyfile. Password required.
    """
    keyfile_path = get_keyfile_path()
    try:
        private_key = eth_keyfile.extract_key_from_keyfile(
            str(keyfile_path), to_bytes(text=password))
    except ValueError:
        raise AuthorizationError(
            f"Provided keyfile password: {password} is not a valid "
            f"password for encrypted keyfile at {keyfile_path}.")
    return private_key
示例#8
0
def get_private_key(key_file_path, password):
    """Gets private key from ethereum key file

    Args:
        key_file_path: path to the ethereum key file
        password: password to decrypt the file

    Returns:
        [str]: hex encoded private key
    """
    private_key_bytes = extract_key_from_keyfile(key_file_path, password)

    return encode_hex(private_key_bytes)
示例#9
0
    def from_prikey_file(cls: Type[T], prikey_file: str, password: Union[str, bytes]) -> T:
        if isinstance(password, str):
            password = password.encode()

        try:
            if prikey_file.endswith('.der'):
                prikey = DerSerializer.deserialize_private_key_file(prikey_file, password)
            elif prikey_file.endswith('.pem'):
                prikey = PemSerializer.deserialize_private_key_file(prikey_file, password)
            else:
                with open(prikey_file, 'rb') as file:
                    prikey = eth_keyfile.extract_key_from_keyfile(file, password)
        except Exception:
            raise ValueError("Invalid Password.")
        return cls.from_prikey(prikey)
示例#10
0
def key_from_key_store(file_path: str, password: (bytes, str)) -> bytes:
    """Get private key from keystore file.

    :param file_path: keystore file path.
    :param password: password of keystore file.

    :return: private key
    """
    try:
        with open(file_path, 'rb') as file:
            private_key = extract_key_from_keyfile(file, password)
    except ValueError:
        raise KeyStoreException('Invalid password.')
    except Exception as e:
        raise KeyStoreException(f'keystore file error.{e}')
    else:
        return private_key
示例#11
0
 def set_password(self, password: str) -> None:
     keystore_path = self._datadir / self.KEYSTORE_FILENAME
     if keystore_path.exists():
         self._privkey = extract_key_from_keyfile(
             str(keystore_path),
             password.encode('utf-8'),
         )
     else:
         log.info("Generating new Ethereum private key")
         self._privkey = os.urandom(32)
         keystore = create_keyfile_json(
             self._privkey,
             password.encode('utf-8'),
             iterations=1024,
         )
         with open(keystore_path, 'w') as f:
             json.dump(keystore, f)
示例#12
0
    def load(file_path: str, password: str) -> "KeyWallet":
        """Loads a wallet from a keystore file with your password and generates an instance of Wallet.

        :param file_path: File path of the keystore file. type(str)
        :param password:
            Password for the keystore file.
            It must include alphabet character, number, and special character.
        :return: An instance of Wallet class.
        """
        try:
            with open(file_path, "rb") as file:
                private_key: bytes = extract_key_from_keyfile(file, bytes(password, "utf-8"))
                return KeyWallet(private_key)
        except FileNotFoundError:
            raise KeyStoreException("File is not found.")
        except ValueError:
            raise KeyStoreException("Password is wrong.")
        except Exception as e:
            raise KeyStoreException(f"keystore file error.{e}")
示例#13
0
    def __init__(self,
                 keyfile=None,
                 password=None,
                 private_key=None,
                 path='./'):
        if isinstance(password, str):
            password = password.encode()

        # create new account if none given
        if all(p is None for p in [keyfile, private_key]):
            private_key = os.urandom(32)
            if password is None:
                password = os.urandom(10)

            if len(password):
                log.info('-' * 15, 'Save this password somewhere', '-' * 15)
                log.info('<', password.hex(), '>')
                log.info('-' * 58)
            else:
                log.info('-' * 5, '<empty password>', '-' * 5)

            keyfile_data = create_keyfile_json(private_key, password)
            # filename = 'keyfile--'+keyfile_data['address']
            filename = os.path.join(path,
                                    'keyfile--' + keyfile_data['address'])
            with open(filename, 'w') as file:
                file.write(json.dumps(keyfile_data))

        # load account from existing keyfile
        else:
            if private_key is None:
                private_key = extract_key_from_keyfile(keyfile, password)

        # init stuff for this account
        self.private_key = KeyAPI.PrivateKey(private_key)
        self.public_key = keys.PublicKey.from_private(self.private_key)
        self.address = self.public_key.to_address()
        self.nonce = 0
        log.debug('public_key=%s type %s', self.public_key,
                  type(self.public_key))
        log.debug('address=%s, type %s', self.address, type(self.address))
        """ convert and keep private_key, public_key, signature in to_bytes() """
示例#14
0
def get_validator_private_key(config: dict) -> bytes:
    """Get the private key of the validator from the configuration.

    The private key get decoded or decrypted into its origin byte
    representation. If the key is provided by a keystore, the password
    is first read in to decrypt the store. This function expects an
    earlier validation of the configuration and does not check if the
    parameters do actually exist. Anyways this is the place where the
    existence of the keystore and password file is verified.
    """

    private_key: dict = config["validator_private_key"]

    if "raw" in private_key:
        return private_key["raw"]
    else:
        keystore_path = private_key["keystore_path"]
        keystore_password_path = private_key["keystore_password_path"]

        if not os.path.isfile(keystore_path) or not os.access(
                keystore_path, os.R_OK):
            raise ValueError(
                f"The keystore file does not exist or is not readable: '{keystore_path}'"
            )

        if not os.path.isfile(keystore_password_path) or not os.access(
                keystore_password_path, os.R_OK):
            raise ValueError(
                f"The keystore password file does not exist or is not readable: '{keystore_password_path}'"
            )

        with open(keystore_password_path, "r") as password_file:
            password = password_file.readline().strip()

        try:
            return extract_key_from_keyfile(keystore_path,
                                            password.encode("utf-8"))

        except ValueError:
            raise ValueError(
                f"Could not decrypt keystore. Please make sure the password is correct."
            )
示例#15
0
文件: wallet.py 项目: icona2/crawling
    def load(file_path, password):
        """Loads a wallet from a keystore file with your password and generates an instance of Wallet.

        :param file_path: File path of the keystore file. type(str)
        :param password:
            Password for the keystore file.
            It must include alphabet character, number, and special character.
        :return: An instance of Wallet class.
        """
        try:
            with open(file_path, 'rb') as file:
                bytes_private_key = extract_key_from_keyfile(file, bytes(password, 'utf-8'))
                private_key_object = PrivateKey(bytes_private_key)
                wallet = KeyWallet(private_key_object)
                return wallet
        except FileNotFoundError:
            raise KeyStoreException("File is not found.")
        except ValueError:
            raise KeyStoreException("Password is wrong.")
        except Exception as e:
            raise KeyStoreException(f'keystore file error.{e}')
示例#16
0
def __key_from_key_store(file_path, password):
    with open(file_path, 'rb') as file:
        private_key = extract_key_from_keyfile(file, password)
    return private_key
示例#17
0
def decrypt_private_key(keystore_path: str, password: str) -> bytes:
    return extract_key_from_keyfile(keystore_path, password.encode("utf-8"))
示例#18
0
def load_keystore(keystore, passphrase):
    keys = KeyAPI(NativeECCBackend)
    priv = extract_key_from_keyfile(keystore, passphrase)
    acc = Account.from_key(priv)
    return keys.PrivateKey(priv), acc
示例#19
0
 def from_eth_keyfile(cls,
                      path: str,
                      password: Optional[str] = None) -> 'PrivateKey':
     key_bytes = extract_key_from_keyfile(path, password)
     return cls.from_bytes(key_bytes)
示例#20
0
def load_private_key_from_keystore(key_path, password='******'):
    key_bytes = extract_key_from_keyfile(key_path, password)
    return key_bytes
示例#21
0
 def get_private_key_from_keyfile_by_asking_password(file: str) -> bytes:
     password = getpass.getpass("Password: "******"hex")
     decoded_private_key = encoded.decode()
     return decoded_private_key
示例#22
0
#!/usr/bin/env python3
"""
Script to convert keystore files to raw hex private keys.

- `keystore files` are used to import/export identities into yagna
- `raw hex private keys` are used in metamask
"""

from eth_keyfile import extract_key_from_keyfile
import sys

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} <private_key_json>")
        exit(1)

    print("Reading keyfile: " + sys.argv[1])
    eth_key_password = b""

    eth_key_hex = extract_key_from_keyfile(sys.argv[1], eth_key_password)

    print(eth_key_hex.hex())
示例#23
0
"""

# First, install required python package:

pip install eth-keyfile

# Then execute the script to extract your private key from the json keystore

python3 decrypt_private_key.py --keystore keystore.json --password 123

"""

import argparse
import binascii
import eth_keyfile

parser = argparse.ArgumentParser()
parser.add_argument("--keystore", type=str, help="path to the json keystore file", required=True)
parser.add_argument("--password", type=str, help="password to decrypt the keystore", required=True)

args = parser.parse_args()

binary_private_key = eth_keyfile.extract_key_from_keyfile(args.keystore, args.password)
hex_data = binascii.hexlify(binary_private_key)
private_key = hex_data.decode('utf-8')
print('Your private key is:')
print(private_key)
示例#24
0
 def get_private_key_from_keyfile_by_explicit_password(
         file: str, password: str) -> bytes:
     private_key = extract_key_from_keyfile(file, password.encode())
     encoded = encode(private_key, "hex")
     decoded_private_key = encoded.decode()
     return decoded_private_key
示例#25
0
def purge(
        db_uri,
        server,
        admin_access_token_file,
        admin_user,
        admin_password,
        admin_private_key,
        admin_private_key_password,
        admin_private_key_generate,
        admin_private_key_print_only,
        server_name,
        admin_set,
        keep_newer,
        keep_min_msgs,
        parallel_purges,
        post_sql,
        docker_restart_label,
):
    """ Purge historic data from rooms in a synapse server

    DB_URI: DB connection string: postgres://user:password@netloc:port/dbname
    SERVER: matrix synapse server url, e.g.: http://hostname

    All option can be passed through uppercase environment variables prefixed with 'MATRIX_'
    e.g.: export MATRIX_KEEP_MIN_MSGS=100
    """
    try:
        session = requests.Session()

        # no --server-name, defaults to server hostname
        if not server_name:
            server_name = urlparse(server).hostname

        # admin_access_token_file has priority over everything else, to avoid re-logins
        if os.path.isfile(admin_access_token_file):
            with open(admin_access_token_file, 'r') as fo:
                admin_user, admin_access_token = itemgetter(
                    'admin_user',
                    'admin_access_token',
                )(json.load(fo))
        else:
            if (
                    not admin_user and
                    not os.path.isfile(admin_private_key) and
                    admin_private_key_generate
            ):
                if admin_private_key_password is None:
                    admin_private_key_password = click.prompt(
                        'JSON keyfile password',
                        default='',
                        hide_input=True,
                    )
                with open(admin_private_key, 'w') as fo:
                    json.dump(create_keyfile_json(
                        os.urandom(32),
                        admin_private_key_password.encode(),
                    ), fo, indent=2)

            # derive admin_user and admin_password from private key
            if not admin_user and os.path.isfile(admin_private_key):
                if admin_private_key_password is None:
                    admin_private_key_password = click.prompt(
                        'JSON keyfile password',
                        default='',
                        hide_input=True,
                    )
                pk_bin = extract_key_from_keyfile(
                    admin_private_key,
                    admin_private_key_password.encode(),
                )
                pk = keys.PrivateKey(pk_bin)

                # username is 0x-prefixed lowercase eth address
                admin_user = f'@{pk.public_key.to_address()}:{server_name}'
                # password is server_name signed with key, with eth_sign prefixed hash
                admin_password_bin = pk.sign_msg_hash(
                    eth_sign_hash(server_name.encode()),
                ).to_bytes()
                admin_password = encode_hex(
                    admin_password_bin[:-1] +
                    bytes([admin_password_bin[-1] + 27])  # v += 27
                )
                if admin_private_key_print_only:
                    click.secho(f'PK to Matrix User:     {admin_user}')
                    click.secho(f'PK to Matrix Password: {admin_password}')
                    return

            if admin_user:
                if not admin_password:
                    admin_password = click.prompt(
                        'Admin user password',
                        default='',
                        hide_input=True,
                    )
                response = session.post(
                    urljoin(server, '/_matrix/client/r0/login'),
                    json={
                        'type': 'm.login.password',
                        'user': admin_user,
                        'password': admin_password,
                    },
                )
                assert response.status_code == 200, f'{response!r} => {response.text!r}'
                admin_access_token = response.json()['access_token']
                with open(admin_access_token_file, 'w') as fo:
                    json.dump({
                        'admin_user': admin_user,
                        'admin_access_token': admin_access_token,
                    }, fo, indent=2)

            else:
                raise RuntimeError('No admin_user nor previous access token found')

        if admin_private_key_print_only:
            # only hit if --admin-private-key-print-only passed, but an access token or admin user
            # was already present, or no --admin-private-key file nor --admin-private-key-generate
            return

        with psycopg2.connect(db_uri) as db, db.cursor() as cur:

            # set user as admin in database if needed
            cur.execute(
                'SELECT admin FROM users WHERE name = %s ;',
                (admin_user,),
            )
            if not cur.rowcount:
                raise RuntimeError(f'User {admin_user!r} not found')
            is_admin, = cur.fetchone()
            if admin_set and not is_admin:
                cur.execute(
                    'UPDATE users SET admin=1 WHERE name = %s ;',
                    (admin_user,),
                )
                db.commit()
            elif not is_admin:
                raise RuntimeError(f'User {admin_user!r} is not an admin. See --admin-set option')

            purges = dict()
            def wait_and_purge_room(room_id=None, event_id=None):
                """ Wait for available slots in parallel_purges and purge room

                If room_id is None, just wait for current purges to complete and return
                If event_id is None, purge all events in room
                """
                while len(purges) >= (parallel_purges if room_id else 1):
                    # wait and clear completed purges
                    time.sleep(1)
                    for _room_id, purge_id in list(purges.items()):
                        response = session.get(
                            urljoin(
                                server,
                                '/_matrix/client/r0/admin/purge_history_status/' + quote(purge_id),
                            ),
                            params={'access_token': admin_access_token},
                        )
                        assert response.status_code == 200, f'{response!r} => {response.text!r}'
                        if response.json()['status'] != 'active':
                            click.secho(f'Finished purge: room {_room_id!r}, purge {purge_id!r}')
                            purges.pop(_room_id)

                if not room_id:
                    return

                body = {'delete_local_events': True}
                if event_id:
                    body['purge_up_to_event_id'] = event_id
                else:
                    body['purge_up_to_ts'] = int(time.time() * 1000)
                response = session.post(
                    urljoin(server, '/_matrix/client/r0/admin/purge_history/' + quote(room_id)),
                    params={'access_token': admin_access_token},
                    json=body,
                )
                if response.status_code == 200:
                    purge_id = response.json()['purge_id']
                    purges[room_id] = purge_id
                    return purge_id

            if not keep_newer and not keep_min_msgs:
                click.confirm(
                    'No --keep-newer nor --keep-min-msgs option provided. Purge all history?',
                    abort=True,
                )

            ts_ms = None
            if keep_newer:
                ts = datetime.datetime.now() - datetime.timedelta(keep_newer)
                ts_ms = int(ts.timestamp() * 1000)

            cur.execute('SELECT room_id FROM rooms ;')
            all_rooms = {row for row, in cur}

            click.secho(f'Processing {len(all_rooms)} rooms')
            for room_id in all_rooms:
                # no --keep-min-msgs nor --keep-newer, purge everything
                if not keep_newer and not keep_min_msgs:
                    wait_and_purge_room(room_id)
                    continue
                cur.execute(
                    f"""
                    SELECT event_id FROM (
                        SELECT event_id,
                            received_ts,
                            COUNT(*) OVER (ORDER BY received_ts DESC) AS msg_count_above
                        FROM events
                        WHERE room_id=%(room_id)s AND type='m.room.message'
                        ORDER BY received_ts DESC
                    ) t WHERE true
                    {'AND received_ts < %(ts_ms)s' if keep_newer else ''}
                    {'AND msg_count_above > %(keep_min_msgs)s' if keep_min_msgs else ''}
                    LIMIT 1 ;""",
                    {
                        'room_id': room_id,
                        'ts_ms': ts_ms,
                        'keep_min_msgs': keep_min_msgs,
                    },
                )
                if cur.rowcount:
                    event_id, = cur.fetchone()
                    wait_and_purge_room(room_id, event_id)
                # else: room doesn't have messages eligible for purging, skip

            wait_and_purge_room(None)

        if post_sql:
            click.secho(f'Running {post_sql.name!r}')
            with psycopg2.connect(db_uri) as db, db.cursor() as cur:
                cur.execute(post_sql.read())
                click.secho(f'Results {cur.rowcount}:')
                for i, row in enumerate(cur):
                    click.secho(f'{i}: {row}')

    finally:
        if docker_restart_label:
            client = docker.from_env()
            for container in client.containers.list():
                if container.attrs['State']['Status'] != 'running' or\
                        not container.attrs['Config']['Labels'].get(docker_restart_label):
                    continue

                try:
                    # parse container's env vars
                    env_vars = dict(
                        itemgetter(0, 2)(e.partition('='))
                        for e in container.attrs['Config']['Env']
                    )
                    remote_config_file = env_vars.get(
                        'URL_KNOWN_FEDERATION_SERVERS',
                    ) or URL_KNOWN_FEDERATION_SERVERS_DEFAULT

                    # fetch remote file
                    remote_whitelist = yaml.load(requests.get(remote_config_file).text)

                    # fetch local list from container's synapse config
                    local_whitelist = yaml.load(
                        container.exec_run(['cat', SYNAPSE_CONFIG_PATH]).output,
                    )['federation_domain_whitelist']

                    # if list didn't change, don't proceed to restart container
                    if local_whitelist and remote_whitelist == local_whitelist:
                        continue

                    click.secho(
                        f'Whitelist changed. Restarting. new_list={remote_whitelist!r}',
                    )
                except (
                        KeyError,
                        IndexError,
                        requests.RequestException,
                        yaml.scanner.ScannerError,
                ) as ex:
                    click.secho(
                        f'An error ocurred while fetching whitelists: {ex!r}\n'
                        'Restarting anyway',
                        err=True,
                    )
                # restart container
                container.restart(timeout=30)
示例#26
0
 def decrypt_keyfile(file: str, password: str):
     private_key = extract_key_from_keyfile(file, password.encode())
     encoded = encode(private_key, "hex")
     decoded_private_key = encoded.decode()
     print(f"{decoded_private_key}")
示例#27
0
from eth_keys import keys
from eth_keyfile import extract_key_from_keyfile

from cpchain import config

from cpchain.utils import join_with_root

priv_bytes = extract_key_from_keyfile(
    join_with_root(config.wallet.private_key_file),
    open(join_with_root(config.wallet.private_key_password_file)).read())

print(priv_bytes)
priv_key = keys.PrivateKey(priv_bytes)

pub_key = priv_key.public_key
addr = pub_key.to_address()
print(addr)