Module tronpytool.common.account

Expand source code
# --------------------------------------------------------------------
# Copyright (c) iEXBase. All rights reserved.
# Licensed under the MIT License.
# See License.txt in the project root for license information.
# --------------------------------------------------------------------

import codecs
from binascii import unhexlify

import base58
import ecdsa
from eth_account import Account as ETHAccount
from eth_keys import KeyAPI
from trx_utils import is_hex, is_bytes

from tronpytool.common.datastructures import AttributeDict
from tronpytool.common.key import PrivateKey as PFactory


class Account:

    def generate_address(self, priv_key=None) -> dict:
        """Generate a random address."""
        if priv_key is None:
            priv_key = PFactory.random()
        return {
            "base58check_address": priv_key.public_key.to_base58check_address(),
            "hex_address": priv_key.public_key.to_hex_address(),
            "private_key": priv_key.hex(),
            "public_key": priv_key.public_key.hex(),
        }

    def get_address_from_passphrase(self, passphrase: str) -> dict:
        """Get an address from a passphrase, compatiable with `wallet/createaddress`."""
        priv_key = PFactory.from_passphrase(passphrase.encode())
        return self.generate_address(priv_key)

    @staticmethod
    def create():
        generate_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
        return PrivateKey(generate_key.to_string().hex())

    @staticmethod
    def sign_hash(message_hash, private_key):
        if not is_hex(message_hash):
            raise ValueError('Invalid message_hash provided')

        return ETHAccount.signHash(message_hash, private_key)

    @staticmethod
    def recover_hash(message_hash, signature):
        if not is_hex(message_hash):
            raise ValueError('Invalid message_hash provided')

        return ETHAccount.recoverHash(message_hash, signature=signature)


class Address:

    @staticmethod
    def from_hex(address) -> str:
        """Helper function that will convert a generic value from hex"""
        if not is_hex(address):
            return address
        return base58.b58encode_check(bytes.fromhex(address)).decode()

    @staticmethod
    def to_hex(address) -> str:
        """Helper function that will convert a generic value to hex"""
        if is_hex(address):
            return address.lower().replace('0x', '41', 2)

        return base58.b58decode_check(address).hex().upper()

    @staticmethod
    def to_hex_0x(address) -> str:
        """Helper function that will convert a generic value to hex"""
        if is_hex(address):
            return address
        return '0x' + base58.b58decode_check(address).hex().upper()[2:]

    @staticmethod
    def to_hex_0x_41(address) -> str:
        """Helper function that will convert a generic value to hex"""
        if is_hex(address):
            return address
        return '0x' + base58.b58decode_check(address).hex().upper()

    @staticmethod
    def from_private_key(private_key) -> AttributeDict:
        return PrivateKey(private_key).address


class PrivateKey(object):

    def __init__(self, private_key: str):
        """Work with private key.
        Getting: PublicKey, PublicToAddress

        Example:::
            PrivateKey("4d1bc37b069b9f2e975c37770b7c87185dc3a10454e3ea024ce1fce8f3eb78bf")
        """
        if private_key is None:
            raise ValueError('Empty private key here')

        _private = unhexlify(bytes(private_key, encoding='utf8'))
        self._key = KeyAPI.PrivateKey(_private)
        self.stored_privkey = private_key
        _length = len(self._key)

        # Key length must not exceed 64 length
        if _length < 64:
            raise ValueError('Key length must not exceed 64 length')

    @property
    def private_key(self) -> str:
        _raw_key = self._key.to_bytes()
        return codecs.decode(codecs.encode(_raw_key, 'hex'), 'ascii')

    @property
    def public_key(self) -> str:
        public_key = self._key.public_key
        return '04' + str(public_key)[2:]

    @property
    def address(self) -> AttributeDict:
        public_key = self._key.public_key
        address = '41' + public_key.to_address()[2:]
        contract_address = '0x' + public_key.to_address()[2:]
        to_base58 = base58.b58encode_check(bytes.fromhex(address))
        # If bytecode then convert to string
        if is_bytes(to_base58):
            to_base58 = to_base58.decode()

        return AttributeDict({
            'hex': address,
            'base58': to_base58,
            'sol': contract_address
        })

    def printKeys(self):
        pair = self.address
        print("public hex: {}".format(pair.hex))
        print("public wallet address in base58: {}".format(pair.base58))
        print("public address in contract: {}".format(pair.sol))

    def __str__(self):
        return self.stored_privkey

    def __bytes__(self):
        return self._key.to_bytes()

