Mint send transaction to create your nft error

Минт – это процесс получения цифрового актива, являющегося преобразованным цифровым файлом, который хранится на блокчейне.

{«id»:13851,»url»:»/distributions/13851/click?bit=1&hash=cee68209c60c746dc6bfd8466db5d93bb423cad3839f3acb2a2f49576b3e800c»,»title»:»u041au0430u043a u043du0430u0445u043eu0434u044fu0442 u0442u0435u0445, u043au043eu0433u043e u043du0438u043au0442u043e u043du0435 u043cu043eu0436u0435u0442 u043du0430u0439u0442u0438″,»buttonText»:»u0423u0437u043du0430u0442u044c»,»imageUuid»:»adc3521d-eabb-5dae-a761-d3b3e63d3df0″,»isPaidAndBannersEnabled»:false}

Минт – это процесс получения цифрового актива, являющегося преобразованным цифровым файлом, который хранится на блокчейне.

Процесс помогает сделать NFT товаром, который можно покупать, продавать и переводить между кошельками официально. Простыми словами, минт – это рождение NFT на блокчейне.

Сразу скажу, что в нашем телеграмм канале «NFT БРИХАСПАТИ» Вы сможете найти перспективные NFT проекты, раздачи от бирж, а также много другой полезной информации.. И еще на любые Ваши вопросы отвечаю в телеграмм!

Что значит минтить NFT?

Покупая NFT на маркетплейсе, мы всего лишь приобретаем его на вторичном рынке. Заминтить токен можно только поучаствовав в самом первом распределении NFT. То есть минтить NFT – значит покупать его впервые.

Какие-то минты проходят бесплатно (нужно оплатить только газ), но чаще всего проектом устанавливается определенная цена продажи. В процессе минта пользователи скупают все NFT, а затем продают на вторичных рынках.

Еще одна особенность минта заключается в том, что покупатель не можете выбрать NFT при покупке. Он просто платит цену минта, а NFT получает случайным образом. Это может быть как самый обычный экземпляр, так и очень редкий.

Что нужно для минта NFT?

Чтобы заминтить NFT, нужно всего три условия:

  • Криптокошелек, совместимый с тем блокчейном, на котором происходит минт NFT. Большинство коллекций минтятся на блокчейне Ethereum. Для него лучше всего подходит MetaMask.
  • Сумма, равная стоимости минта. Соответственно, если вы хотите приобрести больше 1 NFT (такое возможно не всегда), вам нужна соответствующая сумма на кошельке. Лучше минтить все желаемые NFT одной транзакцией, иначе придется оплачивать газ за каждую.
  • Средства для оплаты газа за транзакцию. Здесь важно понимать, что в момент минта комиссия всегда довольно высокая из-за большого наплыва пользователей. Особенно это касается блокчейна Ethereum. При минте особо раскрученных коллекций газ может достигать $10К. Для проверки цены на газ можно использовать обозреватель блокчейна, либо специальные боты в Телеграм (например, EtherDrops).

Как минтить NFT?

Проект всегда заранее объявляет дату минта. В назначенный час вы просто переходите на сайт проекта. Всегда переходите по ссылкам только через официальные соцсети проекта NFT коллекции! Это очень важно, так как мошенники любят размещать фишинговые ссылки. Особенно сильно они любят писать в ЛС в Discord. Запомните: ни один уважающий себя проект никогда не напишет вам в личку.

Скорее всего, на сайте информацию о продаже NFT долго искать не придется. В преддверии минта проекты размещают ее на главной странице, чтобы каждый входящий мог увидеть ее мгновенно при попадании на сайт.

Далее необходимо подключить кошелек. После этого останется только указать сумму и количество NFT. Кошелек покажет сумму, которую нужно будет оплатить за газ.

Как оценить успешность минта?

Вы уже перешли на сайт проекта и готовы приобрести заветный NFT, но все еще сомневаетесь в успехе? Прямо во время минта можно попробовать оценить факторы продаваемости коллекции.

Для этого в первую очередь оцените, сколько прошло времени с начала минта и какой процент NFT уже продан. К примеру, если с начала минта прошло 15 минут, а 2500 из 5000 NFT уже продано, популярность проекта, вероятно, очень высока. Это значит, что перепродать NFT удастся значительно дороже.

Кроме того, обязательно нужно зайти на OpenSea (или другой маркетплейс, где листятся NFT) и посмотреть, по каким ценам продают уже сминченные NFT. Если флор прайс или минимальная цена уже выше цены минта, то поучаствовать стоит. Здесь же можно оценить общую активность продаж данной NFT коллекции.

Если Вы дочитали до этого момента, то для Вас бонус: БЕСПЛАТНАЯ МЕТОДИЧКА ПО NFT 2022. Для этого переходим сюда

Статья предоставлена крупнейшим русскоязычным СМИ об NFT — NFT-ARTY

We are early in the blockchain space and as an early adopter there will be times when things will get funky and fail and it could be a range of different things that are out of our control like volatility in gas/network or just hiccups in the communication between smart contracts, wallets, users device, etc.

There are many things that could go wrong for different users. We’ll look at some ways to prevent issues that leave you asking yourself, “why can’t I mint?”. There are many different places something can go wrong in web3, we’ll take a look at some of the following areas where something can fail and provide some insight on what can be done.

Here are the different levels in the stack where errors can happen during minting:

  • Browser or Device Operating System
  • Desktop or Mobile
  • Location in the World
  • Wifi and Cellular Service Speed and Availibility
  • Minting Website
  • Wallet – MetaMask, Wallet Connect, Coinbase
  • Network Issues for IPFS or Infura
  • Secondary Marketplace Websites

As you can see there are different places where something can affect minting. Let’s look at some examples now and see how we can put a fix in.

Minting Experience

Transaction is pending and taking too long

When NFT Drops go live, there can be a big rush to mint. Sometimes gas prices will spike quickly and cause your transaction to be delayed. Usually this is because the gas spikes after you have submitted and is no longer enough gas set to cover the network fee to process your transaction. You have 3 options:

  • Speed up the transaction – add more gas fees to prioritize this transaction from being verified in the blockchain
  • Wait it out – you can wait until your transaction is verified, however is you are waiting for your transaction to process, you will not be able to confirm any additional transactions in MetaMask until your transaction has completed.
  • Cancel transaction – you can cancel transaction and retry, but usually you will incur a gas fee for the started transaction, but should be minimal compared to the minting price, since you are canceling the transaction.

Minting Page is not loading correctly and showing live data

Some common issues include:

  • Internet connection and service is active and available.
  • Check if your wifi is preventing traffic from the website if you are connected to a network at a university, school, or other place of business that are blocking certain websites from being accessed through their wifi network.
  • Close all open windows and tabs on your browser.
  • Clear your MetaMask browser cache and restart.
  • Disconnect and Reconnect to the networks on MetaMask.
  • Try restarting your browser, computer, phone, or device.
  • MetaMask application is using the latest version. If not, please update from the app store.
  • Operating system version is up to date. Please ensure iOS or your Android mobile systems are updated as well as your Windows and Mac PC operating systems.

