📌

zkSyncでNFT作成するメモ

2021/06/01に公開

前提

libraries

    "ethers": "^5.1.4",
    "web3": "^1.3.5",
    "zksync": "^0.11.0-beta.1"

import

import { getDefaultProvider, Provider, Wallet, types, utils } from "zksync"
import { ethers } from "ethers";

constructor

  ...
  private provider: ethers.providers.Web3Provider
  private zkSyncProvider: Promise<Provider>
  constructor(){
    const web3 = new Web3(window.$web3.currentProvider);
    this.provider = new ethers.providers.Web3Provider(web3.givenProvider);
    this.zkSyncProvider = getDefaultProvider("ropsten");
  }
  ...

MintNFT

// contentHash は "0x0101010101010101010101010101010101010101010101010101010101010101" てきな感じ. IPFSのCIDとかいれる。
public async mintNFT(contentHash: string) {
    const wallet = await Wallet.fromEthSigner(this.provider.getSigner(), await this.zkSyncProvider)

    if (! await wallet.isSigningKeySet()) {
      const onchainAuthTransaction = await wallet.onchainAuthSigningKey();
      // Wait till transaction is committed on ethereum.
      await onchainAuthTransaction.wait();
      const changePubkey = await wallet.setSigningKey({
          feeToken: zkSyncClient.feeToken,
          ethAuthType: "ECDSA"
      });
      // Wait till transaction is committed
      const receipt = await changePubkey.awaitReceipt();
      console.log("receipt", receipt)
    }
    
    const nft = await wallet.mintNFT({
        recipient: wallet.address(),
        contentHash,
        feeToken: "ETH"
    })
    console.log("nft", nft)
    const receipt = await nft.awaitReceipt();
    console.log("receipt", receipt)

    // Get state of account
    const state = await wallet.getAccountState();
    console.log(state.committed.nfts); // 最初はcommitted, 時間が立つと verified
    console.log(state.verified.nfts);
    return;
  }

結果

transaction

https://ropsten.zkscan.io/explorer/transactions/cebe4ba1413776017398e36def1775603fe192f2046b31394f4c92a9c8b233fb

GetNFTs

 public async getVerifiedNFT(): Promise<types.NFT[]>{
    const wallet = await Wallet.fromEthSigner(this.provider.getSigner(), await this.zkSyncProvider)
    const state = await wallet.getAccountState();
    return Object.entries(state.verified.nfts).map(([_, nft]) => nft)
  }
 public async getCommittedNFT(): Promise<types.NFT[]>{
    const wallet = await Wallet.fromEthSigner(this.provider.getSigner(), await this.zkSyncProvider)
    const state = await wallet.getAccountState();
    return Object.entries(state.committed.nfts).map(([_, nft]) => nft)
  }

結果

Memo

ネットワーク

最初 Rinkeby だったが動かず、Discordで見たら Ropsten にしろと 書いてあった

IPFSのCIDを32byte-hexにするコード。

  public getBytes32FromIpfsHash(ipfsListing: string) {
    return "0x"+bs58.decode(ipfsListing).slice(2).toString('hex')
  }

戻すコード。

  public getIpfsHashFromBytes32(bytes32Hex: string) {
    const hashHex = "1220" + bytes32Hex.slice(2)
    const hashBytes = Buffer.from(hashHex, 'hex');
    const hashStr = bs58.encode(hashBytes)
    return hashStr
  }

isSigningKeySet は true でないといけない

Falseの場合accountがロックされていると言われる。

error: Error: zkSync transaction failed: Creator account is locked at Transaction.eval (webpack-internal:///./node_modules/zksync/build/wallet.js:1116:36) at Generator.next (<anonymous>) at fulfilled (webpack-internal:///./node_modules/zksync/build/wallet.js:5:58)

Ref

Discussion