Crear transacciones de tokens TRC20 en TRON
Introducción
Sección titulada «Introducción»Este tutorial cubre los endpoints TRC20 de la API Chaingateway V2: crear una dirección de TRON, leer un contrato de token, consultar un saldo de token y enviar una transferencia TRC20. Los ejemplos se dan en Shell (cURL), PHP (Guzzle), Python (Requests) y JavaScript (Axios).
Para obtener una clave de API y aprender sobre la autorización, consulte la sección Inicio rápido de la documentación de Chaingateway.
Qué hace la API y qué no hace
Sección titulada «Qué hace la API y qué no hace»La API no tiene ningún endpoint que compile o despliegue un smart contract. No hay ninguna ruta que publique un nuevo contrato TRC20 en la red de TRON, y ninguno de los endpoints de TRON acepta bytecode de contrato. Toda ruta TRC20 recibe un contractaddress de un token que ya existe on-chain, tanto USDT como cualquier otro token TRC20.
Si busca una forma de desplegar su propio contrato de token, esta API no es la herramienta para ese paso. Una vez desplegado el contrato, los endpoints siguientes cubren la parte que la mayoría de las integraciones realmente necesitan: direcciones, saldos, transferencias y notificaciones.
| Qué quiere hacer | Endpoint |
|---|---|
| Crear una dirección de TRON | POST /v2/tron/addresses |
| Importar una clave privada existente | POST /v2/tron/addresses/import |
| Leer nombre, símbolo, decimales y supply | GET /v2/tron/trc20/{contract_address} |
| Leer el saldo de un token | GET /v2/tron/balances/{address}/trc20/{contract_address} |
| Enviar una transferencia TRC20 | POST /v2/tron/transactions/trc20 |
| Construir una transferencia sin emitirla | POST /v2/tron/transactions/trc20/build |
| Emitir una transacción que usted firmó | POST /v2/tron/transactions/broadcast |
| Recibir notificaciones de tokens entrantes | POST /v2/tron/webhooks |
Paso 1: crear una dirección de TRON
Sección titulada «Paso 1: crear una dirección de TRON»La dirección emisora tiene que ser conocida por Chaingateway. Créela a través de la API o importe una clave privada existente mediante POST /v2/tron/addresses/import.
Si envía un password, la clave privada se guarda cifrada y firma las transacciones posteriores con esa contraseña. Si omite la contraseña, la respuesta contiene la propia clave privada y debe enviarla con cada solicitud de transacción. El enfoque con contraseña se describe en detalle en Gestión de wallets.
curl --request POST\ --url https://api.chaingateway.io/v2/tron/addresses\ --header 'Accept: application/json'\ --header 'content-type: application/json'\ --header 'Authorization: YOUR_API_TOKEN'\ --data '{"password":"test123"}'import requests
url = "https://api.chaingateway.io/v2/tron/addresses"payload = {"password": "test123"}headers = { 'Accept': 'application/json', 'content-type': 'application/json', 'Authorization': 'YOUR_API_TOKEN'}
response = requests.post(url, json=payload, headers=headers)print(response.json())const axios = require('axios');
const url = 'https://api.chaingateway.io/v2/tron/addresses';const payload = { password: 'test123' };const headers = { 'Accept': 'application/json', 'content-type': 'application/json', 'Authorization': 'YOUR_API_TOKEN'};
axios.post(url, payload, { headers }) .then(response => { console.log(response.data); }) .catch(error => { console.error(error); });<?phprequire 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();$response = $client->post('https://api.chaingateway.io/v2/tron/addresses', [ 'headers' => [ 'Accept' => 'application/json', 'content-type' => 'application/json', 'Authorization' => 'YOUR_API_TOKEN', ], 'json' => [ 'password' => 'test123' ]]);
echo $response->getBody();?>La respuesta lleva la nueva dirección:
{ "status": 201, "ok": true, "message": "Address created", "data": [ { "privateKey": "59f1c6200e01a2ca9471411f10198bfa63678d0e87cc2ca30f9c4a68dee78edc", "publicKey": "040fe6e677442c36f7fdd5535ba3ff1cef0110d78363420f7e24b65298990e3467aed68b9a67e1396d84753db25b32a2fa3e1fc0a673f01638e9bcfab2d8f4ceb5", "hexAddress": "41a56a6505ffbee78eb916dd44f4846874deddaebd", "address": "TR3qx91smURF3R455V1ubqtoUsZbgqikfg" } ]}Chaingateway no almacena contraseñas. Una contraseña perdida es una wallet perdida.
Paso 2: leer el contrato del token
Sección titulada «Paso 2: leer el contrato del token»Antes de mover un token, lea su contrato. El valor decimals es el que necesitará con más frecuencia, porque indica cómo se traduce el saldo bruto on-chain al importe que ve un usuario.
curl --request GET\ --url https://api.chaingateway.io/v2/tron/trc20/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t\ --header 'Accept: application/json'\ --header 'Authorization: YOUR_API_TOKEN'{ "status": 200, "ok": true, "message": "TRC20 contract fetched", "data": { "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "symbol": "USDT", "name": "TetherUSD", "totalSupply": "61742996582033118", "decimals": "6" }}Una dirección de contrato desconocida o que no es TRC20 responde con estado 400 y el mensaje Error fetching TRC20 contract.
Paso 3: consultar el saldo del token
Sección titulada «Paso 3: consultar el saldo del token»curl --request GET\ --url https://api.chaingateway.io/v2/tron/balances/TVF2Mp9QY7FEGTnr3DBpFLobA6jguHyMvi/trc20/TXLAQ63Xg1NAzckPwKHvzw7CSEmLMEqcdj\ --header 'Accept: application/json'\ --header 'Authorization: YOUR_API_TOKEN'{ "status": 200, "ok": true, "message": "TRC20 balance fetched", "data": { "tronaddress": "TVF2Mp9QY7FEGTnr3DBpFLobA6jguHyMvi", "decimals": 6, "balance": "1000000000000000000", "contractaddress": "TXLAQ63Xg1NAzckPwKHvzw7CSEmLMEqcdj" }}El campo balance es el valor entero en bruto. Divídalo entre 10 elevado a decimals para obtener el importe legible.
Paso 4: enviar la transferencia TRC20
Sección titulada «Paso 4: enviar la transferencia TRC20»POST /v2/tron/transactions/trc20 requiere from, to, contractaddress y amount. Para firmar, añada password, si la dirección se creó con contraseña, o privatekey para una dirección no protegida o importada.
Parámetros
Sección titulada «Parámetros»- from: la dirección de TRON del remitente.
- to: la dirección de TRON del destinatario.
- contractaddress: la dirección del contrato del token.
- amount: el importe a enviar.
- password: la contraseña de una dirección de Chaingateway protegida con contraseña. Obligatoria cuando no se envía
privatekey. - privatekey: la clave privada del remitente, para direcciones creadas o importadas sin contraseña.
curl --request POST\ --url https://api.chaingateway.io/v2/tron/transactions/trc20\ --header 'Accept: application/json'\ --header 'content-type: application/json'\ --header 'Authorization: YOUR_API_TOKEN'\ --data '{ "from": "TLkkCeNdJKPNUwucdro84WjswkzM62LCTH", "to": "TUwmZghA7u2GxGxKaxM1mkCmsTF4wHs4vp", "contractaddress": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "amount": 1, "password": "test123"}'import requests
url = "https://api.chaingateway.io/v2/tron/transactions/trc20"payload = { "from": "TLkkCeNdJKPNUwucdro84WjswkzM62LCTH", "to": "TUwmZghA7u2GxGxKaxM1mkCmsTF4wHs4vp", "contractaddress": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "amount": 1, "password": "test123"}headers = { 'Accept': 'application/json', 'content-type': 'application/json', 'Authorization': 'YOUR_API_TOKEN'}
response = requests.post(url, json=payload, headers=headers)print(response.json())const axios = require('axios');
const url = 'https://api.chaingateway.io/v2/tron/transactions/trc20';const payload = { from: 'TLkkCeNdJKPNUwucdro84WjswkzM62LCTH', to: 'TUwmZghA7u2GxGxKaxM1mkCmsTF4wHs4vp', contractaddress: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', amount: 1, password: 'test123'};const headers = { 'Accept': 'application/json', 'content-type': 'application/json', 'Authorization': 'YOUR_API_TOKEN'};
axios.post(url, payload, { headers }) .then(response => { console.log(response.data); }) .catch(error => { console.error(error); });<?phprequire 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();$response = $client->post('https://api.chaingateway.io/v2/tron/transactions/trc20', [ 'headers' => [ 'Accept' => 'application/json', 'content-type' => 'application/json', 'Authorization' => 'YOUR_API_TOKEN', ], 'json' => [ 'from' => 'TLkkCeNdJKPNUwucdro84WjswkzM62LCTH', 'to' => 'TUwmZghA7u2GxGxKaxM1mkCmsTF4wHs4vp', 'contractaddress' => 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', 'amount' => 1, 'password' => 'test123' ]]);
echo $response->getBody();?>Una llamada correcta responde con el hash de la transacción:
{ "status": 201, "ok": true, "message": "Succesfully created transaction", "data": { "txid": "0x73344d178812d4919e9002c560781f288030edf72ece88823ef1c377dfb71f27" }}Dos errores vuelven con estado 422 y merece la pena tratarlos por separado. balance is not sufficient significa que la dirección emisora no puede pagar la transacción. Un mensaje Validate signature error significa que la clave o la contraseña no coinciden con la dirección from.
La wallet emisora necesita TRX
Sección titulada «La wallet emisora necesita TRX»Una transferencia TRC20 es una llamada a un smart contract, y TRON cobra energy y bandwidth por ella. Una dirección que solo tiene tokens no puede enviarlos. O bien financia la dirección con TRX, hace staking para obtener recursos mediante POST /v2/tron/freeze y POST /v2/tron/delegate, o deja que la comisión se patrocine. El patrocinio de comisiones se describe en Patrocinar comisiones de TRC20.
Firmar la transacción usted mismo
Sección titulada «Firmar la transacción usted mismo»Si prefiere mantener la clave privada fuera de la solicitud, divida la transferencia en dos llamadas. POST /v2/tron/transactions/trc20/build devuelve el hex de la transacción en bruto sin emitirla. Usted firma ese hex en su propio código y entrega la transacción firmada a POST /v2/tron/transactions/broadcast.
curl --request POST\ --url https://api.chaingateway.io/v2/tron/transactions/trc20/build\ --header 'Accept: application/json'\ --header 'content-type: application/json'\ --header 'Authorization: YOUR_API_TOKEN'\ --data '{ "from": "TLkkCeNdJKPNUwucdro84WjswkzM62LCTH", "to": "TUwmZghA7u2GxGxKaxM1mkCmsTF4wHs4vp", "contractaddress": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "amount": 1}'La respuesta contiene raw_data y raw_data_hex. En este punto nada ha llegado todavía a la red.
Recibir notificaciones de tokens entrantes
Sección titulada «Recibir notificaciones de tokens entrantes»Para conocer un depósito TRC20 sin hacer polling, suscriba un webhook con type en TRC20 y el contractaddress del token. Los filtros from y to lo acotan a una sola dirección.
curl --request POST\ --url https://api.chaingateway.io/v2/tron/webhooks\ --header 'Accept: application/json'\ --header 'content-type: application/json'\ --header 'Authorization: YOUR_API_TOKEN'\ --data '{ "url": "https://example.com/webhook-receiver", "type": "TRC20", "contractaddress": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "to": "TUwmZghA7u2GxGxKaxM1mkCmsTF4wHs4vp"}'Escribir el extremo receptor se cubre en Crear webhooks, y verificar que una notificación realmente vino de Chaingateway en Proteger los webhooks.
Una notificación que su servidor no aceptó no se reenvía sola. Las notificaciones fallidas se listan en GET /v2/tron/webhooks/notifications/failed y se pueden volver a disparar con POST /v2/tron/webhooks/notifications/{id}/retry.
Pruebas en Nile
Sección titulada «Pruebas en Nile»Todas las llamadas anteriores funcionan contra la testnet Nile de TRON. Añada la cabecera X-Network: testnet y use tokens de prueba en lugar de contratos de mainnet. La lista de redes está documentada en Redes compatibles.