If you are on a NiftyKit mint page and you do not see the correct information about NFTs minted, price, and sale information, then you are not connected to the website with your wallet and must connect using metamask to the correct blockchain network.

Incorrect Data For Live Minting Page showing 0/0 NFTs Minted

If you are seeing the image below, it means you are not connected to the network correctly.

  • Check your internet connection
  • Refresh and change the network on MetaMask to the correct one

Metamask

Getting “Switch Network” modal

NiftyKit supports Ethereum Mainnet and Polygon. Sometimes users will not be on the correct network and when you go to mint and NFT, it will ask you to switch to the correct network. Make sure you disconnect then re-connect in Metamask to the website and try again.

MetaMask is not connecting to the mint page.

Having issues with Metamask not responding? Try to disconnect your MetaMask wallet from the website to fix common issues with the mint button not responding, preventing the MetaMask confirmation from popping up.

Visit this link for instructions on the disconnect methods for both MetaMask Extension and Metamask Mobile. Disconnecting and reconnecting is the quickest and simplest way to remedy NFT minting issues. For more detailed information about permissions surrounding dapps, see the MetaMask User Guide here; or, more for a more in-depth explainer, this blog post by MetaMask. 

“Cannot request JSON-RPC method (eth_call) without provided rpc url”

This error means you do not have the correct settings for the network in MetaMask. Usually occurs for people minting on Polygon. In order to fix the invalid network setting. For Polygon, you can visit https://polygon-rpc.com/ to get the most updated and correct JSON-RPC method for MetaMask.

Connected to MetaMask but get error message “execution reverted: Not active. 1”

Getting this issue means there is a current presale active and the current wallet connected is not on the presale list. If buyer reaches out, check if they are on presale. If they are, validate if the address of the buyer is included on the presale list in NiftyKit. Also ask them to make sure that they are connected to the correct wallet address. You can diagnose the problem by checking:

  • is the correct MetaMask wallet added to presale list
  • is the latest presale list published to the blockchain
  • disconnect MetaMask wallet and reconnect with the confirmed wallet address

Got confirmation it went through but can’t see anything in my wallet.

There are a few things to check if you received your confirmation from MetaMask. Usually there are delays between secondary marketplaces like Opensea, Rarible, and LooksRare. It has taken up to 24 hours sometime for NFTs to show up and render properly in secondary markets. Here are some things you can do to check that your transaction went through:

  • Etherscan – check this blockchain log and see if your transaction processed correctly and sent your NFT. Etherscan can be down or delayed a little bit, but is the most reliable block explorer and a good place to start to see if your transaction went through
  • Refresh Metadata – when you save your metadata to IPFS it can take some time to propagate to other platforms who have to crawl to ingest that information so that they can display your NFTs properly. These best way to check is to refresh your metadata a couple of times and that should help your NFT show up in Opensea. The trick here is to be patient.

Unable to connect to MetaMask Host

By default, MetaMask accesses the blockchain via Infura, which is unavailable in certain jurisdictions due to legal compliance. When you attempt to use MetaMask in one of those regions, you’ll receive this error message:

Additionally, Infura may be experience issues which has known to prevent MetaMask from connecting and running transactions. You will always be able to get a live status to see if MetaMask is down because of issues with Infura. For live status on Infura, you can visit this status page we will publish service outages and other incidents, as well as scheduled maintenance notices.

infura status page errors

Having issues with your Ledger

  • First of all, make sure you have familiarized yourself with the content in the MetaMask how-to article here.
  • Make sure Ledger Live is closed when using your Ledger with MetaMask. Also, ensure it is unlocked and in the Ethereum application.
  • Also, make sure you have:
    • The most up-to-date firmware on your Ledger or Trezor device
    • Re-installed/updated the Ethereum app on the ledger via (ledger live > manager)
    • Your browser up-to-date
    • Enabled “contract data” on the Ethereum app on the ledger device itself

Opensea & Secondary NFT Marketplaces

Collection not showing on Opensea

  • Most common reason is because nothing is minted yet. In order for a collection to be recognized, there must be at least 1 NFT minted into the collection. If you are looking for your collection immediately after you deploy your smart contract, you may need to airdrop or mint an NFT so that you can access your collection details on Opensea. Same will apply to other secondary marketplaces.
  • Resolution: Mint or airdrop at least one NFT to show collection in Opensea
  • Advise customer that image may not show immediately. Advise them to hit “Refresh Metadata”

Set Base URI confirms the request to set metadata URL

Image not showing correctly on Opensea

Here are some things to help you diagnose issues with your NFTs minted on secondary marketplaces.

  • It may take some time to show in Opensea
  • Advise customer to click “Refresh Metadata” on Opensea and wait for up to 1 hour and see if it shows up
  • Try to view NFT on other Marketplaces to see if it is specific to Opensea only.
    • https://opensea.io (Ethereum & Polygon)
    • https://looksrare.org (Ethereum)
    • https://rarible.com (Ethereum)
    • https://nftrade.com/ (Polygon)
  • Also, check transaction if there’s a method already called for “Set Base URI”
    • Open transaction and check IPFS link if correct

If you are having any other issues not list, please email support@niftykit.com for help or send a message to us directly through the app using Intercom.

Как создать DApp для выпуска NFT токенов

В этом руководстве вы создадите минтер NFT и узнаете, как создать полнофункциональное приложение с полным стеком, подключив свой смарт-контракт к веб-интерфейсу React с помощью инструментов Metamask и Web3.

Одна из самых больших проблем для разработчиков, имеющих опыт работы в Web2, — это выяснить, как подключить ваш смартконтакт к внешнему проекту и взаимодействовать с ним.

Создав NFT minter — простой пользовательский интерфейс, в котором вы можете ввести ссылку на свой цифровой актив, название и описание — вы научитесь:

  • Подключитесь к Metamask через свой интерфейсный проект
  • Вызов методов смарт-контракта из вашего интерфейса
  • Подписывать транзакции с помощью Metamask

В этом уроке мы будем использовать React качестве нашего внешнего фреймворка. Поскольку это руководство в первую очередь ориентировано на разработку Web3, мы не будем тратить много времени на изучение основ React. Вместо этого мы сосредоточимся на добавлении функциональности в наш проект.

В качестве предварительного условия вы должны иметь понимание React на начальном уровне:
— знать, как работают компоненты, свойства, useState / useEffect и вызов основных функций.

Если вы никогда раньше не слышали ни одного из этих терминов, возможно, вы захотите ознакомиться с этим учебным курсом Intro to React.

Мы настоятельно рекомендуем эту отличную серию видеороликов Full Modern React Tutorial от Net Ninja.

Шаг 0: создание NFT 101

Прежде чем мы даже начнем изучать какой-либо код, важно понять, как работает NFT. Он состоит из двух этапов:
1) Вы публикуете смарт-контракт NFT в блокчейне Ethereum. Обычно это смарт-контракт ERC-721 или ERC-1155.

