Tất cả bài viết
11 phút đọc

Tạo ví TON bằng code: v3r2, v4, v5r1 và highload

Cách tạo ví TON bằng code chỉ với một lời gọi generate_wallet: các phiên bản v3r2, v4, v5r1, highload. Mnemonic, khóa, địa chỉ và lần nạp đầu an toàn.

TONgenerate_walletví TONví highloadMCPphi lưu ký

Bạn vừa chạy đợt tạo 500 promo code, và mỗi khoản chi trả lại cần một ví TON riêng. Hoặc bạn đang viết một AI agent tự tạo ví "nóng" ngay trong lúc chạy, nhận deposit rồi làm gì đó với nó. Thứ đầu tiên tìm thấy trên mạng là một đống ví dụ SDK: cài @ton/ton, tự mò xem WalletContractV4 khác WalletContractV5R1 ở chỗ nào, gọi tay mnemonicNew(), xuất khóa, tính địa chỉ, đừng quên subwallet_id của highload. Nửa ngày trôi qua cho đống code hạ tầng chẳng liên quan gì tới bài toán của bạn. Còn nếu ví do AI agent tạo, nó phải tự làm được — mà bạn thì không muốn nhét cả phần mật mã học vào trong nó.

Dưới đây là cách tạo ví TON bằng code (generate wallet / tạo ví trong TON) chỉ với một lời gọi tool generate_wallet, cách phân biệt các phiên bản v3r2, v4, v5r1 và highload_v3, và cách không đánh mất khoản nạp đầu tiên vì lỗi kinh điển với địa chỉ bounceable.

Vì sao nên tạo ví TON bằng code (và vì sao không nên qua SDK)

Tự tạo bằng tay qua SDK thì ổn — đúng đến ngày lên production đầu tiên. Ở quy mô lớn, các vấn đề bắt đầu lộ ra:

  • Phiên bản. Trong TON không có một cái "ví" duy nhất, mà là vài contract khác nhau: v3r2, v4, v5r1, highload. Mỗi loại có logic riêng và cho ra địa chỉ riêng dù dùng cùng một khóa. Chọn nhầm phiên bản là nhận nhầm địa chỉ.
  • Định dạng địa chỉ. Cùng một ví lại có dạng EQ và dạng UQ. Đưa nhầm địa chỉ khi nhận deposit thì tiền sẽ "bật" ngược trở lại (nói kỹ ở dưới).
  • AI agent. Bạn không thể "đưa một thư viện" cho agent (Claude, Cursor, ChatGPT/Codex) — nó cần một tool mà nó gọi được dựa trên phần mô tả. Qua MCP (Model Context Protocol), agent gọi generate_wallet như một hàm bình thường và nhận về kết quả có cấu trúc, sẵn dùng. Logic phiên bản, khóa và định dạng sống ở phía MCP server.
  • Stack đa ngôn ngữ. Bạn không muốn duy trì TON SDK cho cả Go, Python lẫn Node cùng lúc — MCP cho bạn một interface duy nhất cho tất cả.

generate_wallet là một trong 16 tool của TONNode, MCP server hosted dành cho TON. Nó làm đúng một việc: tạo một ví mới và trả cho bạn mọi thứ cần thiết để sở hữu nó. Nếu bạn mới làm quen với cách tiếp cận này, hãy bắt đầu từ hướng dẫn MCP cho TON.

generate_wallet trong một lời gọi: chính xác bạn nhận về những gì

generate_wallet tạo một ví TON mới và trả về trọn bộ những gì cần để sở hữu và khôi phục nó:

  • mnemonic (seed phrase) — chuỗi từ ở dạng con người đọc được, từ đó mọi thứ còn lại được suy ra một cách tất định;
  • khóa riêng — để ký giao dịch;
  • khóa công khai;
  • địa chỉ ví — ở các định dạng chuẩn của TON.

Prompt gửi cho agent trông đúng như thế này:

Tạo một ví TON mới phiên bản v5r1 qua generate_wallet
và cho tôi xem địa chỉ cùng mnemonic.

Agent gọi tool kèm tham số phiên bản và trả về một cấu trúc đại khái như sau (giá trị chỉ là minh họa; khóa Ed25519 trong TON là hex thuần, không có tiền tố 0x kiểu Ethereum):

