Skip to content

卫士组

作者 崔棉大师 X:@MasterCui Youtube: 崔棉大师

知识点

在上一章节中,我们引入了保护机制,并使用它们来定义糖果机的访问控制。我们已经看到,使用保护机制,我们可以例如添加每枚糖果 1 SOL 的付款,并确保糖果在某个日期后开始铸造。但如果我们还想在第二个日期后收取 2 SOL 怎么办?如果我们想允许某些代币持有者免费或以折扣价铸造糖果怎么办?

如果我们可以定义多组卫士,每组都有自己的要求,会怎么样?为此,我们创建了卫士组!

课程

1.运作方式

还记得我们只需提供想要启用的Guard设置,就可以在任何糖果机上设置Guard吗?好吧,Guard Group的工作方式相同,只是您还必须为他们提供唯一的标签来识别它们。

因此,每个Guard Group都具有以下属性:

  • 第一组:
    • label:"早鸟"
    • guards
      • SOL 付款:1 SOL
      • 开始时间:下午 4 点
      • 结束时间:下午 5 点
      • 机器人税:0.001 SOL
  • 第二组:
    • label:"公售"
    • guards
      • SOL 付款:2 SOL
      • 开始时间:下午 5 点
      • 机器人税:0.001 SOL

就这样,我们创建了一个定制的两层铸造流程!

现在,每当有人尝试从我们的糖果机铸造糖果时,他们都必须明确告诉我们他们从哪个组铸造糖果。铸造糖果时询问组标签很重要,因为:

  • 它确保买家不会遇到意外的铸造行为。假设我们试图在第一个组的结束日期快结束时铸造 1 SOL,但到交易执行时,我们已经过了那个日期。如果我们不要求组标签,交易就会成功,我们会被收取 2 SOL,尽管我们预计只会被收取 1 SOL。
  • 它使得支持并行组成为可能。我们将在本页的后面部分详细讨论这一点。

candy-guard-group

js
import { some, sol, dateTime } from "@metaplex-foundation/umi";

const candyGuard = await fetchCandyGuard(umi, candyMachine.mintAuthority);
await updateCandyGuard(umi, {
  candyGuard: candyGuard.publicKey,
  guards: candyGuard.guards,
  groups: [
    {
      label: "early",
      guards: {
        solPayment: some({ lamports: sol(1), destination: treasury }),
        startDate: some({ date: dateTime("2024-7-1T16:00:00Z") }),
        endDate: some({ date: dateTime("2024-7-1T17:00:00Z") }),
        botTax: some({ lamports: sol(0.001), lastInstruction: true }),
      },
    },
    {
      label: "public",
      guards: {
        solPayment: some({ lamports: sol(3), destination: treasury }),
        startDate: some({ date: dateTime("2024-7-1T17:00:00Z") }),
        botTax: some({ lamports: sol(0.001), lastInstruction: true }),
      },
    },
  ],
}).sendAndConfirm(umi);

完整代码

2.默认卫士

请注意,在上面的例子中,我们必须为两个组提供相同的Bot Tax保护。这可以通过利用在 Candy Machine 上设置的全局 Guard来简化。

使用Guard Group时,糖果机的全局 Guard将充当默认 Guard!这意味着组将默认使用与全局 Guard相同的 Guard 设置,除非它们通过在组中明确启用它们来覆盖它们。

以下是简要回顾:

  • 如果在默认Guard上启用了某个规则但未在Guard Group上启用这个规则,则使用默认Guard中定义的规则。

  • 如果在默认GuardGuard Group都启用了规则,则使用Guard Group中定义的规则。

  • 如果默认GuardGuard Group都没有启用的规则,则不会使用此规则。

  • 默认Guard

    • 机器人税:0.001 SOL
  • 第一组:

    • label:"早鸟"
    • guards
      • SOL 付款:1 SOL
      • 开始时间:下午 4 点
      • 结束时间:下午 5 点
  • 第二组:

    • label:"公售"
    • guards
      • SOL 付款:2 SOL
      • 开始时间:下午 5 点

正如您所见,默认Guard有助于避免组内重复。

candy-guard-default

请注意,即使使用默认Guard,铸造时也必须提供一个组。这意味着,当使用守卫组时,不能仅使用默认Guard进行铸造。

js
import { some, sol, dateTime } from "@metaplex-foundation/umi";

await create(umi, {
  // ...
  guards: {
    botTax: some({ lamports: sol(0.001), lastInstruction: true }),
  },
  groups: [
    {
      label: "early",
      guards: {
        solPayment: some({ lamports: sol(1), destination: treasury }),
        startDate: some({ date: dateTime("2024-7-1T16:00:00Z") }),
        endDate: some({ date: dateTime("2024-7-1T17:00:00Z") }),
      },
    },
    {
      label: "late",
      guards: {
        solPayment: some({ lamports: sol(2), destination: treasury }),
        startDate: some({ date: dateTime("2024-7-1T17:00:00Z") }),
      },
    },
  ],
}).sendAndConfirm(umi);

完整代码

3.平行组

在铸造时要求组标签的一个真正有趣的好处是能够在给定时间内拥有多个有效组。这消除了程序的任何歧义,并允许购买者选择他们想要尝试铸造的组。

让我们用一个新的例子来说明这一点。假设我们有一个名为"无辜鸟"的 NFT 系列,我们想为任何持有"无辜鸟" NFT 的人提供 1 SOL 的折扣价,并向其他任何人收取 2 SOL。我们希望这两个组能够同时开始铸造 - 比如下午 4 点 - 并且我们还希望保护这两个组免受机器人的攻击。以下是我们可以配置防护的方法:

  • 默认Guard
    • 开始时间:下午 4 点
    • 机器人税:0.001 SOL
  • 第一组:
    • label:"nft"
    • guards
      • SOL 付款:1 SOL
      • NFT 门:"无辜鸟"收藏品
  • 第二组:
    • label:"公售"
    • guards
      • SOL 付款:2 SOL

如您所见,通过这些保护设置,两个组可以同时铸造。如果 NFT 持有者决定从"公售"组铸造,他们甚至可以支付全部 2 SOL。但是,如果可以的话,选择"nft"组对他们最有利。

js
import { some, sol, dateTime } from "@metaplex-foundation/umi";

await create(umi, {
  // ...
  guards: {
    botTax: some({ lamports: sol(0.001), lastInstruction: true }),
    startDate: some({ date: dateTime("2024-7-1T16:00:00Z") }),
  },
  groups: [
    {
      label: "early",
      guards: {
        solPayment: some({ amount: sol(1), destination: treasury }),
        nftGate: some({
          requiredCollection: innocentBirdCollectionNft.publicKey,
        }),
      },
    },
    {
      label: "public",
      guards: {
        solPayment: some({ amount: sol(2), destination: treasury }),
      },
    },
  ],
}).sendAndConfirm(umi);