|
本帖最后由 riyad 于 2025-3-20 00:42 编辑 ( b H# m' u8 w# b3 W+ M q: F$ `- U
0 _) {4 M; [) r) p0 L
在上篇教程中,我分享了如何用 FunC 和 Blueprint 编写并编译一个红包智能合约。今天,我们将把这个合约部署到 TON 测试网,使用 测试币 来完成部署过程。这篇教程将详细介绍如何通过 Telegram 机器人 @testgiver_ton_bot 获取测试币、配置环境并成功部署合约。让我们开始吧!) s `( w6 L+ \+ V0 e* f7 m! T4 G/ E
前提条件# J8 |( ^$ P5 U( k/ A+ h
部署到测试网需要以下准备:+ R3 W4 [4 a/ o
- x2 w& B' q9 O/ k% V
- 完成第一部分:你已经编写并编译了红包合约(参考上一教程)。
- 测试网 TON 币:我们将通过 @testgiver_ton_bot 获取免费测试币。
- 测试网钱包助记词:一个 TON 测试网钱包的 24 字助记词,用于支付部署费用。
! N- U _* @4 O: M! ?$ H 获取测试币( _: G% |0 L" x( {! I, i
由于这是测试网,我们需要测试币来支付部署费用。以下是通过 @testgiver_ton_bot 获取测试币的步骤:) t1 i4 s; N& s5 {" R7 e* Z- f# x
创建测试网钱包:$ }5 B1 d+ r. u; `1 u: d& }2 a
- 下载 TON Wallet 或使用支持测试网的钱包。
- 切换到测试网模式(例如在 wallet.ton.org 上启用 ?testnet=true)。
- 生成新钱包并保存 24 字助记词。) Q/ d/ A) T) N, v" W
) B$ u* d; {5 w; x7 k, w访问 @testgiver_ton_bot:
% a9 q% V# n- A% Y- b0 G! E q- 打开 Telegram,搜索 @testgiver_ton_bot 并启动它。
- 点击 “Start” 开始使用。
: A. b/ c& n+ j( P a " d8 w# X1 w) E& u( c2 l+ X
领取测试币:
7 _+ D, w7 ]+ K; Y# I- 在机器人界面点击 [ GET 2 TON ]。
- 返回你的测试网钱包,点击 “Deposit”(存款),复制钱包地址。
- 在机器人中完成验证码(captcha),粘贴你的钱包地址。
- 提交后,你将收到 2 TON 测试币(每小时可领取一次)。
- 如果需要更多测试币,可以在 TON 开发者社区(如 @tondev_eng)请求帮助。# @+ S f- _" H8 o# N% R* j" i
$ d6 m/ p! F5 ?
步骤 1:配置测试网环境
" R b& W. O* O9 H# V/ F& W我们将使用 TypeScript 和 TON SDK 连接测试网并部署合约。; _/ s! v3 E2 T: U' B
安装依赖: 在项目根目录运行:
( ~" `' {: G; r& [- npm install @ton/ton @ton/crypto @ton/core dotenv
复制代码- MNEMONIC="word1 word2 word3 ... word24"
复制代码 注意:这是测试网助记词,仅用于测试环境。
4 }2 f! p3 A% u
0 F! |2 c" b$ t2 H" R( f* u- A步骤 2:编写测试网部署脚本
3 x0 G4 c. A* J' m3 L F% q% z: E
& C7 k- g5 ]9 w2 z$ u* k我在 scripts/deploy.ts 中编写了部署逻辑,以下是完整代码和说明: - import { TonClient, WalletContractV4, toNano, Address, Sender } from "@ton/ton";; D# J- G5 f3 a; Y5 v( D
- import { mnemonicToWalletKey } from "@ton/crypto";
3 w: b" ]" a- S- H0 d" u - import { Cell, beginCell, SendMode } from "@ton/core";% k# p3 I% r$ k
- import { RedPacket, redPacketConfigToCell } from "../wrappers/RedPacket";0 b9 W9 X, V4 Z$ C7 @
- import * as dotenv from "dotenv";
2 F4 Q @6 x9 A' c2 d0 ]3 Q
/ y% M. M% P8 u' A0 o- dotenv.config();" Q' U% J6 C' t2 s( Y4 x; @ Y
4 f$ }6 b; O O/ v0 o, E, U% O- async function main() {- a# [: G) g% u+ W, u* i
- // 从 .env 加载测试网助记词4 n& C2 W" \8 ]1 S; m- f! {5 C5 }
- const mnemonic = process.env.MNEMONIC; h# C, d8 p/ F, c9 H
- if (!mnemonic) {
1 y0 J$ x: E1 ^. h" c! g - throw new Error("请在 .env 文件中设置测试网 MNEMONIC");
0 P: P0 E8 r3 T$ U$ o. o - }
. t; ?: j. P! p7 s5 ~ - ; g) h/ s' L* @6 g9 v2 B
- // 将助记词转换为钱包密钥0 u B4 U% x. F' L
- const key = await mnemonicToWalletKey(mnemonic.split(" "));
0 k$ w# G1 c. {8 p) F2 ] - / }8 P- v, w: O$ D0 A& k- @
- // 初始化 TON 测试网客户端
/ V' Y: n# x, {8 Z& ]4 [& {' F4 U - const client = new TonClient({1 C6 T3 [! S6 J# |6 W+ ~
- endpoint: "https://testnet.toncenter.com/api/v2/jsonRPC", // 测试网节点
1 t: A2 B7 i7 _ - });9 P6 B) \' m' n' ]! Z6 D
- 5 o7 w& ^9 ?0 t/ G7 c1 L
- // 创建 V4 版本钱包(测试网)
2 M. L/ {% |! C6 S/ I k/ i - const wallet = WalletContractV4.create({" @8 N. Y+ ]8 ]( L
- publicKey: key.publicKey,) ^. v+ v3 d4 b2 H4 a" K
- workchain: 0, // 测试网使用基础链
) m. k$ y3 k; ~ Z" [" m! M9 z - });
' r; W! z9 t8 y4 F, t3 R, Q, T6 M - $ J I/ H# _0 d0 v. _4 P
- // 打开钱包合约* G7 V, M0 h9 ~0 n9 p1 v d, C
- const walletContract = client.open(wallet);+ R9 K% ^: Q5 D5 h! s3 p
* D5 W" |1 t% V- // 获取测试网钱包地址和余额) S5 X' K# i' f
- const walletAddress = walletContract.address.toString();
8 p0 v) D/ E1 w# D' e - console.log("从测试网钱包部署:", walletAddress);
8 _$ v0 H3 R8 s* x8 o
/ ~9 J9 S; P/ i [2 j/ W- const balance = await walletContract.getBalance();
$ L+ Z) O( R6 j* d; ]0 b9 X - console.log("测试网钱包余额:", balance.toString(), "nanoTON"); W) C$ f7 j7 g, E6 |5 _
- 9 F" n3 w1 h, H8 ?
- // 检查余额是否足够(至少 0.5 测试 TON)" D* C5 o, Z6 s3 K+ b, H7 K" R
- if (balance < toNano("0.5")) {
4 b3 B$ j5 y* {- E0 @ J - throw new Error("测试网余额不足,至少需要 0.5 测试 TON 用于部署");
U2 p: j. p8 V4 @9 I( m [! @( n - }
) i. \: g% O* m2 K5 O. c - 1 t+ n9 L3 R% @
- // 加载编译后的合约代码
$ p- R$ N1 I* G6 v - const compiledJson = require("../build/RedPacket.compiled.json");: o7 M" E! V; I7 J. N) _* H4 {% U
- const code = Cell.fromBoc(Buffer.from(compiledJson.hex, "hex"))[0];
/ Y3 ~/ I/ w; ?3 o5 C+ e
$ k P8 Y) w$ `/ B2 p- // 初始化红包合约(无初始配置)
+ y3 ]) @( Y3 n! D& M4 o - const config = {};
" Q+ M) U; R& R$ t# F - const redPacket = RedPacket.createFromConfig(config, code, 0); // workchain 0
2 s! ?$ W% E: e3 [/ V/ q/ O$ j5 b* e - const redPacketAddress = redPacket.address;1 k( Z5 J7 E1 [& T- E1 z- q% s
# Q, h$ t3 N: f5 A! u- // 创建 Sender 对象 D8 K; F8 |$ x- B
- const sender: Sender = walletContract.sender(key.secretKey);
% b% c3 k8 T- _' p7 F
& O: a. G+ D; V$ I- // 部署合约到测试网# M: J8 }. o+ b( z/ h+ ~
- const deployAmount = toNano("0.1"); // 部署费用 0.1 测试 TON
3 V- w5 q/ A6 j+ @2 _. F7 s - console.log("部署合约到测试网地址:", redPacketAddress.toString());# Q: @+ H% e: K) b
- . k* C/ ~1 C1 k' ?3 Y* T
- const provider = client.open(redPacket) as any; // 类型转换简化处理
, A( k8 A( i+ G - await redPacket.sendDeploy(provider, sender, deployAmount);
" M3 B9 ?7 q# J2 t. \
! L+ q0 Z! B+ w3 s( X3 W+ [. ~7 T. Y- console.log("测试网部署交易已发送,等待确认...");4 |7 i M8 R, H7 _6 x; C7 b
- 6 f, J/ `- k6 `* x4 H9 K
- // 轮询检查部署状态
! e5 d. g0 r7 [& g: l8 _0 M9 U - let isDeployed = false;
- \6 w# q- V4 L - for (let i = 0; i < 10; i++) {# |8 ?4 Q4 K0 i$ n2 c
- const state = await client.getContractState(redPacketAddress);
$ d# u+ M r. }/ p1 E - if (state.state === "active") {4 g- h- H4 ~. i0 f; N
- isDeployed = true;
: }' A( `+ @1 y - break;" Z4 U5 Z1 |& t* `) y- l+ a' }/ q
- }" S" {1 R& w0 }& h. ]0 l" n& x& h+ X
- console.log("等待测试网部署... 第", i + 1, "次尝试");* ?5 H3 J/ M% p4 r2 j+ ]& r" |& o
- await new Promise((resolve) => setTimeout(resolve, 3000)); // 等待 3 秒6 a, K* f0 x( Q8 ]4 M9 D5 i3 _
- }- }4 V' n9 s( b/ N
- . A% G, A: W& M/ J+ U% S" m; f; m
- if (isDeployed) {
( B+ x2 m, B+ V- c; Z0 @3 t- u - console.log("合约成功部署到测试网,地址:", redPacketAddress.toString());" a1 D8 B" `: C
- } else {9 E: u/ d, k) H$ i
- console.log("测试网部署可能失败或耗时较长,请检查地址:", redPacketAddress.toString());! L' G& o U5 }0 v2 c; b8 B3 V
- }
) n7 z5 ~, a; R. Z! a4 j - }2 g4 X" G" h! i6 i* o
- 3 @& C4 w9 Y9 u. ^# o& }
- main().catch(console.error);
复制代码 代码说明
; ^4 u' y! t- ]. L) l, N8 y% O2 R9 g: v, @( ]) L% }) U6 [
- 加载测试网助记词:从 .env 获取测试网钱包助记词。
- 生成密钥:将助记词转为公私钥对。
- 连接测试网:使用 TonClient 连接 TON 测试网节点。
- 创建测试网钱包:初始化 V4 版本钱包,检查余额(需至少 0.5 测试 TON)。
- 加载合约代码:读取编译后的代码。
- 初始化合约:生成红包合约实例和测试网地址。
- 部署到测试网:发送 0.1 测试 TON 部署合约。
- 确认部署:轮询检查合约状态变为 "active"。! r$ l% w; v9 ?/ y. d: g5 h& l4 C
3 i4 S, R- g- A8 }1 y5 f: G0 A' o
步骤 3:运行部署脚本; y" [* n' y$ S; p) U& B$ v! G* F
安装依赖:" E' B; O% J# L$ F/ Q
执行部署:7 w: j! i2 `! l& r z* j- R: j
- npx ts-node scripts/deploy.ts
复制代码 输出示例:3 X# i' i: H. o
- 从测试网钱包部署: EQ...xyz
9 v$ X. {; [7 p2 p- N: f - 测试网钱包余额: 2000000000 nanoTON
; R* `6 W6 J$ a/ G+ {1 v( z - 部署合约到测试网地址: EQ...abc
/ _( ~. a% R5 E" g8 y5 ] - 测试网部署交易已发送,等待确认...# f: D! I# p. N4 Y
- 合约成功部署到测试网,地址: EQ...abc
复制代码
% t% j; t8 L9 Y, ?& r* ~5 M下一步计划. m3 ~0 ^& g6 \0 V9 R2 h
合约已部署到测试网,接下来我计划:
% @" t" i1 H$ z. E- 测试交互:用测试币测试创建和领取红包。
- 前端开发:做一个界面,让用户在测试网上体验红包功能。
& s/ h& `0 w" k: Q3 \& t5 k$ p
* J" U/ c& y( [3 s$ {& M3 D总结
( M, `. I, y: U5 f' X这篇教程展示了如何通过 @testgiver_ton_bot 获取测试币并将红包合约部署到 TON 测试网。测试网为我们提供了一个免费的实验环境,完整代码已分享,你可以跟着部署自己的合约。如果测试币领取有问题或部署失败,欢迎留言交流!下次我会分享如何在测试网上与合约交互,敬请期待!
0 H, ~9 E9 z G% N! s& i' L |
|