コード例 #1
0
ファイル: validation.py プロジェクト: zoeas/tron-api-python
def validate_abi_value(abi_type, value):
    """
    Helper function for validating a value against the expected abi_type
    Note: abi_type 'bytes' must either be python3 'bytes' object or ''
    """
    if is_array_type(abi_type) and is_list_like(value):
        # validate length
        specified_length = length_of_array_type(abi_type)
        if specified_length is not None:
            if specified_length < 1:
                raise TypeError(
                    "Invalid abi-type: {abi_type}. Length of fixed sized arrays"
                    "must be greater than 0."
                        .format(abi_type=abi_type)
                )
            if specified_length != len(value):
                raise TypeError(
                    "The following array length does not the length specified"
                    "by the abi-type, {abi_type}: {value}"
                        .format(abi_type=abi_type, value=value)
                )

        # validate sub_types
        sub_type = sub_type_of_array_type(abi_type)
        for v in value:
            validate_abi_value(sub_type, v)
        return
    elif is_bool_type(abi_type) and is_boolean(value):
        return
    elif is_uint_type(abi_type) and is_integer(value) and value >= 0:
        return
    elif is_int_type(abi_type) and is_integer(value):
        return
    elif is_address_type(abi_type):
        validate_address(value)
        return
    elif is_bytes_type(abi_type):
        if is_bytes(value):
            return
        elif is_string(value):
            if is_0x_prefixed(value):
                return
            else:
                raise TypeError(
                    "ABI values of abi-type 'bytes' must be either"
                    "a python3 'bytes' object or an '0x' prefixed string."
                )
    elif is_string_type(abi_type) and is_string(value):
        return

    raise TypeError(
        "The following abi value is not a '{abi_type}': {value}".format(abi_type=abi_type, value=value)
    )
コード例 #2
0
    def update_account(self, account_name, account: str = None):
        """Modify account name

        Note: Username is allowed to edit only once.

        Args:
            account_name (str): name of the account
            account (str): address

        Returns:
            modified Transaction Object

        """

        # If the address of the sender is not specified, we prescribe the default
        if account is None:
            account = self.tron.default_address.hex

        if not is_string(account_name):
            raise ValueError('Name must be a string')

        if not self.tron.isAddress(account):
            raise TronError('Invalid origin address provided')

        response = self.tron.manager.request(
            '/wallet/updateaccount', {
                'account_name': self.tron.toHex(text=account_name),
                'owner_address': self.tron.address.to_hex(account)
            })

        return response
コード例 #3
0
def is_hex_encoded_block_number(value):
    if not is_string(value):
        return False
    elif is_hex_encoded_block_hash(value):
        return False
    try:
        value_as_int = int(value, 16)
    except ValueError:
        return False
    return 0 <= value_as_int < 2**256
コード例 #4
0
def map_collection(func, collection):
    """
    Apply func to each element of a collection, or value of a dictionary.
    If the value is not a collection, return it unmodified
    """
    datatype = type(collection)
    if isinstance(collection, Mapping):
        return datatype((key, func(val)) for key, val in collection.items())
    if is_string(collection):
        return collection
    elif isinstance(collection, Iterable):
        return datatype(map(func, collection))
    else:
        return collection
コード例 #5
0
    def send_token(self, to, amount, token_id, account=None):
        """Transfer Token

        Args:
            to (str): is the recipient address
            amount (int): is the amount of token to transfer. must be integer instead of float
            token_id (any): Token Name and id
            account: (str): is the address of the withdrawal account

        Returns:
            Token transfer Transaction raw data

        """

        # If the address of the sender is not specified, we prescribe the default
        if account is None:
            account = self.tron.default_address.hex

        if not self.tron.isAddress(to):
            raise InvalidTronError('Invalid recipient address provided')

        if not isinstance(amount, int) or amount <= 0:
            raise InvalidTronError('Invalid amount provided')

        if not token_id:
            raise InvalidTronError('Invalid token ID provided')

        if not self.tron.isAddress(account):
            raise InvalidTronError('Invalid origin address provided')

        _to = self.tron.address.to_hex(to)
        _from = self.tron.address.to_hex(account)
        _token_id = self.tron.toHex(text=str(token_id))

        if _to == _from:
            raise TronError('Cannot transfer TRX to the same account')

        # In case if "TRX" is specified, we redirect to another method.
        if is_string(token_id) and token_id.upper() == 'TRX':
            return self.send_transaction(_to, amount, _from)

        return self.tron.manager.request(
            '/wallet/transferasset', {
                'to_address': _to,
                'owner_address': _from,
                'asset_name': _token_id,
                'amount': amount
            })
