Created
February 28, 2020 18:14
-
-
Save andelf/7c2b6b176872ff0e83086828e6f16d2b to your computer and use it in GitHub Desktop.
Get TRC20 balance and Transfer TRC20 tokens
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import base58 | |
import base64 | |
from pprint import pprint | |
ADDRESS = "T....your address" | |
PRIV_KEY = 'hex private key' | |
CONTRACT = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" # USDT | |
CONTRACT = "T,,,,,,,,,,,,,,,,,,,,,,ia" | |
API_URL_BASE = 'https://api.trongrid.io/' | |
# API_URL_BASE = 'https://api.shasta.trongrid.io/' | |
# API_URL_BASE = 'https://api.nileex.io/' | |
# 70a08231: balanceOf(address) | |
METHOD_BALANCE_OF = 'balanceOf(address)' | |
# a9059cbb: transfer(address,uint256) | |
METHOD_TRANSFER = 'transfer(address,uint256)' | |
DEFAULT_FEE_LIMIT = 1_000_000 # 1 TRX | |
def address_to_parameter(addr): | |
return "0" * 24 + base58.b58decode_check(addr)[1:].hex() | |
def amount_to_parameter(amount): | |
return '%064x' % amount | |
def get_balance(address=ADDRESS): | |
url = API_URL_BASE + 'wallet/triggerconstantcontract' | |
payload = { | |
'owner_address': base58.b58decode_check(ADDRESS).hex(), | |
'contract_address': base58.b58decode_check(CONTRACT).hex(), | |
'function_selector': METHOD_BALANCE_OF, | |
'parameter': address_to_parameter(address), | |
} | |
resp = requests.post(url, json=payload) | |
data = resp.json() | |
if data['result'].get('result', None): | |
print(data['constant_result']) | |
val = data['constant_result'][0] | |
print('balance =', int(val, 16)) | |
else: | |
print('error:', bytes.fromhex(data['result']['message']).decode()) | |
def get_trc20_transaction(to, amount, memo=''): | |
url = API_URL_BASE + 'wallet/triggersmartcontract' | |
payload = { | |
'owner_address': base58.b58decode_check(ADDRESS).hex(), | |
'contract_address': base58.b58decode_check(CONTRACT).hex(), | |
'function_selector': METHOD_TRANSFER, | |
'parameter': address_to_parameter(to) + amount_to_parameter(amount), | |
"fee_limit": DEFAULT_FEE_LIMIT, | |
'extra_data': base64.b64encode(memo.encode()).decode(), # TODO: not supported yet | |
} | |
resp = requests.post(url, json=payload) | |
data = resp.json() | |
if data['result'].get('result', None): | |
transaction = data['transaction'] | |
return transaction | |
else: | |
print('error:', bytes.fromhex(data['result']['message']).decode()) | |
raise RuntimeError | |
def sign_transaction(transaction, private_key=PRIV_KEY): | |
url = API_URL_BASE + 'wallet/addtransactionsign' | |
payload = {'transaction': transaction, 'privateKey': private_key} | |
resp = requests.post(url, json=payload) | |
data = resp.json() | |
if 'Error' in data: | |
print('error:', data) | |
raise RuntimeError | |
return data | |
def broadcast_transaction(transaction): | |
url = API_URL_BASE + 'wallet/broadcasttransaction' | |
resp = requests.post(url, json=transaction) | |
data = resp.json() | |
print(data) | |
def transfer(to, amount, memo=''): | |
transaction = get_trc20_transaction(to, amount, memo) | |
pprint(transaction) | |
transaction = sign_transaction(transaction) | |
broadcast_transaction(transaction) | |
get_balance() | |
transfer('T..............q', 5_000, 'test from python') |
Hiii @ikamran, to further buttress what my Boss @andelf posted. Let's presume you want to transfer USDT (a trc20 contract). There are 3 basic steps:
- Create transaction
- Sign transaction (Offline)
- Broadcast transaction to the network
Create
Use the get_trc20_transaction
function in @andelf's initial gist above to Create your transaction
Sign Transaction
from tronpy.keys import PrivateKey
def sign_transaction_offine(self, transaction_object, your_tron_private_key):
# CONVERT PRIVATE KEY TO BYTES
private_key_bytes = bytes.fromhex(your_tron_private_key)
# CONVERT INITIATED TRANSACTION ID TO BYTES
transaction_id_bytes = bytes.fromhex(transaction_object["txID"]
# SIGN TRANSACTION
data = PrivateKey(private_key_bytes=private_key_bytes).sign_msg_hash(transaction_id_bytes))
return data
Broadcast
Use the broadcast_transaction
function in @andelf's initial gist to Broadcast the transaction to the network
Thanks for your help, according to your last email I already did it successfully without any issue the issue comes when I want to send from a multi-signiture address
from tronpy import Tron
from tronpy.keys import PrivateKey
client = Tron(network='nile', conf={'fee_limit': 10_000_000})
priv_key = PrivateKey(bytes.fromhex("e5f4a4acb3ecef9e8589d69c1aa9fa5723b04ff724b1c04ebe6cd746b241ad04"))
contractAddress = 'TLBaRhANQoJFTqre9Nf1mjuwNWjCJeYqUL'
myAddress = 'TGihHToJJ9B1NFi2Vx5bTM8muRmsbdAaJ8'
contract = client.get_contract(contractAddress)
oneUSDJ = 1_000_000_000_000_000_000
class Tron:
def __init__(self):
self.contract = contract
self.myAdd = myAddress
def getTokenBalance(self):
return contract.functions.balanceOf(myAddress) / 10 ** 6
def getBalance(self, address):
return client.get_account_balance(address)
def getAccount(self, address):
return client.get_account(address)
def sendTRX(self, accountAddress):
txn = (
client.trx.transfer(myAddress, accountAddress, 100_000_000)
.with_owner(myAddress)
.permission_id(2)
.build()
.sign(priv_key)
)
print(txn.txid)
print(txn.broadcast().wait())
return txn
tron = Tron()
I included permission_id but I got this error:
>>> tron.sendTRX('TC2r7dPEfMaMt8ToJ3rQ7SuVhX391cFhv5')
{'address': '414a0a401872a17daf91e753226e8981e434e97452', 'weight': 1}
a6c802ca8cbfd1562e6203a43437b98f30aef7b09f2d968be213afe56746c864
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\itk\dev\test\tronpy\example1.py", line 38, in sendTRX
print(txn.broadcast().wait())
File "C:\Users\itk\dev\test\venv\lib\site-packages\tronpy\tron.py", line 154, in broadcast
return TransactionRet(self._client. Broadcast(self), client=self._client, method=self._method)
File "C:\Users\itk\dev\test\venv\lib\site-packages\tronpy\tron.py", line 827, in broadcast
self._handle_api_error(payload)
File "C:\Users\itk\dev\test\venv\lib\site-packages\tronpy\tron.py", line 467, in _handle_api_error
raise BadSignature(msg)
tronpy.exceptions.BadSignature: Validate signature error: sig error
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://tronpy.readthedocs.io/en/latest/contract.html#trigger-call