使用技巧

Web3 DApp 集成:TON Connect、钱包签名与智能合约调用

面向开发者的 Web3 集成指南:讲解 TON Connect 连接、钱包签名与交易结算的区别,如何验证地址归属、诚实描述确认页、处理超时等第三种结果,并提醒隐私与安全风险。

内容导读

面向开发者的 Web3 集成指南:讲解 TON Connect 连接、钱包签名与交易结算的区别,如何验证地址归属、诚实描述确认页、处理超时等第三种结果,并提醒隐私与安全风险。

Web3 DApp 集成:TON Connect、钱包签名与智能合约调用主题插画

第 089 步从持有者的角度讲了钱包。这一步是开发者的角度:一个迷你应用想要知道某人拥有哪个钱包,有时还想请他们发送一些东西。其机制是两个互不信任的软件之间的连接,而这种不信任正是整个设计的核心。

有一个错误造成了出问题的大部分情况。你的页面交给服务器的地址是一种声明,而不是事实。任何人都可以输入任何人的地址,包括一个众所周知的地址。

完成这一步后你将能够做到

  • 区分声称的地址与已证明的地址。
  • 把连接、签名和结算分开——这是三个不同的事件。
  • 编写一笔确认页能够如实描述的交易。
  • 处理既非成功也非失败的结果。

连接究竟是什么

钱包是独立的软件——手机上的另一个应用,或者完全在另一台设备上的东西。你的页面无法伸进去,它也无法伸进你的页面,所以中间有某个东西来回传递消息。

那个中间人不受信任,也不需要被信任。所有重要的内容要么在两端之间加密,要么以你的服务器能够独立校验的方式签名。这正是该设计能奏效的原因,也是跳过校验就会抹掉其全部意义的原因。

从用户的角度看,流程很短:你的应用发出请求,他们的钱包显示被请求的内容,他们批准或不批准。从你的角度看,这是三个独立的事件,人们常把它们混为一谈,但不应该。

连接意味着你现在知道了一个地址,可以请求一些事情。签名意味着他们批准了一个具体的请求。结算意味着网络接受了它,这发生在更晚的时候,并且可能在钱包已经返回之后失败。

你的前端向你的服务器发送了一个钱包地址。你能把那个人当作它的所有者吗?

是的——该地址来自钱包,通过连接传来

不——只有对你生成的挑战进行签名才能证明所有权

是的,前提是该地址有交易历史

你的页面运行在别人的设备上,它发送给你的任何内容在到达之前都可能被篡改。地址是公开信息,所以声称一个著名地址毫无成本,也是任何人针对一个凭余额授予权益的应用首先会尝试的事。修复方法标准且廉价:你的服务器生成一个一次性值,钱包对它签名,然后你对照地址校验该签名。只有到那时你才真正得知了什么。如果你的应用曾经因为持有某物而给予好处——访问权、角色、奖励——却跳过了这一步,那它就是在把好处给任何输入正确字符串的人。

用户把钱包连接到你的应用。他们授权了什么?

在限额内的交易,无需进一步提示

没有任何东西会被转移——你可以看到地址并发出请求,每个请求都单独获得批准

访问余额,以便应用按需扣除费用

连接是介绍,不是许可。你获得的是查看一个公开地址的能力,以及把请求呈现在钱包面前的能力,每一个请求都由本人单独批准或拒绝。由此得出两点。作为开发者,不要设计一种假设已连接用户可以被静默扣款的流程——每个操作都需要自己的批准,也需要自己对拒绝的处理。作为用户,连接是低风险的一步,批准才是要紧的一步,这正是从另一个方向看第 089 步的那个区分。连接确实会暴露你的地址,从而暴露其公开历史,这是一个隐私考量,而非财务考量。

用户批准付款后钱包成功返回。你就把订单标记为已付款吗?

是的——钱包确认了它

不——它只是被签名并发送了,这与被接受不是一回事

是的,然后在网络拒绝时撤销它

成功返回意味着用户批准了,交易离开了钱包。它仍然可能失败——余额不足以支付手续费、有效期窗口过期、消息被拒绝——而且无论如何都需要时间才能结算。把钱包的响应当作付款,正是应用为从未落地的交易交付商品的方式。而第三种选择比第一种更糟:正如第 089 步所说,没有撤销,所以乐观地记为已收款就是白送。正确的形态是一个待处理状态,检查交易确实出现并把预期金额带到了预期地址,然后才履行——同时要有第 094 步对任何付款所要求的防止重复处理的同样保护。

确认页是唯一诚实的界面

用户在此刻之前看到的一切都是你绘制的。钱包渲染的那张确认页是你唯一没有写的东西,也是谨慎的人真正阅读即将发生什么的地方。

所以要编写那张确认页能够很好描述的交易。一个他们能认出的目的地,一个与你页面所说相符的金额,以及一条附加在转账上、人类可读的备注,而不是一个不透明的数据块。一个确认屏幕显示陌生地址且没有任何解释的应用,是在要求人们凭信任批准,而谨慎的人不会这么做。

面向用户的那一半就是第 089 步的规则:在确认页上而不是在生成它的页面上阅读金额和目的地。让两半保持一致地构建,不仅是礼貌,更是决定批准率反映的是意图、还是对你的设计的信任之间的差别。

