tronweb SDK
TronWeb là SDK JavaScript tiêu chuẩn và mang tính đại diện nhất để tương tác với blockchain TRON, cung cấp một giao diện thống nhất cho việc quản lý tài khoản, ký giao dịch và tương tác với Hợp đồng. Tài liệu tham khảo toàn diện này bao gồm quá trình khởi tạo, các tiện ích cốt lõi và các mẫu thiết kế nâng cao để xây dựng các ứng dụng frontend và backend mạnh mẽ.
Kiến trúc SDK
Phần tiêu đề “Kiến trúc SDK”TronWeb là SDK JavaScript chính thức, chuẩn mực dành cho blockchain TRON. Mặc dù các nhà phát triển đến từ Ethereum sẽ thấy cú pháp Solidity quen thuộc, nhưng các mô hình trạng thái và tài nguyên cơ bản của mạng lưới là độc nhất. TronWeb được kiến trúc riêng để tận dụng cơ chế của TRON, cung cấp các giao diện nội bộ nhằm quản lý Năng lượng và Băng thông, tương tác với cả token TRC-10 và token tương thích EVM, đồng thời dẫn xuất các địa chỉ bắt đầu bằng tiền tố T.
Cho dù bạn đang xây dựng một dApp chạy trên trình duyệt với Ví TronLink hay một dịch vụ backend hiệu suất cao trên Node.js, TronWeb luôn đóng vai trò là cây cầu nối chính giữa logic ứng dụng của bạn và các node của mạng lưới.
Cài đặt
Phần tiêu đề “Cài đặt”# Task: Cài đặt SDK JavaScript chính thức của TRON.npm install tronwebtronweb hoạt động tốt trong Node.js (CommonJS và ESM) cũng như trên trình duyệt. Các kiểu (types) của TypeScript đã được đính kèm sẵn.
Khởi tạo
Phần tiêu đề “Khởi tạo”// Task: Khởi tạo TronWeb cho mainnet bằng cách sử dụng một private key.import TronWeb from "tronweb"
// Bằng một private key (phía máy chủ / tập lệnh)const tronWeb = new TronWeb({ fullHost: 'https://api.trongrid.io', // mainnet privateKey: process.env.PRIVATE_KEY,});
// Chỉ đọc (không có private key — chỉ dành cho việc truy vấn)const tronWebReadOnly = new TronWeb({ fullHost: 'https://api.trongrid.io',});Các Endpoint TronGrid
Phần tiêu đề “Các Endpoint TronGrid”| Mạng lưới | fullHost |
|---|---|
| Mainnet | https://api.trongrid.io |
| Nile testnet | https://nile.trongrid.io |
| Shasta testnet | https://api.shasta.trongrid.io |
TronGrid yêu cầu một Khóa API để sử dụng trong sản xuất (production) vượt quá mức giới hạn tỷ lệ (rate limit) của bậc miễn phí. Hãy thiết lập nó:
// Task: Cấu hình TronWeb với Khóa Pro API của TronGrid.const tronWeb = new TronWeb({ fullHost: 'https://api.trongrid.io', headers: { 'TRON-PRO-API-KEY': process.env.TRONGRID_API_KEY }, privateKey: process.env.PRIVATE_KEY,});Tiện ích Địa chỉ
Phần tiêu đề “Tiện ích Địa chỉ”// Task: Xác thực các địa chỉ và chuyển đổi qua lại giữa định dạng Hex/Base58.// Kiểm tra xem một địa chỉ có hợp lệ khôngtronWeb.isAddress('TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb2Jq'); // true
// Chuyển đổi địa chỉ hex sang Base58 (tiền tố T)const base58 = tronWeb.address.fromHex('41e552f6487585c2b58bc2c9bb4492bc1f17132cd0');// → 'TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb2Jq'
// Chuyển đổi Base58 sang hexconst hex = tronWeb.address.toHex('TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb2Jq');// → '41e552f6487585c2b58bc2c9bb4492bc1f17132cd0'
// Dẫn xuất địa chỉ từ private keyconst address = tronWeb.address.fromPrivateKey(process.env.PRIVATE_KEY);Tài khoản và Số dư
Phần tiêu đề “Tài khoản và Số dư”// Task: Truy vấn số dư TRX của tài khoản và các tài nguyên Năng lượng/Băng thông.// Số dư TRX (trả về dưới dạng SUN — chia cho 1,000,000 để tính ra TRX)const balanceSun = await tronWeb.trx.getBalance('TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb2Jq');const balanceTRX = balanceSun / 1_000_000;
// Toàn bộ thông tin tài khoản (số dư, tài nguyên, các lượng đóng băng, quyền hạn)const account = await tronWeb.trx.getAccount('TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb2Jq');
// Thông tin tài nguyên tài khoản (Số dư và hạn mức Năng lượng, Băng thông)const resources = await tronWeb.trx.getAccountResources('TN3W4H6rK2...');console.log(resources.EnergyLimit); // tổng Năng lượng khả dụngconsole.log(resources.EnergyUsed); // Năng lượng đã tiêu thụ trong kỳ nàyconsole.log(resources.NetLimit); // tổng Băng thông khả dụngconsole.log(resources.freeNetUsed); // Băng thông miễn phí đã tiêu thụ trong ngàyGửi TRX
Phần tiêu đề “Gửi TRX”// Task: Chuyển khoản token TRX gốc cho một địa chỉ khác.// Gửi TRX — số lượng tính bằng SUN (1 TRX = 1,000,000 SUN)const tx = await tronWeb.trx.sendTransaction( 'TRecipientAddress...', // gửi tới đâu 10_000_000, // số lượng: 10 TRX);console.log(tx.txid); // hàm băm giao dịch (transaction hash)Tương tác Hợp đồng
Phần tiêu đề “Tương tác Hợp đồng”Tải một Hợp đồng Đã triển khai
Phần tiêu đề “Tải một Hợp đồng Đã triển khai”// Task: Tải một instance Hợp đồng bằng cách sử dụng địa chỉ và ABI tùy chọn của nó.// Tải Hợp đồng thông qua địa chỉ (nạp ABI từ chuỗi nếu nó đã được xác thực)const contract = await tronWeb.contract().at('TContractAddress...');
// Hoặc truyền thẳng ABI một cách rõ ràng (nhanh hơn, có thể dùng cho Hợp đồng chưa được xác minh)const abi = [ /* mảng ABI */ ];const contractExplicit = tronWeb.contract(abi, 'TContractAddress...');Gọi Các Hàm View (miễn phí)
Phần tiêu đề “Gọi Các Hàm View (miễn phí)”Các hàm View và Pure không tốn Năng lượng khi được gọi off-chain:
// Task: Thực thi lệnh gọi phương thức chỉ đọc mà không tạo ra một giao dịch nào.// .call() dành cho các hàm chỉ đọc — không có giao dịch, không mất phíconst result = await contract.balanceOf('TUserAddress...').call();console.log(result.toString()); // Số lớn (BigNumber)Phát Đi Giao dịch (làm thay đổi trạng thái)
Phần tiêu đề “Phát Đi Giao dịch (làm thay đổi trạng thái)”// Task: Tạo và gửi một giao dịch cho một phương thức làm thay đổi trạng thái.// .send() dành cho các hàm thay đổi trạng thái — tạo ra một giao dịchconst txId = await contract.transfer('TRecipient...', 1_000_000).send({ feeLimit: 1_000_000_000, // mức TRX tối đa để đốt nếu không có Năng lượng (tính bằng SUN) callValue: 0, // lượng TRX để gửi kèm cuộc gọi (tính bằng SUN), thường là 0 shouldPollResponse: true, // đợi xác nhận trước khi trả về});console.log(txId); // hàm băm giao dịchChuyển Tham số Hàm tạo (Constructor) Khi Triển khai
Phần tiêu đề “Chuyển Tham số Hàm tạo (Constructor) Khi Triển khai”// Task: Triển khai một Hợp đồng thông minh mới thông qua ABI và bytecode.const deployed = await tronWeb.contract().new({ abi: compiledAbi, bytecode: compiledBytecode, feeLimit: 1_000_000_000, parameters: [constructorArg1, constructorArg2],});console.log(deployed.address);Thao tác Hợp đồng TRC-20
Phần tiêu đề “Thao tác Hợp đồng TRC-20”// Task: Thực hiện các kiểm tra số dư và chuyển khoản TRC-20 chuẩn.const usdtAddress = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'; // USDT trên mainnet
const usdt = await tronWeb.contract().at(usdtAddress);
// Số dư (trả về dưới dạng đơn vị nhỏ nhất của token — USDT dùng 6 số thập phân)const balance = await usdt.balanceOf('TYourAddress...').call();const usdtAmount = balance / 1_000_000;
// Chuyển khoảnawait usdt.transfer('TRecipient...', 5_000_000).send({ feeLimit: 1_000_000_000, shouldPollResponse: true,});
// Phê duyệtawait usdt.approve('TSpenderContract...', 1_000_000_000).send({ feeLimit: 100_000_000,});Lắng nghe Sự kiện
Phần tiêu đề “Lắng nghe Sự kiện”// Task: Theo dõi Sự kiện Transfer (Chuyển khoản) theo thời gian thực trên một Hợp đồng.const contract = await tronWeb.contract().at('TContractAddress...');
// Lắng nghe tất cả các Sự kiện Transfer trên một hợp đồng TRC-20contract.Transfer().watch((err, event) => { if (err) return console.error(err); console.log('Chuyển khoản:', { from: event.result.from, to: event.result.to, value: event.result.value.toString(), txId: event.transaction, });});Trạng thái Giao dịch
Phần tiêu đề “Trạng thái Giao dịch”// Task: Lấy các biên lai giao dịch và dữ liệu tiêu thụ Năng lượng.// Lấy thông tin giao dịch (bao gồm lượng Năng lượng đã tiêu thụ, kết quả, khối)const info = await tronWeb.trx.getTransactionInfo('txHashHere...');console.log(info.receipt.result); // 'SUCCESS' (THÀNH CÔNG) hoặc 'FAILED' (THẤT BẠI)console.log(info.receipt.energy_usage); // Năng lượng đã tiêu thụ
// Lấy giao dịch dạng thô (raw)const tx = await tronWeb.trx.getTransaction('txHashHere...');Xử lý Lỗi
Phần tiêu đề “Xử lý Lỗi”tronweb sẽ ném ngoại lệ hoặc trả về (rejects) các đối tượng lỗi có bao gồm trường message. Hãy bọc các lệnh gọi bằng try/catch:
// Task: Bắt lỗi và phân tích các lỗi từ SDK cũng như các lần Hợp đồng bị hoàn tác (reverts).try { const tx = await contract.someMethod().send({ feeLimit: 100_000_000 });} catch (err) { if (err.includes('REVERT')) { // Hợp đồng bị hoàn tác — hãy kiểm tra lại các đầu vào và giới hạn Năng lượng của bạn } if (err.includes('bandwith')) { // lưu ý: tronweb viết thiếu chữ 'd' // Không đủ Băng thông } console.error(err);}Sử dụng tronweb trong dApp trên Trình duyệt
Phần tiêu đề “Sử dụng tronweb trong dApp trên Trình duyệt”Khi xây dựng một dApp hoạt động trên trình duyệt, hãy dùng biến window.tronWeb được TronLink tiêm vào thay vì tự mình khởi tạo biến tronweb. Việc này sẽ tự động sử dụng ví đã kết nối của người dùng mà không làm lộ private key:
// Task: Kết nối tới phiên bản TronLink được tiêm sẵn của người dùng.if (typeof window.tronWeb === 'undefined') { alert('TronLink chưa được cài đặt.'); return;}
const tronWeb = window.tronWeb;
// Kiểm tra xem người dùng đã phê duyệt kết nối chưaif (!tronWeb.defaultAddress.base58) { // Người dùng chưa kết nối ví của họ với dApp của bạn}
const userAddress = tronWeb.defaultAddress.base58;const contract = await tronWeb.contract().at('TContractAddress...');Đối tượng window.tronWeb được tiêm sẵn đã được định cấu hình chung với tài khoản của người dùng, giúp ký các giao dịch thông qua tiện ích mở rộng Ví TronLink mà không cần dApp của bạn phải trực tiếp nhìn thấy private key.