【问题标题】:How to find all NFTs minted from a v2 candy machine如何找到从 v2 糖果机铸造的所有 NFT
【发布时间】:2022-01-05 18:19:13
【问题描述】:

我正在铸造 Solana NFT。 Candy machine v2 最近发布,v1 已弃用。

如果我创建了一个 v2 糖果机并铸造了一些 NFT,我以后如何从所有铸造的代币中找到哈希值?

【问题讨论】:

    标签: solana nft metaplex solana-cli solana-web3js


    【解决方案1】:

    如果你有糖果机 id,你可以用这个找到所有的薄荷糖:

    import { Connection } from '@metaplex/js';
    import { Metadata, MetadataProgram } from '@metaplex-foundation/mpl-token-metadata';
    const connection = new Connection('mainnet-beta');
    const MAX_NAME_LENGTH = 32;
    const MAX_URI_LENGTH = 200;
    const MAX_SYMBOL_LENGTH = 10;
    const MAX_CREATOR_LEN = 32 + 1 + 1;
    
    
    
    const candyMachineId: string = 'BdNtsrV26ZHdqDFxmDfLib6CrcUNj4ePorhppHreRgER';
    
    export async function fetchHashTable(hash: string){
      const metadataAccounts = await MetadataProgram.getProgramAccounts(
        connection,
        {
          filters: [
            {
              memcmp: {
                offset:
                  1 +
                  32 +
                  32 +
                  4 +
                  MAX_NAME_LENGTH +
                  4 +
                  MAX_URI_LENGTH +
                  4 +
                  MAX_SYMBOL_LENGTH +
                  2 +
                  1 +
                  4 +
                  0 * MAX_CREATOR_LEN,
                bytes: hash,
              },
            },
          ],
        },
      )
    
      const mintHashes: any = []
    
      for (let index = 0; index < metadataAccounts.length; index++) {
        const account = metadataAccounts[index];
        const accountInfo: any = await connection.getParsedAccountInfo(account.pubkey);
        const metadata = new Metadata(hash.toString(), accountInfo.value);
        mintHashes.push(metadata.data.mint)
      }
      console.log(mintHashes)
    }
    fetchHashTable(candyMachineId)
    

    您可以在 solana cookbook 上找到更多信息

    编辑:以上内容适用于 Candy Machine V1。

    对于 Candy Machine V2,您需要执行以下操作:

    import { Connection, clusterApiUrl, PublicKey } from '@solana/web3.js';
    import bs58 from 'bs58';
    
    const connection = new Connection(clusterApiUrl('mainnet-beta'));
    const MAX_NAME_LENGTH = 32;
    const MAX_URI_LENGTH = 200;
    const MAX_SYMBOL_LENGTH = 10;
    const MAX_CREATOR_LEN = 32 + 1 + 1;
    const MAX_CREATOR_LIMIT = 5;
    const MAX_DATA_SIZE = 4 + MAX_NAME_LENGTH + 4 + MAX_SYMBOL_LENGTH + 4 + MAX_URI_LENGTH + 2 + 1 + 4 + MAX_CREATOR_LIMIT * MAX_CREATOR_LEN;
    const MAX_METADATA_LEN = 1 + 32 + 32 + MAX_DATA_SIZE + 1 + 1 + 9 + 172;
    const CREATOR_ARRAY_START = 1 + 32 + 32 + 4 + MAX_NAME_LENGTH + 4 + MAX_URI_LENGTH + 4 + MAX_SYMBOL_LENGTH + 2 + 1 + 4;
    
    const TOKEN_METADATA_PROGRAM = new PublicKey('metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s');
    const CANDY_MACHINE_V2_PROGRAM = new PublicKey('cndy3Z4yapfJBmL3ShUp5exZKqR3z33thTzeNMm2gRZ');
    const candyMachineId = new PublicKey('ENTER_YOUR_CANDY_MACHINE_ID_HERE');
    
    const getMintAddresses = async (firstCreatorAddress: PublicKey) => {
      const metadataAccounts = await connection.getProgramAccounts(
          TOKEN_METADATA_PROGRAM,
          {
            // The mint address is located at byte 33 and lasts for 32 bytes.
            dataSlice: { offset: 33, length: 32 },
    
            filters: [
              // Only get Metadata accounts.
              { dataSize: MAX_METADATA_LEN },
    
              // Filter using the first creator.
              {
                memcmp: {
                  offset: CREATOR_ARRAY_START,
                  bytes: firstCreatorAddress.toBase58(),
                },
              },
            ],
          },
      );
    
      return metadataAccounts.map((metadataAccountInfo) => (
          bs58.encode(metadataAccountInfo.account.data)
      ));
    };
    
    const getCandyMachineCreator = async (candyMachine: PublicKey): Promise<[PublicKey, number]> => (
        PublicKey.findProgramAddress(
            [Buffer.from('candy_machine'), candyMachine.toBuffer()],
            CANDY_MACHINE_V2_PROGRAM,
        )
    );
    
    (async () => {
    
      const candyMachineCreator = await getCandyMachineCreator(candyMachineId);
      getMintAddresses(candyMachineCreator[0]);
    
    })();
    

    确保将 ENTER_YOUR_CANDY_MACHINE_ID_HERE 替换为您的糖果机 ID

    【讨论】:

    • 这看起来很棒!!非常感谢。如果你有时间,你能解释一下这段代码吗?特别是,filters.memcmp.offset 发生了什么?我在食谱上没有看到。今晚我将对此进行测试,并在明天添加赏金。
    • @emersonthis 在cookbook 中有一个关于如何使用这些参数的很好的概述。最终,它会帮助您为您在帐户中寻找的内容找到正确的抵消。
    • 我在运行此代码时没有得到任何结果。我npm ied 这两个包并用我的糖果机地址替换了candyMachineId。但是当我使用ts-node 运行脚本时,我得到一个空数组[ ]。我知道铸币成功了,因为我在钱包里看到了所有的 NFT。任何想法我做错了什么?
    • 我有一种预感:我是用糖果机v2铸造的……这个脚本与最新版本不兼容吗?
    • 可能是糖果机 v2。我们今天更新了 v2 的参考资料。目前,这是带有 v2 代码的 PR,直到它被拉入 github.com/solana-dev-adv/solana-cookbook/pull/184/files
    猜你喜欢
    • 2022-10-19
    • 2022-07-05
    • 1970-01-01
    • 2022-08-12
    • 1970-01-01
    • 2022-01-11
    • 2022-08-12
    • 2022-01-17
    • 2022-07-05
    相关资源
    最近更新 更多