Classes

class Account
Expand source code
class Account:

    def generate_address(self, priv_key=None) -> dict:
        """Generate a random address."""
        if priv_key is None:
            priv_key = PFactory.random()
        return {
            "base58check_address": priv_key.public_key.to_base58check_address(),
            "hex_address": priv_key.public_key.to_hex_address(),
            "private_key": priv_key.hex(),
            "public_key": priv_key.public_key.hex(),
        }

    def get_address_from_passphrase(self, passphrase: str) -> dict:
        """Get an address from a passphrase, compatiable with `wallet/createaddress`."""
        priv_key = PFactory.from_passphrase(passphrase.encode())
        return self.generate_address(priv_key)

    @staticmethod
    def create():
        generate_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
        return PrivateKey(generate_key.to_string().hex())

    @staticmethod
    def sign_hash(message_hash, private_key):
        if not is_hex(message_hash):
            raise ValueError('Invalid message_hash provided')

        return ETHAccount.signHash(message_hash, private_key)

    @staticmethod
    def recover_hash(message_hash, signature):
        if not is_hex(message_hash):
            raise ValueError('Invalid message_hash provided')

        return ETHAccount.recoverHash(message_hash, signature=signature)

Static methods

def create()
Expand source code
@staticmethod
def create():
    generate_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
    return PrivateKey(generate_key.to_string().hex())
def recover_hash(message_hash, signature)
Expand source code
@staticmethod
def recover_hash(message_hash, signature):
    if not is_hex(message_hash):
        raise ValueError('Invalid message_hash provided')

    return ETHAccount.recoverHash(message_hash, signature=signature)
def sign_hash(message_hash, private_key)
Expand source code
@staticmethod
def sign_hash(message_hash, private_key):
    if not is_hex(message_hash):
        raise ValueError('Invalid message_hash provided')

    return ETHAccount.signHash(message_hash, private_key)

Methods

def generate_address(self, priv_key=None) ‑> dict

Generate a random address.

Expand source code
def generate_address(self, priv_key=None) -> dict:
    """Generate a random address."""
    if priv_key is None:
        priv_key = PFactory.random()
    return {
        "base58check_address": priv_key.public_key.to_base58check_address(),
        "hex_address": priv_key.public_key.to_hex_address(),
        "private_key": priv_key.hex(),
        "public_key": priv_key.public_key.hex(),
    }
def get_address_from_passphrase(self, passphrase: str) ‑> dict

Get an address from a passphrase, compatiable with wallet/createaddress.

Expand source code
def get_address_from_passphrase(self, passphrase: str) -> dict:
    """Get an address from a passphrase, compatiable with `wallet/createaddress`."""
    priv_key = PFactory.from_passphrase(passphrase.encode())
    return self.generate_address(priv_key)
class Address
Expand source code
class Address:

    @staticmethod
    def from_hex(address) -> str:
        """Helper function that will convert a generic value from hex"""
        if not is_hex(address):
            return address
        return base58.b58encode_check(bytes.fromhex(address)).decode()

    @staticmethod
    def to_hex(address) -> str:
        """Helper function that will convert a generic value to hex"""
        if is_hex(address):
            return address.lower().replace('0x', '41', 2)

        return base58.b58decode_check(address).hex().upper()

    @staticmethod
    def to_hex_0x(address) -> str:
        """Helper function that will convert a generic value to hex"""
        if is_hex(address):
            return address
        return '0x' + base58.b58decode_check(address).hex().upper()[2:]

    @staticmethod
    def to_hex_0x_41(address) -> str:
        """Helper function that will convert a generic value to hex"""
        if is_hex(address):
            return address
        return '0x' + base58.b58decode_check(address).hex().upper()

    @staticmethod
    def from_private_key(private_key) -> AttributeDict:
        return PrivateKey(private_key).address

Static methods

def from_hex(address) ‑> str

Helper function that will convert a generic value from hex

Expand source code
@staticmethod
def from_hex(address) -> str:
    """Helper function that will convert a generic value from hex"""
    if not is_hex(address):
        return address
    return base58.b58encode_check(bytes.fromhex(address)).decode()