Самая большая разница между двумя стандартами интеллектуальных контактов NFT заключается в том, что ERC-1155 является стандартом с несколькими токенами и включает в себя пакетные функции, тогда как ERC-721 является стандартом с одним токеном и, следовательно, поддерживает передачу только одного токена за раз.

2) Вы вызываете функцию чеканки смарт-контракта NFT для чеканки NFT.

Минтинг — это просто акт публикации уникального экземпляра вашего невзаимозаменяемого токена в блокчейне.

Обычно эта функция чеканки требует, чтобы вы передали две переменные в качестве параметров, во-первых , который указывает адрес, который будет получать ваш недавно созданный NFT, а во-вторых, NFT, строку recipienttokenURI, которая преобразуется в документ JSON, описывающий метаданные NFT.

Метаданные NFT — это действительно то, что оживляет их, позволяя им иметь такие свойства, как имя, описание, изображение (или другой цифровой актив) и другие атрибуты. Вот пример tokenURI, который содержит метаданные NFT.

В этом руководстве мы сосредоточимся на части 2, вызывая существующую функцию чеканки смарт-контрактов NFT с помощью нашего пользовательского интерфейса React.

Вот ссылка на ERC-721 NFT смарт контракта мы будем называть в этом учебнике. Если вы хотите узнать, как мы сделали это, мы настоятельно рекомендуем вам проверить наш другой учебник, «Как создать NFT»

Круто, теперь, когда мы понимаем, как работает NFT, давайте клонируем наши стартовые файлы!

Шаг 1. Клонируйте начальные файлы

Сначала перейдите в репозиторий github nft-minter-tutorial, чтобы получить стартовые файлы для этого проекта. Клонируйте этот репозиторий в свою локальную среду.

Когда вы откроете этот клонированный репозиторий, вы заметите, что он содержит две папки:

  • minter-starter-files содержит стартовые файлы (по сути, пользовательский интерфейс React) для этого проекта. В этом руководстве мы будем работать в этом каталоге, пока вы узнаете, как воплотить в жизнь этот пользовательский интерфейс, подключив его к своему кошельку Ethereum и смарт-контракту NFT.
  • nft-minter содержит весь завершенный учебник и может быть использован в качестве справки, если вы застряли.

Затем откройте свою копию в своем любимом редакторе кода (в Alchemy мы большие поклонники VSCode), а затем перейдите в свою папку :src

Будем работать в папке «src»

Весь код, который мы напишем, будет находиться в папке.

Мы будем редактировать компонент Minter.js и писать дополнительные файлы javascript, чтобы дать нашему проекту функциональность Web3.src

Шаг 2. Ознакомьтесь с нашими стартовыми файлами

Прежде чем мы начнем кодировать, важно проверить, что уже предусмотрено в начальных файлах.

Запустите свой проект React

Начнем с запуска проекта React в нашем браузере. Прелесть React в том, что как только наш проект запущен в нашем браузере, любые сохраненные нами изменения будут обновляться в реальном времени в нашем браузере.

Чтобы запустить проект, перейдите в корневой каталог папки minter-starter-files и запустите npm install в терминале, чтобы установить зависимости проекта:

cd minter-starter-files
npm install

После завершения установки запустите в своем терминале:
npm start

При этом в вашем браузере должен открыться http: // localhost: 3000 / , где вы увидите интерфейс нашего проекта. Он должен состоять из 3 полей:

  • место для ввода ссылки на актив вашего NFT,
  • введите имя вашего NFT
  • предоставьте описание.

Как должен выглядеть ваш пользовательский интерфейс

Если вы попытаетесь нажать кнопки «Подключить кошелек» или «Mint NFT», вы заметите, что они не работают — это потому, что нам все еще нужно запрограммировать их функциональность! :)

Компонент Minter.js

Вернемся в папку в нашем редакторе и откроем файл src Minter.js.

Очень важно, чтобы мы понимали все в этом файле, так как это основной компонент React, над которым мы будем работать.

ПРИМЕЧАНИЕ
Убедитесь, что вы находитесь в minter-starter-files папке, а не nft-minterfolder!

В верхней части нашего файла находятся переменные состояния, которые мы будем обновлять после определенных событий.

//State variables
const [walletAddress, setWallet] = useState("");
const [status, setStatus] = useState("");
const [name, setName] = useState("");
const [description, setDescription] = useState("");
const [url, setURL] = useState("");

Никогда не слышали о переменных состояния React или хуках состояния? Check out these docs.

Вот что представляет собой каждая из переменных:
walletAddress — строка, в которой хранится адрес кошелька пользователя
status — строка, которая содержит сообщение, отображаемое в нижней части пользовательского интерфейса
name — строка, в которой хранится имя NFT
description — строка, в которой хранится описание NFT
url — строка, которая является ссылкой на цифровой актив NFT.

После переменных состояния вы увидите три нереализованные функции:

  • useEffect,
  • connectWalletPressed
  • onMintPressed.

Вы заметите, что все эти функции асинхронные, потому что мы будем выполнять в них асинхронные вызовы API!
Их названия созвучны с их функциональностью:

useEffect(async () => { //TODO: implement
    
  }, []);

  const connectWalletPressed = async () => { //TODO: implement
   
  };

  const onMintPressed = async () => { //TODO: implement
    
  };

  • useEffect — это хук React, который вызывается после рендеринга вашего компонента. Поскольку в него передан пустой массив [] prop (см. строку 3), он будет вызван только при первом рендеринге компонента. Здесь мы вызовем wallet listener и еще одну функцию кошелька, чтобы обновить наш пользовательский интерфейс, чтобы отразить, подключен ли уже кошелек.
  • connectWalletPressed — эта функция будет вызвана для подключения кошелька Metamask пользователя к нашему dApp.
  • onMintPressed — эта функция будет вызвана, чтобы отчеканить пользовательский NFT.

В конце этого файла находится пользовательский интерфейс нашего компонента. Если вы внимательно просканируете этот код, то заметите, что мы обновляем переменные состояния url, name и description при изменении ввода в соответствующих текстовых полях.

Вы также увидите, что connectWalletPressed и onMintPressedare вызывается, когда кнопки с идентификаторами mintButton и walletButton нажимаются соответственно.

//the UI of our component
  return (
    <div className="Minter">
      <button id="walletButton" onClick={connectWalletPressed}>
        {walletAddress.length > 0 ? (
          "Connected: " +
          String(walletAddress).substring(0, 6) +
          "..." +
          String(walletAddress).substring(38)
        ) : (
          <span>Connect Wallet</span>
        )}
      </button>

      <br></br>
      <h1 id="title">????‍♂️ Alchemy NFT Minter</h1>
      <p>
        Simply add your asset's link, name, and description, then press "Mint."
      </p>
      <form>
        <h2>???? Link to asset: </h2>
        <input
          type="text"
          placeholder="e.g. https://gateway.pinata.cloud/ipfs/<hash>"
          onChange={(event) => setURL(event.target.value)}
        />
        <h2>???? Name: </h2>
        <input
          type="text"
          placeholder="e.g. My first NFT!"
          onChange={(event) => setName(event.target.value)}
        />
        <h2>✍️ Description: </h2>
        <input
          type="text"
          placeholder="e.g. Even cooler than cryptokitties ;)"
          onChange={(event) => setDescription(event.target.value)}
        />
      </form>
      <button id="mintButton" onClick={onMintPressed}>
        Mint NFT
      </button>
      <p id="status">
        {status}
      </p>
    </div>
  );

