Gọi get-method bất kỳ của contract TON mà không cần SDK
Cách gọi mọi get-method của contract TON qua run_get_method mà không cần SDK: seqno, get_jetton_data, get_sale_data, tham số, exit_code và cách đọc stack.
Bạn mở explorer chỉ để xem seqno của ví trước khi gửi một giao dịch. Hoặc bạn cần total_supply của một jetton. Hoặc dữ liệu listing NFT trên marketplace. Thế là bạn lại ngồi npm i @ton/ton, dựng TonClient, đi mò một endpoint liteserver còn sống, vật lộn xem phải đóng gói địa chỉ vào beginCell().storeAddress() thế nào, xong còn tự tay parse cái BOC trả về. Ba mươi dòng code — chỉ để lấy đúng một con số mà contract vốn đã cho không.
Vấn đề không nằm ở TON. Vấn đề là giữa bạn và một lời gọi read-only đơn giản lại chắn nguyên một tầng SDK — thứ phải cài, phải cấu hình, rồi phải cầu cho nó đừng gãy ở bản cập nhật kế tiếp. Còn nếu bạn đang nối một AI agent (Claude, Cursor, ChatGPT/Codex) vào TON thì viết tay cái tầng đó là chuyện vô lý: agent chỉ cần gọi method là xong.
Dưới đây là cách gọi mọi get-method của contract TON qua run_get_method, không cần một dòng SDK client nào.
Get-method của contract TON là gì và vì sao gọi nó người ta thường phải lôi SDK vào
Get-method là một hàm read-only của smart contract. Ví có seqno, master contract của jetton có get_jetton_data, contract bán NFT có get_sale_data, còn pool STON.fi/DeDust có get_pool_data. Từ khóa quan trọng ở đây là read-only:
- method không thay đổi gì trong state của contract;
- nó không cần chữ ký và không tiêu gas của người dùng;
- nó chạy trên liteserver hoặc trong emulator TVM (TON Virtual Machine), chứ không phải bằng cách gửi một giao dịch.
Tức là gọi một get-method không phải là giao dịch. Chẳng có gì để ký, chẳng có gì để trả phí, chẳng phải chờ block nào cả. Về bản chất đó là hàm "đọc giá trị từ một contract đang sống".
Nhưng để gọi nó theo "kiểu cũ", bạn cần cả một bộ đồ nghề: SDK (ton, tonweb, tonutils), một ADNL client riêng nối tới liteserver hoặc một lớp bọc HTTP kiểu toncenter, rồi tự tay đóng gói tham số đầu vào thành cell và tự tay bóc cái BOC trả về. Quá nhiều mắt xích chỉ để đọc một giá trị. Và mắt xích nào cũng là một điểm gãy: các liteserver công khai trong global config là của chung và bị giới hạn, khi tải cao chúng trả về not ready hoặc timeout ADNL; còn các HTTP API công khai khi vượt hạn mức sẽ trả về 429 Too Many Requests (không có key thì tầm một request mỗi giây).
run_get_method: một tool cho mọi method read-only của mọi contract
run_get_method là một tool MCP gọi được mọi get-method read-only của mọi contract TON. Bạn truyền vào địa chỉ contract, tên method và danh sách tham số — tool sẽ chạy method on-chain qua TVM rồi trả về stack đầu ra.
Còn những thứ bạn không cần tới:
- cài và nâng cấp SDK (
ton/tonweb/tonutils); - tự viết ADNL client;
- tự tay đóng gói tham số thành cell và parse BOC ở đầu ra.
run_get_method nằm trong bộ công cụ đọc của TONNode — MCP server hosted dành cho TON. MCP (Model Context Protocol) là chuẩn để các AI agent gọi tool. Cả bộ công cụ đọc này dùng được miễn phí ở local qua npx -y @tonnode/mcp (config công khai, không cần thẻ), hoặc qua endpoint hosted https://mcp.tonnode.io/mcp với Bearer key. Bạn có thể thử ngay bây giờ mà không phải mua gì cả.
Tham số và stack: truyền đầu vào và đọc đầu ra của TVM
TVM làm việc với stack. Hình dung thế này: bạn đặt lên bàn vài "tấm thẻ" ghi giá trị đầu vào, method nhặt chúng lên, xử lý, rồi đặt trả lại những "tấm thẻ" ghi kết quả.
Đầu vào được truyền dưới dạng các giá trị đẩy lên stack TVM. Thường là:
int— số nguyên (ví dụ index, số tiền theo đơn vị raw, query id);- địa chỉ dạng
slice— địa chỉ được đóng gói thành một lát cắt của cell; cell— một cell dữ liệu bất kỳ.
Đầu ra trả về dưới dạng một stack các giá trị: int, slice, cell, tuple. Agent bóc nó theo vị trí — giá trị thứ nhất, thứ hai, thứ ba. Ví dụ get_jetton_data trả về theo thứ tự: total_supply (int), cờ mintable, admin (địa chỉ dạng slice), content (cell) và code của ví (cell). Vị trí quyết định ý nghĩa — đó là một phần trong quy ước ABI của chính contract đó.
Rất nhiều method hữu ích (seqno, get_jetton_data) chẳng cần đầu vào gì cả — stack tham số rỗng. Tham số chỉ xuất hiện khi method phải tra cứu thứ gì đó theo khóa: chẳng hạn tính địa chỉ ví jetton từ địa chỉ của chủ sở hữu.
Một điểm quan trọng: run_get_method trả về stack thô theo đơn vị raw. Các con số trả về đúng nguyên trạng, không quy đổi theo decimals và cũng không biến cell thành chuỗi đọc được. Rất linh hoạt, nhưng đòi hỏi bạn hiểu mình đang đọc cái gì — ta sẽ quay lại chuyện này ở phần về get_jetton_info.
exit_code: làm sao biết method đã chạy xong ngon lành
Mỗi lời gọi get-method đều có exit_code — mã kết thúc của TVM. Chỉ nên bóc stack đầu ra khi lời gọi thực sự thành công. Quy tắc dành cho get-method hơi phản trực giác, nên đáng để nhớ nằm lòng:
exit_code0 và 1 đều là thành công (cả hai đều được coi là kết thúc bình thường, nên thấy số 1 thì đừng hoảng);exit_code> 1 là lỗi, không được tin stack đầu ra.
Các mã lỗi hay gặp:
| exit_code | Nghĩa là gì |
|---|---|
| 2 | stack underflow — đẩy lên stack ít tham số hơn mức method cần |
| 4 | integer overflow / chia cho 0 |
| 11 | thường là gọi một method không tồn tại (gõ sai tên) |
| 13 | out of gas |
Trong thực tế: gặp 2 thì kiểm tra lại xem đã truyền đủ tham số và đúng thứ tự chưa. Gặp 11 thì gần như chắc chắn bạn gõ sai tên method, hoặc contract không hề triển khai nó. Gặp 13 thì method quá nặng và đã đụng trần gas.
Ví dụ qua agent: seqno, get_jetton_data, get_sale_data
Điều dễ chịu nhất là khi run_get_method không do con người gọi mà do agent gọi. Bạn diễn đạt yêu cầu bằng lời, agent tự chọn địa chỉ, tên method và tham số, nhận stack về rồi giải thích từng trường.
seqno trước khi gửi. seqno là số thứ tự giao dịch đi ra của ví, người ta đọc nó trước khi dựng lệnh chuyển tiền: thiếu nó thì message không đi được.
Prompt cho agent: "Gọi
seqnotrên víUQD…của tôi và cho biết số hiện tại".
Agent gọi run_get_method không kèm tham số, nhận về đúng một int trên stack đầu ra và đưa cho bạn con số đó.
get_jetton_data — metadata của jetton master. Method này trả về total_supply, cờ mintable, địa chỉ admin và content.
Prompt cho agent: "Gọi
get_jetton_datatrên master USDT này và bóc tách giúp tôi từng trường".
Agent gọi run_get_method với địa chỉ master và tên get_jetton_data, đọc stack rồi giải thích các vị trí. Ở đây có một điểm quan trọng — sẽ nói ngay bên dưới.
get_sale_data — dữ liệu listing NFT. Đây không phải một tool NFT riêng, vẫn là run_get_method đó thôi: bạn đọc chính get-method của contract bán hàng trên marketplace. get_sale_data trả về giá, người bán, trạng thái giao dịch — rất tiện để biết NFT đã bán rồi hay vẫn còn treo đó.
Prompt cho agent: "Đọc
get_sale_datatừ contract bán hàng này và cho tôi biết giá tính bằng GRAM".
Bạn không viết client nào cả. Agent chỉ gọi đúng một tool. Những method thông dụng khác — get_wallet_data (dữ liệu ví jetton), get_pool_data (pool STON.fi/DeDust) — cũng gọi y hệt như vậy: tên method, địa chỉ, kèm tham số nếu cần.
get_jetton_data hay get_jetton_info: khi bạn cần câu trả lời dạng người đọc được
Đây chính là cái bẫy lớn nhất. run_get_method trả về stack thô: get_jetton_data sẽ đưa cho bạn total_supply dưới dạng một số nguyên khổng lồ theo đơn vị raw, còn content là một cell mà bạn còn phải moi tên và ký hiệu ra từ đó. Không có "USDT", không có "6 decimals", không có con số đẹp đẽ nào — đó là đầu ra TVM ở mức thấp. Nếu thứ bạn cần đúng là truy cập mức thấp vào master contract hoặc một trường phi tiêu chuẩn, thì đây chính là tool của bạn.
Nhưng nếu việc bạn cần chỉ là biết tên, ký hiệu và decimals của jetton ở dạng dùng được ngay, thì đừng mất công ngồi bóc cell làm gì. Cho việc đó đã có một tool riêng — get_jetton_info: nó trả về tên, ký hiệu, decimals và tổng cung đã được bóc tách sẵn.
Vì sao chuyện này lại quan trọng: decimals là thứ dùng để quy đổi đơn vị raw ra số tiền thật. USDT trên mạng TON có decimals = 6, còn đa số jetton là 9. Nếu lấy total_supply từ get_jetton_data thô mà không chia cho 10^decimals, bạn sẽ nhận một con số lệch so với thực tế cả triệu hoặc cả tỷ lần. Cái bẫy này được mổ xẻ kỹ trong bài decimals của jetton trên TON.
Quy tắc rất đơn giản:
- cần các trường thô của contract (tổng cung, admin, content, một method tùy biến bất kỳ) →
run_get_method+get_jetton_data; - cần câu trả lời đã dọn sẵn cho người đọc về jetton (tên, ký hiệu, decimals) →
get_jetton_info.
Đừng nhầm các con số raw từ get_jetton_data với câu trả lời đã dọn sẵn của get_jetton_info.
Hai điểm tựa hữu ích: parse_address và get_account_state
Trước khi gọi method, nên dọn dẹp phần địa chỉ cho gọn và kiểm tra xem contract có còn sống hay không:
parse_address— chuẩn hóa địa chỉ qua lại giữa các định dạngEQ/UQ/raw, hoàn toàn offline, không đụng tới mạng. TON có vài định dạng địa chỉ, và không phải method nào cũng chấp nhận mọi định dạng; rất tiện để đưa cáiEQ…mà người dùng nhập về đúng dạng cần trước khi nhét vào tham số.get_account_state— kiểm tra trạng thái, các cờ và giao dịch cuối cùng của contract. Nếu tài khoản chưa deploy (uninit) hoặc bị đóng băng thì mọi get-method đều sẽ gãy — chuyện hoàn toàn đoán trước được, và kiểm tra trạng thái từ đầu vẫn rẻ hơn là ngồi mò mộtexit_codekhó hiểu.
Cách kết nối và gọi mà không cần một dòng client nào
Có hai đường. Đường thứ nhất — miễn phí ở local, trọn bộ công cụ đọc chạy trên config công khai, không cần thẻ:
{
"mcpServers": {
"ton": {
"command": "npx",
"args": ["-y", "@tonnode/mcp"]
}
}
}
Gói @tonnode/mcp là open source (MIT), nằm trên npm và GitHub (tonnode/mcp), chạy trên giao thức ADNL gốc của TON, không qua lớp trung gian HTTP. Về con đường miễn phí này có hẳn một bài riêng — MCP cho TON miễn phí.
Đường thứ hai — endpoint hosted với throughput được đảm bảo và key riêng của bạn:
{
"mcpServers": {
"ton": {
"type": "http",
"url": "https://mcp.tonnode.io/mcp",
"headers": { "Authorization": "Bearer tn_live_…" }
}
}
}
Mọi gói cước đều có đủ cả 16 tool — bạn chỉ trả tiền cho throughput. Key Hobby miễn phí (60 request/phút) được cấp ngay sau khi đăng nhập, không cần thẻ.
Sau khi kết nối, toàn bộ bộ công cụ đọc — gồm cả run_get_method, get_jetton_info, parse_address, get_account_state — hiện ra với agent như những tool bình thường. Lời gọi trông đúng như một câu nói trong chat: "gọi get_pool_data trên pool DeDust này", "đọc seqno của cái ví này" — và agent tự chọn run_get_method, tự dựng tham số rồi giải thích các trường. Còn nếu việc bạn cần chỉ là xem số dư USDT thì đã có sẵn một đường đi gọn trong một lệnh: số dư USDT trên TON chỉ bằng một lời gọi.
Lấy key Hobby miễn phí và gọi run_get_method ngay từ agent của bạn → tonnode.io/dashboard?plan=hobby. Key được cấp ngay sau khi đăng nhập, không cần thẻ, 60 request mỗi phút — thừa sức để đọc contract thoải mái.
Không muốn đăng ký gì hết thì chạy local: npx -y @tonnode/mcp. Danh sách đầy đủ các tool cùng tham số của chúng nằm ở trang tonnode.io/mcp.
Đọc state của blockchain giờ không còn đồng nghĩa với việc lắp ráp một client. Nó đồng nghĩa với việc diễn đạt cho đúng điều bạn muốn hỏi.
Cho agent của bạn quyền truy cập TON
16 công cụ MCP: đọc, swap phi lưu ký, cross-chain và ví. Gói miễn phí — 60 req/phút, không cần thẻ.