绝不要索取助记词,无论出于任何理由,在任何时候 没有任何正当流程需要它,而一个索取它的页面与它所模仿的盗窃无法区分。用户已经被(正确地)训练过这一点,所以即使是一个善意的提示也会把你的应用标记为骗局并终止会话。私钥和登录验证码同样如此。

为那种既非成功也非失败的结果而设计

大多数钱包集成处理了成功和失败,却在第三种情况上崩溃,而这种情况很常见:什么也没返回。

那个人切换到钱包后分了心。他们关掉了它。他们读了确认页,决定再想想。手机锁屏了,来了个电话,连接断了。从你的应用的角度看,请求已发出,而答案不存在,可能永远不存在。

由此得出三点。绝不要留下一个永久转圈——超时后进入一个能自我解释并提供重试的状态。绝不要把超时当作拒绝,因为交易可能仍在进行中,重试可能产生两笔。并且让恢复路径是核对而不是重复:在提供再发一笔之前,先检查预期的交易是否已经到达。

同样的纪律也适用于迷你应用界面本身。第 088 步的警告在这里直接适用——面板可能在流程中途被划走,所以用户投入了精力的任何内容都应该能在关闭并重新打开后存活。

现在试一试——五分钟

四个步骤。第二步是区分一个能用的集成与一个演示的测试。

  1. 检查你的应用是否验证了所有权 找到地址变成已登录用户的地方。如果两者之间没有签名校验,那就是今天的工作。
  2. 批准一笔交易,然后杀掉钱包应用 观察你的界面会怎么做。如果它永远等待或宣告失败,两者都是错的。
  3. 像一个陌生人那样阅读你自己的确认页 目的地能认出来吗?金额与你页面相符吗?有备注解释这是什么吗?
  4. 用一个持有代币但没有网络货币的钱包试试这个流程 这是现实中最常见的卡住状态,而大多数应用对此什么有用的话都不说。

你正在连接起来的东西

构建这个的一个后果值得单独用一段来讲,因为它很容易在不知不觉中产生。

一个迷你应用已经知道打开它的 Telegram 账号(第 088 步)。加上钱包连接,你现在就持有一个人的账号与一个全部历史都公开的地址之间的联系。任何拿到你记录的人都能查到这个地址曾经做过的一切,而任何拿到该地址的人也能反向做同样的事。

这可能正是你的应用所需要的。但它仍然是一条在你制造它之前不存在的记录,由你持有,并且对别人有价值。第 093 步的常规纪律在这里比平时更有力地适用:只存最少的内容,需要多久就保留多久、不要更久,并且对你这边谁能读取它要有明确的考量。

并且告诉人们。一个直白说明它记录了什么的应用没有做任何不寻常的事;一个悄悄建立这种映射却只字不提的应用,是在用户不知情的情况下替他们做了一个决定,而如果被问到,他们很可能会同意。

这个阶段的常见问题

我需要自己的服务器吗,还是可以完全放在页面里?

任何授予权益的东西都需要服务器。第一个测验项里的验证必须发生在用户无法修改的地方,而运行在他们设备上的页面不是那个地方。纯前端的集成对于显示余额或让某人向他们自己选择的地址发起转账是没问题的——一旦你的应用决定这个人有权获得某物,那个决定就属于你这边。

登录挑战应该有效多久?

足够一个人打开钱包、阅读并批准——是几分钟而不是几秒钟——同时又要短到被截获后过一会儿就没用。它还必须是单次使用并存储在你这边,因为其目的是证明这个签名是现在为你而做的,而客户端提供的值什么也证明不了。如果你发现自己因为用户总是错过窗口而延长它,问题通常是流程令人困惑,而不是超时。

我应该支持多个钱包应用吗?

标准的连接机制被设计成让你支持的是一个接口而不是一个产品,这正是重点——你列出实现了它的钱包,由用户挑选。实践中不同的是每个钱包如何渲染你的确认页,所以在断定你的交易被清楚描述之前,用不止一个来测试。那个把你的备注显示得很漂亮的,可能并不是你大多数用户所拥有的。

我的用户抱怨他们的转账无缘无故失败了。

检查他们是否持有该网络自己的货币。转移任何东西都要花费一点用它支付的手续费,所以一个只含代币的钱包无法发送那些代币——这是一个真正令人困惑的状态,看起来像 bug 却不是。一个好的应用会在尝试之前检测到这一点并用平实的话说出来。一个更好的应用会说明需要多少,因为对一个不知道需要多少的人来说,“给你的钱包充值”不是可操作的建议。

我可以在不花真钱的情况下测试吗?

可以——有一个测试网络,钱包可以指向它,你应该在那里做所有的开发。更重要的是你测试哪些路径:成功路径一小时内就能跑通,而让你损失客户的是拒绝、超时、手续费不足、请求过期和重复提交。把这五个写下来并逐一刻意尝试,因为在你构建时它们没有一个会偶然发生。

这些适合普通大众吗?

对你的用户是谁要诚实。第 089 步里的一切都适用于每一个把钱包连接到你的应用的人:不可逆性、助记词的保管,以及一类专门针对正在做你要求他们做的事的人的骗局。构建一个需要钱包的流程会排除大多数人,并让其余的人暴露于风险。如果你的应用的价值并不真正依赖它,第 094 步的应用内支付对你更简单,对他们更安全。

← 返回 TG知识库