Наконец, давайте рассмотрим, куда добавляется этот компонент Minter.

Если вы перейдете к файлу App.js, который является основным компонентом React, выступающим в качестве контейнера для всех остальных компонентов, вы увидите, что наш компонент Minter внедрен в строке 7.

В этом руководстве мы будем редактировать только файл Minter.js и добавлять файлы в папку src.

Теперь, когда мы понимаем, с чем работаем, давайте настроим наш кошелек Ethereum.

Шаг 3. Настройте свой кошелек Ethereum

Чтобы пользователи могли взаимодействовать с вашим смарт-контрактом, им необходимо подключить свой кошелек Ethereum к вашему dApp.

Скачать Metamask

В этом руководстве мы будем использовать Metamask, виртуальный кошелек в браузере, который используется для управления адресом вашей учетной записи Ethereum. Если вы хотите узнать больше о том, как работают транзакции в Ethereum, посетите эту страницу Ethereum Foundation.

Вы можете бесплатно скачать и создать учетную запись Metamask здесь . Когда вы создаете учетную запись или если у вас уже есть учетная запись, обязательно переключитесь на «Тестовую сеть Ropsten» в правом верхнем углу (чтобы мы не имели дело с реальными деньгами).

Образец кошелька Metamask

Добавить эфир из сборщика

Чтобы чеканить наши NFT (или подписать любые транзакции в блокчейне Ethereum), нам понадобится фальшивая Eth. Чтобы получить Eth, вы можете перейти к крану Ropsten и ввести адрес своей учетной записи Ropsten, а затем нажать «Отправить Ropsten Eth». Вскоре после этого вы должны увидеть Eth в своей учетной записи Metamask!

Проверьте свой баланс

Чтобы дважды проверить наш баланс, давайте сделаем запрос eth_getBalance с помощью инструмента композитора Alchemy . Это вернет количество Eth в нашем кошельке. После того, как вы введете адрес своей учетной записи Metamask и нажмете «Отправить запрос», вы должны увидеть такой ответ:

{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}

ПРИМЕЧАНИЕ. Это результат в wei, а не в eth. Вэй используется как наименьшее обозначение эфира. Преобразование wei в eth: 1 eth = 10¹⁸ wei. Итак, если мы преобразуем 0xde0b6b3a7640000 в десятичное число, мы получим 1 * 10¹⁸, что равно 1 eth.

Уф! Все наши фальшивые деньги!

Шаг 4. Подключите Metamask к своему пользовательскому интерфейсу

Теперь, когда наш кошелек Metamask настроен, давайте подключим к нему наше приложение!
Поскольку мы хотим придерживаться парадигмы MVC , мы собираемся создать отдельный файл, содержащий наши функции для управления логикой, данными и правилами нашего dApp, а затем передать эти функции нашему интерфейсу (наш компонент Minter.js ).

Функция connectWallet

To do so, let’s create a new folder called utilsin your src directory and add a file called interact.js inside it, which will contain all of our wallet and smart contract interaction functions.
In our interact.jsfile, we will write a connectWallet function, which we will then import and call in our Minter.js component.

In your interact.js file, add the following

export const connectWallet = async () => {
  if (window.ethereum) {
    try {
      const addressArray = await window.ethereum.request({
        method: "eth_requestAccounts",
      });
      const obj = {
        status: "???????? Write a message in the text-field above.",
        address: addressArray[0],
      };
      return obj;
    } catch (err) {
      return {
        address: "",
        status: "???? " + err.message,
      };
    }
  } else {
    return {
      address: "",
      status: (
        <span>
          <p>
            {" "}
            ????{" "}
            <a target="_blank" href={`https://metamask.io/download.html`}>
              You must install Metamask, a virtual Ethereum wallet, in your
              browser.
            </a>
          </p>
        </span>
      ),
    };
  }
};

Let’s breakdown what this code does:
First, our function checks if it window.ethereum is enabled in your browser.

If window.ethereumis not present, then that means Metamask is not installed. This results in a JSON object being returned, where address returned is an empty string, and the status JSX object relays that the user must install Metamask.

Most of the functions we write will be returning JSON objects that we can use to update our state variables and UI.

Now if window.ethereumis present, then that’s when things get interesting.
Using a try/catch loop, we’ll try to connect to Metamask by callingwindow.ethereum.request({ method: «eth_requestAccounts» }); Calling this function will open up Metamask in the browser, whereby the user will be prompted to connect their wallet to your dApp.

  • If the user chooses to connect, method: «eth_requestAccounts» will return an array that contains all of the user’s account addresses that connected to the dApp. Altogether, our connectWallet function will return a JSON object that contains the firstaddress in this array (see line 9) and a status message that prompts the user to write a message to the smart contract.
  • If the user rejects the connection, then the JSON object will contain an empty string for the address returned and a status message that reflects that the user rejected the connection.

Add connectWallet function to your Minter.js UI Component

Now that we’ve written this connectWallet function, let’s connect it to our Minter.js. component.
First, we’ll have to import our function into our Minter.js file by adding import { connectWallet } from «./utils/interact.js»; to the top of the Minter.js file. Your first 11 lines of Minter.js should now look like this:

import { useEffect, useState } from "react";
import { connectWallet } from "./utils/interact.js";