{
  "version": "v5r1",
  "mnemonic": ["word1", "word2", "...", "word24"],
  "public_key": "e3f1a2…",
  "private_key": "9b7c4d…",
  "address": {
    "bounceable": "EQ…",
    "non_bounceable": "UQ…",
    "raw": "0:abcd…"
  }
}

Không SDK, không tự derive bằng tay. Còn lại là bạn tự quyết định cất nó ở đâu. Điểm mấu chốt: server không lưu lại mnemonic và khóa này ở phía mình — mục về phi lưu ký bên dưới sẽ nói rõ.

Các phiên bản ví v3r2, v4, v5r1 và highload_v3 — chọn cái nào

generate_wallet hỗ trợ bốn phiên bản contract ví. Không phải "mới hơn nghĩa là tốt hơn": mỗi loại có chỗ đứng riêng.

v5r1 (W5) — mặc định cho dự án mới

Phiên bản mới nhất. Hỗ trợ extension và các kịch bản gasless — khi phí giao dịch của người dùng có thể do một relayer bên thứ ba trả thay. Đây là đặc tính của chính contract v5, không phải dịch vụ của TONNode: server chỉ tạo ra loại ví đó, nó không cung cấp relayer gasless nào cả. Nếu bạn đang dựng một agent hiện đại từ đầu và không cần đúng highload — hãy chọn v5r1.

v4 — phiên bản có plugin

Thế hệ phổ biến trước đó. Hỗ trợ plugin: bạn có thể gắn các contract mở rộng vào ví (ví dụ cho subscription và thanh toán theo lịch). Từng là chuẩn de facto trong thời gian dài, được ví và dịch vụ hỗ trợ rộng rãi. Hãy chọn nó nếu bạn có ràng buộc với mô hình plugin của v4.

v3r2 — ví cơ bản, đơn giản

Contract tối giản, không extension, không plugin. Dễ đoán và tốn ít gas. Hợp với các địa chỉ phục vụ nội bộ, nơi toàn bộ logic chỉ là "nhận vào và gửi đi".

highload_v3 — cho chi trả hàng loạt

Một lớp riêng. Ví dành cho throughput cao: một external message có thể mang theo rất nhiều lệnh chuyển. Đây chính là thứ bạn chọn cho chi trả theo lô, airdrop, phát thưởng, payment gateway, rút tiền từ sàn. Đổi lại hiệu năng, nó dùng một mô hình theo dõi message đặc thù (query_id / expiration), nên cần được đối xử cẩn thận — xem phần về lưu tham số.

Phiên bản Khi nào chọn
v5r1 Dự án mới, extension, gasless
v4 Cần plugin (subscription, v.v.), tương thích tối đa
v3r2 Ví nội bộ đơn giản, không màu mè
highload_v3 Chi trả hàng loạt/theo lô, throughput cao

Ví dụ prompt cho kịch bản chi trả:

Sinh cho tôi ví highload_v3 để chi trả theo lô và trả về
mnemonic, khóa và địa chỉ.

Nạp lần đầu: vì sao phải gửi vào địa chỉ non-bounceable UQ

Lỗi phổ biến và cay đắng nhất sau khi tạo ví là mất luôn khoản nạp đầu tiên. Cơ chế thế này: ví vừa tạo xong vẫn chưa được deploy lên blockchain — ở địa chỉ đó thực sự chưa có contract nào, cho tới khi lệnh chuyển đầu tiên tới nơi và triển khai code lên.

Trong TON, địa chỉ có một cờ "bounceable":

  • EQ (bounceable) — nếu ở địa chỉ không có contract sống, mạng sẽ bật ("bounce") khoản chuyển ngược lại cho người gửi. Với ví mới thì đây đúng là trường hợp của bạn.
  • UQ (non-bounceable) — khoản chuyển "dính" lại ở địa chỉ, kể cả khi contract chưa được triển khai. Đúng thứ bạn cần cho lần nạp đầu tiên.

Quy tắc rất đơn giản: lệnh nạp đầu tiên vào ví mới phải gửi tới địa chỉ UQ. Gửi vào EQ thì nó sẽ quay về, còn bạn thì ngồi đoán vì sao số dư vẫn trống. Sau khi ví thực hiện giao dịch gửi đi đầu tiên và được deploy, bạn có thể yên tâm dùng dạng bounceable.

