1655745480
La etapa de implementación de una aplicación es un paso crucial dentro del proceso de desarrollo. Durante esta etapa, la aplicación pasa de estar alojada localmente a estar disponible para el público objetivo en cualquier parte del mundo.
Con el uso creciente de blockchains en la creación de aplicaciones, es posible que se haya preguntado cómo se alojan las DApps, que interactúan con los contratos inteligentes.
En este tutorial, aprenderá a alojar DApps con Fleek mediante la creación de una aplicación de adopción de mascotas descentralizada de muestra con React, Hardhat y Alchemy.
Este tutorial contiene varios pasos prácticos. Para seguir, te recomiendo que hagas lo siguiente:
MetaMask es una billetera de criptomonedas que permite a los usuarios acceder a DApps a través de un navegador o una aplicación móvil. También querrá una cuenta MetaMask de prueba en una red de prueba de Ethereum para probar contratos inteligentes . Estoy usando Ropsten Test Network en este tutorial.
Fleek es una solución Web3 que tiene como objetivo hacer que el proceso de implementación de sus sitios, DApps y servicios sea fluido. Actualmente, Fleek proporciona una puerta de enlace para alojar sus servicios en el Sistema de archivos interplanetarios (IPFS) o en la computadora de Internet (IC) de Dfinity .
Fleek se describe a sí mismo como el equivalente de Netlify para aplicaciones Web3. Como resultado, encontrará algunas características que son similares a Netlify, como ejecutar compilaciones usando imágenes de Docker y generar vistas previas de implementación.
Según el blog de IPFS , “el principal objetivo de Fleek para 2022 es reestructurar su infraestructura de IPFS para descentralizarla e incentivarla aún más. También incluirá nuevos proveedores de infraestructura Web3 para diferentes piezas de la pila de construcción web”.
Fleek ofrece una solución a un desafío de IPFS en el que el hash de su sitio web cambia cada vez que realiza una actualización, lo que dificulta tener un hash de dirección fijo. Después de la implementación inicial, Fleek construirá, anclará y actualizará su sitio.
Comencemos a construir nuestra DApp de muestra en la siguiente sección e implementémosla usando Fleek. Alojaremos la DApp en IPFS.
En esta sección, construiremos un sistema de seguimiento de adopciones descentralizado para una tienda de mascotas.
Si está familiarizado con Truffle Suite , puede reconocer algunas partes de este ejercicio. La inspiración para esta DApp proviene de la guía Truffle . Llevaremos las cosas un paso más allá usando Alchemy, Hardhat y React.
Para permitirle concentrarse en escribir el contrato inteligente e implementar la DApp, ya he creado el componente y el estado de la interfaz de usuario. El contrato inteligente y el código React estarán contenidos en un solo proyecto.
Simplemente clone la aplicación React de mi repositorio de GitHub para comenzar a escribir el contrato inteligente:
git clone https://github.com/vickywane/react-web3
A continuación, cambie el directorio a la carpeta clonada e instale las dependencias enumeradas en el package.json
archivo:
# cambiar el directorio cd react-web3 # instalar las dependencias de la aplicación npm install
With the React application set up, let’s proceed to create the pet adoption smart contract.
Dentro del react-web3
directorio, cree una carpeta de contratos para almacenar el código de Solidity para nuestro contrato inteligente de adopción de mascotas.
Usando su editor de código, cree un archivo llamado Adoption.sol
y pegue el código a continuación para crear las variables y funciones necesarias dentro del contrato inteligente, que incluyen:
//SPDX-License-Identifier: Unlicense
// ./react-web3/contracts/Adoption.sol
pragma solidity ^0.8.0;
contract Adoption {
address[16] public adopters;
event PetAssigned(address indexed petOwner, uint32 petId);
// adopting a pet
function adopt(uint32 petId) public {
require(petId >= 0 && petId <= 15, "Pet does not exist");
adopters[petId] = msg.sender;
emit PetAssigned(msg.sender, petId);
}
// Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
}
A continuación, cree otro archivo con el nombre deploy-contract-script.js
dentro de la carpeta de contratos. Pegue el código JavaScript a continuación en el archivo. El código actuará como un script que utiliza el getContractFactory
método asincrónico de Hardhat para crear una instancia de fábrica del contrato inteligente de adopción y luego implementarlo.
// react-web3/contract/deploy-contract-script.js
require('dotenv').config()
const { ethers } = require("hardhat");
async function main() {
// We get the contract to deploy
const Adoption = await ethers.getContractFactory("Adoption");
const adoption = await Adoption.deploy();
await adoption.deployed();
console.log("Adoption Contract deployed to:", adoption.address);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Finalmente, crea un archivo llamado hardhat.config.js
. Este archivo especificará la configuración del casco.
Agregue el siguiente código JavaScript al hardhat.config.js
archivo para especificar una versión de Solidity y el punto final de URL para su cuenta de red de Ropsten.
require("@nomiclabs/hardhat-waffle");
require('dotenv').config();
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.4",
networks: {
ropsten: {
url: process.env.ALCHEMY_API_URL,
accounts: [`0x${process.env.METAMASK_PRIVATE_KEY}`]
}
}
};
Estoy usando las variables de entorno ALCHEMY_API_URL
y METAMASK_PRIVATE_KEY
para almacenar la URL y los valores de clave de cuenta privada utilizados para la configuración de red de Ropsten:
METAMASK_PRIVATE_KEY
está asociado con su billetera MetaMaskALCHEMY_API_URL
enlaces a una aplicación de AlchemyPuede almacenar y acceder a estas variables de entorno dentro de este react-web3
proyecto utilizando un .env
archivo y el dotenv
paquete. Revisaremos cómo hacer esto en la siguiente sección.
Si ha estado siguiendo con éxito, aún no ha creado una aplicación de Alchemy en este punto del proyecto. Necesitará usar su punto final de URL de API, así que procedamos a crear una aplicación en Alchemy.
Alchemy proporciona funciones que le permiten conectarse a un nodo externo de llamada a procedimiento remoto (RPC) para una red. Los nodos RPC hacen posible que su DApp y la cadena de bloques se comuniquen.
Usando su navegador web, navegue hasta el panel web de Alchemy y cree una nueva aplicación.
Proporcione un nombre y una descripción para la aplicación, luego seleccione la red Ropsten. Haga clic en el botón "Crear aplicación" para continuar.
Después de crear la aplicación, la encontrará en la parte inferior de la página.
Haga clic en "Ver clave" para revelar las claves API para la aplicación Alchemy. Tome nota de la URL HTTP. He redactado esta información en la imagen de abajo.
Cree un .env
archivo dentro de su proyecto Hardhat, como se muestra a continuación. Utilizará este .env
archivo para almacenar la URL de su aplicación Alchemy y la clave privada de MetaMask.
// react-web3/.env
ALCHEMY_API_URL=<ALCHEMY_HTTP_URL>
METAMASK_PRIVATE_KEY=<METAMASK_PRIVATE_KEY>
Reemplace los marcadores de posición ALCHEMY_HTTP_URL
y METAMASK_PRIVATE_KEY
anteriores con la URL HTTP de Alchemy y su clave privada de MetaMask. Siga la guía MetaMask Export Private Key para aprender cómo exportar esta información para su billetera.
Por último, ejecute el siguiente comando para implementar su contrato inteligente de adopción de mascotas en la red Ropsten especificada:
npx hardhat run contracts/deploy-contract-script.js --network ropsten
Como se muestra en la imagen a continuación, tenga en cuenta la dirección que se devuelve a su consola después de implementar el contrato. Necesitará esta dirección en la siguiente sección.
En este punto, se ha implementado el contrato inteligente de adopción de mascotas. Ahora cambiemos el enfoque a la propia DApp y creemos funciones para interactuar con el contrato inteligente de adopción de mascotas.
Similar al tutorial de la tienda de mascotas de la guía Truffle, nuestra DApp mostrará dieciséis razas diferentes de perros que se pueden adoptar. La información detallada de cada perro se almacena en el src/pets.json
archivo . Estamos usando TailwindCSS para darle estilo a esta DApp.
Para comenzar, abra el state/context.js
archivo y reemplace el contenido existente con el siguiente código:
// react-web3/state/context.js
import React, {useEffect, useReducer} from "react";
import Web3 from "web3";
import {ethers, providers} from "ethers";
const {abi} = require('../../artifacts/contracts/Adoption.sol/Adoption.json')
if (!abi) {
throw new Error("Adoptiom.json ABI file missing. Run npx hardhat run contracts/deploy-contract-script.js")
}
export const initialState = {
isModalOpen: false,
dispatch: () => {
},
showToast: false,
adoptPet: (id) => {
},
retrieveAdopters: (id) => {
},
};
const {ethereum, web3} = window
const AppContext = React.createContext(initialState);
export default AppContext;
const reducer = (state, action) => {
switch (action.type) {
case 'INITIATE_WEB3':
return {
...state,
isModalOpen: action.payload,
}
case 'SENT_TOAST':
return {
...state,
showToast: action.payload.toastVisibility
}
default:
return state;
}
};
const createEthContractInstance = () => {
try {
const provider = new providers.Web3Provider(ethereum)
const signer = provider.getSigner()
const contractAddress = process.env.REACT_APP_ADOPTION_CONTRACT_ADDRESS
return new ethers.Contract(contractAddress, abi, signer)
} catch (e) {
console.log('Unable to create ethereum contract. Error:', e)
}
}
export const AppProvider = ({children}) => {
const [state, dispatch] = useReducer(reducer, initialState);
const instantiateWeb3 = async _ => {
if (ethereum) {
try {
// Request account access
return await ethereum.request({method: "eth_requestAccounts"})
} catch (error) {
// User denied account access...
console.error("User denied account access")
}
} else if (web3) {
return
}
return new Web3(Web3.givenProvider || "ws://localhost:8545")
}
const adoptPet = async id => {
try {
const instance = createEthContractInstance()
const accountData = await instantiateWeb3()
await instance.adopt(id, {from: accountData[0]})
dispatch({
type: 'SENT_TOAST', payload: {
toastVisibility: true
}
})
// close success toast after 3s
setTimeout(() => {
dispatch({
type: 'SENT_TOAST', payload: {
toastVisibility: false
}
})
}, 3000)
} catch (e) {
console.log("ERROR:", e)
}
}
const retrieveAdopters = async _ => {
try {
const instance = createEthContractInstance()
return await instance.getAdopters()
} catch (e) {
console.log("RETRIEVING:", e)
}
}
useEffect(() => {
(async () => { await instantiateWeb3() })()
})
return (
<AppContext.Provider
value={{
...state,
dispatch,
adoptPet,
retrieveAdopters
}}
>
{children}
</AppContext.Provider>
);
};
Al leer el bloque de código anterior, observará lo siguiente:
Los objetos Ethereum y Web3 se desestructuran desde la ventana del navegador. La extensión MetaMask inyectará el objeto Ethereum en el navegador.
La createEthContractInstance
función auxiliar crea y devuelve una instancia del contrato de adopción de mascotas utilizando la ABI y la dirección del contrato de Alchemy.
La instantiateWeb3
función auxiliar recuperará y devolverá la dirección de la cuenta del usuario en una matriz, utilizando MetaMask para verificar que el objeto de la ventana de Ethereum esté definido.
La instantiateWeb3
función auxiliar también se ejecuta en un useEffect
enlace para garantizar que los usuarios se conecten con MetaMask inmediatamente después de abrir la aplicación en el navegador web.
La adoptPet
función espera un parámetro numérico petId
, crea la instancia del contrato de adopción y recupera la dirección del usuario mediante las funciones auxiliares createEthContractInstance
y .instantiateWeb3
El petId
parámetro y la dirección de la cuenta de usuario se pasan al adopt
método desde la instancia del contrato de adopción de mascotas para adoptar una mascota.
La retrieveAdopters
función ejecuta el getAdopters
método en la instancia de adopción para recuperar la dirección de todas las mascotas adoptadas.
Guarde estos cambios e inicie el servidor de desarrollo de React para ver la DApp de la tienda de mascotas en http://localhost4040/ .
En este punto, las funciones dentro del contrato de adopción se han implementado en el state/context.js
archivo, pero aún no se han ejecutado. Sin autenticarse con MetaMask, la dirección de la cuenta del usuario no estará definida y todos los botones para adoptar una mascota estarán deshabilitados, como se muestra a continuación:
Procedamos a agregar la dirección del contrato de adopción de mascotas como una variable de entorno y alojemos la DApp en Fleek.
El alojamiento de una DApp en Fleek se puede realizar a través del panel de control de Fleek, la CLI de Fleek o incluso mediante programación mediante Fleek GitHub Actions . En esta sección, aprenderá a usar la CLI de Fleek mientras alojamos la DApp de la tienda de mascotas en IPFS a través de Fleek.
Ejecute el siguiente comando para instalar Fleek CLI globalmente en su computadora:
npm install -g @fleek/cli
Para usar la CLI de Fleek instalada, debe tener una clave API para una cuenta de Fleek almacenada como una variable de entorno en su terminal. Procedamos a generar una clave API para su cuenta utilizando el panel web de Fleek.
Usando su navegador web, navegue hasta el panel de control de su cuenta de Fleek y haga clic en el avatar de su cuenta para mostrar un menú emergente. Dentro de este menú, haga clic en "Configuración" para navegar a la configuración de su cuenta de Fleek.
Dentro de la configuración de su cuenta de Fleek, haga clic en el botón "Generar API" para iniciar el modal "Detalles de API", que generará una clave de API para su cuenta de Fleek.
Tome la clave API generada y reemplace el FLEEK_API_KEY
marcador de posición en el siguiente comando:
export FLEEK_API_KEY='FLEEK_API_KEY'
Ejecute este comando para exportar la clave API de Fleek como una variable de entorno temporal para su terminal de computadora. La CLI de Fleek leerá el valor de la FLEEK_API_KEY
variable cuando ejecute un comando en su cuenta de Fleek.
Debe generar los archivos estáticos para React DApp localmente antes de poder alojar la DApp y sus archivos en IPFS usando Fleek.
La generación de archivos estáticos se puede automatizar durante el proceso de compilación especificando una imagen de Docker y los comandos que se usarán para crear sus archivos estáticos. Sin embargo, en este tutorial, generará los archivos estáticos manualmente.
Ejecute el siguiente comando npm para generar archivos estáticos para la DApp en un build
directorio.
npm run build
A continuación, inicialice un espacio de trabajo del sitio de Fleek dentro de la react-web3
carpeta con el siguiente comando:
fleek site:init
El proceso de inicialización es un paso único para cada sitio de Fleek. Fleek CLI iniciará una sesión interactiva que lo guiará a través del proceso de inicialización del sitio.
Durante el proceso de inicialización, se le pedirá que ingrese un teamId
, como se ve en la siguiente imagen:
Encontrará sus teamId
números en la URL del panel de control de Fleek. A continuación se muestra un ejemplo teamId
:
En este punto, la CLI de Fleek ha generado un .fleek.json
archivo dentro del react-web3
directorio con las configuraciones de alojamiento de Fleek. Sin embargo, falta una cosa: la variable de entorno que contiene la dirección del contrato inteligente de adopción de mascotas.
Procedamos a ver cómo agregar variables de entorno para sitios implementados localmente en Fleek.
Fleek permite a los desarrolladores administrar credenciales confidenciales para sus sitios de forma segura, ya sea a través del panel de Fleek o del archivo de configuración. Como está alojando localmente un sitio desde su línea de comandos en este tutorial, especificará su variable de entorno en el .fleek.json
archivo.
En el siguiente código, reemplace el ADOPTION_CONTRACT_ADDRESS
marcador de posición con la dirección del contrato inteligente de adopción de mascotas. Recuerde, esta dirección se devolvió después de que creamos la aplicación Alchemy e implementamos el contrato inteligente con el comando npx anteriormente en este tutorial .
{
"site": {
"id": "SITE_ID",
"team": "TEAM_ID",
"platform": "ipfs",
"source": "ipfs",
"name": "SITE_NAME"
},
"build": {
"baseDir": "",
"publicDir": "build",
"rootDir": "",
"environment": {
"REACT_APP_ADOPTION_CONTRACT": "ADOPTION_CONTRACT_ADDRESS"
}
}
}
Nota: La CLI SITE_ID
de Fleek generará automáticamente los marcadores de posición , y en el TEAM_ID
archivo cuando inicialice un sitio de Fleek.SITE_NAME.fleek.json
El código anterior también contiene el siguiente objeto, que debe agregar al objeto de compilación dentro de su .fleek.json
archivo:
"environment": {
"REACT_APP_ADOPTION_CONTRACT": "ADOPTION_CONTRACT_ADDRESS"
}
El objeto JSON anterior especifica una imagen acoplable de nodo que utilizará Fleek para crear la DApp. Durante el proceso de compilación, se ejecutarán los comandos npm en el command
campo.
Ejecute el siguiente comando para volver a implementar la DApp usando la nueva configuración de compilación en el .fleek.json
archivo.
fleek site:deploy
¡Felicidades! La DApp se ha implementado por completo y ahora puede acceder al sitio en vivo a través de su navegador web. También puede obtener información más detallada sobre la DApp alojada a través del panel de control de Fleek siguiendo estos pasos:
Haga clic en la URL del sitio para abrir la DApp en una nueva pestaña del navegador. Se le pedirá que conecte una billetera MetaMask inmediatamente después de que se inicie la DApp. Después de conectar una billetera, podrá adoptar cualquiera de los dieciséis perros haciendo clic en los botones "Adoptar".
¡Eso es todo! Su DApp de adopción de mascotas de muestra se implementó en Fleek.
En este tutorial, nos enfocamos en crear y alojar una DApp de muestra en IPFS a través de Fleek. El proceso comenzó de manera similar al contrato inteligente de adopción de mascotas de la guía de Truffle. Luego, dio un paso más al crear una DApp para interactuar con el contrato inteligente de adopción de mascotas.
Si desea aprovechar los pasos de este tutorial para alojar una DApp lista para producción, le recomiendo que considere lo siguiente:
Primero, asegúrese de conectar Fleek a un proveedor de host de código, como GitHub, e implemente la DApp desde una rama de producción dentro de su repositorio. Esto permitirá que Fleek vuelva a implementar automáticamente la DApp cuando envíe una nueva confirmación de código a la rama implementada.
En segundo lugar, si está utilizando un .fleek.json
archivo para almacenar variables de entorno, incluya el nombre del .fleek.json
archivo en su .gitignore
archivo. Hacer esto garantizará que el .fleek.json
archivo no se inserte y que las variables de entorno no queden expuestas.
Espero que hayas encontrado útil este tutorial. Si tiene alguna pregunta, no dude en compartir un comentario.
Esta historia se publicó originalmente en https://blog.logrocket.com/how-build-dapp-host-ipfs-fleek/
1655745180
アプリケーションの展開段階は、開発プロセス内の重要なステップです。この段階で、アプリケーションはローカルでホストされるようになり、世界中のターゲットオーディエンスが利用できるようになります。
アプリケーションの構築におけるブロックチェーンの使用が増えるにつれ、スマートコントラクトと相互作用するDAppがどのようにホストされているのか疑問に思われるかもしれません。
このチュートリアルでは、React、Hardhat、およびAlchemyを使用してサンプルの分散型ペットの養子縁組アプリケーションを構築することにより、FleekでDAppをホストする方法を学習します。
このチュートリアルには、いくつかの実践的な手順が含まれています。フォローするには、次のことを行うことをお勧めします。
MetaMaskは、ユーザーがブラウザーまたはモバイルアプリを介してDAppにアクセスできるようにする暗号通貨ウォレットです。スマートコントラクトをテストするために、EthereumテストネットでテストMetaMaskアカウントも必要になります。このチュートリアルでは、RopstenTestNetworkを使用しています。
Fleekは、サイト、DApp、およびサービスをシームレスに展開するプロセスを作成することを目的としたWeb3ソリューションです。現在、Fleekは、InterPlanetary File System(IPFS)またはDfinityのインターネットコンピューター(IC)でサービスをホストするためのゲートウェイを提供しています。
Fleekは、それ自体をWeb3アプリケーションと同等のNetlifyと表現しています。その結果、Dockerイメージを使用したビルドの実行やデプロイメントプレビューの生成など、Netlifyに類似したいくつかの機能が見つかります。
IPFSブログによると、「2022年のFleekの主な目標は、IPFSインフラストラクチャを再構築して、さらに分散化し、インセンティブを与えることです。また、Web構築スタックのさまざまな部分に対応する新しいWeb3インフラストラクチャプロバイダーも含まれます。」
Fleekは、更新を行うたびにWebサイトのハッシュが変更されるため、固定アドレスハッシュを使用することが困難になるというIPFSの課題に対するソリューションを提供します。最初の展開後、Fleekはサイトを構築、固定、更新します。
次のセクションでサンプルDAppの構築を開始し、Fleekを使用してデプロイしましょう。DAppをIPFSでホストします。
このセクションでは、ペットショップ向けの分散型採用追跡システムを構築します。
Truffle Suiteに精通している場合は、この演習の一部に気付くかもしれません。このDAppのインスピレーションは、トリュフガイドから来ています。Alchemy、Hardhat、Reactを使用して、さらに一歩進んでいきます。
スマートコントラクトの作成とDAppのデプロイに集中できるようにするために、私はすでにUIコンポーネントと状態を構築しました。スマートコントラクトとReactコードは単一のプロジェクトに含まれます。
GitHubリポジトリからReactアプリケーションのクローンを作成するだけで、スマートコントラクトの作成を開始できます。
git clone https://github.com/vickywane/react-web3
次に、ディレクトリを複製フォルダに変更し、package.json
ファイルにリストされている依存関係をインストールします。
#ディレクトリを変更するcd react-web3#アプリケーションの依存関係をインストールするnpm install
With the React application set up, let’s proceed to create the pet adoption smart contract.
ディレクトリ内にreact-web3
、ペットの養子縁組のスマートコントラクトのSolidityコードを保存するコントラクトフォルダーを作成します。
コードエディタを使用して、という名前のファイルAdoption.sol
を作成し、以下のコードに貼り付けて、スマートコントラクト内に必要な変数と関数を作成します。
//SPDX-License-Identifier: Unlicense
// ./react-web3/contracts/Adoption.sol
pragma solidity ^0.8.0;
contract Adoption {
address[16] public adopters;
event PetAssigned(address indexed petOwner, uint32 petId);
// adopting a pet
function adopt(uint32 petId) public {
require(petId >= 0 && petId <= 15, "Pet does not exist");
adopters[petId] = msg.sender;
emit PetAssigned(msg.sender, petId);
}
// Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
}
deploy-contract-script.js
次に、 contractsフォルダー内に名前を付けた別のファイルを作成します。以下のJavaScriptコードをファイルに貼り付けます。このコードはgetContractFactory
、Hardhatの非同期メソッドを使用して、養子縁組スマートコントラクトのファクトリインスタンスを作成し、それをデプロイするスクリプトとして機能します。
// react-web3/contract/deploy-contract-script.js
require('dotenv').config()
const { ethers } = require("hardhat");
async function main() {
// We get the contract to deploy
const Adoption = await ethers.getContractFactory("Adoption");
const adoption = await Adoption.deploy();
await adoption.deployed();
console.log("Adoption Contract deployed to:", adoption.address);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
最後に、というファイルを作成しますhardhat.config.js
。このファイルは、ヘルメットの構成を指定します。
次のJavaScriptコードをhardhat.config.js
ファイルに追加して、RopstenネットワークアカウントのSolidityバージョンとURLエンドポイントを指定します。
require("@nomiclabs/hardhat-waffle");
require('dotenv').config();
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.4",
networks: {
ropsten: {
url: process.env.ALCHEMY_API_URL,
accounts: [`0x${process.env.METAMASK_PRIVATE_KEY}`]
}
}
};
私は環境変数ALCHEMY_API_URL
をMETAMASK_PRIVATE_KEY
使用しており、Ropstenネットワーク構成に使用されるURLとプライベートアカウントキーの値を保存しています。
METAMASK_PRIVATE_KEY
MetaMaskウォレットに関連付けられていますALCHEMY_API_URL
Alchemyアプリケーションへのリンクファイルとパッケージを使用して、このプロジェクト内にこれらの環境変数を保存してアクセスできます。これを行う方法については、次のセクションで確認します。react-web3.envdotenv
順調に進んでいる場合は、プロジェクトのこの時点ではまだAlchemyアプリケーションを作成していません。API URLエンドポイントを使用する必要があるので、Alchemyでアプリケーションを作成してみましょう。
Alchemyは、ネットワークの外部リモートプロシージャコール(RPC)ノードに接続できるようにする機能を提供します。RPCノードを使用すると、DAppとブロックチェーンが通信できるようになります。
Webブラウザーを使用して、Alchemy Webダッシュボードに移動し、新しいアプリを作成します。
アプリの名前と説明を入力してから、Ropstenネットワークを選択します。「アプリの作成」ボタンをクリックして続行します。
アプリが作成されると、ページの下部に表示されます。
「キーの表示」をクリックして、AlchemyアプリのAPIキーを表示します。HTTPURLに注意してください。下の画像でこの情報を編集しました。
.env
以下に示すように、Hardhatプロジェクト内にファイルを作成します。この.env
ファイルを使用して、AlchemyアプリのURLとMetaMask秘密鍵を保存します。
// react-web3/.env
ALCHEMY_API_URL=<ALCHEMY_HTTP_URL>
METAMASK_PRIVATE_KEY=<METAMASK_PRIVATE_KEY>
上記のALCHEMY_HTTP_URL
andMETAMASK_PRIVATE_KEY
プレースホルダーを、AlchemyのHTTPURLとMetaMask秘密鍵に置き換えます。MetaMaskエクスポート秘密鍵ガイドに従って、この情報をウォレットにエクスポートする方法を学習してください。
最後に、次のコマンドを実行して、ペットの養子縁組のスマートコントラクトを指定されたRopstenネットワークにデプロイします。
npx hardhat run contracts/deploy-contract-script.js --network ropsten
次の画像に示すように、コントラクトがデプロイされた後にコンソールに返されるアドレスに注意してください。このアドレスは次のセクションで必要になります。
この時点で、ペットの養子縁組のスマートコントラクトが展開されています。次に、焦点をDApp自体に移し、ペットの養子縁組のスマートコントラクトと対話するための関数を作成しましょう。
トリュフガイドのペットショップのチュートリアルと同様に、DAppには養子縁組できる16種類の犬が表示されます。各犬の詳細情報はsrc/pets.json
ファイルに保存されます。このDAppのスタイルを設定するためにTailwindCSSを使用しています。
まず、state/context.js
ファイルを開き、既存のコンテンツを次のコードに置き換えます。
// react-web3/state/context.js
import React, {useEffect, useReducer} from "react";
import Web3 from "web3";
import {ethers, providers} from "ethers";
const {abi} = require('../../artifacts/contracts/Adoption.sol/Adoption.json')
if (!abi) {
throw new Error("Adoptiom.json ABI file missing. Run npx hardhat run contracts/deploy-contract-script.js")
}
export const initialState = {
isModalOpen: false,
dispatch: () => {
},
showToast: false,
adoptPet: (id) => {
},
retrieveAdopters: (id) => {
},
};
const {ethereum, web3} = window
const AppContext = React.createContext(initialState);
export default AppContext;
const reducer = (state, action) => {
switch (action.type) {
case 'INITIATE_WEB3':
return {
...state,
isModalOpen: action.payload,
}
case 'SENT_TOAST':
return {
...state,
showToast: action.payload.toastVisibility
}
default:
return state;
}
};
const createEthContractInstance = () => {
try {
const provider = new providers.Web3Provider(ethereum)
const signer = provider.getSigner()
const contractAddress = process.env.REACT_APP_ADOPTION_CONTRACT_ADDRESS
return new ethers.Contract(contractAddress, abi, signer)
} catch (e) {
console.log('Unable to create ethereum contract. Error:', e)
}
}
export const AppProvider = ({children}) => {
const [state, dispatch] = useReducer(reducer, initialState);
const instantiateWeb3 = async _ => {
if (ethereum) {
try {
// Request account access
return await ethereum.request({method: "eth_requestAccounts"})
} catch (error) {
// User denied account access...
console.error("User denied account access")
}
} else if (web3) {
return
}
return new Web3(Web3.givenProvider || "ws://localhost:8545")
}
const adoptPet = async id => {
try {
const instance = createEthContractInstance()
const accountData = await instantiateWeb3()
await instance.adopt(id, {from: accountData[0]})
dispatch({
type: 'SENT_TOAST', payload: {
toastVisibility: true
}
})
// close success toast after 3s
setTimeout(() => {
dispatch({
type: 'SENT_TOAST', payload: {
toastVisibility: false
}
})
}, 3000)
} catch (e) {
console.log("ERROR:", e)
}
}
const retrieveAdopters = async _ => {
try {
const instance = createEthContractInstance()
return await instance.getAdopters()
} catch (e) {
console.log("RETRIEVING:", e)
}
}
useEffect(() => {
(async () => { await instantiateWeb3() })()
})
return (
<AppContext.Provider
value={{
...state,
dispatch,
adoptPet,
retrieveAdopters
}}
>
{children}
</AppContext.Provider>
);
};
上記のコードブロックを読むと、次のことがわかります。
イーサリアムとWeb3オブジェクトは、ブラウザウィンドウから分解されます。MetaMask拡張機能は、Ethereumオブジェクトをブラウザーに挿入します。
ヘルパー関数はcreateEthContractInstance
、契約のABIとAlchemyからのアドレスを使用して、ペットの養子縁組契約のインスタンスを作成して返します。
ヘルパー関数は、instantiateWeb3
MetaMaskを使用してEthereumウィンドウオブジェクトが定義されていることを確認し、配列内のユーザーのアカウントアドレスを取得して返します。
instantiateWeb3
ヘルパー関数もフックで実行され、ユーザーuseEffect
がWebブラウザーでアプリケーションを開いた直後にMetaMaskに接続できるようにします。
このadoptPet
関数は数値petId
パラメーターを期待し、Adoptionコントラクトインスタンスを作成し、createEthContractInstance
およびinstantiateWeb3
ヘルパー関数を使用してユーザーのアドレスを取得します。
パラメータとユーザーアカウントアドレスは、ペットの養子縁組契約インスタンスからメソッドpetId
に渡され、ペットを養子縁組します。adopt
このretrieveAdopters
関数はgetAdopters
、Adoptionインスタンスでメソッドを実行して、採用されたすべてのペットのアドレスを取得します。
これらの変更を保存し、React開発サーバーを起動して、 http://localhost4040/にあるペットショップのDAppを表示します。
この時点で、養子縁組契約内の機能はstate/context.js
ファイルに実装されていますが、まだ実行されていません。以下に示すように、MetaMaskで認証しないと、ユーザーのアカウントアドレスは未定義になり、ペットを養子にするためのすべてのボタンが無効になります。
ペットの養子縁組契約アドレスを環境変数として追加し、FleekでDAppをホストしてみましょう。
FleekでDAppをホストするには、Fleekダッシュボード、Fleek CLIを使用するか、FleekGitHubActionsをプログラムで使用することもできます。このセクションでは、Fleekを介してIPFSでペットショップDAppをホストするときにFleekCLIを使用する方法を学習します。
以下のコマンドを実行して、FleekCLIをコンピューターにグローバルにインストールします。
npm install -g @fleek/cli
インストールされたFleekCLIを使用するには、FleekアカウントのAPIキーを環境変数としてターミナルに保存する必要があります。Fleek Webダッシュボードを使用して、アカウントのAPIキーの生成に進みましょう。
Webブラウザーを使用して、Fleekアカウントダッシュボードに移動し、アカウントアバターをクリックして、ポップアップメニューを表示します。このメニュー内で、「設定」をクリックして、Fleekアカウント設定に移動します。
Fleekアカウント設定内で、[Generate API]ボタンをクリックして、[API Details]モーダルを起動します。これにより、FleekアカウントのAPIキーが生成されます。
FLEEK_API_KEY
生成されたAPIキーを取得し、以下のコマンドでプレースホルダーを置き換えます。
export FLEEK_API_KEY='FLEEK_API_KEY'
このコマンドを実行して、FleekAPIキーをコンピューター端末の一時的な環境変数としてエクスポートします。FLEEK_API_KEY
Fleekアカウントに対してコマンドを実行すると、FleekCLIは変数の値を読み取ります。
Fleekを使用してIPFSでDAppとそのファイルをホストする前に、ReactDAppの静的ファイルをローカルで生成する必要があります。
静的ファイルの生成は、Dockerイメージと静的ファイルのビルドに使用するコマンドを指定することにより、ビルドプロセス中に自動化できます。ただし、このチュートリアルでは、静的ファイルを手動で生成します。
以下のnpmコマンドを実行して、ディレクトリにDAppの静的ファイルを生成しますbuild
。
npm run build
react-web3
次に、次のコマンドを使用して、フォルダー内のFleekサイトワークスペースを初期化します。
fleek site:init
初期化プロセスは、Fleekサイトごとに1回限りのステップです。Fleek CLIは、サイトを初期化するプロセスをガイドするインタラクティブセッションを開始します。
次の図に示すように、初期化プロセス中に、を入力するように求めteamId
られます。
teamId
FleekダッシュボードのURL内に番号が表示されます。例teamId
を以下に示します。
この時点で、Fleek CLIは、Fleekのホスティング構成を使用し.fleek.json
てディレクトリ内にファイルを生成しました。react-web3
ただし、1つ欠けているのは、ペットの養子縁組のスマートコントラクトアドレスを含む環境変数です。
Fleekにローカルにデプロイされたサイトの環境変数を追加する方法を見てみましょう。
Fleekを使用すると、開発者はFleekダッシュボードまたは構成ファイルを介してサイトの機密性の高いクレデンシャルを安全に管理できます。このチュートリアルでは、コマンドラインからサイトをローカルでホストしているため、.fleek.json
ファイルで環境変数を指定します。
以下のコードで、ADOPTION_CONTRACT_ADDRESS
プレースホルダーをペットの養子縁組のスマートコントラクトアドレスに置き換えます。このアドレスは、Alchemyアプリケーションを作成し、このチュートリアルの前半でnpxコマンドを使用してスマートコントラクトをデプロイした後に返されたことを忘れないでください。
{
"site": {
"id": "SITE_ID",
"team": "TEAM_ID",
"platform": "ipfs",
"source": "ipfs",
"name": "SITE_NAME"
},
"build": {
"baseDir": "",
"publicDir": "build",
"rootDir": "",
"environment": {
"REACT_APP_ADOPTION_CONTRACT": "ADOPTION_CONTRACT_ADDRESS"
}
}
}
注:SITE_ID
、、、TEAM_ID
およびプレースホルダーは、Fleekサイトを初期化するときSITE_NAME
に、ファイル内のFleekCLIによって自動的に生成されます。.fleek.json
.fleek.json
上記のコードには、ファイル内のビルドオブジェクトに追加する必要がある次のオブジェクトも含まれています。
"environment": {
"REACT_APP_ADOPTION_CONTRACT": "ADOPTION_CONTRACT_ADDRESS"
}
上記のJSONオブジェクトは、FleekがDAppの構築に使用するノードDockerイメージを指定します。command
ビルドプロセス中に、フィールドのnpmコマンドが実行されます。
以下のコマンドを実行して、ファイル内の新しいビルド構成を使用してDAppを再デプロイし.fleek.json
ます。
fleek site:deploy
おめでとう!DAppが完全にデプロイされ、Webブラウザーからライブサイトにアクセスできるようになりました。次の手順に従って、FleekダッシュボードからホストされたDAppに関する詳細情報を取得することもできます。
サイトのURLをクリックして、新しいブラウザタブでDAppを開きます。DAppが起動するとすぐに、MetaMaskウォレットを接続するように求められます。ウォレットが接続されたら、「採用」ボタンをクリックして、16匹の犬のいずれかを採用することができます。
それでおしまい!サンプルのペットの養子縁組DAppがFleekにデプロイされました。
このチュートリアルでは、Fleekを介してIPFSでサンプルDAppを構築してホストすることに焦点を当てました。プロセスは、トリュフのガイドからのペットの養子縁組のスマートコントラクトと同様に始まりました。次に、ペットの養子縁組のスマートコントラクトと対話するためのDAppを構築することで、さらに一歩進んだ。
このチュートリアル内の手順を活用して本番環境に対応したDAppをホストする場合は、次のことを検討することを強くお勧めします。
まず、FleekをGitHubなどのコードホストプロバイダーに接続し、リポジトリ内の本番ブランチからDAppをデプロイするようにしてください。これにより、デプロイされたブランチに新しいコードコミットをプッシュしたときに、FleekがDAppを自動的に再デプロイできるようになります。
次に、.fleek.json
ファイルを使用して環境変数を保存している場合は、.fleek.json
ファイルにファイル名を含め.gitignore
ます。これを行うと、.fleek.json
ファイルがプッシュされず、環境変数が公開されなくなります。
このチュートリアルがお役に立てば幸いです。ご不明な点がございましたら、お気軽にコメントをお寄せください。
このストーリーは、もともとhttps://blog.logrocket.com/how-build-dapp-host-ipfs-fleek/で公開されました