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

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

回答

收藏

5.4 从 dApp 启动交易

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

上次的交互是只读的,现在我们通过发送交易来与合约交互。
我们在合约上开发的第一个功能是递增。让我们在主页面上添加一个发送交易的按钮。正如您所记得的,在链上发送交易需要花费GAS,因此我们希望钱包能与用户一起批准这一操作,并显示将花费多少Ton币。
在开始之前,我们将添加另一个钩子,从 TON Connect 接口生成一个发送方对象。该发送方代表已连接的钱包,允许我们代表它们发送交易。
在处理该交易请求时,我们还将在用户界面中显示钱包的连接状态,以便我们的用户界面将隐藏需要授权的元素。
就像我们在之前的课程中所做的那样,让我们使用 React 钩子来保留一些我们稍后将在代码中使用的功能。
让我们创建包含以下内容的文件 src/hooks/useTonConnect.ts:
  1. import { useTonConnectUI } from '@tonconnect/ui-react';% Z+ W! U6 N/ `
  2. import { Sender, SenderArguments } from 'ton-core';
    # G0 g7 m0 y  E- D1 a2 W- n" F9 b
  3. . T  G; d) d  R
  4. export function useTonConnect(): { sender: Sender; connected: boolean } {( N* R2 N6 x  R! x: }
  5.   const [tonConnectUI] = useTonConnectUI();( f/ ?$ I3 U# k7 h" E
  6. % ?7 _- _# x0 g" A) T" e5 T  ~1 ]
  7.   return {3 l7 M6 Y% H, e, T, q8 g1 V* b6 W
  8.     sender: {, q5 |$ H+ Y( }1 T8 e' `5 i, Y
  9.       send: async (args: SenderArguments) => {
    0 k1 u, ^- c2 \) D  U
  10.         tonConnectUI.sendTransaction({- h% Q7 B; o% s4 ]
  11.           messages: [
    - s& @5 w) H/ F
  12.             {
    ! V/ [/ v, Y1 g, C
  13.               address: args.to.toString(),3 M/ D( S+ K% |
  14.               amount: args.value.toString(),# B5 \  t* v, `9 x' o
  15.               payload: args.body?.toBoc().toString('base64'),. |, a6 v8 i/ H  n
  16.             },
    + _1 e% Z5 [: A( m$ w! C
  17.           ],
    % d5 A; L% w. c2 [8 P% z- J7 }
  18.           validUntil: Date.now() + 5 * 60 * 1000, // 5 minutes for user to approve
    / E+ S5 [* K" O( X& |5 {: N1 W" z4 W
  19.         });9 ^8 k1 W# |$ T) P  S
  20.       },4 Z; `! O6 K* Z: w
  21.     },
    , d2 `  f/ e. |6 t
  22.     connected: tonConnectUI.connected,
    ' \: W( T9 B0 Q* j( }
  23.   };8 s& N" [- g: @( W$ o) t
  24. }
复制代码
您可以看到,我们正在返回一个对象,其中的函数 send 可以让我们触发交易请求,参数 connected 可以存储连接的当前状态。
接下来我们要做的是优化现有的 useCounterContract 钩子,并添加两个小功能。
  • 每 5 秒自动轮询一次计数器值。这将有助于向用户显示数值确实发生了变化。
  • 公开接口类的 sendIncrement 并将其连接到发送者。

    , n2 Q" C5 f! P8 q4 N% t
