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

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

回答

收藏

5.4 从 dApp 启动交易

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

上次的交互是只读的,现在我们通过发送交易来与合约交互。
我们在合约上开发的第一个功能是递增。让我们在主页面上添加一个发送交易的按钮。正如您所记得的,在链上发送交易需要花费GAS,因此我们希望钱包能与用户一起批准这一操作,并显示将花费多少Ton币。
在开始之前,我们将添加另一个钩子,从 TON Connect 接口生成一个发送方对象。该发送方代表已连接的钱包,允许我们代表它们发送交易。
在处理该交易请求时,我们还将在用户界面中显示钱包的连接状态,以便我们的用户界面将隐藏需要授权的元素。
就像我们在之前的课程中所做的那样,让我们使用 React 钩子来保留一些我们稍后将在代码中使用的功能。
让我们创建包含以下内容的文件 src/hooks/useTonConnect.ts:
  1. import { useTonConnectUI } from '@tonconnect/ui-react';+ l7 k4 z- _; C6 e( g
  2. import { Sender, SenderArguments } from 'ton-core';# U# Y* n, p" i
  3. & Q0 |( D, R) h4 J
  4. export function useTonConnect(): { sender: Sender; connected: boolean } {
    & f; k  E" ~9 `3 {# i# n8 I; o
  5.   const [tonConnectUI] = useTonConnectUI();& F% f. P7 y$ B* b( C# Z

  6. ! s! r; j" i' z5 |) T0 m
  7.   return {( }1 n& B7 F' l8 \2 l8 u
  8.     sender: {
    * s; [$ i8 z8 B' W# C' |: U! g
  9.       send: async (args: SenderArguments) => {, N7 F+ x. Y' D+ r" _' l0 v
  10.         tonConnectUI.sendTransaction({
    0 Y4 p" W' b, [! t- b
  11.           messages: [8 G) @' N7 S1 i& S
  12.             {
    2 T: C% c' u- `& H; w
  13.               address: args.to.toString(),) x) X  p+ z* I  H
  14.               amount: args.value.toString(),
    % B2 |$ u7 w1 A/ L, i) A
  15.               payload: args.body?.toBoc().toString('base64'),
    3 y4 ]6 \3 k0 y9 ]- s
  16.             },/ Q% Y4 R6 `% x1 v  f
  17.           ],% P3 a6 y$ T7 ?0 b
  18.           validUntil: Date.now() + 5 * 60 * 1000, // 5 minutes for user to approve
    " k8 C5 q- o+ A
  19.         });2 Z$ e$ U' P3 \5 u+ c
  20.       },
    ; i/ @/ _6 G; x1 j4 a8 t  b" T
  21.     },6 A* j3 x& Y) H: {% ^
  22.     connected: tonConnectUI.connected,
    0 N+ h1 Y9 U$ D# `0 y- d: d
  23.   };8 Z- {( P9 }5 b2 t7 _
  24. }
复制代码
您可以看到,我们正在返回一个对象,其中的函数 send 可以让我们触发交易请求,参数 connected 可以存储连接的当前状态。
接下来我们要做的是优化现有的 useCounterContract 钩子,并添加两个小功能。
  • 每 5 秒自动轮询一次计数器值。这将有助于向用户显示数值确实发生了变化。
  • 公开接口类的 sendIncrement 并将其连接到发送者。

    & d2 P9 u3 i5 w# R
我们需要更新一些代码:
  1. // ... previous imports
    1 k6 Q+ |- r6 s- \
  2. import { toNano } from "ton-core";  \. c/ q3 L9 D& n- T
  3. import { useTonConnect } from "./useTonConnect";
    4 c. X9 p7 G$ f& e. I3 N

  4. $ A9 f/ B4 B5 b  b" P6 R$ [; s
  5. 6 C, ^. \. Q4 v8 _
  6. export function useCounterContract() {
    + c5 m: ]% |( N& V, z  p4 o
  7. * g% h0 _6 u+ t- ]- z/ \  [" p/ [
  8.     // ... variables definitions
    , H' @! _( E6 S5 k
  9.     const { sender } = useTonConnect();
    * L7 K2 E2 D; W& q4 t6 i+ K* t
  10.    
    1 O' s8 @6 J8 ^5 n5 U: \
  11.     const sleep = (time: number) => new Promise((resolve) => setTimeout(resolve, time));
    / q; _1 L8 v0 |& v( @3 K
  12.    
    5 u: u: u$ H8 w& {$ O3 i+ k
  13.     // ... mainContract definition1 L/ y. Y& h1 }/ T! T; y* y
  14.    
    2 a. g( F4 W6 k& s: |. |
  15.     useEffect(() => {' D7 @( a: r5 B2 M+ Y. `3 C
  16.         async function getValue() {1 Z: Z: ]9 `: D2 c
  17.    
    : L; V2 P+ F/ Z! u: j1 \( u' o
  18.           // ... previous getValue code
    / Y% g* r3 Z  l$ Z  ^
  19. # H9 \+ _: l% J- A
  20.           await sleep(5000); // sleep 5 seconds and poll value again
    ( n2 _1 g+ |7 i0 z  e& o4 m
  21.           getValue();
    ! L7 P2 M5 ]9 Z) \
  22.         }% c: Z6 |. g& o
  23.         getValue();
    ' U: ^+ `1 q7 h; M
  24.     }, [counterContract]);% v' f0 ?- I, Y# G! c; I- C+ P

  25. / D5 k7 _, T. r/ Q- k. {
  26. 1 n4 X: d- f6 |/ [* w3 d. T
  27.     return {
      q% Z9 O% x$ P; D
  28.         value: val,
    6 u6 r4 b5 U4 M" p4 U! l$ P& k
  29.         address: counterContract?.address.toString(),
    ! M1 [- `2 U8 l- Q9 U1 R0 q$ i
  30.         sendIncrement: () => {
    + L2 s4 L  {& n3 a/ _5 w
  31.           return mainContract?.sendIncrement(sender, toNano(0.05), 3);
    1 x2 w+ _2 ]  Z* `
  32.         },  X6 h) R8 M5 C8 q1 z7 `
  33.     };
    0 @% E  `  }1 Z' ~; L& Z
  34. }
复制代码
此时,我们只需更新用户界面,就可以触发所需的交易。我们还需要在其中添加两样东西:
. |9 M, g' X- D8 q7 _3 {; z
  1. // ... previous imports
    / j& v$ W5 U4 J: {8 _
  2. import { useTonConnect } from "./hooks/useTonConnect";3 q1 z7 z% ?9 @4 t) }+ O* m

  3. , q' L# W/ Q4 z. K

  4. , _: D5 j6 A0 v4 [$ m: i5 M
  5. function App() {" P/ {  B2 t1 C. z
  6.     ) _# z6 a, ?( D2 i/ w
  7.     const { ..., sendIncrement } = useMainContract();
    1 _, x4 q/ I, G' l; ?# E' H5 n
  8.     const { connected } = useTonConnect()' j9 B* j  C# H
  9.     1 _! h  J: m  }$ [' a
  10.     return (
    , n" t1 {4 r* t- J
  11.         // ... other HTML code
    & b$ C) ?4 l7 F! h
  12.             3 X; P: B4 M- k1 K  i# @
  13.             {connected && (
    * {3 T/ q* ~" @9 x  l3 b7 _. [
  14.               <a1 O+ o  B% s* u+ h+ _7 S
  15.                 onClick={() => {) h" b5 _$ ?9 [- x* B
  16.                   sendIncrement();
    2 N  O2 F. M+ S9 N0 E3 V: y
  17.                 }}" o) ?% i4 T- o9 u; S0 \
  18.               >
    # {4 ]6 V$ H; {. \
  19.                 Increment' C8 f; g2 g0 J
  20.               </a>- o" _  U8 G( V; X
  21.             )}7 H2 o- w$ F: v, z, l& }
  22.         " H! t  c4 p% M1 N
  23.         // ... other HTML code
    $ R# _1 {9 d+ `# ^6 x
  24.     )
    , O) @- s) d& [5 i5 [; R. z
  25. }
复制代码

9 g" r# y1 _  v& w) @9 {4 W  ?" U- M$ z5 V- m" A: _
. d  F  |* p! y' m* ]# X9 S
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则