def from_private_key(private_key) ‑> AttributeDict
Expand source code
@staticmethod
def from_private_key(private_key) -> AttributeDict:
    return PrivateKey(private_key).address
def to_hex(address) ‑> str

Helper function that will convert a generic value to hex

Expand source code
@staticmethod
def to_hex(address) -> str:
    """Helper function that will convert a generic value to hex"""
    if is_hex(address):
        return address.lower().replace('0x', '41', 2)

    return base58.b58decode_check(address).hex().upper()
def to_hex_0x(address) ‑> str

Helper function that will convert a generic value to hex

Expand source code
@staticmethod
def to_hex_0x(address) -> str:
    """Helper function that will convert a generic value to hex"""
    if is_hex(address):
        return address
    return '0x' + base58.b58decode_check(address).hex().upper()[2:]
def to_hex_0x_41(address) ‑> str

Helper function that will convert a generic value to hex

Expand source code
@staticmethod
def to_hex_0x_41(address) -> str:
    """Helper function that will convert a generic value to hex"""
    if is_hex(address):
        return address
    return '0x' + base58.b58decode_check(address).hex().upper()
class PrivateKey (private_key: str)

Work with private key. Getting: PublicKey, PublicToAddress

Example::: PrivateKey("4d1bc37b069b9f2e975c37770b7c87185dc3a10454e3ea024ce1fce8f3eb78bf")

Expand source code
class PrivateKey(object):

    def __init__(self, private_key: str):
        """Work with private key.
        Getting: PublicKey, PublicToAddress

        Example:::
            PrivateKey("4d1bc37b069b9f2e975c37770b7c87185dc3a10454e3ea024ce1fce8f3eb78bf")
        """
        if private_key is None:
            raise ValueError('Empty private key here')

        _private = unhexlify(bytes(private_key, encoding='utf8'))
        self._key = KeyAPI.PrivateKey(_private)
        self.stored_privkey = private_key
        _length = len(self._key)

        # Key length must not exceed 64 length
        if _length < 64:
            raise ValueError('Key length must not exceed 64 length')

    @property
    def private_key(self) -> str:
        _raw_key = self._key.to_bytes()
        return codecs.decode(codecs.encode(_raw_key, 'hex'), 'ascii')

    @property
    def public_key(self) -> str:
        public_key = self._key.public_key
        return '04' + str(public_key)[2:]

    @property
    def address(self) -> AttributeDict:
        public_key = self._key.public_key
        address = '41' + public_key.to_address()[2:]
        contract_address = '0x' + public_key.to_address()[2:]
        to_base58 = base58.b58encode_check(bytes.fromhex(address))
        # If bytecode then convert to string
        if is_bytes(to_base58):
            to_base58 = to_base58.decode()

        return AttributeDict({
            'hex': address,
            'base58': to_base58,
            'sol': contract_address
        })

    def printKeys(self):
        pair = self.address
        print("public hex: {}".format(pair.hex))
        print("public wallet address in base58: {}".format(pair.base58))
        print("public address in contract: {}".format(pair.sol))

    def __str__(self):
        return self.stored_privkey

    def __bytes__(self):
        return self._key.to_bytes()

Instance variables

var addressAttributeDict
Expand source code
@property
def address(self) -> AttributeDict:
    public_key = self._key.public_key
    address = '41' + public_key.to_address()[2:]
    contract_address = '0x' + public_key.to_address()[2:]
    to_base58 = base58.b58encode_check(bytes.fromhex(address))
    # If bytecode then convert to string
    if is_bytes(to_base58):
        to_base58 = to_base58.decode()

    return AttributeDict({
        'hex': address,
        'base58': to_base58,
        'sol': contract_address
    })
var private_key : str
Expand source code
@property
def private_key(self) -> str:
    _raw_key = self._key.to_bytes()
    return codecs.decode(codecs.encode(_raw_key, 'hex'), 'ascii')
var public_key : str
Expand source code
@property
def public_key(self) -> str:
    public_key = self._key.public_key
    return '04' + str(public_key)[2:]

Methods

def printKeys(self)
Expand source code
def printKeys(self):
    pair = self.address
    print("public hex: {}".format(pair.hex))
    print("public wallet address in base58: {}".format(pair.base58))
    print("public address in contract: {}".format(pair.sol))