Làm sao lấy dạng UQ một cách chắc chắn? Bằng tool offline parse_address — nó chuyển đổi và kiểm tra các định dạng EQ/UQ/raw mà không cần gọi ra mạng:

Dùng parse_address chuyển địa chỉ này sang dạng non-bounceable
UQ để nạp lần đầu

Sau khi nạp, hãy kiểm tra trạng thái bằng get_account_state — nó cho biết trạng thái account (uninitialized / active), các cờ và giao dịch gần nhất:

Kiểm tra get_account_state cho UQ… — ví đã được deploy chưa
và số dư là bao nhiêu

Chừng nào contract chưa active, trạng thái sẽ cho bạn biết rằng khoản nạp vẫn chưa "dựng" được ví lên. Phân tích chi tiết về các định dạng nằm trong bài định dạng địa chỉ EQ/UQ/raw.

Ví highload: tự chốt subwallet_id và timeout

Một cảnh báo riêng cho những ai chọn highload_v3. Ở đây chỉ mỗi mnemonic là chưa đủ để tái tạo đúng cái ví đang chạy và lặp lại hành vi của nó. Ngoài khóa ra, contract highload còn hai tham số nữa được đặt lúc tạo và nằm trong initial data (state init) của nó:

  • subwallet_id — định danh ví con (cho phép từ một seed phrase sinh ra nhiều địa chỉ khác nhau);
  • timeout — cửa sổ sống của external message, thứ mà toàn bộ logic query_id và hết hạn dựa vào.

Lưu ý: generate_wallet trả về mnemonic, khóa và địa chỉ — còn subwallet_idtimeout là do bạn tự chọn và tự chốt như những tham số cấu tạo của ví highload. Chính bạn là người chịu trách nhiệm ghi lại đúng những giá trị đã dùng khi tạo ví.

Ví highload theo dõi xem message nào còn "sống" dựa trên timeout. Nếu bạn khôi phục ví chỉ bằng seed phrase, không có subwallet_idtimeout, thì:

  • bạn sẽ nhận địa chỉ khác — cả subwallet_id lẫn timeout đều nằm trong state init, nên thay đổi bất kỳ giá trị nào cũng làm thay đổi initial data của contract, và kéo theo là địa chỉ của nó;
  • bạn sẽ không tái hiện đúng logic hết hạn và khử trùng lặp message — và có nguy cơ làm hỏng việc theo dõi các lệnh chuyển đi.

Quy tắc thực dụng: với highload_v3, hãy cất subwallet_idtimeout vào kho lưu trữ ngay cạnh mnemonic, như một phần của cùng một bản ghi về ví. Đây không phải metadata tùy chọn — đây là một phần danh tính của ví.

# bản ghi bí mật, dạng giả định
mnemonic:      "word1 word2 … word24"
version:       "highload_v3"
subwallet_id:  <giá trị bạn đã đặt lúc tạo>
timeout:       <giá trị bạn đã đặt lúc tạo>

Với v3r2/v4/v5r1 thì không có yêu cầu đó — chỉ cần mnemonic và biết phiên bản là đủ.

Phi lưu ký: server không giữ và không ký bằng khóa của bạn

Câu hỏi lớn nhất khi ví được tạo "ở đâu đó trên server": rốt cuộc ai sở hữu khóa? Câu trả lời ở đây rất rõ ràng.

generate_wallet hoàn toàn phi lưu ký:

  • server không bao giờ lưu khóa riêng, mnemonic và tiền;
  • server không bao giờ ký giao dịch thay bạn;
  • ví được sinh ra — mnemonic, khóa, địa chỉ — được giao trọn vẹn cho bạn trong phản hồi và không được lưu lại ở phía server.

Không có cơ sở dữ liệu chứa seed phrase của người khác, không có operator key nào ký hộ bạn thứ gì. Về bản chất, generate_wallet chỉ là một lớp bọc tiện lợi quanh việc sinh khóa tất định: phần mật mã diễn ra, kết quả được trả hết về cho bạn, còn server thì chẳng giữ lại gì. Đây là khác biệt mang tính nguyên tắc so với các ví agent lưu ký, nơi dịch vụ nắm khóa (hoặc một phần khóa) và tự ký giao dịch. Sự khác biệt đó được mổ xẻ riêng: MCP lưu ký và MCP phi lưu ký.