const Minter = (props) => {

  //State variables
  const [walletAddress, setWallet] = useState("");
  const [status, setStatus] = useState("");
  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [url, setURL] = useState("");

Then, inside our connectWalletPressed function, we’ll call our imported connectWallet function, like so:

const connectWalletPressed = async () => {
    const walletResponse = await connectWallet();
    setStatus(walletResponse.status);
    setWallet(walletResponse.address);
  };

Notice how most of our functionality is abstracted away from our Minter.js component from the interact.js file? This is so we comply with the M-V-C paradigm!
In connectWalletPressed, we simply make an await call to our imported connectWallet function, and using its response, we update our status and walletAddress variables via their state hooks.
Now, let’s save both files (Minter.js and interact.js) and test out our UI so far.
Open your browser on the http://localhost:3000/ page, and press the «Connect Wallet» button on the top right of the page.
If you have Metamask installed, you should be prompted to connect your wallet to your dApp. Accept the invitation to connect.
You should see that the wallet button now reflects that your address is connected! Yasssss ????
Next, try refreshing the page… this is strange. Our wallet button is prompting us to connect Metamask, even though it is already connected…

The problem on page reload

Don’t worry though! We easily can fix that by implementing a function calledgetCurrentWalletConnected, which will check if an address is already connected to our dApp and update our UI accordingly!

The getCurrentWalletConnected function

In your interact.js file, add the following getCurrentWalletConnected function:

export const getCurrentWalletConnected = async () => {
  if (window.ethereum) {
    try {
      const addressArray = await window.ethereum.request({
        method: "eth_accounts",
      });
      if (addressArray.length > 0) {
        return {
          address: addressArray[0],
          status: "???????? Write a message in the text-field above.",
        };
      } else {
        return {
          address: "",
          status: "???? Connect to Metamask using the top right button.",
        };
      }
    } catch (err) {
      return {
        address: "",
        status: "???? " + err.message,
      };
    }
  } else {
    return {
      address: "",
      status: (
        <span>
          <p>
            {" "}
            ????{" "}
            <a target="_blank" href={`https://metamask.io/download.html`}>
              You must install Metamask, a virtual Ethereum wallet, in your
              browser.
            </a>
          </p>
        </span>
      ),
    };
  }
};

This code is very similar to the connectWallet function we just wrote earlier.
The main difference is that instead of calling the method eth_requestAccounts, which opens Metamask for the user to connect their wallet, here we call the method eth_accounts, which simply returns an array containing the Metamask addresses currently connected to our dApp.
To see this function in action, let’s call it in the useEffect function of our Minter.js component.
Like we did for connectWallet, we must import this function from our interact.js file into our Minter.js file like so:

import { useEffect, useState } from "react";
import {
  connectWallet,
  getCurrentWalletConnected //import here
} from "./utils/interact.js";

Now, we simply call it in our useEffect function:

useEffect(async () => {
    const {address, status} = await getCurrentWalletConnected();
    setWallet(address)
    setStatus(status); 
}, []);

Notice, we use the response of our call to getCurrentWalletConnected to update our walletAddress and status state variables.
Once you’ve added this code, try refreshing our browser window. The button should say that you’re connected, and show a preview of your connected wallet’s address — even after you refresh! ????

Implement addWalletListener

The final step in our dApp wallet setup is implementing the wallet listener so our UI updates when our wallet’s state changes, such as when the user disconnects or switches accounts.
In your Minter.js file, add a function addWalletListener that looks like the following:

function addWalletListener() {
  if (window.ethereum) {
    window.ethereum.on("accountsChanged", (accounts) => {
      if (accounts.length > 0) {
        setWallet(accounts[0]);
        setStatus("???????? Write a message in the text-field above.");
      } else {
        setWallet("");
        setStatus("???? Connect to Metamask using the top right button.");
      }
    });
  } else {
    setStatus(
      <p>
        {" "}
        ????{" "}
        <a target="_blank" href={`https://metamask.io/download.html`}>
          You must install Metamask, a virtual Ethereum wallet, in your
          browser.
        </a>
      </p>
    );
  }
}

Let’s quickly break down what’s happening here:

  • First, our function checks if window.ethereum is enabled (i.e. Metamask is installed).
  • If it’s not, we simply set our status state variable to a JSX string that prompts the user to install Metamask.
  • If it is enabled, we set up the listener window.ethereum.on(«accountsChanged») on line 3 that listens for state changes in the Metamask wallet, which include when the user connects an additional account to the dApp, switches accounts, or disconnects an account. If there is at least one account connected, the walletAddress state variable is updated as the first account in the accounts array returned by the listener. Otherwise, walletAddress is set as an empty string.

Finally, we must call it in our useEffect function:

useEffect(async () => {
    const {address, status} = await getCurrentWalletConnected();
    setWallet(address)
    setStatus(status);
    
    addWalletListener(); 
}, []);

And voila! We’ve completed programming all of our wallet functionality! Now that our wallet is set up, let’s figure out how to mint our NFT!

Step 5: NFT Metadata 101

So remember the NFT metadata we just talked about in Step 0 of this tutorial—it brings an NFT to life, allowing it to have properties, such as a digital asset, name, description, and other attributes.
We’re going to need to configure this metadata as a JSON object and store it, so we can pass it in as the tokenURI parameter when calling our smart contract’s mintNFT function.
The text in the «Link to Asset», «Name», «Description» fields will comprise the different properties of our NFT’s metadata. We’ll format this metadata as a JSON object, but there are a couple options for where we can store this JSON object:

  • We could store it on the Ethereum blockchain; however, doing so would be SUPER expensive (we’re talking upwards of hundreds of dollars) due to the nature of Ethereum. ❌
  • We could store it on a centralized server, like AWS or Firebase. But that would defeat our decentralization ethos. ❌
  • We could use IPFS, a decentralized protocol and peer-to-peer network for storing and sharing data in a distributed file system. As this protocol as decentralized and free, it is our best option! ✅

To store our metadata on IPFS, we will use Pinata, a convenient IPFS API and toolkit. In the next step, we’ll explain exactly how to do this!

Step 6: Use Pinata to pin your metadata to IPFS

If you don’t have a Pinata account, sign up for a free account here and complete the steps to verify your email and account.

Create your Pinata API key

Navigate to the https://pinata.cloud/keys page, then select the «New Key» button at the top, set the Admin widget as enabled, and name your key.

Create your Pinata API key

You’ll then be shown a popup with your API info. Make sure to put this somewhere safe.

Make sure to save your API key and secret in a safe place

Now that our key is set up, let’s add it to our project so we can use it.

Create a .env file

We can safely store our Pinata key and secret in an environment file. Let’s install the dotenv package in your project directory.
Open up a new tab in your terminal (separate from the one running local host) and make sure you are in the minter-starter-files folder, then run the following command in your terminal:

npm install dotenv --save

Next, create a .env file in the root directory of your minter-starter-files by entering the following on your command line:

This will pop open your .env file in vim (a text editor). To save it hit «esc» + «:» + «q» on your keyboard in that order.
Next, in VSCode, navigate to your .env file and add your Pinata API key and API secret to it, like so:

REACT_APP_PINATA_KEY = <pinata-api-key>
REACT_APP_PINATA_SECRET = <pinata-api-secret>

Save the file, and then you’re ready to start writing the function to upload your JSON metadata to IPFS!

Implement pinJSONToIPFS

Fortunately for us, Pinata has an API specifically for uploading JSON data to IPFS and a convenient JavaScript with axios example that we can use, with some slight modifications.
In your utils folder, let’s create another file called pinata.js and then import our Pinata secret and key from the .env file like so:

require('dotenv').config();
const key = process.env.REACT_APP_PINATA_KEY;
const secret = process.env.REACT_APP_PINATA_SECRET;

Next, paste the additional code from below into your pinata.js file. Don’t worry, we’ll break down what everything means!

require('dotenv').config();
const key = process.env.REACT_APP_PINATA_KEY;
const secret = process.env.REACT_APP_PINATA_SECRET;

const axios = require('axios');

export const pinJSONToIPFS = async(JSONBody) => {
    const url = `https://api.pinata.cloud/pinning/pinJSONToIPFS`;
    //making axios POST request to Pinata ⬇️
    return axios 
        .post(url, JSONBody, {
            headers: {
                pinata_api_key: key,
                pinata_secret_api_key: secret,
            }
        })
        .then(function (response) {
           return {
               success: true,
               pinataUrl: "https://gateway.pinata.cloud/ipfs/" + response.data.IpfsHash
           };
        })
        .catch(function (error) {
            console.log(error)
            return {
                success: false,
                message: error.message,
            }
           
    });
};

So what does this code do exactly?
First, it imports axios, a promise based HTTP client for the browser and node.js, which we will use to make a request to Pinata.
Then we have our asynchronous function pinJSONToIPFS, which takes a JSONBody as its input and the Pinata api key and secret in its header, all to make a POST request to theirpinJSONToIPFS API.

  • If this POST request is successful, then our function returns an JSON object with the success boolean as true and the pinataUrl where our metadata was pinned. We will use this pinataUrl returned as the tokenURI input to our smart contract’s mint function.
  • If this post request fails, then our function returns an JSON object with the success boolean as false and a message string that relays our error.

As with our connectWalletfunction return types, we’re returning JSON objects so we can use their parameters to update our state variables and UI.

Step 7: Load your smart contract

Now that we have a way to upload our NFT metadata to IPFS via our pinJSONToIPFS function, we’re going to need a way to load an instance of our smart contract so we can call its mintNFT function.

The contract ABI

If you examined our files closely, you’ll have noticed that in our src directory, there’s a contract-abi.json file. An ABI is necessary for specifying which function a contract will invoke as well ensuring that the function will return data in the format you’re expecting.
We’re also going to need an Alchemy API key and the Alchemy Web3 API to connect to the Ethereum blockchain and load our smart contract.

Create your Alchemy API key

If you don’t already have an Alchemy account, sign up for free here.
Once you’ve created an Alchemy account, you can generate an API key by creating an app. This will allow us to make requests to the Ropsten test network.
Navigate to the “Create App” page in your Alchemy Dashboard by hovering over “Apps” in the nav bar and clicking “Create App”

Name your app (we chose «My First NFT!»), offer a short description, select “Staging” for the Environment (used for your app bookkeeping), and choose “Ropsten” for your network.

Configure your app details

Click “Create app” and that’s it! Your app should appear in the table below.
Awesome so now that we’ve created our HTTP Alchemy API URL, copy it to your clipboard like so…

Copy your Alchemy API key

…and then let’s add it to our .env file. Altogether, your .env file should look like this:

REACT_APP_PINATA_KEY = <pinata-key>
REACT_APP_PINATA_SECRET = <pinata-secret>
REACT_APP_ALCHEMY_KEY = https://eth-ropsten.alchemyapi.io/v2/<alchemy-key>

Now that we have our contract ABI and our Alchemy API key, we’re ready to load our smart contract using Alchemy Web3.

Set up your Alchemy Web3 endpoint and contract

First, if you don’t have it already, you’ll need to install Alchemy Web3 by navigating to the home directory: nft-minter-tutorialin the terminal:

cd ..
npm install @alch/alchemy-web3

Next let’s go back to our interact.jsfile. At the top of the file, add the following code to import your Alchemy key from your .env file and set up your Alchemy Web3 endpoint:

require('dotenv').config();
const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY;
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3(alchemyKey); 

Alchemy Web3 is a wrapper around Web3.js, providing enhanced API methods and other crucial benefits to make your life as a web3 developer easier. It is designed to require minimal configuration so you can start using it in your app right away!

Next, let’s add our contract ABI and contract address to our file.

require('dotenv').config();
const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY;
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3(alchemyKey); 

const contractABI = require('../contract-abi.json')
const contractAddress = "0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE";

Once we have both of those, we’re ready to start coding our mint function!

Step 8: Implement the mintNFT function

Inside your interact.js file, let’s define our function, mintNFT , which eponymously will mint our NFT.
Because we will be making numerous asynchronous calls (to Pinata to pin our metadata to IPFS, Alchemy Web3 to load our smart contract, and Metamask to sign our transactions), our function will also be asynchronous.
The three inputs to our function will be the url of our digital asset, name, and description. Add the following function signature below the connectWallet function:

export const mintNFT = async (url, name, description) => {
}

Input error handling

Naturally, it makes sense to have some sort of input error handling at the start of the function, so we exit this function if our input parameters aren’t correct. Inside our function, let’s add the following code:

export const mintNFT = async(url, name, description) => {
 //error handling
 if (url.trim() == "" || (name.trim() == "" || description.trim() == "")) { 
   return {
    success: false,
    status: "❗Please make sure all fields are completed before minting.",
   }
  }
}

Essentially, if any of the input parameters are an empty string, then we return a JSON object where the success boolean is false, and the status string relays that all fields in our UI must be complete.

Upload the metadata to IPFS

Once we know our metadata is formatted properly, the next step is to wrap it into a JSON object and upload it to IPFS via the pinJSONToIPFS we wrote!
To do so, we first we need to import the pinJSONToIPFSfunction into our interact.js file. At the very top of the interact.js, let’s add:

import {pinJSONToIPFS} from './pinata.js'

Recall that pinJSONToIPFS takes in a JSON body. So before we make a call to it, we’re going to need to format our url, name, and description parameters into a JSON object.
Let’s update our code to create a JSON object called metadata and then make a call to pinJSONToIPFS with this metadata parameter:

export const mintNFT = async(url, name, description) => {
 //error handling
 if (url.trim() == "" || (name.trim() == "" || description.trim() == "")) { 
        return {
            success: false,
            status: "❗Please make sure all fields are completed before minting.",
        }
  }

  //make metadata
  const metadata = new Object();
  metadata.name = name;
  metadata.image = url;
  metadata.description = description;

  //make pinata call
  const pinataResponse = await pinJSONToIPFS(metadata);
  if (!pinataResponse.success) {
      return {
          success: false,
          status: "???? Something went wrong while uploading your tokenURI.",
      }
  } 
  const tokenURI = pinataResponse.pinataUrl;  
}

Notice, we store the response of our call to pinJSONToIPFS(metadata) in the pinataResponse object. Then, we parse this object for any errors.
If there’s an error, we return a JSON object where the success boolean is false and our status string relays that our call failed. Otherwise, we extract the pinataURL from the pinataResponse and store it as our tokenURIvariable.
Now it’s time to load our smart contract using the Alchemy Web3 API that we initialized at the top of our file. Add the following line of code to the bottom of the mintNFT function to set the contract at the window.contract global variable:

window.contract = await new web3.eth.Contract(contractABI, contractAddress);

The last thing to add in our mintNFT function is our Ethereum transaction:

//set up your Ethereum transaction
 const transactionParameters = {
        to: contractAddress, // Required except during contract publications.
        from: window.ethereum.selectedAddress, // must match user's active address.
        'data': window.contract.methods.mintNFT(window.ethereum.selectedAddress, tokenURI).encodeABI()//make call to NFT smart contract 
 };

//sign the transaction via Metamask
 try {
    const txHash = await window.ethereum
        .request({
            method: 'eth_sendTransaction',
            params: [transactionParameters],
        });
    return {
        success: true,
        status: "✅ Check out your transaction on Etherscan: https://ropsten.etherscan.io/tx/" + txHash
    }
 } catch (error) {
    return {
        success: false,
        status: "???? Something went wrong: " + error.message
    }

 }

If you’re already familiar with Ethereum transactions, you’ll notice that the structure is pretty similar to what you’ve seen.

  • First, we set up our transactions parameters.
  • to specifies the recipient address (our smart contract)
  • from specifies the signer of the transaction (the user’s connected address to Metamask: window.ethereum.selectedAddress)
  • data contains the call to our smart contract mintNFT method, which receives our tokenURI and the user’s wallet address, window.ethereum.selectedAddress, as inputs
  • Then, we make an await call, window.ethereum.request, where we ask Metamask to sign the transaction. Notice, in this request, we’re specifying our eth method (eth_SentTransaction) and passing in our transactionParameters. At this point, Metamask will open up in the browser, and prompt the user to sign or reject the transaction.
  • If the transaction is successful, the function will return a JSON object where the boolean success is set to true and the status string prompts the user to check out Etherscan for more information about their transaction.
  • If the transaction fails, the function will return a JSON object where the success boolean is set to false, and the status string relays the error message.

Altogether, our mintNFT function should look like this:

export const mintNFT = async(url, name, description) => {

    //error handling
    if (url.trim() == "" || (name.trim() == "" || description.trim() == "")) { 
        return {
            success: false,
            status: "❗Please make sure all fields are completed before minting.",
        }
    }

    //make metadata
    const metadata = new Object();
    metadata.name = name;
    metadata.image = url;
    metadata.description = description;

    //pinata pin request
    const pinataResponse = await pinJSONToIPFS(metadata);
    if (!pinataResponse.success) {
        return {
            success: false,
            status: "???? Something went wrong while uploading your tokenURI.",
        }
    } 
    const tokenURI = pinataResponse.pinataUrl;  

    //load smart contract
    window.contract = await new web3.eth.Contract(contractABI, contractAddress);//loadContract();

    //set up your Ethereum transaction
    const transactionParameters = {
        to: contractAddress, // Required except during contract publications.
        from: window.ethereum.selectedAddress, // must match user's active address.
        'data': window.contract.methods.mintNFT(window.ethereum.selectedAddress, tokenURI).encodeABI() //make call to NFT smart contract 
    };

    //sign transaction via Metamask
    try {
        const txHash = await window.ethereum
            .request({
                method: 'eth_sendTransaction',
                params: [transactionParameters],
            });
        return {
            success: true,
            status: "✅ Check out your transaction on Etherscan: https://ropsten.etherscan.io/tx/" + txHash
        }
    } catch (error) {
        return {
            success: false,
            status: "???? Something went wrong: " + error.message
        }
    }
}

That’s one giant function! Now, we just need to connect our mintNFT function to our Minter.js component…

Step 9: Connect mintNFT to our Minter.js frontend

Open up your Minter.js file and update the import { connectWallet, getCurrentWalletConnected } from «./utils/interact.js»; line at the top to be:

 import { connectWallet, getCurrentWalletConnected, mintNFT } from "./utils/interact.js";

Finally, implement the onMintPressed function to make await call to your imported mintNFTfunction and update the status state variable to reflect whether our transaction succeeded or failed:

const onMintPressed = async () => {
    const { status } = await mintNFT(url, name, description);
    setStatus(status);
};

Step 10: Deploy your NFT to a Live Website

Ready to take your project live for users to interact with? Check out the tutorial below for deploying your Minter to a live website:

Step 11: Take the blockchain world by storm

JK, you made it to the end of the tutorial! To recap, by building an NFT minter, you successfully learned how to:

  • Connect to Metamask via your frontend project
  • Call smart contract methods from your frontend
  • Sign transactions using Metamask

Presumably, you’d like to be able to show off the NFTs minted via your dApp in your wallet — so be sure to check out our quick tutorial How to View Your NFT in Your Wallet!
And, as always, if you have any questions, we’re here to help in the Alchemy Discord. We can’t wait to see how you apply the concepts from this tutorial to your future projects!

Bonus: Put your NFT Minter to work!

Ready to mint an NFT using your minter? Check out this demo video!

NOTE: The transactions sent through Metamask will use Metamask’s default provider (not necessarily your Alchemy endpoint). If you’d like to send those transactions through Alchemy to unlock debugging tools and the Alchemy Notify suite, check out this guide for connecting Metamask to Alchemy.

Поддержите блог, перечислив небольшие чаевые

Если у вас нет кошелька MetaMask, вы можете получить его здесь

This tutorial describes how to mint an NFT using the ethers library, and the smart contract from Part I: How to Create an NFT.

Estimated time to complete this guide: ~10 minutes
__

Minting an NFT is the act of publishing a unique instance of an ERC721 token on the blockchain. Now that we have successfully deployed a smart contract to the Goerli network in Part I of this NFT tutorial series, let’s flex our web3 skills and mint an NFT!

At the end of this tutorial, you’ll be able to mint as many NFTs as you’d like with this code —let’s get started!


Open the repository from Part 1 in your favorite code editor (e.g. VSCode), and create a new file in the scripts folder called mint-nft.js. We will be using the ethers library from Part 1 to connect to the Alchemy Provider. Add the following code to the file:

require('dotenv').config();
const ethers = require('ethers');

// Get Alchemy API Key
const API_KEY = process.env.API_KEY;

// Define an Alchemy Provider
const provider = new ethers.providers.AlchemyProvider('goerli', API_KEY)

Note that we are using API_KEY and not API_URL. Make sure you add this to your .env file so that it looks something like this:

API_URL = "https://eth-goerli.g.alchemy.com/v2/your-api-key"
PRIVATE_KEY = "your-metamask-private-key"
API_KEY = "your-api-key"

The contract ABI (Application Binary Interface) is an interface to interact with our smart contract. You can learn more about Contract ABIs here. Hardhat automatically generates an ABI for us and saves it in the MyNFT.json file. In order to use this we’ll need to parse out the contents by adding the following code to the mint-nft.js file:

const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");

If you want to see the ABI you can print it to your console:

console.log(JSON.stringify(contract.abi));

To run and see your ABI printed to the console navigate to your terminal and run

Our mintNFT smart contract function takes in a tokenURI parameter that should resolve to a JSON document describing the NFT’s metadata— which is really what brings the NFT to life, allowing it to have configurable properties, such as a name, description, image, and other attributes.

Interplanetary File System (IPFS) is a decentralized protocol and peer-to-peer network for storing and sharing data in a distributed file system.

We will use Pinata, a convenient IPFS API and toolkit, to store our NFT asset and metadata and ensure that our NFT is truly decentralized. If you don’t have a Pinata account, sign up for a free account here.

Once you’ve created an account:

  • Navigate to the Pinata Upload button on the top right
  • Upload an image to pinata — this will be the image asset for your NFT. Feel free to name the asset whatever you wish
  • After you upload, at the top of the page, there should be a green popup that allows you to view the hash of your upload —> Copy that hashcode. You can view your upload at: https://gateway.pinata.cloud/ipfs/<hash-code>

For the more visual learners, the steps above are summarized here: Now, we’re going to want to upload one more document to Pinata. But before we do that, we need to create it!

844

In your root directory, make a new file called nft-metadata.json and add the following json code:

{
    "attributes" : [ {
      "trait_type" : "Breed",
      "value" : "Maltipoo"
    }, {
      "trait_type" : "Eye color",
      "value" : "Mocha"
    } ],
    "description" : "The world's most adorable and sensitive pup.",
    "image" : "https://gateway.pinata.cloud/ipfs/QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb",
    "name" : "Ramses"
}

Feel free to change the data in the json. You can add or remove attributes. Most importantly, make sure the image field points to the location of your IPFS image— otherwise, your NFT will not include a photo of a (very cute!) dog.

Once you’re done editing the json file, save it and upload it to Pinata, following the same steps we did for uploading the image.

844

In order to be able to call the functions on our deployed contract, we need to define an ethers Signer using our wallet’s private key. Next, we need to use the contract’s deployed address, the contract ABI, and the aforementioned signer to define a contract instance.

In the mint-nft.js file, add the following code:

// Create a signer
const privateKey = process.env.PRIVATE_KEY
const signer = new ethers.Wallet(privateKey, provider)

// Get contract ABI and address
const abi = contract.abi
const contractAddress = '0xA4766Ceb9E84a71D282A4CED9fB8Fe93C49b2Ff7'

// Create a contract instance
const myNftContract = new ethers.Contract(contractAddress, abi, signer)

In the snippet above, you can see that our contract’s deployed address is 0xA4766Ceb9E84a71D282A4CED9fB8Fe93C49b2Ff7. If you don’t remember your contract address or can’t find it on Etherscan, simply re-deploy the contract from Part 1 again and note down the new address.

Remember the metadata.json you uploaded to Pinata? Get its hashcode from Pinata and pass the following into a call to mintNFT https://gateway.pinata.cloud/ipfs/<metadata-hash-code>

Here’s how to get the hashcode:

844

❗️

Hashcode

Double check that the hashcode you copied links to your metadata.json by loading https://gateway.pinata.cloud/ipfs/<metadata-hash-code> into a separate window. The page should look similar to the screenshot below:

2878

Now add the following piece of code to mint-nft.js to call the mintNFT function:

// Get the NFT Metadata IPFS URL
const tokenUri = "https://gateway.pinata.cloud/ipfs/QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP"

// Call mintNFT function
const mintNFT = async () => {
    let nftTxn = await myNftContract.mintNFT(signer.address, tokenUri)
    await nftTxn.wait()
    console.log(`NFT Minted! Check it out at: https://goerli.etherscan.io/tx/${nftTxn.hash}`)
}

mintNFT()
    .then(() => process.exit(0))
    .catch((error) => {
        console.error(error);
        process.exit(1);
    });java

The final mint-nft.js file should look something like this:

require('dotenv').config();
const ethers = require('ethers');

// Get Alchemy App URL
const API_KEY = process.env.API_KEY;

// Define an Alchemy Provider
const provider = new ethers.providers.AlchemyProvider('goerli', API_KEY)

// Get contract ABI file
const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");

// Create a signer
const privateKey = process.env.PRIVATE_KEY
const signer = new ethers.Wallet(privateKey, provider)

// Get contract ABI and address
const abi = contract.abi
const contractAddress = '0xA4766Ceb9E84a71D282A4CED9fB8Fe93C49b2Ff7'

// Create a contract instance
const myNftContract = new ethers.Contract(contractAddress, abi, signer)

// Get the NFT Metadata IPFS URL
const tokenUri = "https://gateway.pinata.cloud/ipfs/QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP"

// Call mintNFT function
const mintNFT = async () => {
    let nftTxn = await myNftContract.mintNFT(signer.address, tokenUri)
    await nftTxn.wait()
    console.log(`NFT Minted! Check it out at: https://goerli.etherscan.io/tx/${nftTxn.hash}`)
}

mintNFT()
    .then(() => process.exit(0))
    .catch((error) => {
        console.error(error);
        process.exit(1);
    });

We’re all set. Let’s mint our NFT by running the following command:

You should get an output that looks something like this:

NFT Minted! Check it out at: https://goerli.etherscan.io/tx/0x06a7a06aea5d55eb6e7a0f0f17bfeaad2fb4e310de55f5a884e1b623a3fab080

You can check out your NFT mint on Etherscan by following the URL above.

2880

You can view your NFT on OpenSea by searching for your contract address. Check out our NFT here.

Using the mint-nft.js you can mint as many NFT’s as your heart (and wallet) desires! Just be sure to pass in a new tokenURI describing the NFT’s metadata —otherwise, you’ll just end up making a bunch of identical ones with different IDs.

Presumably, you’d like to be able to show off your NFT in your wallet 😉— so be sure to check out Part III: How to View Your NFT in Your Wallet.

Updated 3 months ago


Error message is:

  1. Unit tests
    Governor
    mint first nft:
    Error: VM Exception while processing transaction: reverted with reason string ‘Not enough ether to purchase NFTs.’
    at MyNftToken.approve (@openzeppelin/contracts/token/ERC721/ERC721.sol:114)
    at MyNftToken.safeMint (contracts/MyNftToken.sol:54)
    at async HardhatNode._mineBlockWithPendingTxs (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1773:23)
    at async HardhatNode.mineBlock (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:466:16)
    at async EthModule._sendTransactionAndReturnHash (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1504:18)
    at async HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:118:18)
    at async EthersProviderWrapper.send (node_modules/@nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)