コード例 #6
0
    def check_permissions(self, permissions, _type):
        if permissions is not None:
            if permissions['type'] != _type or \
                    not permissions['permission_name'] or \
                    not is_string(permissions['permission_name']) or \
                    not is_integer(permissions['threshold']) or \
                    permissions['threshold'] < 1 or not permissions['keys']:
                return False

        for key in permissions['key']:
            if not self.tron.isAddress(key['address']) or \
                    not is_integer(key['weight']) or \
                    key['weight'] > permissions['threshold'] or \
                    key['weight'] < 1 or _type == 2 and not permissions['operations']:
                return False

        return True
コード例 #7
0
ファイル: manager.py プロジェクト: zoeas/tron-api-python
    def __init__(self, tron, providers):
        """Create new manager tron instance

        Args:
            tron: The tron implementation
            providers: List of providers

        """
        self.tron = tron
        self.providers = providers
        self.preferred_node = None

        for key, value in self.providers.items():
            # This condition checks the nodes,
            # if the link to the node is not specified,
            # we insert the default value to avoid an error.
            if not providers[key]:
                self.providers[key] = HttpProvider(DEFAULT_NODES[key])

            # If the type of the accepted provider is lower-case,
            # then we transform it to “HttpProvider”,
            if is_string(value):
                self.providers[key] = HttpProvider(value)
            self.providers[key].status_page = STATUS_PAGE[key]
