English 简体中文 繁體中文 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french

简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE คนไทย Français русский

回答

收藏

5.4 从 dApp 启动交易

开源社区 开源社区 8041 人阅读 | 0 人回复 | 2025-03-11

上次的交互是只读的,现在我们通过发送交易来与合约交互。
我们在合约上开发的第一个功能是递增。让我们在主页面上添加一个发送交易的按钮。正如您所记得的,在链上发送交易需要花费GAS,因此我们希望钱包能与用户一起批准这一操作,并显示将花费多少Ton币。
在开始之前,我们将添加另一个钩子,从 TON Connect 接口生成一个发送方对象。该发送方代表已连接的钱包,允许我们代表它们发送交易。
在处理该交易请求时,我们还将在用户界面中显示钱包的连接状态,以便我们的用户界面将隐藏需要授权的元素。
就像我们在之前的课程中所做的那样,让我们使用 React 钩子来保留一些我们稍后将在代码中使用的功能。
让我们创建包含以下内容的文件 src/hooks/useTonConnect.ts:
  1. import { useTonConnectUI } from '@tonconnect/ui-react';
    0 S1 \+ r6 @! a$ c
  2. import { Sender, SenderArguments } from 'ton-core';
    ! o+ ?2 l, ?/ v+ |3 v' O

  3. 2 f, ~8 E9 U1 v. {* Q9 i2 o2 L
  4. export function useTonConnect(): { sender: Sender; connected: boolean } {
    , X) A$ N$ G* ]  A% x. C" u
  5.   const [tonConnectUI] = useTonConnectUI();$ f6 R6 `7 r6 [3 |9 ?
  6. 6 z2 u) C* s$ O3 x! O, c+ q: `
  7.   return {
    . h9 h9 v# b, |' A
  8.     sender: {
    / P* \  Y0 i; V% o2 j; Z5 Q0 Y9 N
  9.       send: async (args: SenderArguments) => {7 z' q6 Y8 o. r- A
  10.         tonConnectUI.sendTransaction({2 i# ~% ]1 b: p- S5 k
  11.           messages: [
    5 Z3 u/ ]  U2 q6 Q" a4 D* s( k% U
  12.             {
    ! b7 _; p. \, Q" @8 q0 X! S# ?5 ~  F
  13.               address: args.to.toString(),
    ! R8 r) `( T! ~! v0 I  U. D# R* ?- T
  14.               amount: args.value.toString(),4 F5 u5 e6 O! p9 y$ U, o. i
  15.               payload: args.body?.toBoc().toString('base64')," ]3 n! }+ ]0 i, S
  16.             },
    " k# H, T- G  w; e
  17.           ],
    - v9 g% b$ g& m; m$ T
  18.           validUntil: Date.now() + 5 * 60 * 1000, // 5 minutes for user to approve( a4 q* e! j6 R) M) d
  19.         });
    1 i* u7 b7 H' R/ |
  20.       },+ U  q/ c0 V4 V  k, {7 e. v
  21.     },7 k, _' ~. ^" A3 Q
  22.     connected: tonConnectUI.connected,% F! B, v( t3 }, W1 Q
  23.   };( W  m+ D% e9 @7 h
  24. }
复制代码
您可以看到,我们正在返回一个对象,其中的函数 send 可以让我们触发交易请求,参数 connected 可以存储连接的当前状态。
接下来我们要做的是优化现有的 useCounterContract 钩子,并添加两个小功能。
  • 每 5 秒自动轮询一次计数器值。这将有助于向用户显示数值确实发生了变化。
  • 公开接口类的 sendIncrement 并将其连接到发送者。

    6 s7 N; L  e1 _5 ?; i
我们需要更新一些代码:
  1. // ... previous imports9 R  c; w* }; }) O( D8 e
  2. import { toNano } from "ton-core";
    ( ^& O, E+ m, S* |; L
  3. import { useTonConnect } from "./useTonConnect";& c. N% N# _% B/ h2 {( b; f

  4. ; s5 O( r! Z, y# L* v4 b; i
  5. , d  e* i' \4 v4 K# @6 T
  6. export function useCounterContract() {7 G- D; z8 j; K1 o3 p3 @

  7. / k/ o; _$ ?' Z
  8.     // ... variables definitions# Q2 A+ J1 d" h$ D7 h
  9.     const { sender } = useTonConnect();
    ) F3 j; q5 ^1 C; x
  10.     7 {, {6 [  p+ [
  11.     const sleep = (time: number) => new Promise((resolve) => setTimeout(resolve, time));
    5 y8 c/ T; y9 w) ~, r+ w
  12.     ! Q/ k) @; R+ o1 B; u* O  h! p
  13.     // ... mainContract definition
    8 @+ {: s) S, o; C3 {7 C7 ]
  14.     4 w* Q6 w- d% M8 \
  15.     useEffect(() => {- j# c; b0 ]# w& l4 {" s
  16.         async function getValue() {; N8 P+ T+ W$ X1 }
  17.     + v+ F9 M) y8 L  A
  18.           // ... previous getValue code
    8 X$ @1 D; A, A: ~2 Y
  19. 6 U2 C; g" `7 q/ g( T& j- u  B" Y
  20.           await sleep(5000); // sleep 5 seconds and poll value again
    + N) o5 L" _1 v6 x: |- A: `: f' S+ }
  21.           getValue();
    + K- S1 N) g" r6 m
  22.         }
    ! p# N( {9 I3 L9 N4 x
  23.         getValue();" |) R$ G0 I" C2 x1 `
  24.     }, [counterContract]);
    . ]' F* C5 l: V
  25. 0 M3 a1 H3 Q- G2 }2 }+ Y. n7 M
  26. 3 ]% W: H$ F6 S+ F  d- f# x! U
  27.     return {
    3 m8 [! z0 m$ D4 W
  28.         value: val,
    0 G2 j5 q3 @4 u/ A' `8 X
  29.         address: counterContract?.address.toString(),
    . Q; _% I8 k8 k- S& p6 o
  30.         sendIncrement: () => {
    2 e) J. k  e/ }% ?% i
  31.           return mainContract?.sendIncrement(sender, toNano(0.05), 3);
    & g( R3 P7 V/ k& V* E
  32.         },
    " R/ ]& a. p" u% w8 i. r4 e! u
  33.     };/ N# I# X8 ~  ~' E8 `. ]
  34. }
