Návod na minter pro NFT
Jednou z největších výzev pro vývojáře přicházející z prostředí Web2 je přijít na to, jak propojit chytrý kontrakt s frontendovým projektem a pracovat s ním.
Vytvořením minteru pro NFT – jednoduchého uživatelského rozhraní, do kterého můžete zadat odkaz na své digitální aktivum, název a popis – se naučíte:
- Připojit se k MetaMasku prostřednictvím vašeho frontendového projektu
- Volat metody chytrého kontraktu z vašeho frontendu
- Podepisovat transakce pomocí MetaMasku
V tomto návodu budeme jako náš frontendový framework používat Reactopens in a new tab. Protože se tento návod zaměřuje především na vývoj pro Web3, nebudeme trávit mnoho času rozebíráním základů Reactu. Místo toho se zaměříme na to, abychom našemu projektu dodali funkcionalitu.
Předpokladem je, že byste měli mít základní znalosti Reactu – vědět, jak fungují komponenty, props, useState/useEffect a základní volání funkcí. Pokud jste o žádném z těchto pojmů nikdy neslyšeli, možná se budete chtít podívat na tento návod Úvod do Reactuopens in a new tab. Těm, kteří se učí spíše vizuálně, vřele doporučujeme tuto vynikající sérii videí Kompletní moderní návod na Reactopens in a new tab od Net Ninja.
A pokud ho ještě nemáte, budete k dokončení tohoto návodu a k vytváření čehokoli na blockchainu určitě potřebovat účet Alchemy. Zaregistrujte si bezplatný účet zdeopens in a new tab.
Bez dalších okolků se do toho pusťme!
Tvorba NFT 101
Než se vůbec začneme dívat na jakýkoli kód, je důležité pochopit, jak funguje tvorba NFT. Zahrnuje to dva kroky:
Zveřejnění chytrého kontraktu NFT na blockchainu Ethereum
Největší rozdíl mezi dvěma standardy chytrých kontraktů pro NFT je ten, že ERC-1155 je standard pro více tokenů a zahrnuje dávkovou funkcionalitu, zatímco ERC-721 je standard pro jeden token, a proto podporuje pouze přenos jednoho tokenu najednou.
Volání funkce mintování
Obvykle tato funkce mintování vyžaduje, abyste jako parametry předali dvě proměnné: zaprvé recipient, která určuje adresu, jež obdrží vaše nově namintované NFT, a zadruhé tokenURI NFT, což je řetězec, který odkazuje na dokument JSON popisující metadata NFT.
Metadata NFT jsou to, co ho skutečně oživuje a umožňuje mu mít vlastnosti, jako je název, popis, obrázek (nebo jiné digitální aktivum) a další atributy. Zde je příklad tokenURIopens in a new tab, které obsahuje metadata NFT.
V tomto návodu se zaměříme na část 2, volání funkce mintování existujícího chytrého kontraktu NFT pomocí našeho uživatelského rozhraní React.
Zde je odkazopens in a new tab na chytrý kontrakt ERC-721 NFT, který budeme v tomto návodu volat. Pokud byste se chtěli dozvědět, jak jsme ho vytvořili, vřele doporučujeme podívat se na náš další návod, "Jak vytvořit NFT"opens in a new tab.
Super, teď když chápeme, jak funguje tvorba NFT, naklonujme si naše startovací soubory!
Naklonujte si startovací soubory
Nejprve přejděte do GitHub repozitáře nft-minter-tutorialopens in a new tab, abyste získali startovací soubory pro tento projekt. Naklonujte tento repozitář do svého lokálního prostředí.
Když otevřete tento naklonovaný repozitář nft-minter-tutorial, všimnete si, že obsahuje dvě složky: minter-starter-files a nft-minter.
minter-starter-filesobsahuje startovací soubory (v podstatě uživatelské rozhraní React) pro tento projekt. V tomto návodu budeme pracovat v tomto adresáři, kde se naučíte, jak toto uživatelské rozhraní oživit připojením k vaší peněžence Ethereum a chytrému kontraktu NFT.nft-minterobsahuje celý dokončený návod a je vám k dispozici jako reference, pokud se zaseknete.
Dále otevřete svou kopii minter-starter-files v editoru kódu a poté přejděte do složky src.
Veškerý kód, který napíšeme, bude umístěn ve složce src. Budeme upravovat komponentu Minter.js a psát další javascriptové soubory, abychom našemu projektu dodali funkcionalitu Web3.
Krok 2: Prohlédněte si naše startovací soubory
Než začneme kódovat, je důležité si prohlédnout, co je pro nás již připraveno ve startovacích souborech.
Spusťte svůj projekt v Reactu
Začněme spuštěním projektu React v našem prohlížeči. Krása Reactu spočívá v tom, že jakmile náš projekt běží v prohlížeči, veškeré uložené změny se v prohlížeči projeví v reálném čase.
Chcete-li projekt spustit, přejděte do kořenového adresáře složky minter-starter-files a spusťte v terminálu příkaz npm install pro instalaci závislostí projektu:
cd minter-starter-filesnpm installJakmile se dokončí instalace, spusťte v terminálu npm start:
npm startTím by se vám měl v prohlížeči otevřít http://localhost:3000/opens in a new tab, kde uvidíte frontend našeho projektu. Měl by se skládat ze 3 polí: místo pro zadání odkazu na aktivum vašeho NFT, zadání názvu vašeho NFT a poskytnutí popisu.
Pokud se pokusíte kliknout na tlačítka „Připojit peněženku“ nebo „Mintovat NFT“, zjistíte, že nefungují – to proto, že jejich funkcionalitu musíme teprve naprogramovat! :)
Komponenta Minter.js
POZNÁMKA: Ujistěte se, že se nacházíte ve složce minter-starter-files a ne ve složce nft-minter!
Vraťme se do složky src v našem editoru a otevřete soubor Minter.js. Je nesmírně důležité, abychom všemu v tomto souboru rozuměli, protože se jedná o primární komponentu Reactu, na které budeme pracovat.
V horní části tohoto souboru máme naše stavové proměnné, které budeme aktualizovat po konkrétních událostech.
1//Stavové proměnné2const [walletAddress, setWallet] = useState("")3const [status, setStatus] = useState("")4const [name, setName] = useState("")5const [description, setDescription] = useState("")6const [url, setURL] = useState("")Nikdy jste neslyšeli o stavových proměnných Reactu nebo stavových hácích (hooks)? Podívejte se na tutoopens in a new tab dokumentaci.
Zde je přehled toho, co jednotlivé proměnné představují:
walletAddress– řetězec, který ukládá adresu peněženky uživatelestatus– řetězec, který obsahuje zprávu k zobrazení v dolní části uživatelského rozhraníname– řetězec, který ukládá název NFTdescription– řetězec, který ukládá popis NFTurl– řetězec, který je odkazem na digitální aktivum NFT
Po stavových proměnných uvidíte tři neimplementované funkce: useEffect, connectWalletPressed a onMintPressed. Všimnete si, že všechny tyto funkce jsou async, protože v nich budeme provádět asynchronní volání API! Jejich názvy jsou synonymem jejich funkcí:
1useEffect(async () => {2 //TODO: implementovat3}, [])45const connectWalletPressed = async () => {6 //TODO: implementovat7}89const onMintPressed = async () => {10 //TODO: implementovat11}Zobrazit všeuseEffectopens in a new tab – toto je React hook, který se volá po vykreslení vaší komponenty. Protože má předanou prázdnou rekvizitu pole[](viz řádek 3), bude volána pouze při prvním vykreslení komponenty. Zde zavoláme náš posluchač peněženky a další funkci peněženky, abychom aktualizovali naše uživatelské rozhraní tak, aby odráželo, zda je peněženka již připojena.connectWalletPressed– tato funkce bude volána pro připojení peněženky MetaMask uživatele k naší dapp.onMintPressed– tato funkce bude volána pro mintování NFT uživatele.
Na konci tohoto souboru máme uživatelské rozhraní naší komponenty. Pokud si tento kód pečlivě projdete, všimnete si, že aktualizujeme naše stavové proměnné url, name a description při změně vstupu v jejich odpovídajících textových polích.
Také uvidíte, že connectWalletPressed a onMintPressed se volají při kliknutí na tlačítka s ID mintButton a walletButton.
1//uživatelské rozhraní naší komponenty2return (3 <div className="Minter">4 <button id="walletButton" onClick={connectWalletPressed}>5 {walletAddress.length > 0 ? (6 "Připojeno: " +7 String(walletAddress).substring(0, 6) +8 "..." +9 String(walletAddress).substring(38)10 ) : (11 <span>Připojit peněženku</span>12 )}13 </button>1415 <br></br>16 <h1 id="title">🧙♂️ Minter NFT od Alchemy</h1>17 <p>18 Jednoduše přidejte odkaz na své aktivum, název a popis a poté stiskněte „Mintovat“.19 </p>20 <form>21 <h2>🖼 Odkaz na aktivum: </h2>22 <input23 type="text"24 placeholder="např., https://gateway.pinata.cloud/ipfs/<hash>"25 onChange={(event) => setURL(event.target.value)}26 />27 <h2>🤔 Název: </h2>28 <input29 type="text"30 placeholder="např., Moje první NFT!"31 onChange={(event) => setName(event.target.value)}32 />33 <h2>✍️ Popis: </h2>34 <input35 type="text"36 placeholder="např., Ještě víc cool než cryptokitties ;)"37 onChange={(event) => setDescription(event.target.value)}38 />39 </form>40 <button id="mintButton" onClick={onMintPressed}>41 Mintovat NFT42 </button>43 <p id="status">{status}</p>44</div>45)Zobrazit všeNakonec se podívejme, kam se tato komponenta Minter přidává.
Pokud přejdete do souboru App.js, který je hlavní komponentou v Reactu a funguje jako kontejner pro všechny ostatní komponenty, uvidíte, že naše komponenta Minter je vložena na řádku 7.
V tomto návodu budeme upravovat pouze soubor Minter.js a přidávat soubory do naší složky src.
Nyní, když chápeme, s čím pracujeme, nastavme si naši peněženku Ethereum!
Nastavte si svou peněženku Ethereum
Aby uživatelé mohli interagovat s vaším chytrým kontraktem, budou muset ke své dapp připojit svou peněženku Ethereum.
Stáhněte si MetaMask
Pro tento výukový program použijeme MetaMask, virtuální peněženku v prohlížeči, která slouží ke správě adresy vašeho ethereového účtu. Pokud chcete lépe porozumět tomu, jak fungují transakce na Ethereu, podívejte se na tuto stránku.
Účet MetaMask si můžete zdarma stáhnout a vytvořit zdeopens in a new tab. Při vytváření účtu, nebo pokud již účet máte, se ujistěte, že jste vpravo nahoře přepnuli na „Ropsten Test Network“ (abychom nepracovali se skutečnými penězi).
Přidejte ether z Faucetu
Abychom mohli mintovat naše NFT (nebo podepisovat jakékoli transakce na blockchainu Ethereum), budeme potřebovat nějaké falešné Eth. Pro získání Eth můžete přejít na Ropsten faucetopens in a new tab, zadat adresu svého účtu Ropsten a kliknout na „Send Ropsten Eth“. Krátce poté byste měli vidět Eth ve svém účtu MetaMask!
Zkontrolujte si zůstatek
Abychom si ověřili, že náš zůstatek je k dispozici, proveďte požadavek eth_getBalanceopens in a new tab pomocí nástroje Composer od Alchemyopens in a new tab. Tím získáte množství Eth ve vaší peněžence. Po zadání adresy vašeho účtu MetaMask a kliknutí na „Send Request“ byste měli vidět takovouto odpověď:
1{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}POZNÁMKA: Tento výsledek je ve wei, nikoli v eth. Wei se používá jako nejmenší denominace etheru. Převod z wei na eth je: 1 eth = 10¹⁸ wei. Takže pokud převedeme 0xde0b6b3a7640000 na desetinné číslo, dostaneme 1*10¹⁸, což se rovná 1 eth.
Uf! Naše falešné peníze jsou všechny tam!
Připojte MetaMask k vašemu UI
Nyní, když je naše peněženka MetaMask nastavena, připojme k ní naši dapp!
Protože se chceme držet paradigmatu MVCopens in a new tab, vytvoříme si samostatný soubor, který bude obsahovat naše funkce pro správu logiky, dat a pravidel naší dapp, a poté tyto funkce předáme našemu frontendu (naší komponentě Minter.js).
Funkce connectWallet
K tomu si vytvoříme novou složku s názvem utils ve vašem adresáři src a do ní přidáme soubor s názvem interact.js, který bude obsahovat všechny naše funkce pro interakci s peněženkou a chytrým kontraktem.
V našem souboru interact.js napíšeme funkci connectWallet, kterou pak naimportujeme a zavoláme v naší komponentě Minter.js.
Do svého souboru interact.js přidejte následující
1export const connectWallet = async () => {2 if (window.ethereum) {3 try {4 const addressArray = await window.ethereum.request({5 method: "eth_requestAccounts",6 })7 const obj = {8 status: "👆🏽 Napište zprávu do textového pole výše.",9 address: addressArray[0],10 }11 return obj12 } catch (err) {13 return {14 address: "",15 status: "😥 " + err.message,16 }17 }18 } else {19 return {20 address: "",21 status: (22 <span>23 <p>24 {" "}25 🦊 <a target="_blank" href={`https://metamask.io/download`}>26 Do prohlížeče si musíte nainstalovat MetaMask, virtuální peněženku pro Ethereum.27 </a>28 </p>29 </span>30 ),31 }32 }33}Zobrazit všePojďme si rozebrat, co tento kód dělá:
Nejprve naše funkce zkontroluje, zda je ve vašem prohlížeči povoleno window.ethereum.
window.ethereum je globální API, které vkládá MetaMask a další poskytovatelé peněženek a které webovým stránkám umožňuje žádat o účty uživatelů Etherea. Pokud je schváleno, může číst data z blockchainů, ke kterým je uživatel připojen, a navrhovat uživateli podepisování zpráv a transakcí. Pro více informací se podívejte do dokumentace MetaMaskuopens in a new tab!
Pokud window.ethereum není přítomno, znamená to, že MetaMask není nainstalován. Výsledkem je vrácení objektu JSON, kde vrácená adresa je prázdný řetězec a objekt JSX status sděluje, že uživatel si musí nainstalovat MetaMask.
Většina funkcí, které napíšeme, bude vracet objekty JSON, které můžeme použít k aktualizaci našich stavových proměnných a uživatelského rozhraní.
Pokud window.ethereum je přítomno, pak to začne být zajímavé.
Pomocí smyčky try/catch se pokusíme připojit k MetaMasku voláním window.ethereum.request({ method: \"eth_requestAccounts\" });opens in a new tab. Volání této funkce otevře MetaMask v prohlížeči, kde bude uživatel vyzván k připojení své peněženky k vaší dapp.
- Pokud se uživatel rozhodne připojit,
method: \"eth_requestAccounts\"vrátí pole, které obsahuje všechny adresy účtů uživatele připojené k dapp. Celkově naše funkceconnectWalletvrátí objekt JSON, který obsahuje prvníadresuv tomto poli (viz řádek 9) a zprávustatus, která vyzve uživatele k napsání zprávy do chytrého kontraktu. - Pokud uživatel spojení odmítne, objekt JSON bude obsahovat prázdný řetězec pro vrácenou
adresua zprávustatus, která odráží, že uživatel spojení odmítl.
Přidejte funkci connectWallet do své komponenty UI Minter.js
Nyní, když jsme napsali tuto funkci connectWallet, připojme ji k naší komponentě Minter.js.
Nejprve budeme muset naimportovat naši funkci do našeho souboru Minter.js přidáním import { connectWallet } from \"./utils/interact.js\"; na začátek souboru Minter.js. Vašich prvních 11 řádků souboru Minter.js by nyní mělo vypadat takto:
1import { useEffect, useState } from "react";2import { connectWallet } from "./utils/interact.js";34const Minter = (props) => {56 //Stavové proměnné7 const [walletAddress, setWallet] = useState("");8 const [status, setStatus] = useState("");9 const [name, setName] = useState("");10 const [description, setDescription] = useState("");11 const [url, setURL] = useState("");Zobrazit všePoté uvnitř naší funkce connectWalletPressed zavoláme naši importovanou funkci connectWallet takto:
1const connectWalletPressed = async () => {2 const walletResponse = await connectWallet()3 setStatus(walletResponse.status)4 setWallet(walletResponse.address)5}Všimněte si, jak je většina naší funkcionality abstrahována z naší komponenty Minter.js ze souboru interact.js? To proto, abychom dodrželi paradigma M-V-C!
V connectWalletPressed jednoduše provedeme await volání naší importované funkce connectWallet a pomocí její odpovědi aktualizujeme naše proměnné status a walletAddress prostřednictvím jejich stavových háků (hooks).
Nyní uložme oba soubory Minter.js a interact.js a vyzkoušejme naše dosavadní uživatelské rozhraní.
Otevřete svůj prohlížeč na adrese localhost:3000 a stiskněte tlačítko „Připojit peněženku“ vpravo nahoře na stránce.
Pokud máte nainstalovaný MetaMask, měli byste být vyzváni k připojení své peněženky k vaší dapp. Přijměte výzvu k připojení.
Měli byste vidět, že tlačítko peněženky nyní ukazuje, že je vaše adresa připojena.
Dále zkuste obnovit stránku... to je divné. Naše tlačítko peněženky nás vyzývá k připojení MetaMasku, i když už je připojen...
Ale nebojte se! To můžeme snadno opravit implementací funkce nazvané getCurrentWalletConnected, která zkontroluje, zda je adresa již připojena k naší dapp, a podle toho aktualizuje naše uživatelské rozhraní!
Funkce getCurrentWalletConnected
Do svého souboru interact.js přidejte následující funkci getCurrentWalletConnected:
1export const getCurrentWalletConnected = async () => {2 if (window.ethereum) {3 try {4 const addressArray = await window.ethereum.request({5 method: "eth_accounts",6 })7 if (addressArray.length > 0) {8 return {9 address: addressArray[0],10 status: "👆🏽 Napište zprávu do textového pole výše.",11 }12 } else {13 return {14 address: "",15 status: "🦊 Připojte se k MetaMasku pomocí tlačítka vpravo nahoře.",16 }17 }18 } catch (err) {19 return {20 address: "",21 status: "😥 " + err.message,22 }23 }24 } else {25 return {26 address: "",27 status: (28 <span>29 <p>30 {" "}31 🦊 <a target="_blank" href={`https://metamask.io/download`}>32 Do prohlížeče si musíte nainstalovat MetaMask, virtuální peněženku pro Ethereum.33 </a>34 </p>35 </span>36 ),37 }38 }39}Zobrazit všeTento kód je velmi podobný funkci connectWallet, kterou jsme napsali dříve.
Hlavní rozdíl je v tom, že místo volání metody eth_requestAccounts, která otevře MetaMask, aby si uživatel mohl připojit svou peněženku, zde voláme metodu eth_accounts, která jednoduše vrací pole obsahující adresy MetaMask aktuálně připojené k naší dapp.
Abychom viděli tuto funkci v akci, zavoláme ji ve funkci useEffect naší komponenty Minter.js.
Stejně jako u connectWallet musíme tuto funkci naimportovat z našeho souboru interact.js do našeho souboru Minter.js takto:
1import { useEffect, useState } from "react"2import {3 connectWallet,4 getCurrentWalletConnected, //importovat zde5} from "./utils/interact.js"Nyní ji jednoduše zavoláme v naší funkci useEffect:
1useEffect(async () => {2 const { address, status } = await getCurrentWalletConnected()3 setWallet(address)4 setStatus(status)5}, [])Všimněte si, že odpověď z našeho volání getCurrentWalletConnected používáme k aktualizaci našich stavových proměnných walletAddress a status.
Jakmile přidáte tento kód, zkuste obnovit okno prohlížeče. Tlačítko by mělo hlásit, že jste připojeni, a zobrazovat náhled adresy vaší připojené peněženky – i po obnovení!
Implementujte addWalletListener
Posledním krokem v nastavení peněženky naší dapp je implementace posluchače peněženky, aby se naše uživatelské rozhraní aktualizovalo, když se změní stav naší peněženky, například když se uživatel odpojí nebo přepne účty.
Do svého souboru Minter.js přidejte funkci addWalletListener, která vypadá následovně:
1function addWalletListener() {2 if (window.ethereum) {3 window.ethereum.on("accountsChanged", (accounts) => {4 if (accounts.length > 0) {5 setWallet(accounts[0])6 setStatus("👆🏽 Napište zprávu do textového pole výše.")7 } else {8 setWallet("")9 setStatus("🦊 Připojte se k MetaMasku pomocí tlačítka vpravo nahoře.")10 }11 })12 } else {13 setStatus(14 <p>15 {" "}16 🦊 <a target="_blank" href={`https://metamask.io/download`}>17 Do prohlížeče si musíte nainstalovat MetaMask, virtuální peněženku pro Ethereum.18 </a>19 </p>20 )21 }22}Zobrazit všePojďme si rychle rozebrat, co se zde děje:
- Nejprve naše funkce zkontroluje, zda je
window.ethereumpovoleno (tj. zda je MetaMask nainstalován).- Pokud není, jednoduše nastavíme naši stavovou proměnnou
statusna řetězec JSX, který uživatele vyzve k instalaci MetaMasku. - Pokud je povoleno, nastavíme na řádku 3 posluchače
window.ethereum.on(\"accountsChanged\"), který naslouchá změnám stavu v peněžence MetaMask, což zahrnuje případy, kdy uživatel připojí další účet k dapp, přepne účty nebo odpojí účet. Pokud je připojen alespoň jeden účet, stavová proměnnáwalletAddressse aktualizuje jako první účet v poliaccountsvráceném posluchačem. V opačném případě jewalletAddressnastaveno jako prázdný řetězec.
- Pokud není, jednoduše nastavíme naši stavovou proměnnou
Nakonec ji musíme zavolat v naší funkci useEffect:
1useEffect(async () => {2 const { address, status } = await getCurrentWalletConnected()3 setWallet(address)4 setStatus(status)56 addWalletListener()7}, [])A je to! Dokončili jsme programování veškeré funkcionality naší peněženky! Nyní, když je naše peněženka nastavena, pojďme zjistit, jak mintovat naše NFT!
Metadata NFT 101
Vzpomeňte si na metadata NFT, o kterých jsme mluvili v kroku 0 tohoto návodu – oživují NFT a umožňují mu mít vlastnosti, jako je digitální aktivum, název, popis a další atributy.
Tato metadata budeme muset nakonfigurovat jako objekt JSON a uložit je, abychom je mohli předat jako parametr tokenURI při volání funkce mintNFT našeho chytrého kontraktu.
Text v polích „Odkaz na aktivum“, „Název“ a „Popis“ bude tvořit různé vlastnosti metadat našeho NFT. Tato metadata naformátujeme jako objekt JSON, ale existuje několik možností, kde tento objekt JSON můžeme uložit:
- Mohli bychom je uložit na blockchainu Ethereum, avšak to by bylo velmi drahé.
- Mohli bychom je uložit na centralizovaném serveru, jako je AWS nebo Firebase. To by ale bylo v rozporu s naším decentralizačním étosem.
- Mohli bychom použít IPFS, decentralizovaný protokol a peer-to-peer síť pro ukládání a sdílení dat v distribuovaném souborovém systému. Protože je tento protokol decentralizovaný a bezplatný, je to naše nejlepší volba!
K uložení našich metadat na IPFS použijeme Pinataopens in a new tab, pohodlné API a sadu nástrojů pro IPFS. V dalším kroku si přesně vysvětlíme, jak na to!
Použijte Pinata k připnutí vašich metadat na IPFS
Pokud nemáte účet Pinataopens in a new tab, zaregistrujte si bezplatný účet zdeopens in a new tab a dokončete kroky k ověření svého e-mailu a účtu.
Vytvořte si API klíč Pinata
Přejděte na stránku https://pinata.cloud/keysopens in a new tab, poté vyberte tlačítko „New Key“ nahoře, nastavte widget Admin jako povolený a pojmenujte svůj klíč.
Poté se vám zobrazí vyskakovací okno s vašimi informacemi o API. Ujistěte se, že si je uložíte na bezpečné místo.
Nyní, když máme náš klíč nastavený, přidejme ho do našeho projektu, abychom ho mohli používat.
Vytvořte soubor .env
Náš klíč Pinata a tajný klíč můžeme bezpečně uložit do souboru s proměnnými prostředí. Nainstalujme si do adresáře projektu balíček dotenvopens in a new tab.
Otevřete novou kartu v terminálu (jinou než tu, na které běží localhost), ujistěte se, že se nacházíte ve složce minter-starter-files a spusťte následující příkaz:
1npm install dotenv --saveDále vytvořte soubor .env v kořenovém adresáři minter-starter-files zadáním následujícího příkazu:
1vim.envTím se vám otevře soubor .env ve vimu (textovém editoru). Pro uložení stiskněte na klávesnici v tomto pořadí „esc“ + „:“ + „q“.
Dále v editoru VSCode přejděte do souboru .env a přidejte do něj svůj API klíč Pinata a API secret takto:
1REACT_APP_PINATA_KEY = <pinata-api-key>2REACT_APP_PINATA_SECRET = <pinata-api-secret>Uložte soubor a pak jste připraveni začít psát funkci pro nahrání vašich metadat JSON na IPFS!
Implementujte pinJSONToIPFS
Naštěstí pro nás má Pinata API speciálně pro nahrávání dat JSON na IPFSopens in a new tab a pohodlný příklad v JavaScriptu s axios, který můžeme s drobnými úpravami použít.
Ve složce utils vytvořme další soubor s názvem pinata.js a poté naimportujme náš Pinata secret a klíč ze souboru .env takto:
1require("dotenv").config()2const key = process.env.REACT_APP_PINATA_KEY3const secret = process.env.REACT_APP_PINATA_SECRETDále vložte další kód z níže uvedeného do svého souboru pinata.js. Nebojte se, rozebereme si, co všechno znamená!
1require("dotenv").config()2const key = process.env.REACT_APP_PINATA_KEY3const secret = process.env.REACT_APP_PINATA_SECRET45const axios = require("axios")67export const pinJSONToIPFS = async (JSONBody) => {8 const url = `https://api.pinata.cloud/pinning/pinJSONToIPFS`9 //odeslání POST požadavku pomocí axios na Pinata ⬇️10 return axios11 .post(url, JSONBody, {12 headers: {13 pinata_api_key: key,14 pinata_secret_api_key: secret,15 },16 })17 .then(function (response) {18 return {19 success: true,20 pinataUrl:21 "https://gateway.pinata.cloud/ipfs/" + response.data.IpfsHash,22 }23 })24 .catch(function (error) {25 console.log(error)26 return {27 success: false,28 message: error.message,29 }30 })31}Zobrazit všeCo přesně tedy tento kód dělá?
Nejprve importuje axiosopens in a new tab, HTTP klienta založeného na promises pro prohlížeč a node.js, který použijeme k provedení požadavku na Pinata.
Poté máme naši asynchronní funkci pinJSONToIPFS, která jako vstup přijímá JSONBody a v hlavičce API klíč a secret Pinata, a to vše pro provedení POST požadavku na jejich API pinJSONToIPFS.
- Pokud je tento POST požadavek úspěšný, naše funkce vrátí objekt JSON s booleovskou hodnotou
successjako true apinataUrl, kde byla naše metadata připnuta. Tuto vrácenoupinataUrlpoužijeme jako vstuptokenURIdo funkce mintování našeho chytrého kontraktu. - Pokud tento post požadavek selže, naše funkce vrátí objekt JSON s booleovskou hodnotou
successjako false a řetězcemmessage, který sděluje naši chybu.
Stejně jako u návratových typů naší funkce connectWallet vracíme objekty JSON, abychom mohli jejich parametry použít k aktualizaci našich stavových proměnných a uživatelského rozhraní.
Načtěte svůj chytrý kontrakt
Nyní, když máme způsob, jak nahrát naše metadata NFT na IPFS prostřednictvím naší funkce pinJSONToIPFS, budeme potřebovat způsob, jak načíst instanci našeho chytrého kontraktu, abychom mohli volat jeho funkci mintNFT.
Jak jsme již zmínili, v tomto návodu budeme používat tento existující chytrý kontrakt NFTopens in a new tab; nicméně, pokud byste se chtěli dozvědět, jak jsme ho vytvořili, nebo si vytvořit vlastní, vřele doporučujeme podívat se na náš další návod "Jak vytvořit NFT"opens in a new tab.
ABI kontraktu
Pokud jste si naše soubory pozorně prohlédli, jistě jste si všimli, že v našem adresáři src se nachází soubor contract-abi.json. ABI je nezbytné pro specifikaci, kterou funkci kontrakt vyvolá, a také pro zajištění, že funkce vrátí data ve formátu, který očekáváte.
Budeme také potřebovat API klíč Alchemy a Alchemy Web3 API, abychom se připojili k blockchainu Ethereum a načetli náš chytrý kontrakt.
Vytvořte si API klíč Alchemy
Pokud ještě nemáte účet Alchemy, zaregistrujte se zdarma zde.opens in a new tab
Jakmile si vytvoříte účet na Alchemy, můžete si vygenerovat klíč API vytvořením aplikace. To nám umožní provádět požadavky na testovací síť Ropsten.
Přejděte na stránku „Create App“ ve svém panelu Alchemy tak, že najedete myší na „Apps“ v navigační liště a kliknete na „Create App“.
Pojmenujte svou aplikaci – my jsme zvolili „My First NFT!“, nabídněte krátký popis, vyberte „Staging“ pro prostředí používané pro účetnictví vaší aplikace a jako síť zvolte „Ropsten“.
Klikněte na „Create app“ a to je vše! Vaše aplikace by se měla objevit v tabulce níže.
Skvělé, takže teď, když jsme vytvořili naši HTTP Alchemy API URL, zkopírujte si ji do schránky...
… a poté ji přidejme do našeho souboru .env. Celkově by váš soubor .env měl vypadat takto:
1REACT_APP_PINATA_KEY = <pinata-key>2REACT_APP_PINATA_SECRET = <pinata-secret>3REACT_APP_ALCHEMY_KEY = https://eth-ropsten.alchemyapi.io/v2/<alchemy-key>Nyní, když máme naše ABI kontraktu a náš API klíč Alchemy, jsme připraveni načíst náš chytrý kontrakt pomocí Alchemy Web3opens in a new tab.
Nastavte si svůj koncový bod Alchemy Web3 a kontrakt
Nejprve, pokud ho ještě nemáte, budete muset nainstalovat Alchemy Web3opens in a new tab tak, že přejdete do domovského adresáře: nft-minter-tutorial v terminálu:
1cd ..2npm install @alch/alchemy-web3Dále se vraťme do našeho souboru interact.js. Na začátek souboru přidejte následující kód, abyste naimportovali svůj klíč Alchemy ze souboru .env a nastavili si svůj koncový bod Alchemy Web3:
1require("dotenv").config()2const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY3const { createAlchemyWeb3 } = require("@alch/alchemy-web3")4const web3 = createAlchemyWeb3(alchemyKey)Alchemy Web3opens in a new tab je nadstavba nad Web3.jsopens in a new tab, která poskytuje vylepšené metody API a další klíčové výhody, které vám usnadní život vývojáře web3. Je navržen tak, aby vyžadoval minimální konfiguraci, takže jej můžete ve své aplikaci začít používat okamžitě!
Dále přidejme do našeho souboru ABI a adresu kontraktu.
1require("dotenv").config()2const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY3const { createAlchemyWeb3 } = require("@alch/alchemy-web3")4const web3 = createAlchemyWeb3(alchemyKey)56const contractABI = require("../contract-abi.json")7const contractAddress = "0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE"Jakmile máme obojí, jsme připraveni začít kódovat naši funkci mintování!
Implementujte funkci mintNFT
Uvnitř vašeho souboru interact.js definujme naši funkci mintNFT, která bude, jak název napovídá, mintovat naše NFT.
Protože budeme provádět četná asynchronní volání (na Pinata pro připnutí našich metadat na IPFS, Alchemy Web3 pro načtení našeho chytrého kontraktu a MetaMask pro podepsání našich transakcí), bude naše funkce také asynchronní.
Tři vstupy do naší funkce budou url našeho digitálního aktiva, name a description. Pod funkci connectWallet přidejte následující signaturu funkce:
1export const mintNFT = async (url, name, description) => {}Zpracování chyb na vstupu
Je samozřejmě logické mít na začátku funkce nějaké zpracování chyb na vstupu, takže z této funkce odejdeme, pokud naše vstupní parametry nejsou správné. Do naší funkce přidejme následující kód:
1export const mintNFT = async (url, name, description) => {2 //zpracování chyb3 if (url.trim() == "" || name.trim() == "" || description.trim() == "") {4 return {5 success: false,6 status: "❗Před mintováním se prosím ujistěte, že jsou všechna pole vyplněna.",7 }8 }9}Zobrazit všeV podstatě, pokud je některý ze vstupních parametrů prázdný řetězec, vrátíme objekt JSON, kde je booleovská hodnota success false a řetězec status sděluje, že všechna pole v našem uživatelském rozhraní musí být vyplněna.
Nahrajte metadata na IPFS
Jakmile víme, že jsou naše metadata správně naformátována, dalším krokem je zabalit je do objektu JSON a nahrát je na IPFS prostřednictvím funkce pinJSONToIPFS, kterou jsme napsali!
K tomu musíme nejprve naimportovat funkci pinJSONToIPFS do našeho souboru interact.js. Na samý začátek interact.js přidejme:
1import { pinJSONToIPFS } from "./pinata.js"Vzpomeňte si, že pinJSONToIPFS přijímá jako vstup tělo JSON. Takže než ji zavoláme, budeme muset naformátovat naše parametry url, name a description do objektu JSON.
Aktualizujme náš kód tak, aby vytvořil objekt JSON nazvaný metadata a poté proveďme volání pinJSONToIPFS s tímto parametrem metadata:
1export const mintNFT = async (url, name, description) => {2 //zpracování chyb3 if (url.trim() == "" || name.trim() == "" || description.trim() == "") {4 return {5 success: false,6 status: "❗Před mintováním se prosím ujistěte, že jsou všechna pole vyplněna.",7 }8 }910 //vytvořit metadata11 const metadata = new Object()12 metadata.name = name13 metadata.image = url14 metadata.description = description1516 //volání pinata17 const pinataResponse = await pinJSONToIPFS(metadata)18 if (!pinataResponse.success) {19 return {20 success: false,21 status: "😢 Něco se pokazilo při nahrávání vašeho tokenURI.",22 }23 }24 const tokenURI = pinataResponse.pinataUrl25}Zobrazit všeVšimněte si, že odpověď na naše volání pinJSONToIPFS(metadata) ukládáme do objektu pinataResponse. Poté tento objekt analyzujeme na případné chyby.
Pokud dojde k chybě, vrátíme objekt JSON, kde je booleovská hodnota success false a náš řetězec status sděluje, že naše volání selhalo. V opačném případě extrahujeme pinataURL z pinataResponse a uložíme ji jako naši proměnnou tokenURI.
Nyní je čas načíst náš chytrý kontrakt pomocí Alchemy Web3 API, které jsme inicializovali na začátku našeho souboru. Na konec funkce mintNFT přidejte následující řádek kódu, který nastaví kontrakt na globální proměnnou window.contract:
1window.contract = await new web3.eth.Contract(contractABI, contractAddress)Poslední věc, kterou je třeba přidat do naší funkce mintNFT, je naše transakce Ethereum:
1//nastavte si svou transakci Ethereum2const transactionParameters = {3 to: contractAddress, // Povinné s výjimkou zveřejnění kontraktu.4 from: window.ethereum.selectedAddress, // musí odpovídat aktivní adrese uživatele.5 data: window.contract.methods6 .mintNFT(window.ethereum.selectedAddress, tokenURI)7 .encodeABI(), //provést volání chytrého kontraktu NFT8}910//podepsat transakci přes MetaMask11try {12 const txHash = await window.ethereum.request({13 method: "eth_sendTransaction",14 params: [transactionParameters],15 })16 return {17 success: true,18 status:19 "✅ Podívejte se na svou transakci na Etherscanu: https://ropsten.etherscan.io/tx/" +20 txHash,21 }22} catch (error) {23 return {24 success: false,25 status: "😥 Něco se pokazilo: " + error.message,26 }27}Zobrazit všePokud jste již obeznámeni s transakcemi na Ethereu, všimnete si, že struktura je docela podobná tomu, co jste již viděli.
- Nejprve nastavíme naše parametry transakce.
tourčuje adresu příjemce (náš chytrý kontrakt)fromurčuje podepisujícího transakce (připojená adresa uživatele k MetaMasku:window.ethereum.selectedAddress)dataobsahuje volání metodymintNFTnašeho chytrého kontraktu, která jako vstup přijímá náštokenURIa adresu peněženky uživatele,window.ethereum.selectedAddress
- Poté provedeme await volání
window.ethereum.request, kde požádáme MetaMask o podepsání transakce. Všimněte si, že v tomto požadavku specifikujeme naši eth metodu (eth_SentTransaction) a předáváme našetransactionParameters. V tomto okamžiku se v prohlížeči otevře MetaMask a vyzve uživatele k podepsání nebo zamítnutí transakce.- Pokud je transakce úspěšná, funkce vrátí objekt JSON, kde je booleovská hodnota
successnastavena na true a řetězecstatusvyzve uživatele, aby se podíval na Etherscan pro více informací o své transakci. - Pokud transakce selže, funkce vrátí objekt JSON, kde je booleovská hodnota
successnastavena na false a řetězecstatussděluje chybovou zprávu.
- Pokud je transakce úspěšná, funkce vrátí objekt JSON, kde je booleovská hodnota
Celkově by naše funkce mintNFT měla vypadat takto:
1export const mintNFT = async (url, name, description) => {2 //zpracování chyb3 if (url.trim() == "" || name.trim() == "" || description.trim() == "") {4 return {5 success: false,6 status: "❗Před mintováním se prosím ujistěte, že jsou všechna pole vyplněna.",7 }8 }910 //vytvořit metadata11 const metadata = new Object()12 metadata.name = name13 metadata.image = url14 metadata.description = description1516 //žádost o připnutí pinata17 const pinataResponse = await pinJSONToIPFS(metadata)18 if (!pinataResponse.success) {19 return {20 success: false,21 status: "😢 Něco se pokazilo při nahrávání vašeho tokenURI.",22 }23 }24 const tokenURI = pinataResponse.pinataUrl2526 //načíst chytrý kontrakt27 window.contract = await new web3.eth.Contract(contractABI, contractAddress) //loadContract();2829 //nastavte si svou transakci Ethereum30 const transactionParameters = {31 to: contractAddress, // Povinné s výjimkou zveřejnění kontraktu.32 from: window.ethereum.selectedAddress, // musí odpovídat aktivní adrese uživatele.33 data: window.contract.methods34 .mintNFT(window.ethereum.selectedAddress, tokenURI)35 .encodeABI(), //provést volání chytrého kontraktu NFT36 }3738 //podepsat transakci přes MetaMask39 try {40 const txHash = await window.ethereum.request({41 method: "eth_sendTransaction",42 params: [transactionParameters],43 })44 return {45 success: true,46 status:47 "✅ Podívejte se na svou transakci na Etherscanu: https://ropsten.etherscan.io/tx/" +48 txHash,49 }50 } catch (error) {51 return {52 success: false,53 status: "😥 Něco se pokazilo: " + error.message,54 }55 }56}Zobrazit všeTo je jedna obrovská funkce! Nyní už jen stačí připojit naši funkci mintNFT k naší komponentě Minter.js...
Připojte mintNFT k našemu frontendu Minter.js
Otevřete svůj soubor Minter.js a aktualizujte řádek import { connectWallet, getCurrentWalletConnected } from \"./utils/interact.js\"; na začátku na:
1import {2 connectWallet,3 getCurrentWalletConnected,4 mintNFT,5} from "./utils/interact.js"Nakonec implementujte funkci onMintPressed, abyste provedli await volání na vaši importovanou funkci mintNFT a aktualizovali stavovou proměnnou status tak, aby odrážela, zda naše transakce uspěla nebo selhala:
1const onMintPressed = async () => {2 const { status } = await mintNFT(url, name, description)3 setStatus(status)4}Nasaďte své NFT na živou webovou stránku
Jste připraveni uvést svůj projekt do provozu, aby s ním uživatelé mohli interagovat? Podívejte se na tento návodopens in a new tab pro nasazení vašeho Minteru na živou webovou stránku.
Ještě poslední krok...
Dobijte svět blockchainu
Děláme si legraci, dostali jste se až na konec návodu!
Abychom to shrnuli, vytvořením minteru NFT jste se úspěšně naučili, jak:
- Připojit se k MetaMasku prostřednictvím vašeho frontendového projektu
- Volat metody chytrého kontraktu z vašeho frontendu
- Podepisovat transakce pomocí MetaMasku
Pravděpodobně se budete chtít pochlubit NFT vyraženými prostřednictvím vaší dapp ve své peněžence – proto se určitě podívejte na náš rychlý návod Jak si zobrazit NFT ve vaší peněženceopens in a new tab!
A jako vždy, pokud máte nějaké dotazy, jsme tu, abychom vám pomohli na Alchemy Discorduopens in a new tab. Nemůžeme se dočkat, až uvidíme, jak koncepty z tohoto návodu uplatníte ve svých budoucích projektech!
Stránka naposledy aktualizována: 25. února 2026