Typescript
使用Web3.js的Token2022

使用Web3.js的Token2022

群組與成員擴展

GroupMember 擴展是 Mint 帳戶擴展,提供了創建群組的功能,例如與多個資產相關聯的 NFT 集合。

初始化鑄幣帳戶

MemberGroup 擴展與我們習慣的方式有些不同,因為它由兩個不同的擴展組成,這兩個擴展都位於 Mint 帳戶上:

  • 包含有關群組或成員的所有信息的 Extension

  • 參考 Mint 帳戶的 Pointer Extension,該帳戶中存有 GroupMember 擴展。

通常情況下,ExtensionPointer Extension 位於同一個 Mint 帳戶中;在這個例子中,我們也會這樣做。

GroupMember 擴展不能位於同一個帳戶中

在深入代碼之前,讓我們先了解一些基礎知識:

雖然 GroupPointerMemberPointer 擴展位於 @solana/spl-token 套件中,但要初始化 GroupMember,我們需要使用 @solana/spl-token-group 套件。

因此,讓我們安裝所需的套件:

text
npm i @solana/spl-token-group

此外,GroupMember 擴展是少數需要在初始化 Mint 帳戶後再初始化擴展的擴展之一。

這是因為元數據初始化指令會根據群組和成員內容的長度動態分配所需的空間。

同時,這意味著我們需要在初始化 Mint 帳戶時,為包含 GroupMember 擴展的情況提供足夠的 lamports 以達到免租金的要求,但僅為 GroupPointerMemberPointer 擴展分配足夠的空間,因為 token_group_initialize()token_group_member_initialize() 指令實際上會正確地增加空間。

在程式碼中初始化 Group 看起來是這樣的:

ts
const mint = Keypair.generate();

// Size of Mint Account with extensions
const mintLen = getMintLen([ExtensionType.GroupPointer]);

// Minimum lamports required for Mint Account
const lamports = await connection.getMinimumBalanceForRentExemption(
  mintLen + TYPE_SIZE + LENGTH_SIZE + TOKEN_GROUP_SIZE,
);

const createAccountInstruction = SystemProgram.createAccount({
  fromPubkey: keypair.publicKey,
  newAccountPubkey: mint.publicKey,
  space: mintLen,
  lamports,
  programId: TOKEN_2022_PROGRAM_ID,
});

const initializeGroupPointer = createInitializeGroupPointerInstruction(
  mint.publicKey,
  keypair.publicKey,
  mint.publicKey,
  TOKEN_2022_PROGRAM_ID,
);

const initializeMintInstruction = createInitializeMintInstruction(
  mint.publicKey,
  6,
  keypair.publicKey,
  null,
  TOKEN_2022_PROGRAM_ID,
);

const initializeGroupInstruction = createInitializeGroupInstruction({
  programId: TOKEN_2022_PROGRAM_ID,
  group: mint.publicKey,
  mint: mint.publicKey,
  mintAuthority: keypair.publicKey,
  updateAuthority: keypair.publicKey,
  maxSize: BigInt(100),
});

const transaction = new Transaction().add(
  createAccountInstruction,
  initializeGroupPointer,
  initializeMintInstruction,
  initializeGroupInstruction,
);

const signature = await sendAndConfirmTransaction(connection, transaction, [keypair, mint], {
  commitment: "finalized",
});

console.log(
  `Mint created! Check out your TX here: https://explorer.solana.com/tx/${signature}?cluster=devnet`,
);
Expand
[41 more lines]

完成這一步後,我們可以使用剛剛建立的群組來新增成員,如下所示:

ts
const member = Keypair.generate();

// Size of Member Account with extensions
const memberLen = getMintLen([ExtensionType.GroupMemberPointer]);

// Minimum lamports required for Member Account
const lamports = await connection.getMinimumBalanceForRentExemption(
  memberLen + TYPE_SIZE + LENGTH_SIZE + TOKEN_GROUP_MEMBER_SIZE,
);

const createAccountInstruction = SystemProgram.createAccount({
  fromPubkey: keypair.publicKey,
  newAccountPubkey: member.publicKey,
  space: memberLen,
  lamports,
  programId: TOKEN_2022_PROGRAM_ID,
});

const initializeGroupMemberPointer = createInitializeGroupMemberPointerInstruction(
  member.publicKey,
  keypair.publicKey,
  member.publicKey,
  TOKEN_2022_PROGRAM_ID,
);

const initializeMintInstruction = createInitializeMintInstruction(
  member.publicKey,
  6,
  keypair.publicKey,
  null,
  TOKEN_2022_PROGRAM_ID,
);

const initializeGroupMemberInstruction = createInitializeMemberInstruction({
  programId: TOKEN_2022_PROGRAM_ID,
  group: mint.publicKey,
  member: member.publicKey,
  memberMint: member.publicKey,
  memberMintAuthority: keypair.publicKey,
  groupUpdateAuthority: keypair.publicKey,
});

const transaction = new Transaction().add(
  createAccountInstruction,
  initializeGroupMemberPointer,
  initializeMintInstruction,
  initializeGroupMemberInstruction,
);

const signature = await sendAndConfirmTransaction(connection, transaction, [keypair, member], {
  commitment: "finalized",
});

console.log(
  `Member created! Check out your TX here: https://explorer.solana.com/tx/${signature}?cluster=devnet`,
);
Expand
[41 more lines]
Blueshift © 2026Commit: 3c44267