Ton WalletV4 Plugin 功能介绍

  • erick
  • 更新于 2024-10-24 17:02
  • 阅读 250

前提工作中碰到一个需求:如何在ton链上实现定阅功能,用户授权之后,项目方可以根据订阅条件进行扣款,比如项目方法推出会员机制,每月收费1Ton,但是不想用户自己发起支付交易,太麻烦,想要主动去扣费。

前提

工作中碰到一个需求:如何在ton链上实现定阅功能,用户授权之后,项目方可以根据订阅条件进行扣款,比如项目方法推出会员机制,每月收费1Ton,但是不想用户自己发起支付交易,太麻烦,想要主动去扣费。

正好有次看到ton的官方文档中好像有介绍这个功能

官方文档:https://docs.ton.org/mandarin/participate/wallets/contracts#%E9%92%B1%E5%8C%85v4 官方walletV4和plugin源码:ton-blockchain/wallet-contract

image.png

官方的文档只给出了源码,没有示例,研究之后写了一个demo。分享出来互相学习一下。

准备工作

  • 两个钱包,一个来部署plugin合约和当做plugin的admin权限,一个为测试账户
  • 获取测试代币,可以通过电报bot@testgiver_ton_bot,获取测试代币。

完成demo

demo的地址:https://github.com/erick785/ton-walletV4-plugin.git

初始化: yarn

研究WalletV4

我们看walletV4的源码(上面的官方仓库中有)会发现:

在合约中recv_external 接收外部消息方法有四个op操作码。这四个操作码,分别对应:

  • op==0 simple send: 简单发送交易功能
  • op==1 deploy and install plugin: 部署和加载 plugin功能
  • op==2 install plugin: 加载 plugin功能
  • op==3 remove plugin: 卸载 plugin功能

在合约中recv_internal 接受内部消息有两个op 操作码

  • op == 0x706c7567 request funds :请求付款,
  • op == 0x64737472 remove plugin by its request: 销毁卸载remove

在op == 0x706c7567 的代码逻辑中,会向plugin 插件合约发送一个op为0x706c7567 | 0x80000000的Message。

image.png

在op == 0x64737472 也有类似的逻辑。

所以我们plugin合约中要实现这个两个op操作,让钱包合约去调用。

实现Plugin合约

经过上述分析,我们来实现两个操作码:

image.png

在plugin合约的recv_internal 方法中,处理接收到op后需要进行的操作,收款人都是admin

image.png

那现在我们要怎么去操作,才能通过plugin 去扣款用户的钱呢?就是触发WalletV4的请求付款操作。 所以要在plugin再加一个操作码,通过调用plugin合约 ==> 触发用户WalletV4 合约==>触发plugin合约 这样的方式,来对用户进行扣款。 下面的事新增的op操作

image.png

image.png

所以扣款的逻辑就变成了这样:

  1. admin 调用 plugin合约的op:external_payment_request() 操作,通过函数request_payment 向用户发消息。这个消息的op是钱包WalletV4的op == 0x706c7567 request funds 。
  2. 用户的钱包接收到这个消息,将请求的金额携带做成消息,这个消息是调用plugin合约的op == (op:payment_request() | 0x80000000),
  3. plugin接受到用户的消息,把钱再转给了admin。

具体实现,看demo仓库中的plugin.fc

测试

部署plugin合约

  1. yarn 初始化项目
  2. mv .env.example .env 将admin的助记词填到WALLET_MNEMONIC,注意之间空格分隔就行
  3. yarn start ,根据提示选择选项

image.png

这个时候会打印 plugin合约的地址和plugin 合约地址的hash,记录下来

这是我测试的合约地址:EQBwsl7FTjVMPRSrFumW6kZxamxldPBemnflvVGpM6c7OGHD plugin合约地址Hash:0x70b25ec54e354c3d14ab16e996ea46716a6c6574f05e9a77e5bd51a933a73b38

交易tx

用户intsall 插件

  1. 打开installPlugin.ts, 修改用户的助记词和plugin合约地址Hash

image.png

  1. ts-node ./scripts/installPlugin.ts 执行脚本,用户就会intsall插件成功

image.png

交易tx

插件执行扣款

1.打开payRequest.ts 脚本,替换插件合约地址,和要扣款的用户的地址。

image.png

  1. yarn start 完成扣款 image.png

交易tx

在详情中我们就可以看到整个流程

image.png

用户销毁流程

和intsall 类似,大家可以自己试试。

总结

当用户完成intsall插件,插件就可不经过用户同意进行扣款。实话说风险确实很高,而且用户install插件是向钱包WalletV4发送 外部消息,现在市面的ton钱包都是不支持向钱包合约发送外部消息的。所以项目最后也没有使用这个功能去实现业务。而且这个功能只能扣除用户的ton,不能扣除jetton token,也是个缺点。不过听说walletV5的会有更强大的插件功能,有机会去看看,学习一下。

  • 原创
  • 学分: 2
  • 分类: TON
  • 标签:
点赞 0
收藏 0
分享

0 条评论

请先 登录 后评论
erick
erick
0xc1C0...1FC3
联系邮箱:yerick785@gmail.com