Let's Move (写一个抢红包脚本)

  • xing.sir
  • 更新于 2024-04-08 09:36
  • 阅读 1219

社区的小伙伴应该都收到过ASCII红包吧。来自https://sui-red-packet.vercel.app/。如果没收到那就发一个吧😄。

社区的小伙伴应该都收到过 ASCII 红包吧。 来自 https://sui-red-packet.vercel.app/ 。 如果没收到那就发一个吧 😄 。 看到红包,应该大家都想收入囊中,这篇文章就尝试搞定这个事情。

合约分析

合约被movefuns的大佬开源在 github : https://github.com/movefuns/sui-red-packet/blob/main/contract/sources/red_packet.move 关于合约部分的分析,大家可以转移到 https://learnblockchain.cn/article/7772 这篇文章来看,写的很详细。 这篇文章,主要是客户端调用。

脚本逻辑分析

脚本主要逻辑是通过监控合约的事件,自动触发抢红包的交易。

  1. 监控合约交互有两种办法: 一种是 通过 subscribe event ,另一种 是轮询 event 。其中第一种较为节省系统资源,第二种,在做轮询的时候还需要考虑重复性。
  2. 获取到触发的event 事件后,就可以解析event 中的数据,获取需要的资源对象。
  3. 根据获取到的相关资源,拼装交易内容,通过 client 发送交易。

脚本实现:

环境安装

使用标准的typescript 开发环境,安装 sui 的客户端sdk :

npm init -y 
pnpm i typescript ts-node ts-node-dev @types/node --save-dev
pnpm tsc --init 
pnpm i @mysten/sui.js

账户初始化:

因为涉及实际交易,同时,后期还会将抢到的 Token 转移到 自己的Wallet 中。所以,请保证一个有效的账号信息, 这里通过助记词导入账户,你也可以通过其他的方式获取账户信息。

const seedText = "";
const seedHex = mnemonicToSeedHex(mnemonic);
const hexpair = Ed25519Keypair.deriveKeypairFromSeed(seedHex);

获取 event

这里使用客户端轮询的方式获取, 每次获取最新的5个时间信息,然后轮询。 1秒钟获取一次。 如果你想提高你的脚本灵敏度,可以适当调整轮询的时间。

while (true) {
    const events = await client.queryEvents({
      query: {
        MoveEventType: "0xcontractaddress..................::packet....::NewRedPacket<0x2::sui::SUI>",
      },
      order: "descending",
      limit: 5,
    });
    for (let event of events.data) {
      // 解析event  数据
      const j = event.parsedJson as any;
      // 获取 红包id 备用。
      let redPacketId = j.red_packet_id as string;
      // 可以加入一层缓存,避免无效的事件处理
      if (emptyRedpacketCache.has(redPacketId)) {
        console.log(`red packet ${redPacketId}  is empty from cache !`);
      } else {
        // 触发自动抢红包的交易。
        await autoClaim(redPacketId);
      }
    }
    await new Promise((r) => setTimeout(r, 1000));
  }

subscribe 的方式,对服务器的要求比较高,比较节约客户端资源。目前 官方的 rpc 还有些问题,所以大家选择性使用。

autoClaim 抢红包交易

抢之前,先判断下红包的状态,以避免无效的交易:

 // 获取红包资源对象
 const redPacket = await client.getObject({
    id: redpacketId,
    options: {
      showContent: true,
    },
  });
  // 判断资源非空
  if (redPacket && redPacket.data?.content) {
    const content = redPacket.data.content as any;
    const fields = content.fields as any;

   // 判断还可以抢
    if (fields.left_amount != 0) {
        ......
    }

claim_red_packet 交易相关参数:

  1. red_packet_id 红包id , 从 event 中获取
  2. weather oralce 设置随机性的
  3. 时间戳参数 0x6 固定参数
      const txb = new TransactionBlock();
      txb.moveCall({
        target: "0xcontractaddress..................::packet....::claim_red_packet",
        typeArguments: ["0x2::sui::SUI"],
        arguments: [
          txb.pure(redpacketId),
          txb.pure(
            "0x1aedcca0b67b891c64ca113fce87f89835236b4c77294ba7e2db534ad49a58dc"
          ),
          txb.pure("0x6"),
        ],
      });
      const result = await client.signAndExecuteTransactionBlock({
        transactionBlock: txb,
        signer: keypair,
        requestType: "WaitForLocalExecution",
        options: {
          showEffects: true,
        },
      });

写到最后

希望通过这篇文章大家可以掌握合约自动事件流的方法。 😄

欢迎加入 Let's Move 社区:

telegram: <https://t.me/move_cn> QQ群: 79489587

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
xing.sir
xing.sir
0x427f...39a8
web3 让世界更美好。