コード例 #8
0
    def create_token(self, **kwargs):
        """Issue Token

        Issuing a token on the TRON Protocol can be done by anyone
        who has at least 1024 TRX in their account.
        When a token is issued it will be shown on the token overview page.
        Users can then participate within the issuing time and exchange their
        TRX for tokens.After issuing the token your account will
        receive the amount of tokens equal to the total supply.
        When other users exchange their TRX for tokens then the tokens
        will be withdrawn from your account and you will receive
        TRX equal to the specified exchange rate.


        Args:
            **kwargs: Fill in the required parameters

        Examples:

            >>> start_func = datetime.now()
            >>> start = int(start_func.timestamp() * 1000)
            >>>
            >>> end_func = datetime.now() + timedelta(days=2)
            >>> end = int(end_func.timestamp() * 1000)
            >>>
            >>> opt = {
            >>>     'name': 'Tron',
            >>>     'abbreviation': 'TRX',
            >>>     'description': 'Hello World',
            >>>     'url': 'https://github.com',
            >>>     'totalSupply': 25000000,
            >>>     'frozenAmount': 1,
            >>>     'frozenDuration': 2,
            >>>     'freeBandwidth': 10000,
            >>>     'freeBandwidthLimit': 10000,
            >>>     'saleStart': start,
            >>>     'saleEnd': end,
            >>>     'voteScore': 1
            >>> }

        """
        issuer_address = kwargs.setdefault('issuer_address',
                                           self.tron.default_address.hex)

        if not self.tron.isAddress(issuer_address):
            raise TronError('Invalid issuer address provided')

        total_supply = kwargs.setdefault('totalSupply', 0)
        trx_ratio = kwargs.setdefault('trxRatio', 1)
        token_ratio = kwargs.setdefault('tokenRatio', 1)
        sale_start = kwargs.setdefault('saleStart', START_DATE)
        free_bandwidth = kwargs.setdefault('freeBandwidth', 0)
        free_bandwidth_limit = kwargs.setdefault('freeBandwidthLimit', 0)
        frozen_amount = kwargs.setdefault('frozenAmount', 0)
        frozen_duration = kwargs.setdefault('frozenDuration', 0)
        vote_score = kwargs.setdefault('voteScore', 0)
        precision = kwargs.setdefault('precision', 0)

        if not is_string(kwargs.get('name')):
            raise ValueError('Invalid token name provided')

        if not is_string(kwargs.get('abbreviation')):
            raise ValueError('Invalid token abbreviation provided')

        if not is_integer(total_supply) or total_supply <= 0:
            raise ValueError('Invalid supply amount provided')

        if not is_integer(trx_ratio) or trx_ratio <= 0:
            raise ValueError('TRX ratio must be a positive integer')

        if not is_integer(token_ratio) or token_ratio <= 0:
            raise ValueError('Token ratio must be a positive integer')

        if not is_integer(vote_score) or vote_score <= 0:
            raise ValueError(
                'voteScore must be a positive integer greater than 0')

        if not is_integer(precision) or precision <= 0 or precision > 6:
            raise ValueError(
                'precision must be a positive integer > 0 and <= 6')

        if not is_integer(sale_start) or sale_start < START_DATE:
            raise ValueError('Invalid sale start timestamp provided')

        if not is_integer(kwargs.get('saleEnd')) or \
                kwargs.get('saleEnd') <= sale_start:
            raise ValueError('Invalid sale end timestamp provided')

        if not is_string(kwargs.get('description')):
            raise ValueError('Invalid token description provided')

        if not is_valid_url(kwargs.get('url')):
            raise ValueError('Invalid token url provided')

        if not is_integer(free_bandwidth) or free_bandwidth < 0:
            raise ValueError('Invalid free bandwidth amount provided')

        if not is_integer(free_bandwidth_limit) or free_bandwidth_limit < 0 \
                or (free_bandwidth and not free_bandwidth_limit):
            raise ValueError('Invalid free bandwidth limit provided')

        if not is_integer(frozen_amount) or frozen_amount < 0 \
                or (not frozen_duration and frozen_amount):
            raise ValueError('Invalid frozen supply provided')

        if not is_integer(frozen_duration) or frozen_duration < 0 \
                or (frozen_duration and not frozen_amount):
            raise ValueError('Invalid frozen duration provided')

        frozen_supply = {
            'frozen_amount': int(frozen_amount),
            'frozen_days': int(frozen_duration)
        }

        response = self.tron.manager.request(
            '/wallet/createassetissue', {
                'owner_address': self.tron.address.to_hex(issuer_address),
                'name': self.tron.toHex(text=kwargs.get('name')),
                'abbr': self.tron.toHex(text=kwargs.get('abbreviation')),
                'description': self.tron.toHex(text=kwargs.get('description')),
                'url': self.tron.toHex(text=kwargs.get('url')),
                'total_supply': int(total_supply),
                'trx_num': int(trx_ratio),
                'num': int(token_ratio),
                'start_time': int(sale_start),
                'end_time': int(kwargs.get('saleEnd')),
                'free_asset_net_limit': int(free_bandwidth),
                'public_free_asset_net_limit': int(free_bandwidth_limit),
                'frozen_supply': frozen_supply,
                'vote_score': vote_score,
                'precision': precision
            })

        return response
