I'd like to get the balance of a TRC20 token (in this case the WIN token) for a Tron wallet address that owns WIN tokens.
I'm using the Python module tron-api-python and based on what i've read on GitHub and the docs the code for that should look something like this:
from tronapi import Tron
# Source for ABI: https://tronscan.org/#/token20/TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7/code
contract_abi = '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"addMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"decimals","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]'
tron = Tron()
contract = tron.trx.contract("TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7", abi=contract_abi)
balance = contract.functions.balanceOf("TXRZqGMEXsGTX6AQtcSgYknos93hqw18P7")
print(balance)
But the result i get is:
eth_abi.exceptions.NoEntriesFound: No matching entries for 'address' in encoder registry
You can use this API:
import requests
import json
def get_balance(address, token_symbol):
url = "https://apilist.tronscan.org/api/account"
payload = {
"address": address,
}
res = requests.get(url, params=payload)
trc20token_balances = json.loads(res.text)["trc20token_balances"]
token_balance = next((item for item in trc20token_balances if item["symbol"] == token_symbol), None)
if token_balance == None:
return 0
else:
return int(token_balance["balance"])
The previous response broadcasts a transaction to read a constant function; you don't need to do that if you're only going to read the balance.
Found it myself. This is not the code to get the balance but to send the WIN token so for this to return the balance the function_selector and the parameters would need to change but the rest should be fine since both is based on triggering a smart contract.
tron_kwargs = dict()
tron_kwargs["private_key"] = your_privkey
tron_kwargs["default_address"] = your_base58_address
tron = Tron(**tron_kwargs)
kwargs = dict()
kwargs["contract_address"] = tron.address.to_hex(wink_base58_contract_address)
kwargs["function_selector"] = "transfer(address,uint256)"
kwargs["fee_limit"] = 100000
kwargs["call_value"] = 0
kwargs["parameters"] = [
{
'type': 'address',
'value': tron.address.to_hex(recipients_base58_address)
},
{
'type': 'uint256',
'value': 8000000
}
]
raw_tx = tron.transaction_builder.trigger_smart_contract(**kwargs)
sign = tron.trx.sign(raw_tx["transaction"])
result = tron.trx.broadcast(sign)
Looking for some advice customizing requests for json style syntax.
json.dumps will format the like this:
{"tenantid": 1, "name": "NewRoleName", "users": "[djones]"}
But the servers wants something like this:
{"tenantid": 1, "name": "NewRoleName", "users": ["djones"]}
Any easy way to manipulate the double quotes to be placed with in the square brackets?
payload = {}
funcURL = "roles"
if name is not None: payload.update({'name': name})
if userStore is not None: payload.update({'userStore': userStore})
if users is not None: payload.update({'users': "[" + users + "]"})
if tenantid is not None: payload.update({'tenantid': tenantid})
if permissions is not None: payload.update({'userClaims': permissions})
print users
print payload
payload = json.dumps(payload)
return self._call_url('POST', funcURL, payload)
_call_url uses requests to send the payload out:
response = requests.request( methodType, baseURL + "/" + funcURL, data=payload, headers=self.headers, timeout=timeout, verify=False)
Have you tried:
if users is not None: payload.update({'users': users})
This should work if users is something like users = ["djones","mjones","todd"]
The square brackets denote a list. So you have to put users into a list:
funcURL = "roles"
payload = {}
if name is not None:
payload['name'] = name
if userStore is not None:
payload['userStore'] = userStore
if users is not None:
payload['users'] = [users]
if tenantid is not None:
payload['tenantid'] = tenantid
if permissions is not None:
payload['userClaims'] = permissions
payload = json.dumps(payload)
return self._call_url('POST', funcURL, payload)