更新 Metaplex NFT 的元数据

Update Metadata of Metaplex NFT

我在更新 Metaplex NFT 元数据时遇到了一些问题。 我使用了@metaplex/js,这是我的代码。

import { programs } from '@metaplex/js';

export const updateMetadataV1 = async () => {
  let { metadata : {Metadata, UpdateMetadata, MetadataDataData, Creator} } = programs;
  let signer = loadWalletKey(keyfile);
  let nftMintAccount = new PublicKey("EC8gGdtVFDoTf3vEGbLvPp7SVWta2xQrs99iWMbaFrdE");
  let metadataAccount = await Metadata.getPDA(nftMintAccount);
  const metadat = await Metadata.load(solConnection, metadataAccount);
  let newUri = "https://arweave.net/my arweave address";
  if (metadat.data.data.creators != null) {
    const creators = metadat.data.data.creators.map(
      (el) =>
          new Creator({
              ...el,
          }),
    );
    let newMetadataData = new MetadataDataData({
      name: metadat.data.data.name,
      symbol: metadat.data.data.symbol,
      uri: newUri,
      creators: [...creators],
      sellerFeeBasisPoints: metadat.data.data.sellerFeeBasisPoints,
    })
    const updateTx = new UpdateMetadata(
      { feePayer: signer.publicKey },
      {
        metadata: metadataAccount,
        updateAuthority: signer.publicKey,
        metadataData: newMetadataData,
        newUpdateAuthority: signer.publicKey,
        primarySaleHappened: metadat.data.primarySaleHappened,
      },
    );
    let result = await sendAndConfirmTransaction(solConnection, updateTx, [signer]);
    console.log("result =", result);
  }
}

交易结果没有错误,代表交易成功。 我在 Solana Explorer 上查看过。 但是元数据不会改变。怎么了?

 
let blockhashObj = await solConnection.getLatestBlockhash();
  updateTx.recentBlockhash = blockhashObj.blockhash;

  updateTx.sign(alice);

  let endocdeTransction = updateTx.serialize({
    requireAllSignatures: false,
    verifySignatures: false,
  });
  var signature = await solConnection.sendRawTransaction(endocdeTransction, {
    skipPreflight: false,
  });

要解决此问题,可以使用此代码,这是使用 mpl-token-metadata npm 包调用 on-chain updateMetadata 函数的 low-level 代码。

import { Wallet } from "@project-serum/anchor";
import * as anchor from "@project-serum/anchor";
import {createUpdateMetadataAccountV2Instruction,DataV2,UpdateMetadataAccountV2InstructionArgs,UpdateMetadataAccountV2InstructionAccounts} from "@metaplex-foundation/mpl-token-metadata"
const fs = require("fs");

(async() => {
    // This is the Update Authority Secret Key
    const secretKey = fs.readFileSync(
        "/Users/pratiksaria/.config/solana/id.json",
        "utf8"
      );
      const keypair = anchor.web3.Keypair.fromSecretKey(
        Buffer.from(JSON.parse(secretKey))
      );
      const endpoint = "https://metaplex.devnet.rpcpool.com/";
  const connection = new anchor.web3.Connection(endpoint);

  const wallet = new Wallet(keypair);
  console.log("Connected Wallet", wallet.publicKey.toString());

  const TOKEN_METADATA_PROGRAM_ID = new anchor.web3.PublicKey(
    "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
  );

  // You have to enter your NFT Mint address Over Here
  const mintKey = new anchor.web3.PublicKey("5iSxT33FyHWsnb8NYSytY17TTXfkFn62FiCyFVFxYhqY");

  const [metadatakey] = await anchor.web3.PublicKey.findProgramAddress(
    [
      Buffer.from("metadata"),
      TOKEN_METADATA_PROGRAM_ID.toBuffer(),
      mintKey.toBuffer(),
    ],
    TOKEN_METADATA_PROGRAM_ID
  );

  // BTW DeGods is my FAV collection although i cant afford one 
  const updated_data: DataV2 = {
    name: "DeGods",
    symbol: "DG",
    uri: "https://metadata.degods.com/g/4924.json",
    sellerFeeBasisPoints: 1000,
    creators: [
      {
        address: new anchor.web3.PublicKey(
          "CsEYyFxVtXxezfLTUWYwpj4ia5oCAsBKznJBWiNKLyxK"
        ),
        verified: false,
        share: 0,
      },
      {
        address: wallet.publicKey,
        verified: false,
        share: 100,
      },
    ],
    collection: null,
    uses: null,
  };

  const accounts:UpdateMetadataAccountV2InstructionAccounts = {
    metadata: metadatakey,
    updateAuthority: wallet.publicKey,
  }

  const args:UpdateMetadataAccountV2InstructionArgs = {
    updateMetadataAccountArgsV2: {
      data: updated_data,
      updateAuthority: wallet.publicKey,
      primarySaleHappened: true,
      isMutable: true,
    }
  }

  const updateMetadataAccount = createUpdateMetadataAccountV2Instruction(
  accounts,
  args
  );

  const transaction = new anchor.web3.Transaction()
  transaction.add(updateMetadataAccount);
  const {blockhash} = await connection.getLatestBlockhash();
  transaction.recentBlockhash = blockhash;
  transaction.feePayer = wallet.publicKey;
  const signedTx = await wallet.signTransaction(transaction);
  const txid = await connection.sendRawTransaction(signedTx.serialize());

  console.log("Transaction ID --",txid);

})()