コード例 #9
0
    def trigger_smart_contract(self, **kwargs):
        """Trigger Smart Contract
        Calls a function on a contract

        Args:
            **kwargs: Fill in the required parameters

        Examples:
            >>> tron = Tron()
            >>> tron.transaction_builder.trigger_smart_contract(
            >>>     contract_address='413c8143e98b3e2fe1b1a8fb82b34557505a752390',
            >>>     function_selector='set(uint256,uint256)',
            >>>     fee_limit=30000,
            >>>     call_value=0,
            >>>     parameters=[
            >>>        {'type': 'int256', 'value': 1},
            >>>        {'type': 'int256', 'value': 1}
    ]
)

        Returns:
            TransactionExtention, TransactionExtention contains unsigned Transaction
        """

        contract_address = kwargs.setdefault('contract_address', None)
        function_selector = kwargs.setdefault('function_selector', None)
        parameters = kwargs.setdefault('parameters', [])
        issuer_address = kwargs.setdefault('issuer_address',
                                           self.tron.default_address.hex)
        call_value = kwargs.setdefault('call_value', 0)
        fee_limit = kwargs.setdefault('fee_limit', 1000000000)
        token_value = kwargs.setdefault('token_value', 0)
        token_id = kwargs.setdefault('token_id', 0)

        if not is_integer(token_value) or token_value < 0:
            raise ValueError('Invalid options.tokenValue provided')

        if not is_integer(token_id) or token_id < 0:
            raise ValueError('Invalid options.tokenId provided')

        if not self.tron.isAddress(contract_address):
            raise InvalidAddress('Invalid contract address provided')

        if not is_string(function_selector):
            raise ValueError('Invalid function selector provided')

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

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

        function_selector = function_selector.replace('/\s*/g', '')

        if len(parameters) > 0:
            types = []
            values = []
            for abi in parameters:
                if 'type' not in abi or not is_string(abi['type']):
                    raise ValueError('Invalid parameter type provided: ' +
                                     abi['type'])

                if abi['type'] == 'address':
                    abi['value'] = self.tron.address.to_hex(
                        abi['value']).replace('41', '0x', 2)

                types.append(abi['type'])
                values.append(abi['value'])

            try:
                parameters = encode_hex(encode_abi(types, values)).replace(
                    '0x', '', 2)
            except ValueError as ex:
                print(ex)

        else:
            parameters = ''

        data = {
            'contract_address': self.tron.address.to_hex(contract_address),
            'owner_address': self.tron.address.to_hex(issuer_address),
            'function_selector': function_selector,
            'fee_limit': int(fee_limit),
            'call_value': int(call_value),
            'parameter': parameters
        }

        if token_value:
            data.call_token_value = int(token_value)

        if token_id:
            data.token_id = int(token_id)

        return self.tron.manager.request('/wallet/triggersmartcontract', data)
コード例 #10
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)
コード例 #11
0
    def trigger_smart_contract(self,
                               contract_address,
                               function_selector,
                               fee_limit: int = 1000000000,
                               call_value: int = 0,
                               parameters=None,
                               issuer_address=None):
        """Trigger Smart Contract (Beta Version)
        Calls a function on a contract

        Args:
            contract_address (str): Contract address, converted to a hex string
            function_selector (str): Function signature. No spaces.
            fee_limit (int): Maximum TRX consumption, measured in SUN(1TRX = 1,000,000SUN)
            call_value (int): Amount of TRX transferred with this transaction, measured in SUN(1TRX = 1,000,000SUN)
            parameters (any): Call the virtual machine format of the parameter [1, 2],
                                use the js tool provided by remix, convert the parameter array [1, 2]
                                called by the contract caller into
                                the parameter format required by the virtual machine.

            issuer_address (str): address that is trigger the contract

        Examples:
            >>> tron = Tron()
            >>> tron.transaction_builder.trigger_smart_contract(
            >>> '413c8143e98b3e2fe1b1a8fb82b34557505a752390',
            >>> 'set(uint256,uint256)',
            >>> 30000,
            >>> 0,
            >>> [
            >>>     {'type': 'int256', 'value': 1},
            >>>     {'type': 'int256', 'value': 1}
            >>> ])

        Returns:
            TransactionExtention, TransactionExtention contains unsigned Transaction
        """

        if parameters is None:
            parameters = []

        if issuer_address is None:
            issuer_address = self.tron.default_address.hex

        if not self.tron.isAddress(contract_address):
            raise InvalidAddress('Invalid contract address provided')

        if not is_string(function_selector):
            raise ValueError('Invalid function selector provided')

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

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

        if len(parameters) > 0:
            types = []
            values = []
            for abi in parameters:
                if 'type' not in abi or not is_string(abi['type']):
                    raise ValueError('Invalid parameter type provided: ' +
                                     abi['type'])

                if abi['type'] == 'address':
                    abi['value'] = self.tron.address.to_hex(
                        abi['value']).replace('41', '0x', 2)

                types.append(abi['type'])
                values.append(abi['value'])

            try:
                parameters = encode_hex(encode_abi(types, values)).replace(
                    '0x', '', 2)
            except ValueError as ex:
                print(ex)

        else:
            parameters = ''

        return self.tron.manager.request(
            '/wallet/triggersmartcontract', {
                'contract_address': self.tron.address.to_hex(contract_address),
                'owner_address': self.tron.address.to_hex(issuer_address),
                'function_selector': function_selector,
                'fee_limit': int(fee_limit),
                'call_value': int(call_value),
                'parameter': parameters
            })