Esempio n. 1
0
def is_hex_address(value: Any) -> bool:
    """Checks if the given string of text type is an address in hexadecimal encoded form."""
    if len(value) != 42:
        return False
    elif not is_text(value):
        return False
    elif not is_hex(value):
        return False
    else:
        return is_address(hex_to_base58(value))
Esempio n. 2
0
    def to_hex(address):
        """Helper function that will convert a generic value to hex

        Args:
            address (str): address

        """
        if is_hex(address):
            return address.lower().replace('0x', '41', 2)

        return base58.b58decode_check(address).hex().upper()
Esempio n. 3
0
    def from_hex(address):
        """Helper function that will convert a generic value from hex

        Args:
            address (str): address

        """
        if not is_hex(address):
            return address

        return base58.b58encode_check(bytes.fromhex(address))
Esempio n. 4
0
    def sign(self, transaction: Any, use_tron: bool = True):
        """Sign the transaction, the api has the risk of leaking the private key,
        please make sure to call the api in a secure environment

        Warnings:
            Do not use this in any web / user-facing applications.
            This will expose the private key.

        Args:
            transaction (Any): transaction details
            use_tron (bool): is Tron header

        """

        if is_string(transaction):
            if not is_hex(transaction):
                raise TronError('Expected hex message input')

            # Determine which header to attach to the message
            # before encrypting or decrypting
            header = TRX_MESSAGE_HEADER if use_tron else ETH_MESSAGE_HEADER
            header += str(len(transaction))

            message_hash = self.tron.sha3(text=header + transaction)
            signed_message = Account.signHash(
                message_hash, private_key=self.tron.private_key)

            return signed_message

        if 'signature' in transaction:
            raise TronError('Transaction is already signed')

        address = self.tron.address.from_private_key(
            self.tron.private_key).hex.lower()
        owner_address = transaction['raw_data']['contract'][0]['parameter'][
            'value']['owner_address']

        if address != owner_address:
            raise ValueError(
                'Private key does not match address in transaction')

        # This option deals with signing of transactions, and writing to the array
        signed_tx = Account.signHash(message_hash=transaction['txID'],
                                     private_key=self.tron.private_key)
        transaction['signature'] = [signed_tx['signature'].hex()[2:]]

        return transaction
Esempio n. 5
0
    def get_block(self, block=None):
        """Get block details using HashString or blockNumber

        Args:
            block (int|str): Number or Hash Block

        """
        if block is None:
            block = self.default_block

        if block == 'earliest':
            block = 0

        if block == 'latest':
            return self.get_current_block()

        if is_hex(block):
            return self.get_block_by_hash(block)

        return self.get_block_by_number(int(block))
Esempio n. 6
0
    def sign(self, transaction: Any, use_tron: bool = True):
        """Sign the transaction, the api has the risk of leaking the private key,
        please make sure to call the api in a secure environment

        Args:
            transaction (Any): transaction details
            use_tron (bool): is Tron header

        """

        if is_string(transaction):
            if not is_hex(transaction):
                raise TronError('Expected hex message input')

            # Determine which header to attach to the message
            # before encrypting or decrypting
            header = TRX_MESSAGE_HEADER if use_tron else ETH_MESSAGE_HEADER
            message_hash = self.tron.sha3(text=header + transaction)
            signed_message = EthAccount.signHash(
                message_hash, private_key=self.tron.private_key)

            return signed_message

        if 'signature' in transaction:
            raise TronError('Transaction is already signed')

        address = self.tron.address.from_private_key(
            self.tron.private_key).hex.lower()
        owner_address = transaction['raw_data']['contract'][0]['parameter'][
            'value']['owner_address']

        if address != owner_address:
            raise ValueError(
                'Private key does not match address in transaction')

        return self.tron.manager.request('/wallet/gettransactionsign', {
            'transaction': transaction,
            'privateKey': self.tron.private_key
        })
Esempio n. 7
0
    def verify_message(self,
                       message,
                       signed_message=None,
                       address=None,
                       use_tron: bool = True):
        """ Get the address of the account that signed the message with the given hash.
        You must specify exactly one of: vrs or signature

        Args:
            message (str): The message in the format "hex"
            signed_message (AttributeDict): Signature
            address (str): is Address
            use_tron (bool): is Tron header

        """
        if address is None:
            address = self.tron.default_address.base58

        if not is_hex(message):
            raise TronError('Expected hex message input')

        # Determine which header to attach to the message
        # before encrypting or decrypting
        header = TRX_MESSAGE_HEADER if use_tron else ETH_MESSAGE_HEADER

        message_hash = self.tron.sha3(text=header + message)
        recovered = Account.recoverHash(message_hash,
                                        signature=signed_message.signature)

        tron_address = '41' + recovered[2:]
        base58address = self.tron.address.from_hex(tron_address).decode()

        if base58address == address:
            return True

        raise ValueError('Signature does not match')
    def create_smart_contract(self, **kwargs):
        """Deploy Contract

        Deploys a contract.
        Returns TransactionExtention, which contains an unsigned transaction.

        Example:
        .. code-block:: python
            >>> from tronapi import Tron
            >>>
            >>> tron = Tron()
            >>> tron.transaction_builder.create_smart_contract(
            >>>    fee_limit=10**9,
            >>>    call_value=0,
            >>>    consume_user_resource_percent=10
            >>> )

        Args:
            **kwargs: Transaction parameters for the deployment
            transaction as a dict

        """

        if 'bytecode' not in kwargs:
            raise ValueError(
                "Cannot deploy a contract that does not have 'bytecode' associated "
                "with it")

        # Maximum TRX consumption, measured in SUN (1 TRX = 1,000,000 SUN).
        fee_limit = kwargs.setdefault('fee_limit', 0)
        # The same as User Pay Ratio.
        # The percentage of resources specified for users who use this contract.
        # This field accepts integers between [0, 100].
        user_fee_percentage = kwargs.setdefault(
            'consume_user_resource_percent', 0)
        # Amount of TRX transferred with this transaction, measured in SUN (1TRX = 1,000,000 SUN)
        call_value = kwargs.setdefault('call_value', 0)
        # Contract owner address, converted to a hex string
        owner_address = kwargs.setdefault('owner_address',
                                          self.tron.default_address.hex)
        # The max energy which will be consumed by the owner
        # in the process of excution or creation of the contract,
        # is an integer which should be greater than 0.
        origin_energy_limit = kwargs.setdefault('origin_energy_limit',
                                                10000000)

        if not is_hex(kwargs.get('bytecode')):
            raise ValueError('Invalid bytecode provided')

        if not is_integer(fee_limit) or fee_limit <= 0 or \
                fee_limit > 1000000000:
            raise ValueError('Invalid fee limit provided')

        if not is_integer(call_value) or call_value < 0:
            raise ValueError('Invalid call value provided')

        if not is_integer(user_fee_percentage) or user_fee_percentage < 0 or \
                user_fee_percentage > 100:
            raise ValueError('Invalid user fee percentage provided')

        if not is_integer(origin_energy_limit) or origin_energy_limit < 0:
            return ValueError('Invalid origin_energy_limit provided')

        if not self.tron.isAddress(owner_address):
            raise InvalidAddress('Invalid issuer address provided')

        # We write all the results in one object
        transaction = dict(**kwargs)
        transaction.setdefault('owner_address',
                               self.tron.address.to_hex(owner_address))

        return self.tron.manager.request('/wallet/deploycontract', transaction)
Esempio n. 9
0
def is_hex_encoded_block_hash(value):
    if not is_string(value):
        return False
    return len(remove_0x_prefix(value)) == 64 and is_hex(value)