Prior to running my test I set the ether balance to 10 ether:

await this.token.deployed();
      await hre.network.provider.request({ method: 'hardhat_setBalance', params: [this.signers.admin.address, ethers.utils.parseEther('10').toHexString()] });

I mint setting a a gas limit so I don’t get the Unable to estimate gas error:

const myFirstMint = await this.token.safeMint(this.signers.admin.address, {
      gasLimit: 250000,
    });
    await myFirstMint.wait();

Anyone knows what more I can do?

asked Aug 4, 2022 at 14:43

Julia's user avatar

Smart contracts are for security reasons not able to just pull ETH from a wallet — you need to explicitly state how much you want to send while creating the transaction.

ethersjs use the overrides parameter where you can also specify the amount of wei sent along with the transaction. Example below shows sending 1 ETH (which is 1e18 wei).

const myFirstMint = await this.token.safeMint(this.signers.admin.address, {
    gasLimit: 250000,
    value: ethers.utils.parseEther("1.0"),
});
await myFirstMint.wait();

answered Aug 4, 2022 at 15:20

Petr Hejda's user avatar

Petr HejdaPetr Hejda

37.3k8 gold badges70 silver badges93 bronze badges

Понравилась статья? Поделить с друзьями:
  • Minor error cisco
  • Minizip error while extracting 111
  • Minitube error transferring
  • Minimum hardware check battlefield 1 как исправить
  • Minikube addons enable ingress error