[Metaplex Candy Machine] #4. Candy Guard 이해하기
목차
[Metaplex Candy Machine] #4. Candy Guard 이해하기 이 글은 Metaplex Candy Machine 시리즈의 4번째 글입니다. 하나의 Guard는 Candy Machine으로의 접근을 제어하는 모듈화 된 코드 조각으로 볼 수 있습니다. 선택할 수 있는 다양한 Guard들이 존재하고 각각은 활성화되거나 설정될 수 있습니다. 잠깐 몇 가지 Guard들을 살펴봅시다. 이 같은 Guard들을 필요에 따라 선택해서 Candy Machine을 만들 수 있습니다. 이전에 살펴봤듯이 Candy Machine Account에는 Guard들에 대한 표시가 없습니다. 이는 Guard들이 Candy Guard Program에 의해 생성되는 Candy Guard Account라 불리는 또 다른 Account에 존재하기 때문입니다. 각 Candy Machine Account는 자신의 Candy Guard Account와 연결되고, 이는 Protection 레이어를 추가하는 결과를 만듭니다. 즉, Candy Guard Account를 생성하고 Candy Machine의 Mint Authority 값으로 설정하는 것입니다. 이렇게 하고 나면 더 이상 Candy Machine Program으로부터 직접 Minting 하는 것이 불가능해집니다. 대신에 설정된 Guard들의 조건을 충족시켜 Candy Guard Program을 거쳐 Minting 해야 합니다. Candy Machine과 Candy Guard Account들은 함께 작동하고, Metaplex SDK는 이것들을 하나의 객체로 다룹니다. 우리가 SDK를 통해 Candy Machine을 만들 때, 기본적으로 연관된 Candy Guard Account 또한 생성됩니다. Guard들이 Candy Machine Program에 존재하지 않는 이유는 NFT 발행하는 책임을 가진 Candy Machine으로부터 접근 제어 로직을 분리하기 위해서입니다. 이것은 guard들을 모듈화 시킬 수 있고 확장가능하게 만들 수 있습니다. 즉, 누구나 커스텀한 Candy Guard Program을 만들어서 배포할 수 있습니다. 이제 우리는 Guard가 무엇인지 알았고, 기본적으로 제공되는 Guard들에 대해 간략히 알아봅시다. 이전에 우리가 생성했던 Candy Machine에는 어떤 Guard도 포함시키지 않았습니다. 이제 Guard에 대해 알았으니 Guard들을 포함시켜 Candy Machine을 만들어봅시다. 설정되지 않은 모든 Guard들은 기본적으로 비활성화됩니다. JS SDK를 사용해 Guard를 활성화하는 방법은 create 메서드에 guards 속성을 제공하고, 활성화를 원하는 guard들의 설정 값들을 작성하면 됩니다. Guard들 설정 값들을 변경하고 싶으면 생성할 때와 같이 업데이트할 수 있습니다. 새로운 값들을 넣을 수도 있고 기존 Guard의 값을 빈 상태로 제공해 비활성화시킬 수도 있습니다. update를 통해 guards 속성의 전체가 덮어쓰기 방식으로 업데이트되는 것입니다. 즉, 변경사항이 없는 Guard라도 유지하고 싶다면 동일하게 작성해야 합니다. Candy Machine에 Guard들을 설정하고 나면 누구나 이 설정을 조회하고 볼 수 있습니다. Metaplex SDK는 Candy Machine과 연관된 Guard들을 자동으로 하나의 객체에 포함시키기 때문에 우리는 하나의 객체를 통해 모든 데이터를 확인할 수 있습니다. Candy Machine과 Candy Guards는 따로 생성되고 연결시킬 수도 있는데, Metaplex SDK를 통해서도 가능합니다. 이 외에도 Guard Group을 만들거나 Guard Instruction을 Routing 하는 등의 내용도 있으니 좀 더 자세한 내용은 Reference를 참고해 주세요. 전체 목차:Candy Guard 이해하기
The Candy Guard Account
Why another program ?
All available guards
Creating a Candy Machine with guards
import { sol, toBigNumber, toDateTime } from "@metaplex-foundation/js";
const { candyMachine } = await metaplex.candyMachines().create({
itemsAvailable: toBigNumber(5000),
sellerFeeBasisPoints: 333, // 3.33%
collection: {
address: collectionNft.address,
updateAuthority: metaplex.identity(),
},
guards: {
botTax: { lamports: sol(0.01), lastInstruction: false },
solPayment: { amount: sol(1.5), destination: treasury },
startDate: { date: toDateTime("2022-10-17T16:00:00Z") },
// All other guards are disabled...
},
});Updating guards
import { sol, toDateTime } from "@metaplex-foundation/js";
await metaplex.candyMachines().update({
candyMachine,
guards: {
botTax: { lamports: sol(0.01), lastInstruction: false },
solPayment: { amount: sol(3), destination: treasury },
startDate: { date: toDateTime("2022-10-18T16:00:00Z") },
},
});Viewing the guards of a Candy Machine
const candyMachine = await metaplex.candyMachines().findByAddress({...});
// This is how you can access the Candy Guard account
// associated with the Candy Machine. When `null`,
// the Candy Machine does not use guards.
candyMachine.candyGuard;
candyMachine.candyGuard.guards; // All guard settings.
candyMachine.candyGuard.guards.botTax; // Bot Tax settings.
candyMachine.candyGuard.guards.solPayment; // Sol Payment settings.
// ...Wrapping and unwrapping Candy Guard accounts manually
import { sol, toBigNumber, toDateTime } from "@metaplex-foundation/js";
// Create a Candy Machine without a Candy Guard.
const { candyMachine } = await metaplex.candyMachines().create({
itemsAvailable: toBigNumber(5000),
sellerFeeBasisPoints: 333, // 3.33%
collection: {
address: collectionNft.address,
updateAuthority: metaplex.identity(),
},
withoutCandyGuard: true,
});
// Create a Candy Guard.
const { candyGuard } = await metaplex.candyMachines().createCandyGuard({
guards: {
botTax: { lamports: sol(0.01), lastInstruction: false },
solPayment: { amount: sol(1.5), destination: treasury },
startDate: { date: toDateTime("2022-10-17T16:00:00Z") },
},
});
// Associate the Candy Guard with the Candy Machine.
await mx.candyMachines().wrapCandyGuard({
candyMachine: candyMachine.address,
candyGuard: candyGuard.address,
});
// Dissociate them.
await mx.candyMachines().unwrapCandyGuard({
candyMachine: candyMachine.address,
candyGuard: candyGuard.address,
});References