我们需要更新一些代码:
  1. // ... previous imports+ }1 i9 X2 x: \3 L/ O8 \
  2. import { toNano } from "ton-core";
    ( ~# F8 a6 G1 U+ o9 ~
  3. import { useTonConnect } from "./useTonConnect";
    - p. [( h3 P% _- u- A: d7 T8 R  E

  4. * i: Q  U1 F. S; |! y2 Y

  5. 2 X  v* G; ~. \
  6. export function useCounterContract() {
    7 r+ e9 S% C9 @) @
  7. 7 _  a% w+ D4 I, y' o; C
  8.     // ... variables definitions) N# F: x2 j1 J+ i' ~
  9.     const { sender } = useTonConnect();
    5 g: f7 d+ N9 N2 ?
  10.     ( V# m) d. b- @2 n1 I- B+ e8 O! d( x
  11.     const sleep = (time: number) => new Promise((resolve) => setTimeout(resolve, time));6 t; |* `1 K/ g8 N5 M" B
  12.    
    6 L$ L5 Q% t* f
  13.     // ... mainContract definition0 N- I' |" i' e  Y! ]. o: m/ r* @% H! u
  14.    
    - ?. t* ]) o, s9 X
  15.     useEffect(() => {
    8 b+ J- g4 [9 u5 |8 M' ^; p
  16.         async function getValue() {- J' k, }  `( J/ j# {$ t' ]
  17.     - V8 }+ \3 h. W1 O7 p+ l
  18.           // ... previous getValue code
    9 f* v2 g% e, g& u
  19. 1 a; Z6 O9 p  z( p" q1 Z! E' p* F
  20.           await sleep(5000); // sleep 5 seconds and poll value again
    7 t% ~) E5 K0 {7 t# ]2 j
  21.           getValue();3 N* T% T5 H* Q' y& N. Q0 l: D7 {
  22.         }) m7 m  }7 y  A: ~: j
  23.         getValue();* @/ ^6 i5 {+ A. ?. }+ D3 ]
  24.     }, [counterContract]);$ F8 n: d. w+ f4 p& j$ l

  25. / H7 W: i8 ]8 r

  26. ' j+ o# f2 y0 [% {* j% w% D9 j6 x
  27.     return {
    : A- _* I9 V! b( O; \/ e9 a) {
  28.         value: val,
    7 r5 M7 o+ u# T5 L8 C. c
  29.         address: counterContract?.address.toString(),% ?' M. K' ?) [. q) O. f0 W* k4 M
  30.         sendIncrement: () => {
    4 |. V- d5 R: W1 G
  31.           return mainContract?.sendIncrement(sender, toNano(0.05), 3);8 q* l' l3 D4 k
  32.         },
    - N4 |& f, x; Q' r- \! a, u, g- n' E* ]
  33.     };, P/ X" }9 _, K, [& {
  34. }
复制代码
此时,我们只需更新用户界面,就可以触发所需的交易。我们还需要在其中添加两样东西:

3 F1 l% M! e& K: F  ^8 A% m- x
  1. // ... previous imports
    8 u) b# o5 }& x
  2. import { useTonConnect } from "./hooks/useTonConnect";
    3 x$ X0 ?: i# |+ K
  3. ' V8 s7 s: F+ R! N  O$ `' _

  4. , ^2 H6 _2 x1 q3 j2 _7 t2 F
  5. function App() {
    , E: T2 X) u& \* t: K
  6.     ; H  l2 d7 N0 q7 `8 q& m
  7.     const { ..., sendIncrement } = useMainContract();9 z: ~. a8 @. g4 A
  8.     const { connected } = useTonConnect()
    # P( Q3 t" _3 o& L
  9.     + V, Y# a2 O3 ^" r6 U' l
  10.     return (
    " V/ A4 L. r, V* t9 Z# A/ k; w/ U
  11.         // ... other HTML code
    ; V3 U* f, T# r: R- k% w' H- T+ b& ]
  12.             
    2 D! @' M: c$ y
  13.             {connected && (
    ' l+ b& }4 q+ X0 `
  14.               <a
    & B2 W6 J7 k) H) Z, ~8 L
  15.                 onClick={() => {7 X' H/ @( U7 N& w  Q
  16.                   sendIncrement();* ?- X* ?  p) p- R, S
  17.                 }}
    " }5 \# C' L: Q
  18.               ># L. w8 |+ T3 Q% B* E) p9 g& G
  19.                 Increment
    . ?: H8 \% G$ S9 f
  20.               </a>
    # \: N2 l; ^4 G$ ?8 b- A, o
  21.             )}
    $ K% q6 p" }7 R4 f5 e8 f4 @4 r
  22.         $ y' @$ o. P( V5 m6 T. j
  23.         // ... other HTML code
    # ]# ]- O$ Z5 _) W! j2 g
  24.     )# \- q3 H( @% ?
  25. }
复制代码
5 D2 m" H6 w% u8 d( _# P4 L7 _

4 F  j2 R) N, C$ j  K" R2 p% T3 R/ X; K7 Z7 \  Z4 L* n7 ~+ T/ z
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则