使用Umi创建CandyMachine遇0x39错误及鉴别器问题求助
错误原因分析
1. 创建Candy Machine时的0x39错误
日志中的Incorrect account owner和自定义错误码0x39,核心问题是Collection NFT的权限配置错误:
- 原代码中创建Collection NFT时使用了临时生成的
collectionUpdateAuthority作为权限签名者,但该签名者未被设置为UMI的身份主体,导致后续Candy Machine调用元数据程序的Delegate指令时,权限验证失败。 - 创建Candy Machine时,必须确保Collection NFT的更新权限持有者能合法委托权限给Candy Guard,而临时生成的无权限签名者无法完成这一步。
2. Wrong Discriminator错误
该错误是Candy Machine账户未成功创建的连锁反应:SDK查询账户时,无法识别未正确初始化的账户结构(discriminator是账户类型的唯一标识),只要解决第一个问题成功创建Candy Machine,此错误会自动消失。
修复方案及代码
核心修复点
- 将Collection NFT的更新权限直接设置为UMI的身份(你的钱包密钥对),确保后续Candy Machine能正常获取委托权限。
- 统一Candy Machine创建时的
collectionUpdateAuthority参数为UMI身份,保持权限一致性。
完整修复代码
import { Keypair } from "@solana/web3.js"; import { createUmi } from '@metaplex-foundation/umi-bundle-defaults' import { publicKey, some, generateSigner, percentAmount, keypairIdentity, createSignerFromKeypair } from "@metaplex-foundation/umi"; import { fetchCandyMachine, fetchCandyGuard, mplCandyMachine, create, } from '@metaplex-foundation/mpl-candy-machine' import { createNft, TokenStandard, } from '@metaplex-foundation/mpl-token-metadata' async function manageCandyMachine() { const umi = createUmi('https://api.devnet.solana.com').use(mplCandyMachine()) // 初始化身份主体 const myKeypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array([15,96,246,96,168,118,204,153,41,122,14,70,62,175,75,122,122,10,202,172,60,76,153,241,33,130,7,194,51,240,101,221,168,191,211,242,139,189,173,204,59,2,253,72,101,253,176,40,31,52,98,56,62,115,191,231,79,53,241,119,160,252,8,129])); const myKeypairSigner = createSignerFromKeypair(umi, myKeypair); umi.use(keypairIdentity(myKeypairSigner)); // 创建Collection NFT:使用UMI身份作为更新权限 const collectionMint = generateSigner(umi) await createNft(umi, { mint: collectionMint, authority: umi.identity, name: 'My Collection NFT', uri: 'https://example.com/path/to/some/json/metadata.json', sellerFeeBasisPoints: percentAmount(9.99, 2), // 9.99% isCollection: true, }).sendAndConfirm(umi) console.log('Collection Mint地址:', collectionMint.publicKey.toString()); console.log('当前操作钱包:', umi.identity.publicKey.toString()); // 创建Candy Machine:保持权限参数一致 const candyMachine = generateSigner(umi); await(await create(umi, { candyMachine, collectionMint: collectionMint.publicKey, collectionUpdateAuthority: umi.identity, tokenStandard: TokenStandard.NonFungible, sellerFeeBasisPoints: percentAmount(9.99, 2), // 9.99% itemsAvailable: 5, creators: [ { address: umi.identity.publicKey, verified: true, percentageShare: 100, }, ], configLineSettings: some({ prefixName: '', nameLength: 32, prefixUri: '', uriLength: 200, isSequential: false, }), })).sendAndConfirm(umi) const candyMachinePublicKey = candyMachine.publicKey console.log('Candy Machine公钥:', candyMachinePublicKey.toString()) // 查询并打印Candy Machine信息 const cm = await fetchCandyMachine(umi, candyMachinePublicKey) console.log('Candy Machine详情:'); console.log('- 公钥:', cm.publicKey.toString()) console.log('- Mint权限地址(Candy Guard):', cm.mintAuthority.toString()) console.log('- 总NFT数量:', cm.data.itemsAvailable) console.log('- 已铸造数量:', cm.itemsRedeemed) const candyGuard = await fetchCandyGuard(umi, cm.mintAuthority) console.log('Candy Guard公钥:', candyGuard.publicKey.toString()) } manageCandyMachine()
额外注意事项
- 确保你的钱包有足够的Devnet SOL,可通过Solana水龙头获取。
- 运行命令保持不变:
ts-node createCandyMachine.ts。 - 若仍有问题,可通过Solana Explorer查询
collectionMint地址的元数据账户,确认更新权限是否正确设置为你的钱包地址。
内容的提问来源于stack exchange,提问作者MXX
相关产品推荐
相关产品推荐