Kết luận thực tế: hãy lưu ngay phản hồi của generate_wallet vào kho bí mật an toàn của bạn. Server sẽ không "moi" lại đúng cái ví đó lần thứ hai — nó không nhớ, và việc khôi phục "qua support" là bất khả thi. Đó là tính năng, không phải lỗi.

Cách kết nối và tạo ví đầu tiên

Kết nối chỉ mất một phút. Bạn dựng package @tonnode/mcp chạy local và miễn phí bằng npx; toàn bộ nhóm tool đọc dữ liệu dùng được mà không cần key.

Config cho MCP client (Claude Desktop, Cursor, bất kỳ MCP client nào):

{
  "mcpServers": {
    "ton": {
      "command": "npx",
      "args": ["-y", "@tonnode/mcp"]
    }
  }
}

Package @tonnode/mcpopen source (MIT), nằm trên npm và GitHub (tonnode/mcp), và chạy qua giao thức ADNL gốc của TON, không có lớp HTTP trung gian nào giữa agent của bạn và mạng. Khởi động lại client — và cả 16 tool, bao gồm generate_wallet, parse_addressget_account_state, sẽ sẵn sàng cho agent. Cách gắn nó vào từng client cụ thể nằm trong hướng dẫn kết nối Claude và Cursor với TON.

generate_wallet nằm trong trọn bộ 16 tool và có mặt trên mọi gói, kể cả gói Hobby miễn phí — 60 request mỗi phút, không cần thẻ. Key miễn phí được cấp ngay sau khi đăng nhập. Bạn chỉ trả tiền cho thông lượng, chứ không phải để được dùng tool.

Tiếp theo là ba tool phủ trọn kịch bản "tạo ví và nạp tiền an toàn":

  1. generate_wallet — tạo ví đúng phiên bản cần, lấy mnemonic, khóa, địa chỉ.
  2. parse_address — lấy dạng UQ của địa chỉ để nạp lần đầu (offline).
  3. get_account_state — xác nhận rằng khoản nạp đã triển khai contract.

Ví dụ một prompt đầy đủ cho agent:

Tạo ví v5r1 qua generate_wallet. Sau đó dùng parse_address
đưa tôi địa chỉ UQ của nó để nạp lần đầu.
Sau khi tôi chuyển coin vào, hãy kiểm tra get_account_state
xem ví đã được deploy chưa.

Khi nào cần hosted key

Chạy npx local dùng config công khai và rất hợp cho giai đoạn phát triển. Nếu bạn cần thông lượng được đảm bảo khi có tải (chính là các đợt chi trả hàng loạt bằng highload), hãy kết nối endpoint hosted với key riêng của bạn:

{
  "mcpServers": {
    "ton": {
      "type": "http",
      "url": "https://mcp.tonnode.io/mcp",
      "headers": { "Authorization": "Bearer tn_live_…" }
    }
  }
}

Tóm lại

  • generate_wallet tạo ví TON trong một lời gọi và trả về mnemonic, khóa riêng/khóa công khai cùng địa chỉ — đó là một lời gọi có chọn phiên bản, chứ không phải tự lắp SDK bằng tay.
  • Phiên bản mặc định cho dự án mới là v5r1; cho chi trả hàng loạt là highload_v3; v4 khi cần plugin; v3r2 khi chỉ cần một cái ví đơn giản.
  • Khoản nạp đầu tiên hãy gửi vào địa chỉ non-bounceable UQ, nếu không nó sẽ bật ngược lại; dạng UQ do parse_address cung cấp, còn trạng thái thì get_account_state kiểm tra.
  • Với highload, hãy tự chốt subwallet_idtimeout rồi lưu chúng cùng mnemonic — cả hai đều nằm trong state init và ảnh hưởng tới địa chỉ.
  • Server phi lưu ký: không lưu khóa lẫn tiền của bạn, cũng không ký thay bạn — khóa là của bạn.

Hãy lấy key Hobby miễn phí và tạo cái ví đầu tiên qua generate_wallet chỉ trong vài phút — tonnode.io/dashboard?plan=hobby.

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ẻ.