复制代码
此时,我们只需更新用户界面,就可以触发所需的交易。我们还需要在其中添加两样东西:

  X, k/ o; j) A
  1. // ... previous imports! y3 n) z2 m* I. @9 |2 X
  2. import { useTonConnect } from "./hooks/useTonConnect";& G9 k8 J8 N9 h) H  E

  3. 1 ^- [- m" j9 x- y" B4 u3 J; a8 G

  4. 0 s" g) H$ \1 M3 e- L
  5. function App() {
    * J6 G9 g6 C8 |+ ]8 q/ g. M/ {
  6.    
    ; }0 q+ C+ H: o0 J9 u* y
  7.     const { ..., sendIncrement } = useMainContract();
    " s. v$ c% h* J: `- l
  8.     const { connected } = useTonConnect()
    # H0 f  p  N6 O$ l  l# A
  9.    
      L8 }. d  e' i7 J
  10.     return (
    3 H+ E9 x7 b* p4 ~) ?
  11.         // ... other HTML code, y( b3 \/ o! k% P& i, }* Y8 f9 ^
  12.             : ?* j( _4 X) g9 `6 g& F0 W8 K/ n+ D' i
  13.             {connected && (
    . P& c. p, B$ ^: |0 e" f! r- y
  14.               <a* [- E/ P# w5 L
  15.                 onClick={() => {6 E- G  R9 l" s# x1 z
  16.                   sendIncrement();
      ]0 J2 Q7 S; _- [& L! d
  17.                 }}, K1 W/ H8 ]6 H: g
  18.               >1 ^( b# E3 s/ k  d
  19.                 Increment
    " Q5 Q8 w' J2 a, c
  20.               </a>: Y  w7 l0 f" r9 |
  21.             )}! l6 A) Q" R" M  G1 i
  22.         4 y; g: }! d4 x+ @  }
  23.         // ... other HTML code
    8 y1 f6 C; S" O3 _
  24.     )
    " |& `% g* w( x
  25. }
复制代码

1 O' A: b4 u! r+ t3 u& a
  S7 k  r* q" a8 ]7 o" ]4 ]8 y# g& Z) W
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则