From df8da85925d02fbf356bcea13710bfb24456eb7f Mon Sep 17 00:00:00 2001 From: Vini Black Date: Tue, 9 Jan 2024 12:48:23 -0300 Subject: [PATCH 01/21] add: info sobre a NFT no final do build --- .../pt-br/Section_0/Lesson_1_What_Are_We_Building.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/NFT_Game/pt-br/Section_0/Lesson_1_What_Are_We_Building.md b/NFT_Game/pt-br/Section_0/Lesson_1_What_Are_We_Building.md index d5176e07c..5e9c0e554 100644 --- a/NFT_Game/pt-br/Section_0/Lesson_1_What_Are_We_Building.md +++ b/NFT_Game/pt-br/Section_0/Lesson_1_What_Are_We_Building.md @@ -8,6 +8,16 @@ Então, o que vamos construir aqui :)? Aqui está um pequeno vídeo: [Loom](https://www.loom.com/share/bfea6f9e52444d189952ade6ab89605d) +👀 No final, ganhe um NFT da WEB3DEV. +------------------- + +Quando você chegar no fim deste projeto, poderá ganhar um NFT. +**Realizaremos o airdrop de um NFT para a sua carteira conectada se você terminar o projeto dentro de 9 dias após o kick-off.** + +![Imagem do NFT](https://i.imgur.com/U8leQpj.png) + +A sua turma terá um nome especial que aparecerá no NFT - cada turma tem um nome diferente! Além disso, o # embaixo à direita será o # cunhado que dependerá de quando você conquistar o NFT. + ### **🤘 Vê um problema? Quer melhorar algo? Conserte você mesmo ;). 🤘** **[Todo esse conteúdo é completamente open-source](https://github.com/w3b3d3v/buildspace-projects/tree/web3dev-version/NFT_Game)**. Se você vir um problema, erro de digitação, etc - você pode consertar você mesmo facilmente e fazer um Pull Request! From cff69c294db77593c2d0089ac374e049e75c9901 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Tue, 9 Jan 2024 14:04:08 -0300 Subject: [PATCH 02/21] add: emoji e ajustando texto --- .../pt-br/Section_0/Lesson_1_What_Are_We_Building.md | 8 ++++---- .../Section_0/Lesson_2_Gaming_And_Crypto_Intro.md | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/NFT_Game/pt-br/Section_0/Lesson_1_What_Are_We_Building.md b/NFT_Game/pt-br/Section_0/Lesson_1_What_Are_We_Building.md index 5e9c0e554..930a1c411 100644 --- a/NFT_Game/pt-br/Section_0/Lesson_1_What_Are_We_Building.md +++ b/NFT_Game/pt-br/Section_0/Lesson_1_What_Are_We_Building.md @@ -1,17 +1,17 @@ -### 👋 Bem vindo. +### 👋 Bem vindo Você conseguiu - é isso aí! Bem vindo :). Meu nome é danicuki e serei seu instrutor. Esse projeto é para desenvolvedores que querem conhecer e entrar mais no mundo de tecnologia cripto. Tudo que você precisa saber para entrar nisso são **algumas habilidades com o terminal, um pouco de javascript e um pouco de React.js**. O resto você aprende no caminho. -### 🛠 O projeto. +### 🛠 O projeto Então, o que vamos construir aqui :)? Aqui está um pequeno vídeo: [Loom](https://www.loom.com/share/bfea6f9e52444d189952ade6ab89605d) -👀 No final, ganhe um NFT da WEB3DEV. +👀 No final, ganhe um NFT da WEB3DEV ------------------- -Quando você chegar no fim deste projeto, poderá ganhar um NFT. +Quando você chegar no fim deste projeto, poderá ganhar um NFT. **Realizaremos o airdrop de um NFT para a sua carteira conectada se você terminar o projeto dentro de 9 dias após o kick-off.** ![Imagem do NFT](https://i.imgur.com/U8leQpj.png) diff --git a/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md b/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md index c2383ea41..3b8bd24ec 100644 --- a/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md +++ b/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md @@ -8,9 +8,9 @@ Por que as pessoas estão perdendo a cabeça desse jeito? **Nota: isso é uma NFT "Axie" - que é o personagem que você joga dentro de Axie Infinity! Jogadores compram NFTs Axie primeiro, e depois vão jogar o jogo. Bem estranho, certo? Comprar os personagens antes de você jogar o jogo!** -A filosofia da WEB3DEV é entender construindo e mexendo com a tecnologia. Mas, eu gostaria de passar por um exemplo rápido e informal ;)! +A filosofia da WEB3DEV é entender construindo e mexendo com a tecnologia. Mas, eu gostaria de passar por um exemplo rápido e informal 😉! -### 🎮 Um exemplo rápido com a Nintendo. +### 🎮 Um exemplo rápido com a Nintendo **Vamos dizer que você é a Nintendo** e você criou o Super Mario Bros. Mario é agora **sua** Propriedade Intelectual. **Você** é o criador ou criadora. Ninguém está permitido criar mais jogos com o Mario exceto **você**. Você também quer controlar quem ganha % em cima dos seus personagens/universo. @@ -40,7 +40,7 @@ Isso é causado basicamente pela inflação do mercado. Só uma quantidade de Ax "_O crescimento da população Axie é um grande fator dentro do ecossistema Axie. Até agora em nenhum momento existiu uma taxa de inflação que nos permitiu crescer até nosso potencial máximo. Muito lento e os preços do Axie estão muito altos para pessoas nova entrarem; especialmente os Axies competitivos. Muito rápido e você tem uma inflação não saudável._" -### 🛠 Construindo jogos abertos. +### 🛠 Construindo jogos abertos Eu quero passar por um outro benefício. Fazer jogos e universos que qualquer um pode construir em cima via NFTs facilmente. @@ -56,10 +56,10 @@ $5 Iriam diretamente para a wallet da Nintendo, e $5 para a wallet do desenvolve As possibilidades são literalmente infinitas porque nós podemos programar o sistema de royalty para funcionar como quisermos. -### 💪 Vamos ao trabalho; +### 💪 Vamos ao trabalho Nós falamos muito. Vamos construir nossa pequena versão de um jogo NFT. No final, eu espero que tudo isso se torne bem mais concreto, e talvez você esteja no seu caminho de construir o próximo hit dos jogos NFT ;). -### 🚨 Reporte seu Progresso! +### 🚨 Reporte seu Progresso Poste uma screenshot em #progresso com o nome do seu video game favorito! Ajude a levantar o ânimo de jogadores na galera! From ada419dfe1392c3085e0d59c17447a88afb0151d Mon Sep 17 00:00:00 2001 From: Vini Black Date: Tue, 9 Jan 2024 15:09:21 -0300 Subject: [PATCH 03/21] =?UTF-8?q?fix:=20melhorando=20texto=20|=20atualizan?= =?UTF-8?q?do=20a=20vers=C3=A3o=20das=20ferramentas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Lesson_2_Gaming_And_Crypto_Intro.md | 2 +- .../Section_1/Lesson_1_Get_Local_Env_Setup.md | 74 ++++++++++++------- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md b/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md index 3b8bd24ec..04e83b6ba 100644 --- a/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md +++ b/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md @@ -6,7 +6,7 @@ Por que as pessoas estão perdendo a cabeça desse jeito? ![Untitled](https://i.imgur.com/wkPSIjR.png) -**Nota: isso é uma NFT "Axie" - que é o personagem que você joga dentro de Axie Infinity! Jogadores compram NFTs Axie primeiro, e depois vão jogar o jogo. Bem estranho, certo? Comprar os personagens antes de você jogar o jogo!** +> **📝Nota:** isso é uma NFT "Axie" - que é o personagem que você joga dentro de Axie Infinity! Jogadores compram NFTs Axie primeiro, e depois vão jogar o jogo. Bem estranho, certo? Comprar os personagens antes de você jogar o jogo! A filosofia da WEB3DEV é entender construindo e mexendo com a tecnologia. Mas, eu gostaria de passar por um exemplo rápido e informal 😉! diff --git a/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md b/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md index 787d671d3..2d99ef10c 100644 --- a/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md +++ b/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md @@ -8,27 +8,30 @@ Por agora, tudo o que você precisa saber é que um contrato inteligente é um p O quadro maior aqui é: -1 -- **Nós vamos escrever um contrato inteligente**. Esse contrato terá toda a lógica acerca do nosso jogo. +1. **Nós vamos escrever um contrato inteligente**. Esse contrato terá toda a lógica acerca do nosso jogo. -2 -- **Nosso contrato inteligente será implantado na blockchain (deployed)**. Desse jeito, qualquer pessoa no mundo poderá acessar e rodar nosso contrato inteligente - e nós vamos deixá-los acessar nosso jogo. +2. **Nosso contrato inteligente será implantado na blockchain (deployed)**. Desse jeito, qualquer pessoa no mundo poderá acessar e rodar nosso contrato inteligente - e nós vamos deixá-los acessar nosso jogo. -3 -- **Nós vamos construir um site para o cliente**. Isso vai deixar as pessoas conectarem suas carteiras Ethereum facilmente e jogar nosso jogo. +3. **Nós vamos construir um site para o cliente**. Isso vai deixar as pessoas conectarem suas carteiras Ethereum facilmente e jogar nosso jogo. -Eu recomendo ler [essas](https://ethereum.org/pt/developers/docs/intro-to-ethereum/) documentações quando você puder, por diversão. Esses são os melhores guias da internet para entender como o Ethereum funciona, na minha opinião! +Eu recomendo ler [essas](https://ethereum.org/pt-br/developers/docs/intro-to-ethereum/) documentações quando você puder, por diversão. Esses são os melhores guias da internet para entender como o Ethereum funciona, na minha opinião! ### **⚙️ Configurando ferramentas locais.** -Nós vamos usar uma muito ferramenta chamada **Hardhat**, a qual vai nos deixar compilar e testar contratos inteligentes rapidamente e localmente. Primeiro você precisa ter o node/npm. Se você não tiver, vá até [aqui](https://hardhat.org/tutorial/setting-up-the-environment.html). +Nós vamos usar uma muito ferramenta chamada **Hardhat**, a qual vai nos deixar compilar e testar contratos inteligentes rapidamente e localmente. Primeiro você precisa ter o node/npm. Se você não tiver, vá até [aqui](https://hardhat.org/tutorial/setting-up-the-environment). -_Nota: Eu estou usando o Node 16. Eu sei que algumas pessoas tiveram "erros de falta de memória" em versões mais velhas, então, se isso acontecer, pegue o Node 16!_ +>Nota: Eu estou usando o Node 16. Eu sei que algumas pessoas tiveram "erros de falta de memória" em versões mais velhas, então, se isso acontecer, utilize um versão do Node `>=16.0`! -Depois, vamos para o terminal. Vá em frente e `cd` para o diretório que você quer trabalhar. Uma vez que estiver lá, rode esses comandos: +Depois, vamos abrir o terminal. Crie a pasta chamada `epic-game` acesse ela pelo terminal utilizando o comando `cd`. Uma vez que estiver lá, rode esses comandos: -```javascript +```bash +# Criar uma pasta e acessá-la mkdir epic-game cd epic-game + +# Inicializar o projeto npm init -y -npm install --save-dev hardhat@2.9.9 +npm install --save-dev hardhat@2.19.4 ``` Você pode ver uma mensagem sobre vulnerabilidades depois de rodar o último comando e instalar o Hardhat. Toda vez que você instalar algo do NPM, existe uma triagem de segurança para ver se algum dos pacotes da biblioteca que você está instalando teve alguma vulnerabilidade reportada. Isso é mais como um aviso para que você esteja ciente! Pesquise no google um pouco mais sobre essas vulnerabilidades se quiser saber mais! @@ -37,35 +40,56 @@ Você pode ver uma mensagem sobre vulnerabilidades depois de rodar o último com Legal, agora nós temos o hardhat. Vamos colocar um projeto experimental funcionando. -```javascript -npx hardhat +```bash +npx hardhat init ``` -_Nota: Se você estiver no Windows usando Git Bash para instalar o Hardhat, você pode dar de cara com um erro nesse passo (HH1). Você pode tentar usar a CMD Windows para performar a instalação do HardHat se você tiver problemas. Informações adicionais podem ser encontradas [aqui](https://github.com/nomiclabs/hardhat/issues/1400#issuecomment-824097242)._ +> **📝Nota:** Se você estiver no Windows usando Git Bash para instalar o Hardhat, você pode dar de cara com um erro nesse passo (HH1). Você pode tentar usar a CMD Windows para performar a instalação do HardHat se você tiver problemas. Informações adicionais podem ser encontradas [aqui](https://github.com/nomiclabs/hardhat/issues/1400#issuecomment-824097242). + +1. Esse comando irá te fazer algumas perguntas para saber que tipo de projeto você deseja criar, vamos criar um projeto JavaScript: -Escolha a opção de criar um projeto básico. Diga sim para tudo. +```bash +What do you want to do? +┗ Create a JavaScript project +``` -O projeto vai pedir para você instalar `hardhat-waffle` e `hardhat-ethers`. Essas são outras coisas que vamos usar mais tarde. +2. Onde você deseja criar o projeto do hardhat: + +```bash +Hardhat project root: +┗ Enter +``` -Vá em frente e instale essas outras dependências em caso delas não terem sido instaladas automaticamente. +3. Se deseja criar o arquivo `.gitignore`: -```javascript -npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers +```bash +Do you want to add a .gitignore? +┗ Y ``` -Você também vai querer instalar algo chamado **OpenZeppelin** , que é outra biblioteca muito usada para desenvolver contratos inteligentes seguros. Vamos aprender mais sobre ela depois. Por agora, só a instale :). +4. Se deseja já instalar as dependências do projeto: + +```bash +Do you want to install this sample project's dependencies with npm (@nomicfoundation/hardhat-toolbox)? +┗ Y +``` + +O projeto vai pedir para você instalar o `@nomicfoundation/hardhat-toolbox`. Vamos utilizar isso mais tarde. + +Você também vai querer instalar algo chamado **OpenZeppelin** , que é outra biblioteca muito usada para desenvolver contratos inteligentes seguros. Vamos aprender mais sobre ela depois. Por agora, só a instale 😃. -```javascript +```bash npm install @openzeppelin/contracts ``` Depois rode: -```javascript -npx hardhat run scripts/sample-script.js +```bash +npx hardhat run scripts/deploy.js ``` -Boom! Se você vir algumas coisas no seu terminal sobre um contrato sendo implantado (deployed), isso significa que seu ambiente local está configurando **e** você também rodou/implantou um contrato inteligente numa blockchain local. +Boom! Se você vir algumas coisas no seu terminal sobre um contrato sendo implantado **deployed**. +Isso **significa que seu ambiente local está configurando** e você também implantou **um contrato inteligente numa blockchain local** 🥳. Isso é bastante épico. Vamos mais a fundo nisso, mas basicamente o que está acontecendo aqui é: @@ -73,10 +97,10 @@ Isso é bastante épico. Vamos mais a fundo nisso, mas basicamente o que está a 2. O Hardhat vai rodar uma "blockchain local" no seu computador. É como uma mini versão de teste do Ethereum rodando no seu computador para ajudar você a rapidamente testar coisas. 3. O Hardhat vai então fazer o "deploy" do seu contrato inteligente compilado. Esse é o endereço que você vê no final. É o seu contrato inteligente já implantado, na nossa mini versão do Ethereum. -Se estiver curioso, sinta-se livre para olhar o código dentro do projeto e ver como ele funciona. Especificamente, olhe `Greeter.sol` que é o contrato inteligente e `sample-script.js` que roda o contrato. +Se estiver curioso, sinta-se livre para olhar o código dentro do projeto e ver como ele funciona. Especificamente, olhe `Lock.sol` que é o contrato inteligente e `deploy.js` que roda o contrato. Uma vez que tiver explorado, vamos para a próxima seção e começar o contrato do nosso jogo. -### 🚨 Reporte seu Progresso! +### 🚨 Reporte seu Progresso -Poste uma screenshot em #progresso com a saída do terminal quando você rodou `sample-script.js` para mostrar que seu ambiente local tá rodando :). +Poste uma screenshot em #progresso com a saída do terminal quando você rodou `deploy.js` para mostrar que seu ambiente local tá rodando 😃. From 4784a92c1c8114da2d983b8d545f4ea4307ea451 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Tue, 9 Jan 2024 16:13:57 -0300 Subject: [PATCH 04/21] =?UTF-8?q?fix:=20atualizando=20c=C3=B3digo=20do=20b?= =?UTF-8?q?uild?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Lesson_2_Gaming_And_Crypto_Intro.md | 2 +- .../Section_1/Lesson_1_Get_Local_Env_Setup.md | 6 +- .../Lesson_2_Running_Basic_Contract.md | 90 ++++++++----------- 3 files changed, 42 insertions(+), 56 deletions(-) diff --git a/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md b/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md index 04e83b6ba..388c8d588 100644 --- a/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md +++ b/NFT_Game/pt-br/Section_0/Lesson_2_Gaming_And_Crypto_Intro.md @@ -6,7 +6,7 @@ Por que as pessoas estão perdendo a cabeça desse jeito? ![Untitled](https://i.imgur.com/wkPSIjR.png) -> **📝Nota:** isso é uma NFT "Axie" - que é o personagem que você joga dentro de Axie Infinity! Jogadores compram NFTs Axie primeiro, e depois vão jogar o jogo. Bem estranho, certo? Comprar os personagens antes de você jogar o jogo! +> 💡**Nota:** isso é uma NFT "Axie" - que é o personagem que você joga dentro de Axie Infinity! Jogadores compram NFTs Axie primeiro, e depois vão jogar o jogo. Bem estranho, certo? Comprar os personagens antes de você jogar o jogo! A filosofia da WEB3DEV é entender construindo e mexendo com a tecnologia. Mas, eu gostaria de passar por um exemplo rápido e informal 😉! diff --git a/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md b/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md index 2d99ef10c..7d9564b7e 100644 --- a/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md +++ b/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md @@ -1,4 +1,4 @@ -_Nota: Se você já fez outros projetos na WEB3DEV, vários dos itens de configuração das próximas duas aulas são repetidos de projetos passados. Se você ja entende, incrível! Você é um pro. Sinta-se livre para passar por eles bem rápido._ +>_Se você já fez outros projetos na WEB3DEV, vários dos itens de configuração das próximas duas aulas são repetidos de projetos passados. Se você ja entende, incrível! Você é um pro. Sinta-se livre para passar por eles bem rápido._ ### **📚 Um pequeno resumo sobre blockchain.** @@ -20,7 +20,7 @@ Eu recomendo ler [essas](https://ethereum.org/pt-br/developers/docs/intro-to-eth Nós vamos usar uma muito ferramenta chamada **Hardhat**, a qual vai nos deixar compilar e testar contratos inteligentes rapidamente e localmente. Primeiro você precisa ter o node/npm. Se você não tiver, vá até [aqui](https://hardhat.org/tutorial/setting-up-the-environment). ->Nota: Eu estou usando o Node 16. Eu sei que algumas pessoas tiveram "erros de falta de memória" em versões mais velhas, então, se isso acontecer, utilize um versão do Node `>=16.0`! +> 💡**Nota:** Eu estou usando o Node 16. Eu sei que algumas pessoas tiveram "erros de falta de memória" em versões mais velhas, então, se isso acontecer, utilize um versão do Node `>=16.0`! Depois, vamos abrir o terminal. Crie a pasta chamada `epic-game` acesse ela pelo terminal utilizando o comando `cd`. Uma vez que estiver lá, rode esses comandos: @@ -44,7 +44,7 @@ Legal, agora nós temos o hardhat. Vamos colocar um projeto experimental funcion npx hardhat init ``` -> **📝Nota:** Se você estiver no Windows usando Git Bash para instalar o Hardhat, você pode dar de cara com um erro nesse passo (HH1). Você pode tentar usar a CMD Windows para performar a instalação do HardHat se você tiver problemas. Informações adicionais podem ser encontradas [aqui](https://github.com/nomiclabs/hardhat/issues/1400#issuecomment-824097242). +> 💡**Nota:** Se você estiver no Windows usando Git Bash para instalar o Hardhat, você pode dar de cara com um erro nesse passo (HH1). Você pode tentar usar a CMD Windows para performar a instalação do HardHat se você tiver problemas. Informações adicionais podem ser encontradas [aqui](https://github.com/nomiclabs/hardhat/issues/1400#issuecomment-824097242). 1. Esse comando irá te fazer algumas perguntas para saber que tipo de projeto você deseja criar, vamos criar um projeto JavaScript: diff --git a/NFT_Game/pt-br/Section_1/Lesson_2_Running_Basic_Contract.md b/NFT_Game/pt-br/Section_1/Lesson_2_Running_Basic_Contract.md index 569a5f00c..e50f14fe4 100644 --- a/NFT_Game/pt-br/Section_1/Lesson_2_Running_Basic_Contract.md +++ b/NFT_Game/pt-br/Section_1/Lesson_2_Running_Basic_Contract.md @@ -2,54 +2,55 @@ Escolha seu editor de código favorito e abra o diretório em que você configurou o projeto hardhat. Vamos fazer uma pequena faxina. -Nós queremos deletar todo o código inicial gerado para nós. Vamos escrever as coisas nós mesmos! Vá em frente e delete o arquivo `sample-test.js` dentro de `test`. Também delete `sample-script.js` dentro de `scripts`. Depois, delete `Greeter.sol` dentro de `contracts`. **Não delete os diretórios!** +Nós queremos deletar todo o código inicial gerado para nós. Vamos escrever as coisas nós mesmos! Vá em frente e delete o arquivo `Lock.js` dentro de `test`. Também delete `deploy.js` dentro de `scripts`. Depois, delete `Lock.sol` dentro de `contracts`. **Não delete os diretórios!** -Agora, vamos começar a escrever nosso contrato NFT. Se você nunca escreveu um contrato inteligente, não se preocupe. **Só siga os passos. Procure no Google coisas que você não entenda.** +Agora, vamos começar a escrever nosso contrato NFT. Se você nunca escreveu um contrato inteligente, não se preocupe. **Só siga os passos. Procure no Google o que você não entenda.** -Crie um arquivo chamado `MyEpicGame.sol` dentro de `contracts` . A estrutura de arquivos é super importante quando usamos Hardhat, então seja cuidadoso. +Crie um arquivo chamado `MyEpicGame.sol` dentro de `contracts` . **A estrutura de arquivos é super importante quando usamos Hardhat**, então seja cuidadoso⚠️. -Nota: eu recomendo baixar a [extensão Solidity](https://marketplace.visualstudio.com/items?itemName=JuanBlanco.solidity) para VSCode que dá um boa colorida na sintaxe. +> 💡**Nota:** eu recomendo baixar a [extensão Solidity](https://marketplace.visualstudio.com/items?itemName=JuanBlanco.solidity) para VSCode que dá um boa colorida na sintaxe. Eu sempre gosto de começar com um contrato bem básico, só para as coisas fluírem. -```javascript +```solidity // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.4; +pragma solidity ^0.8.19; import "hardhat/console.sol"; contract MyEpicGame { constructor() { //nao pode usar acentos nos arquivos .sol, pois dah ruim! - console.log("Esse eh o contrato do meu jogo, vamo!"); + console.log("Esse eh o contrato do meu jogo, vamo bora!"); } } ``` -Nota: As vezes o VSCode nos dá erros que não são um problema de verdade. Por exemplo, pode sublinhar o import do Hardhat e dizer que não existe. Isso acontece porque seu compilador global de Solidity não está configurado localmente. Se você não sabe arrumar isso, sem problemas. Ignore isso por agora. Eu também recomendo que você não use o terminal VSCode, use o seu terminal separado. As vezes o terminal VSCode nos dá erros se o compilador não estiver configurado. +> 💡**Nota:** As vezes o **VSCode nos dá erros que não são um problema de verdade**. Por exemplo, pode sublinhar o import do Hardhat e dizer que não existe. **Isso acontece porque seu compilador global de Solidity não está configurado localmente**. Se você não sabe arrumar isso, sem problemas. **Ignore isso por agora**. Eu também recomendo que você não use o terminal VSCode, **use o seu terminal separado**. As vezes o terminal VSCode nos dá erros se o compilador não estiver configurado. Vamos entender linha-por-linha do que fizemos até aqui. -```javascript +```solidity // SPDX-License-Identifier: UNLICENSED ``` -Só um comentário chique. É chamado um "Identificador de licença SPDX", sinta-se livre para pesquisar o que é isso :). +Só um comentário chique. É chamado um "**Identificador de licença SPDX**", sinta-se livre para pesquisar o que é isso 😃. -```javascript -pragma solidity ^0.8.4; +```solidity +pragma solidity ^0.8.19; ``` -Essa é a versão do compilador Solidity que queremos que o nosso contrato use. Basicamente diz: "quando rodar isso, eu só quero usar a versão 0.8.4 do compilador Solidity, nada menos que isso. Nota, tenha certeza que o seu compilador esteja configurado para 0.8.4 no arquivo `hardhat.config.js`. +Essa é a versão do compilador Solidity que queremos que o nosso contrato use. Basicamente diz: "**quando rodar isso, eu só quero usar a versão 0.8.19 do compilador Solidity, nada menos que isso**". +Nota, tenha certeza que o seu compilador esteja configurado para 0.8.19 no arquivo `hardhat.config.js`. -```javascript +```solidity import "hardhat/console.sol"; ``` Um pouco de mágica nos é dada pelo Hardhat para fazermos alguns console logs no nosso contrato. É bem desafiador debugar contratos inteligentes, mas essa é uma das coisas boas que o Hardhat nos dá para deixar a vida mais fácil. -```javascript +```solidity contract MyEpicGame { constructor() { console.log("Esse é o contrato do meu jogo, vamo!"); @@ -57,7 +58,7 @@ contract MyEpicGame { } ``` -Então, contratos inteligentes se parecem com uma `class` em outras linguagens, se você já viu alguma delas! Uma vez que inicializarmos esse contrato pela primeira vez, esse construtor vai rodar e escrever aquela linha. Por favor, faça a linha dizer o que você quiser. Se divirta! +Então, contratos inteligentes se parecem com uma `class` em outras linguagens, se você já viu alguma delas! Uma vez que inicializarmos esse contrato pela primeira vez, esse construtor vai rodar e escrever aquela linha. **Faça a linha dizer o que você quiser**. Se divirta! ### **😲 Como nós rodamos?** @@ -69,53 +70,38 @@ Legal - nós temos um contrato inteligente! Mas, nós não sabemos se ele funcio Nós vamos escrever um script customizado que cuide desses 3 passo para nós. -Vá dentro de `scripts` e crie um arquivo chamado `run.js`. Isso é o que `run.js` vai ter dentro dele: +Vá dentro de `scripts` e crie um arquivo chamado `run.js` e escreva o seguinte código. ```javascript -const main = async () => { - const gameContractFactory = await hre.ethers.getContractFactory("MyEpicGame"); - const gameContract = await gameContractFactory.deploy(); - await gameContract.deployed(); - console.log("Contrato implantado no endereço:", gameContract.address); +async function main() { + const gameContract = await hre.ethers.deployContract("MyEpicGame"); + await gameContract.waitForDeployment(); + console.log("Contrato implantado no endereço:", gameContract.target); }; -const runMain = async () => { - try { - await main(); - process.exit(0); - } catch (error) { - console.log(error); - process.exit(1); - } -}; - -runMain(); +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); ``` -`run.js` é o nosso playground para brincar com o contrato! +Com esse código o Hardhat cria uma rede Ethereum local para a gente, mas só para esse contrato. Depois que o script for completo, ele vai destruir essa rede local. Então, cada vez que você rodar o contrato, será uma blockchain nova. E qual é o objetivo? É como refazer o seu server local toda vez de maneira que você sempre parta de um ponto limpo, o que deixa mais fácil o debug de erros. +O `run.js` é o nosso playground para brincar com o contrato! ### **🤔 Como isso funciona?** -**Nota: VSCode vai auto-importar o ethers. Nós não precisamos importar o ethers ou qualquer coias. Então, esteja certo de não importar nada.** +> 💡**Nota:** Nós não precisamos importar o ethers ou qualquer coias. porque o VSCode vai auto-importar para nós. Vamos entender linha-por-linha do que fizemos até aqui. ```javascript -const gameContractFactory = await hre.ethers.getContractFactory("MyEpicGame"); -``` - -Isso vai compilar nosso contrato e gerar os arquivos necessários que precisamos para trabalhar com o contrato dentro de `artifacts` . Vá olhar depois que rodarmos isso :). - -```javascript -const gameContract = await gameContractFactory.deploy(); +const gameContract = await hre.ethers.deployContract("MyEpicGame"); ``` -Isso é bem chique :). - -O que está acontecendo aqui é que o Hardhat cria uma rede Ethereum local para a gente, mas só para esse contrato. Depois que o script for completo, ele vai destruir essa rede local. Então, cada vez que você rodar o contrato, será uma blockchain nova. E qual é o objetivo? É como refazer o seu server local toda vez de maneira que você sempre parta de um ponto limpo, o que deixa mais fácil o debug de erros. +Isso vai compilar nosso contrato e gerar os arquivos necessários que precisamos para trabalhar com o contrato dentro de `artifacts` . Olhe depois que rodarmos esse código 😃. ```javascript -await gameContract.deployed(); +await gameContract.waitForDeployment(); ``` Nós vamos esperar até que o nosso contrato esteja oficialmente minerado e implementado na nossa blockchain local! Exatamente, hardhat cria "mineradores" falsos na nossa máquina para tentar imitar da melhor forma a blockchain. @@ -123,16 +109,16 @@ Nós vamos esperar até que o nosso contrato esteja oficialmente minerado e impl Nosso `constructor` roda quando o contrato está completamente implantado (deployed)! ```javascript -console.log("Contrato implantado no endereço:", gameContract.address); +console.log("Contrato implantado no endereço:", gameContract.target); ``` -Finalmente, uma vez que estiver implantado, `gameContract.address` vai basicamente nos dar o endereço do contrato implementado. Esse endereço é como nós vamos achar o nosso contrato na blockchain. Nesse momento nossa blockchain local só tem nós. Então, isso não é tão legal. +Finalmente, uma vez que estiver implantado, `gameContract.target` vai basicamente nos dar o endereço do contrato implementado. Esse endereço é como nós vamos achar o nosso contrato na blockchain. Nesse momento na blockchain local só tem você. Então, isso não é tão legal. Mas, tem milhões de contratos na blockchain de verdade. Então, esse endereço nos dá fácil acesso ao contrato que estamos interessados em trabalhar! Isso vai ser muito útil quando implantarmos nosso contrato na blockchain de verdade algumas aulas para frente. ### **💨 Rode.** -Antes de rodar isso, esteja certo de trocar para `solidity: "0.8.4",` no seu `hardhat.config.js`. +Antes de rodar isso, esteja certo de trocar para `solidity: "0.8.19",` no seu `hardhat.config.js`. Vamos rodá-lo! Abra o terminal e rode: @@ -144,7 +130,7 @@ Você deve ver o seu `console.log` rodar de dentro do contrato e você deve ver ### **🎩 Hardhat & HRE** -Nesses blocos de código você vai notar constantemente que usamos hre.ethers, mas hre não está importado em lugar nenhum? Que tipo de magia é essa? +Nesses blocos de código você vai notar constantemente que usamos `hre.ethers`, mas `hre` não está importado em lugar nenhum? Que tipo de magia é essa? Diretamente das documentações do Hardhat (traduzidas), vocês notarão isso: @@ -154,8 +140,8 @@ Mas o que isso significa? Então, toda vez que você roda um comando de terminal `const hardhat = require("hardhat")` -Você vai ver hre várias vezes no seu código, mas nunca importado em lugar nenhum! Dê uma olhada na [documentação Hardhat](https://hardhat.org/advanced/hardhat-runtime-environment.html) para aprender mais sobre! +Você vai ver hre várias vezes no seu código, mas nunca importado em lugar nenhum! Dê uma olhada na [documentação Hardhat](https://hardhat.org/hardhat-runner/docs/advanced/hardhat-runtime-environment) para aprender mais sobre! -### 🚨 Reporte seu Progresso! +### 🚨 Reporte seu Progresso Poste uma screenshot em #progresso com a saída do terminal quando você rodou `npx hardhat run scripts/run.js` :). From 715c5cd61706941065e5d972b85f660e94c01d85 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Fri, 12 Jan 2024 14:21:21 -0300 Subject: [PATCH 05/21] fix: ajustando bloco de code --- .../Section_1/Lesson_2_Running_Basic_Contract.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/NFT_Game/pt-br/Section_1/Lesson_2_Running_Basic_Contract.md b/NFT_Game/pt-br/Section_1/Lesson_2_Running_Basic_Contract.md index e50f14fe4..35efe07ea 100644 --- a/NFT_Game/pt-br/Section_1/Lesson_2_Running_Basic_Contract.md +++ b/NFT_Game/pt-br/Section_1/Lesson_2_Running_Basic_Contract.md @@ -53,7 +53,7 @@ Um pouco de mágica nos é dada pelo Hardhat para fazermos alguns console logs n ```solidity contract MyEpicGame { constructor() { - console.log("Esse é o contrato do meu jogo, vamo!"); + console.log("Esse eh o contrato do meu jogo, vamo!"); } } ``` @@ -74,8 +74,8 @@ Vá dentro de `scripts` e crie um arquivo chamado `run.js` e escreva o seguinte ```javascript async function main() { - const gameContract = await hre.ethers.deployContract("MyEpicGame"); - await gameContract.waitForDeployment(); + const gameContractFactory = await hre.ethers.getContractFactory("MyEpicGame"); + const gameContract = await gameContractFactory.deploy(); console.log("Contrato implantado no endereço:", gameContract.target); }; @@ -85,7 +85,6 @@ main().catch((error) => { }); ``` -Com esse código o Hardhat cria uma rede Ethereum local para a gente, mas só para esse contrato. Depois que o script for completo, ele vai destruir essa rede local. Então, cada vez que você rodar o contrato, será uma blockchain nova. E qual é o objetivo? É como refazer o seu server local toda vez de maneira que você sempre parta de um ponto limpo, o que deixa mais fácil o debug de erros. O `run.js` é o nosso playground para brincar com o contrato! ### **🤔 Como isso funciona?** @@ -95,14 +94,17 @@ O `run.js` é o nosso playground para brincar com o contrato! Vamos entender linha-por-linha do que fizemos até aqui. ```javascript -const gameContract = await hre.ethers.deployContract("MyEpicGame"); +const gameContractFactory = await hre.ethers.getContractFactory("MyEpicGame"); ``` Isso vai compilar nosso contrato e gerar os arquivos necessários que precisamos para trabalhar com o contrato dentro de `artifacts` . Olhe depois que rodarmos esse código 😃. ```javascript -await gameContract.waitForDeployment(); +const gameContract = await gameContractFactory.deploy(); ``` +Isso é bem chique 😃. + +O que está acontecendo aqui é que o Hardhat cria uma rede Ethereum local para a gente, mas só para esse contrato. Depois que o script for completo, ele vai destruir essa rede local. Então, cada vez que você rodar o contrato, será uma blockchain nova. E qual é o objetivo? É como refazer o seu server local toda vez de maneira que você sempre parta de um ponto limpo, o que deixa mais fácil o debug de erros. Nós vamos esperar até que o nosso contrato esteja oficialmente minerado e implementado na nossa blockchain local! Exatamente, hardhat cria "mineradores" falsos na nossa máquina para tentar imitar da melhor forma a blockchain. From 564e6fb8415f91316e55f9f89ffccb526c4ad1b8 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Fri, 12 Jan 2024 14:21:54 -0300 Subject: [PATCH 06/21] fix: ajustando texto --- .../Lesson_3_Setup_Data_For_Character_NFTs.md | 63 ++++++++----------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/NFT_Game/pt-br/Section_1/Lesson_3_Setup_Data_For_Character_NFTs.md b/NFT_Game/pt-br/Section_1/Lesson_3_Setup_Data_For_Character_NFTs.md index 64e5da72d..26c8f1cda 100644 --- a/NFT_Game/pt-br/Section_1/Lesson_3_Setup_Data_For_Character_NFTs.md +++ b/NFT_Game/pt-br/Section_1/Lesson_3_Setup_Data_For_Character_NFTs.md @@ -2,7 +2,7 @@ Haha, essa é uma grande questão. Esteja certo de ler [isso](https://github.com/w3b3d3v/buildspace-projects/blob/web3dev-version/NFT_Collection/pt-br/Section_1/Lesson_1_What_Is_A_NFT.md) rapidamente para te dar uma noção antes de seguir em frente. Enquanto você tiver a _ideia geral_ sobre o que é uma NFT, isso é tudo o que você precisa aqui! -### 😮 Como vamos usar NFTs jogáveis. +### 😮 Como vamos usar NFTs jogáveis Legal. Nós temos todo ambiente básico configurado. Vamos dar uma passo pra trás para explicar esse jogo que estamos fazendo em um nível mais alto: @@ -10,7 +10,7 @@ O objetivo do nosso jogo vai ser destruir um chefão, um boss. Vamos falar que o O objetivo? Jogadores precisam trabalhar juntos para atacar o boss e trazer seu HP (vida) para 0. Qual é o truque? Toda vez que um player bater no boss, o boss bate nele de volta! Se a vida da NFT for pra 0 ou menos, o jogador daquela NFT **morre** e ele não pode mais bater no boss. Jogadores **só podem ter um personagem NFT em suas carteiras.** Uma vez que o personagem NFT morre, o jogo acaba. Isso significa que muitos jogadores precisam juntar forças para atacar o boss e matá-lo. -**Nota: Se você quiser que o seu jogador esteja apto a segurar múltiplos personagens em sua carteira (como no Pokémon), sinta-se livro para fazer modificações você mesmo!** +> 💡**Nota:** Se você quiser que o seu jogador esteja apto a segurar múltiplos personagens em sua carteira (como no Pokémon), sinta-se livre para fazer modificações você mesmo! O importante a saber aqui é que os personagens são **NFTs**. @@ -38,7 +38,7 @@ Eu atualizei `MyEpicGame.sol` para parecer com isso: ```solidity // SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; +pragma solidity ^0.8.19; import "hardhat/console.sol"; @@ -116,49 +116,36 @@ Tudo isso nos dá fácil acesso a cada personagem. Por exemplo, eu posso apenas Precisamos atualizar `run.js`. Aqui está como se parece: ```javascript -const main = async () => { +async function main() { const gameContractFactory = await hre.ethers.getContractFactory("MyEpicGame"); const gameContract = await gameContractFactory.deploy( ["Anitta", "Ronaldinho Gaúcho", "Zeca Pagodinho"], - [ - "https://i.imgur.com/gC5qXsl.png", - "https://i.imgur.com/0PvxtwP.png", - "https://i.imgur.com/Pj8lHpM.png", - ], - [100, 200, 300], // HP values - [100, 50, 25] // Attack damage values + [ + "https://i.imgur.com/gC5qXsl.png", + "https://i.imgur.com/0PvxtwP.png", + "https://i.imgur.com/Pj8lHpM.png", + ], + [100, 200, 300], // Pontos de vida + [100, 50, 25] // Dando de ataque ); - await gameContract.deployed(); - console.log("Contrato implantado no endereço:", gameContract.address); -}; - -const runMain = async () => { - try { - await main(); - process.exit(0); - } catch (error) { - console.log(error); - process.exit(1); - } -}; + console.log("Contrato implantado no endereço:", gameContract.target); +} -runMain(); +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); ``` -Não estou fazendo nada muito chique aqui. Em `run.js`, basicamente definimos os três personagens e suas estatísticas. Meus personagens são Anitta, Ronaldinho Gaúcho e Zeca Pagodinho... Cada personagem tem basicamente um id, nome, imagem, valor de vida, e valor de ataque. +Não estou fazendo nada muito chique aqui. Em `run.js`, basicamente definimos os três personagens e suas estatísticas. Meus personagens são `Anitta`, `Ronaldinho Gaúcho` e `Zeca Pagodinho`... Cada personagem tem basicamente um `id`, `nome`, `imagem`, `pontos de vida`, e `dano de ataque`. -Por exemplo, nesse caso `Ronaldinho Gaúcho` tem 200 HP, 50 de dano de ataque. Ele tem muita vida, mas seu ataque não dá tanto dano quanto o de Anitta! Anitta tem menos HP, mas dá mais dano. Isso significa que no jogo, ele morrerá mais rápido, mas dará muito dano. +Por exemplo, nesse caso `Ronaldinho Gaúcho` tem `200 HP`, `50 de dano de ataque`. Ele tem muita vida, mas seu ataque não dá tanto dano comparado ao da Anitta! Ela tem menos vida (HP), mas dá mais dano. Isso significa que no jogo, ela morrerá mais rápido, mas dará muito dano. -**Você pode balancear seus personagens como quiser :). Por favor, não copie os meus. Adicione três seus.** +**Você pode balancear seus personagens como quiser 😃. Para ser mais legal, não copie os meus. Adicione seus próprios três.** -Ok, é isso :)!! Quando eu rodar isso usando `npx hardhat run scripts/run.js` e aqui é o que eu tenho: +Ok, é isso 😃!! Quando eu rodar isso usando `npx hardhat run scripts/run.js` e aqui é o que eu tenho: -```plaintext -Personagem inicializado: Anitta com 100 de HP, img https://i.imgur.com/gC5qXsl.png -Personagem inicializado: Ronaldinho Gaúcho com 200 de HP, img https://i.imgur.com/NplQpes.png -Personagem inicializado: Zeca Pagodinho com 300 de HP, img https://i.imgur.com/WMB6g9u.png -Contrato implantado no endereço: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -``` +![Imgur](https://i.imgur.com/pWJ35N2.png) Boom! Nós oficialmente criamos três personagens e estamos salvando os dados deles diretamente no nosso contrato. @@ -170,10 +157,10 @@ Talvez você nem queria personagens. Você pode querer que as pessoas mintem "** Talvez queira que seus personagens tenham coisas como "mana", "energia", ou "chakra" onde os seus personagens podem invocar "feitiços" usando esses atributos. -**Customize seus personagens. É isso que faz ficar divertido!** Por exemplo, eu adicionei Anitta e Zeca Pagodinho como personagens pois pensei que seria engraçado - e eu rio toda vez que vejo haha. +**Customize seus personagens. É isso que faz ficar divertido!** Por exemplo, eu adicionei Anitta e Zeca Pagodinho como personagens pois pensei que seria engraçado - e dou risada toda vez que vejo 😂. -Mudar coisas pequenas como personagens vai fazer você sentir que é uma coisa mais sua e você estará mais motivado a construir tudo isso no caminho :). +**Mudar coisas pequenas como personagens vai fazer você sentir que é uma coisa mais sua** e você estará mais motivado a construir tudo isso no caminho :). -### 🚨 Reporte seu Progresso! +### 🚨 Reporte seu Progresso Poste uma screenshot em #progresso exibindo alguns dos seus personagens -- talvez você possa mostrar o personagem e nos falar o nome dele e quanto HP e Ataque ele tem!!! From e07273225e0978a526889a048695f42f7aa1b701 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Fri, 12 Jan 2024 17:09:53 -0300 Subject: [PATCH 07/21] fix: ajustando texto --- .../Section_1/Lesson_1_Get_Local_Env_Setup.md | 2 +- .../Lesson_4_Mint_Your_NFT_Locally.md | 218 +++++++++--------- 2 files changed, 109 insertions(+), 111 deletions(-) diff --git a/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md b/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md index 7d9564b7e..f9af4e566 100644 --- a/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md +++ b/NFT_Game/pt-br/Section_1/Lesson_1_Get_Local_Env_Setup.md @@ -79,7 +79,7 @@ O projeto vai pedir para você instalar o `@nomicfoundation/hardhat-toolbox`. Va Você também vai querer instalar algo chamado **OpenZeppelin** , que é outra biblioteca muito usada para desenvolver contratos inteligentes seguros. Vamos aprender mais sobre ela depois. Por agora, só a instale 😃. ```bash -npm install @openzeppelin/contracts +npm install @openzeppelin/contracts@4.9.5 ``` Depois rode: diff --git a/NFT_Game/pt-br/Section_1/Lesson_4_Mint_Your_NFT_Locally.md b/NFT_Game/pt-br/Section_1/Lesson_4_Mint_Your_NFT_Locally.md index b6bf97f58..69b740eaa 100644 --- a/NFT_Game/pt-br/Section_1/Lesson_4_Mint_Your_NFT_Locally.md +++ b/NFT_Game/pt-br/Section_1/Lesson_4_Mint_Your_NFT_Locally.md @@ -4,108 +4,113 @@ Agora que temos todos os dados configurados para nossos personagens, a próxima ```solidity // SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; +pragma solidity ^0.8.19; // Contrato NFT para herdar. -import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; // Funcoes de ajuda que o OpenZeppelin providencia. -import "@openzeppelin/contracts/utils/Counters.sol"; -import "@openzeppelin/contracts/utils/Strings.sol"; - +import {Counters} from "@openzeppelin/contracts/utils/Counters.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import "hardhat/console.sol"; -// Nosso contrato herda do ERC721, que eh o contrato padrao de -// NFT! +// Nosso contrato herda do ERC721, que eh o contrato padrao de NFT! contract MyEpicGame is ERC721 { - - struct CharacterAttributes { - uint characterIndex; - string name; - string imageURI; - uint hp; - uint maxHp; - uint attackDamage; - } - - // O tokenId eh o identificador unico das NFTs, eh um numero - // que vai incrementando, como 0, 1, 2, 3, etc. - - using Counters for Counters.Counter; - Counters.Counter private _tokenIds; - - CharacterAttributes[] defaultCharacters; - - // Criamos um mapping do tokenId => atributos das NFTs. - mapping(uint256 => CharacterAttributes) public nftHolderAttributes; - - // Um mapping de um endereco => tokenId das NFTs, nos da um - // jeito facil de armazenar o dono da NFT e referenciar ele - // depois. - mapping(address => uint256) public nftHolders; - - constructor( - string[] memory characterNames, - string[] memory characterImageURIs, - uint[] memory characterHp, - uint[] memory characterAttackDmg - // Embaixo, voce tambem pode ver que adicionei um simbolo especial para identificar nossas NFTs - // Esse eh o nome e o simbolo do nosso token, ex Ethereum ETH. - // Eu chamei o meu de Heroes e HERO. Lembre-se, um NFT eh soh um token! - ) - ERC721("Heroes", "HERO") - { - for(uint i = 0; i < characterNames.length; i += 1) { - defaultCharacters.push(CharacterAttributes({ - characterIndex: i, - name: characterNames[i], - imageURI: characterImageURIs[i], - hp: characterHp[i], - maxHp: characterHp[i], - attackDamage: characterAttackDmg[i] - })); - - CharacterAttributes memory c = defaultCharacters[i]; - - // O uso do console.log() do hardhat nos permite 4 parametros em qualquer order dos seguintes tipos: uint, string, bool, address - - console.log("Personagem inicializado: %s com %s de HP, img %s", c.name, c.hp, c.imageURI); + struct CharacterAttributes { + uint characterIndex; + string name; + string imageURI; + uint hp; + uint maxHp; + uint attackDamage; } - // Eu incrementei tokenIds aqui para que minha primeira NFT tenha o ID 1. - // Mais nisso na aula! - _tokenIds.increment(); - } + // O tokenId eh o identificador unico das NFTs, eh um numero + // que vai incrementando, Ex: 0, 1, 2, 3, etc... + using Counters for Counters.Counter; + Counters.Counter private _tokenIds; + + CharacterAttributes[] defaultCharacters; + + // Criamos um mapping do tokenId => atributos das NFTs. + mapping(uint256 => CharacterAttributes) public nftHolderAttributes; + + // Um mapping de um endereco => tokenId das NFTs, nos da um + // jeito facil de armazenar o dono da NFT e referenciar ele depois. + mapping(address => uint256) public nftHolders; + + constructor( + string[] memory characterNames, + string[] memory characterImageURIs, + uint[] memory characterHp, + uint[] memory characterAttackDmg + ) + // Embaixo, voce tambem pode ver que adicionei um simbolo especial para identificar nossas NFTs + // Esse eh o nome e o simbolo do nosso token, ex Ethereum ETH. + // Eu chamei o meu de Heroes e HERO. Lembre-se, um NFT eh soh um token! + ERC721("Heroes", "HERO") + { + for (uint i = 0; i < characterNames.length; i += 1) { + defaultCharacters.push( + CharacterAttributes({ + characterIndex: i, + name: characterNames[i], + imageURI: characterImageURIs[i], + hp: characterHp[i], + maxHp: characterHp[i], + attackDamage: characterAttackDmg[i] + })); + + CharacterAttributes memory c = defaultCharacters[i]; + + // O uso do console.log() do hardhat nos permite 4 parametros em qualquer order dos seguintes tipos: uint, string, bool, address + + console.log( + "Personagem inicializado: %s com %s de HP, img %s", + c.name, + c.hp, + c.imageURI + ); + } + + // Eu incrementei tokenIds aqui para que minha primeira NFT tenha o ID 1. + // Mais nisso na aula! + _tokenIds.increment(); + } - // Usuarios vao poder usar essa funcao e pegar a NFT baseado no personagem que mandarem! - function mintCharacterNFT(uint _characterIndex) external { - // Pega o tokenId atual (começa em 1 já que incrementamos no constructor). - uint256 newItemId = _tokenIds.current(); + // Usuarios vao poder usar essa funcao e pegar a NFT baseado no personagem que mandarem! + function mintCharacterNFT(uint _characterIndex) external { + // Pega o tokenId atual (começa em 1 já que incrementamos no constructor). + uint256 newItemId = _tokenIds.current(); - // A funcao magica! Atribui o tokenID para o endereço da carteira de quem chamou o contrato. + // A funcao magica! Atribui o tokenID para o endereço da carteira de quem chamou o contrato. - _safeMint(msg.sender, newItemId); + _safeMint(msg.sender, newItemId); - // Nos mapeamos o tokenId => os atributos dos personagens. Mais disso abaixo + // Nos mapeamos o tokenId => os atributos dos personagens. Mais disso abaixo - nftHolderAttributes[newItemId] = CharacterAttributes({ - characterIndex: _characterIndex, - name: defaultCharacters[_characterIndex].name, - imageURI: defaultCharacters[_characterIndex].imageURI, - hp: defaultCharacters[_characterIndex].hp, - maxHp: defaultCharacters[_characterIndex].maxHp, - attackDamage: defaultCharacters[_characterIndex].attackDamage - }); + nftHolderAttributes[newItemId] = CharacterAttributes({ + characterIndex: _characterIndex, + name: defaultCharacters[_characterIndex].name, + imageURI: defaultCharacters[_characterIndex].imageURI, + hp: defaultCharacters[_characterIndex].hp, + maxHp: defaultCharacters[_characterIndex].maxHp, + attackDamage: defaultCharacters[_characterIndex].attackDamage + }); - console.log("Mintou NFT c/ tokenId %s e characterIndex %s", newItemId, _characterIndex); + console.log( + "Mintou NFT c/ tokenId %s e characterIndex %s", + newItemId, + _characterIndex + ); - // Mantem um jeito facil de ver quem possui a NFT - nftHolders[msg.sender] = newItemId; + // Mantem um jeito facil de ver quem possui a NFT + nftHolders[msg.sender] = newItemId; - // Incrementa o tokenId para a proxima pessoa que usar. - _tokenIds.increment(); - } + // Incrementa o tokenId para a proxima pessoa que usar. + _tokenIds.increment(); + } } ``` @@ -124,9 +129,9 @@ Depois, eu tenho `nftHolders` que basicamente me deixa mapear facilmente o ender ### ⚡️ ERC 721 -Você também vai ver que eu "herdo" um contrato OpenZeppelin usando `is ERC721` quando eu declaro o contrato. Você pode ler mais sobre hereditariedade [aqui](https://solidity-by-example.org/inheritance/), mas basicamente, significa que podemos chamar outros contratos a partir do nosso. É quase como importar funções para usarmos. +Você também vai ver que eu "herdo" um contrato OpenZeppelin usando `is ERC721` quando eu declaro o contrato. Você pode ler mais sobre hereditariedade [aqui](https://solidity.w3d.community/apostila/extra-avancado/24.-heranca.html), mas basicamente, significa que podemos chamar outros contratos a partir do nosso. É quase como importar funções para usarmos. -O padrão NFT é conhecido como `ERC721` , o qual você pode ler um pouco mais sobre [aqui](https://eips.ethereum.org/EIPS/eip-721). OpenZeppelin essencialmente implementa o padrão NFT para nós e nos deixa escrever nossa própria lógica em cima disso para customizá-lo. Isso significa que não precisamos escrever código repetitivo e básico. +O padrão NFT é conhecido como `ERC721` , o qual você pode ler um pouco mais sobre [aqui](https://ethereum.org/pt-br/developers/docs/standards/tokens/erc-721). OpenZeppelin essencialmente implementa o padrão NFT para nós e nos deixa escrever nossa própria lógica em cima disso para customizá-lo. Isso significa que não precisamos escrever código repetitivo e básico. Seria loucura escrever um servidor HTTP do zero sem usar uma biblioteca, certo? Claro, a menos que você quisesse explorar. De maneira semelhante - seria loucura apenas escrever um contrato NFT do zero! Você pode explorar o contrato `ERC721` que estamos herdando [daqui](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol). @@ -136,9 +141,9 @@ _tokenIds.increment(); Então, `_tokenIds` começa no `0`. É só um contador. `increment()´ só adiciona mais 1 - veja [aqui](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/fa64a1ced0b70ab89073d5d0b6e01b0778f7e7d6/contracts/utils/Counters.sol#L32). -**No constructor** eu incremento ele em 1. Por quê? Basicamente porque eu não gosto de lidar com zeros no meu código. Em Solidity, 0 é um [valor padrão](https://docs.soliditylang.org/en/v0.5.11/control-structures.html#scoping-and-declarations) e eu tento me manter longe de valores padrão. Só confie em mim por agora ;). +**No constructor** eu incremento ele em 1. Por quê? Basicamente porque eu não gosto de lidar com zeros no meu código. Em Solidity, 0 é um [valor padrão](https://docs.soliditylang.org/en/v0.5.11/control-structures.html#scoping-and-declarations) e eu tento me manter longe de valores padrão. Só confie em mim por agora 😉. -Eu também tenho `increment()` em `mintCharacterNFT` mas não esqueça de adicioná-la no `constructor` também ;). +Eu também tenho `increment()` em `mintCharacterNFT` mas não esqueça de adicioná-la no `constructor` também 😉. ```solidity function mintCharacterNFT(uint _characterIndex) @@ -164,13 +169,13 @@ Nós estamos usando `_tokenIds` para manter a contagem dos identificadores únic _safeMint(msg.sender, newItemId). ``` -Essa é a linha mágica! Quando fazemos `_safeMint(msg.sender, newItemId)` está basicamente dizendo: "minte a NFT com o id `newItemId` para o usuário com endereço `msg.sender`". Aqui, `msg.sender` é uma variável que o [Solidity providencia](https://docs.soliditylang.org/en/develop/units-and-global-variables.html#block-and-transaction-properties) que nos dá fácil acesso ao **endereço público** da pessoa que estiver chamando o contrato. +Essa é a linha mágica! Quando fazemos `_safeMint(msg.sender, newItemId)` está basicamente dizendo: "mint a NFT com o id `newItemId` para o usuário com endereço `msg.sender`". Aqui, `msg.sender` é uma variável que o [Solidity providencia](https://docs.soliditylang.org/en/develop/units-and-global-variables.html#block-and-transaction-properties) que nos dá fácil acesso ao **endereço público** da pessoa que estiver chamando o contrato. **Você não pode chamar um contrato anonimamente**, você precisa ter as credenciais da sua carteira conectadas. Isso é quase como "fazendo login" e ser autenticado :). O que é incrível aqui é que essa é uma **maneira super segura de conseguir o endereço público do usuário**. Manter o endereço público em segredo não é um problema, já é público, todo mundo consegue enxergar. Mas, usando `msg.sender` você não consegue fingir ser o endereço público de outra pessoa a não ser que você tenha as credenciais da carteira dela! -### 🎨 Mantendo dados dinâmicos em uma NFT. +### 🎨 Mantendo dados dinâmicos em uma NFT Então, na medida que jogadores jogam o jogo, certos valores em seus personagens vão mudar, certo? Por exemplo, se meu personagem atacar o boss, o boss vai atacar de volta! **Nesse caso, o HP da minha NFT vai precisar ser diminuído.** Nós precisamos de uma maneira de armazenar esses dados por jogador: @@ -198,7 +203,7 @@ Muitas coisas acontecendo aqui! Basicamente, **nossa NFT segura dados relacionad } ``` -**Lembre-se, todo jogador tem seu próprio personagem NFT e a NFT mesma segura os dados do estado do personagem.** +**Lembre-se, todo jogador tem seu próprio personagem NFT e ela segura os dados do estado do personagem.** Digamos que o meu personagem seja atacado e perca 50 de HP, bom, então o HP iria de 200 -> 150, certo? Esse valor vai precisar mudar na NFT! @@ -229,7 +234,7 @@ nftHolders[msg.sender] = newItemId; Mapeia o endereço público da carteira para o tokenId das NFTs. Isso é o que nos deixa manter a contagem de quem possui as NFTs facilmente. -_Nota: Nesse momento isso é desenhado de maneira que cada jogador possa ter apenas um personagem NFT por endereço de carteira. Se você quisesse, você poderia ajustar isso para os jogadores poderem ter múltiplos personagens, mas eu fiquei com 1 por jogador para facilitar! Esse é nosso jogo, faça o que quiser!_ +> 💡**Nota:** Nesse momento isso é desenhado de maneira que **cada jogador possa ter apenas um personagem NFT por endereço de carteira**. Se você quisesse, você poderia ajustar isso para os **jogadores poderem ter múltiplos personagens**, mas eu fiquei com 1 por jogador para facilitar! **Esse é nosso jogo, faça o que você quiser!** ```solidity _tokenIds.increment(); @@ -237,7 +242,7 @@ _tokenIds.increment(); Depois que a NFT é mintada, nós incrementamos `tokenIds` usando `_tokenIds.increment()` (que é uma função que o OpenZeppelin nos dá). Isso nos dá a certeza de que da próxima vez que uma NFT for mintada, vai ter um identificador `tokenIds` diferente. Ninguém pode ter um `tokenIds` que já foi mintado. -### 😳 Rodando localmente. +### 😳 Rodando localmente Em `run.js` o que precisamos fazer é chamar `mintCharacterNFT`. Eu adicionei as linhas seguintes em `run.js` logo embaixo de onde escrevemos o endereço do contrato. @@ -257,7 +262,7 @@ Quando fazemos `mintCharacterNFT(2)` o Hardhat vai chamar essa função com uma A função `tokenURI` é algo que pegamos de graça do `ERC721` já que herdamos dele. -Basicamente, `tokenUri` é uma função em **cada NFT** que retorna os **dados atuais** que estão ligados à NFT. Então quando eu chamo `gameContract.tokenURI(1)` está basicamente dizendo, _"vá pegar para mims os dados dentro da NFT com tokenId 1"_, que seria a primeira NFT mintada. E, deveria me devolver todas as coisas, como o nome do personagem, o hp atual e etc. +Basicamente, `tokenUri` é uma função em **cada NFT** que retorna os **dados atuais** que estão ligados à NFT. Então quando eu chamo `gameContract.tokenURI(1)` está basicamente dizendo, _"vá pegar para mim os dados dentro da NFT com tokenId 1"_, que seria a primeira NFT mintada. E, deveria me devolver todas as coisas, como o nome do personagem, o hp atual e etc. Plataformas como o OpenSea e Rarible sabem como pegar o `tokenURI` já que a forma padrão de pegar os metadados da NFT. Vamos tentar rodar o nosso contrato de novo (lembre-se que o comando é `npx hardhat run scripts/run.js`) @@ -272,7 +277,7 @@ Mintou um NFT com tokenId 1 e characterIndex 2 Token URI: ``` -**Hmmmmmm**. Token URI não escreve nada! Isso significa que não temos nenhum dado ligado à nossa NFT. Mas espera, isso não faz sentido. Nós não configuramos os dados com `nftHolderAttributes`? +**Hmmm**. Token URI não escreve nada! Isso significa que não temos nenhum dado ligado à nossa NFT. Mas espera, isso não faz sentido. Nós não configuramos os dados com `nftHolderAttributes`? **Não. `nftHolderAttributes` não ligou os dados às NFTs de nenhuma maneira. É só um mapping que vive no contrato nesse momento.** O que vamos fazer agora é basicamente fixar `nftHolderAttributes` para o `tokenURI` sobrescrevendo ele :). @@ -280,7 +285,7 @@ Token URI: O `tokenURI` tem um formato específico, na verdade! Na verdade, está esperando os dados NFT em **JSON**. -Vamos ver como fazer isso :). +Vamos ver como fazer isso 😃. Crie uma pasta nova dentro de `contracts` chamada `libraries`. Crie um arquivo chamado `Base64.sol` e coloque ele dentro de libraries. Copie e cole [esse código](https://gist.github.com/danicuki/4157b854d6dc83021674c5b08bd5f2df) dentro de `Base64.sol`. Isso basicamente nos dá funções que nos ajudam a codificar qualquer tipo de dado em uma string Base64 - que é um padrão para codificar pedaços de dado em uma string. Não se preocupe, você vai ver como isso funciona logo! @@ -363,9 +368,9 @@ string memory json = Base64.encode( ); ``` -Nós configuramos coisas como o nome da NFT, o HP, o Dano de ataque e etc **dinâmicamente**. _Nota: abi.encodePacked só combina strings._ Isso é realmente legal porque nós podemos mudar coisas como o HP da NFT e a imagem dela se quiséssemos, e atualizar na NFT! **É dinâmico!** +Nós configuramos coisas como o nome da NFT, o HP, o Dano de ataque e etc **dinamicamente**. _Nota: abi.encodePacked só combina strings._ Isso é realmente legal porque nós podemos mudar coisas como o HP da NFT e a imagem dela se quisermos, e atualizar na NFT! **É dinâmico!** -Também esse padrão de metadados é seguido por muitos sites populares de NFT como o OpenSea. Então, tudo que estamos fazendo na função é formatando a nossa variável `json` para seguir os padrões. Note: `max_value` não é necessário, mas eu quis adicioná-lo por diversão. +Também esse padrão de metadados é seguido por muitos sites populares de NFT como o **OpenSea**. Então, tudo que estamos fazendo na função é formatando a nossa variável `json` para seguir os padrões. Note: `max_value` não é necessário, mas eu quis adicioná-lo por diversão. ```solidity abi.encodePacked("data:application/json;base64,", json) @@ -373,14 +378,7 @@ abi.encodePacked("data:application/json;base64,", json) Essa linha é na verdade difícil de explicar, é mais fácil apenas mostrar! Vá em frente e rode `run.js`. Aqui está meu output: -```plaintext -Personagem inicializado: Anitta com 100 de HP, img https://i.imgur.com/gC5qXsl.png -Personagem inicializado: Ronaldinho Gaúcho com 200 de HP, img https://i.imgur.com/NplQpes.png -Personagem inicializado: Zeca Pagodinho com 300 de HP, img https://i.imgur.com/Pj8lHpM.png -Contrato implantado no endereço: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -Mintou um NFT com tokenId 1 e characterIndex 2 -Token URI: data:application/json;base64,eyJuYW1lIjogIlplY2EgUGFnb2RpbmhvIC0tIE5GVCAjOiAxIiwgImRlc2NyaXB0aW9uIjogIkVzdGEgTkZUIGRhIGFjZXNzbyBhbyBtZXUgam9nbyBORlQhIiwgImltYWdlIjogImh0dHBzOi8vaS5pbWd1ci5jb20vUGo4bEhwTS5wbmciLCAiYXR0cmlidXRlcyI6IFsgeyAidHJhaXRfdHlwZSI6ICJIZWFsdGggUG9pbnRzIiwgInZhbHVlIjogMzAwLCAibWF4X3ZhbHVlIjozMDB9LCB7ICJ0cmFpdF90eXBlIjogIkF0dGFjayBEYW1hZ2UiLCAidmFsdWUiOiAyNX0gXX0= -``` +![Terminal](https://i.imgur.com/giXoab3.png) Você verá que Token URI agora escreve coisas! **Boa!!** Vá em frente e copie essa grande string depois de `Token URI:`. Por exemplo, a minha se parece com isso: @@ -392,7 +390,7 @@ Cole essa string dentro da barra de URL no seu browser. Você vai ver algo como ![Imagem](https://i.imgur.com/5qVWxSQ.png) -BOOOM!!! +🤯 **BOOM!!!** Basicamente o que fizemos foi que formatamos nosso arquivo JSON e **codificamos ele** em Base64. Então, acontece que o arquivo JSON se torna essa string codificada super longa, que é legível para o nosso browser quando usamos o prefixo `data:application/json;base64,`. @@ -402,12 +400,12 @@ Adicionamos `data:application/json;base64,` porque o nosso browser precisa saber De novo, isso é considerado um padrão para a maioria dos navegadores, o que é perfeito porque nós queremos que os dados das nossas NFT sejam compatíveis com o maior número de sistemas possível. -Por que estamos fazendo essas coisas de Base64? Bom, basicamente isso é como sites populares ocomo o OpenSea, Rarible e muitos outros preferem quando passam dados JSON diretamente do nosso conrtato. +Por que estamos fazendo essas coisas de Base64? Bom, basicamente isso é como sites populares como o OpenSea, Rarible e muitos outros preferem quando passam dados JSON diretamente do nosso contrato. **Incrível**. Então, agora estamos no ponto em que mintamos oficialmente e localmente as NFTs e a NFT tem dados fixados nela em uma maneira que siga os padrões. **Estamos prontos para fazer o deploy da nossa NFT no OpenSea :).** -### 🚨 Reporte seu Progresso ! +### 🚨 Reporte seu Progresso -Poste uma screenshot do seu JSON quando você colou o `tokenURI` no endereço do seu navegador :)! \ No newline at end of file +Poste uma screenshot do seu JSON quando você colou o `tokenURI` no endereço do seu navegador :)! From 84d2b9be27c2caea3d23ac1ec8e03b79f5c975cc Mon Sep 17 00:00:00 2001 From: Vini Black Date: Mon, 15 Jan 2024 15:11:30 -0300 Subject: [PATCH 08/21] =?UTF-8?q?fix:=20atualizando=20c=C3=B3digo=20do=20b?= =?UTF-8?q?uild=20e=20atualizando=20txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...oerli.md => Lesson_5_Deploy_To_Sepolia.md} | 100 +++++++----------- 1 file changed, 38 insertions(+), 62 deletions(-) rename NFT_Game/pt-br/Section_1/{Lesson_5_Deploy_To_Goerli.md => Lesson_5_Deploy_To_Sepolia.md} (68%) diff --git a/NFT_Game/pt-br/Section_1/Lesson_5_Deploy_To_Goerli.md b/NFT_Game/pt-br/Section_1/Lesson_5_Deploy_To_Sepolia.md similarity index 68% rename from NFT_Game/pt-br/Section_1/Lesson_5_Deploy_To_Goerli.md rename to NFT_Game/pt-br/Section_1/Lesson_5_Deploy_To_Sepolia.md index 1b7daafdd..b37f05382 100644 --- a/NFT_Game/pt-br/Section_1/Lesson_5_Deploy_To_Goerli.md +++ b/NFT_Game/pt-br/Section_1/Lesson_5_Deploy_To_Sepolia.md @@ -6,7 +6,7 @@ O próximo passo é uma testnet, que você pode pensar como ambiente de desenvol ### 🦊 Metamask -Depois, precisamos de uma carteira Ethereum. Existem várias, mas, para esse projeto, vamos usar a Metamask. Baixe a extensão de navegador e configure sua carteira [aqui](https://metamask.io/download.html). Mesmo se você tiver outra carteira, só use a Metamask por agora. +Depois, precisamos de uma carteira Ethereum. Existem várias, mas, para esse projeto, vamos usar a **Metamask**. Baixe a extensão de navegador e configure sua carteira [aqui](https://metamask.io/download/). Mesmo se você tiver outra carteira, **vamos usar a Metamask por agora**. Por que precisamos da Metamask? Bom. Precisamos estar aptos a chamar funções no nosso contrato inteligente que vive na blockchain. E, para fazer isso, precisamos ter uma carteira que tem nosso endereço Ethereum e chave privada. @@ -14,7 +14,7 @@ Por que precisamos da Metamask? Bom. Precisamos estar aptos a chamar funções n É quase como autenticação. Precisamos de algo para fazer "login" na blockchain e depois usar essas credenciais para fazer requisições na API pelo nosso site. -Então, vá em frente e configure! O fluxo de setup deles é bem autoexplicativo :). +Então, vá em frente e configure! O fluxo de setup deles é bem autoexplicativo 😃. ### **💳 Transações** @@ -24,22 +24,22 @@ Então, quando nós quisermos realizar uma ação que mude a blockchain, nós ch Lembre-se, a blockchain não tem dono. É só um monte de computadores ao redor do mundo rodando através de **mineradores** que tem a cópia da blockchain. -Quando implementarmos nosso contrato, nós precisamos falar **para todos esses** mineradores, "ei, esse é um contrato inteligente novo, por favor adicione meu contrato inteligente à blockchain e diga para todo mundo sobre ele também". +Quando implementarmos nosso contrato, nós precisamos falar **para todos esses** mineradores, "_ei, esse é um contrato inteligente novo, por favor adicione meu contrato inteligente à blockchain e diga para todo mundo sobre ele também_". -Aqui é onde o [Alchemy](https://alchemy.com/?r=jQ3MDMxMzUyMDU3N) entra. +Aqui é onde o [Alchemy](https://www.alchemy.com/) entra. -Alchemy essencialmente nos ajuda a transmitir a criação do nosso contrato para que ele possa ser pego pelos mineradores o mais rápido possível. Uma vez que a transação for minerada (validada), será então transmitida para a blockchain como uma transação legítima. A partir daí, todo mundo atualiza suas cópias da blockchain. +**Alchemy** essencialmente nos ajuda a transmitir a criação do nosso contrato para que ele possa ser pego pelos mineradores o mais rápido possível. Uma vez que a transação for minerada (validada), será então transmitida para a blockchain como uma transação legítima. A partir daí, todo mundo atualiza suas cópias da blockchain. Isso é complicado. E, não se preocupe se você não entendeu completamente. Enquanto você escrever mais código e construir esse app, vai fazer mais sentido naturalmente. -Então, crie uma conta com o Alchemy [aqui](https://alchemy.com/?r=jQ3MDMxMzUyMDU3N). +Então, crie uma conta com o Alchemy [aqui](https://www.alchemy.com/). E depois dê uma olhada no meu vídeo abaixo: [Loom](https://www.loom.com/share/35aabe54c3294ef88145a03c311f1933) ## 🕸 Testnets -Nós não vamos estar implantando (deploying) diretamente na rede principal do Ethereum (Ethereum mainnet) por enquanto. Por quê? Porque custa dinheiro real e não vale a pena bagunçar as coisas. Nós estamos apenas aprendendo nesse momento. Nós vamos começar com uma "tesnet" (rede de teste) que é um clone da mainnet, mas usa dinheiro falso para que possamos testar coisas o quanto quisermos. Mas, é importante saber que testnets são mantidas por minerados e cenários mímicos de mundo real. +Nós não vamos estar implantando (deploying) diretamente na rede principal do Ethereum (Ethereum mainnet) por enquanto. Por quê? Porque custa dinheiro real e não vale a pena bagunçar as coisas. Nós estamos apenas aprendendo nesse momento. Nós vamos começar com uma **"tesnet" (rede de teste) que é um clone da mainnet**, mas usa **dinheiro falso para que possamos testar coisas o quanto quisermos**. Mas, é importante saber que **testnets são mantidas por minerados e cenários mímicos de mundo real**. Isso é incrível porque podemos testar nossa aplicação num cenário de mundo real, onde vamos fazer algumas coisas: @@ -53,21 +53,19 @@ Isso é incrível porque podemos testar nossa aplicação num cenário de mundo ## 🤑 Pegando um pouco de dinheiro falso -Existem algumas testnets por aí, e a que usaremos é chamada "Goerli". +Existem algumas testnets por aí, e a que usaremos é chamada "Sepolia". -Para poder fazer deploy na Goerli, precisamos de ETH falso. Por quê? Porque se estivéssemos fazendo deploy na mainnet Ethereum, você usaria dinheiro real! Por isso, testnets copiam como a mainnet funciona, a única diferença é que não tem dinheiro real envolvido. +Para poder fazer deploy na Sepolia, precisamos de ETH falso. Por quê? Porque se estivéssemos fazendo deploy na mainnet Ethereum, você usaria dinheiro real! Por isso, testnets copiam como a mainnet funciona, a única diferença é que não tem dinheiro real envolvido. -Para conseguirmos ETH falso, precisamos pedir alguns para a rede. **Esse ETH falso só vai funcionar nessa testnet específica.** Você pode conseguir alguns Ethereum falsos para o Goerli por um faucet. Você só precisa achar algum que funcione. +Para conseguirmos ETH falso, precisamos pedir alguns para a rede. **Esse ETH falso só vai funcionar nessa testnet específica.** Você pode conseguir alguns Ethereum falsos para o Sepolia por um faucet. Você só precisa achar algum que funcione. Você tem alguns faucets para escolher: | Nome | Link | ---------------- | -------------------------- -| Alchemy | https://goerlifaucet.com/ -| Mudit | https://goerli-faucet.mudit.blog/ -| Paradigm | https://faucet.paradigm.xyz/ - -Nota: para o MyCrypto, você vai ter que conectar sua carteira, criar uma conta e clicar no mesmo link **de novo** para pedir fundos. O faucet do buildspace é bem confiável também, só tenha certeza que o seu Metamask estiver na rede Goerli :). +| Alchemy | +| Rockx | +| PoWFaucet | ## 🚀 Configurar um arquivo deploy.js @@ -80,16 +78,16 @@ const main = async () => { const gameContractFactory = await hre.ethers.getContractFactory("MyEpicGame"); const gameContract = await gameContractFactory.deploy( ["Anitta", "Ronaldinho Gaúcho", "Zeca Pagodinho"], - [ + [ "https://i.imgur.com/gC5qXsl.png", "https://i.imgur.com/0PvxtwP.png", "https://i.imgur.com/Pj8lHpM.png", - ], + ], [100, 200, 300], [100, 50, 25] ); await gameContract.deployed(); - console.log("Contrato implantado no endereço:", gameContract.address) + console.log("Contrato implantado no endereço:", gameContract.target) let txn; txn = await gameContract.mintCharacterNFT(0); @@ -104,10 +102,6 @@ const main = async () => { await txn.wait(); console.log("Mintou NFT #3"); - txn = await gameContract.mintCharacterNFT(1); - await txn.wait(); - console.log("Minted NFT #4"); - console.log("Fim do deploy e mint!"); }; @@ -124,24 +118,27 @@ const runMain = async () => { runMain(); ``` -## **📈 Fazer o deploy para a testnet Goerli.** +## **📈 Fazer o deploy para a testnet Sepolia.** Nós vamos precisar mudar nosso arquivo `hardhat.config.js` . Você pode encontrá-lo na raíz do diretório do projeto do seu contrato inteligente. ```javascript -require("@nomiclabs/hardhat-waffle"); +require("@nomicfoundation/hardhat-toolbox"); + +/** @type import('hardhat/config').HardhatUserConfig */ module.exports = { - solidity: "0.8.4", + solidity: "0.8.19", networks: { - goerli: { + sepolia: { url: "SEU_URL_DA_API_ALCHEMY", - accounts: ["SUA_KEY_PRIVADA_DA_CONTA_GOERLI"], + accounts: ["SUA_KEY_PRIVADA_DA_CONTA_SEPOLIA"], }, }, }; + ``` -Você pode conseguir URL da sua API no dashboard do Alchemy e colar ali mesmo. Depois, você vai precisar da sua chave **privada** do Goerli (não o seu endereço público!) o qual você pode [pegar no metamask](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) e colar ali também. +Você pode conseguir URL da sua API no dashboard do Alchemy e colar ali mesmo. Depois, você vai precisar da sua chave **privada** do Sepolia (não o seu endereço público!) o qual você pode [pegar no metamask](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) e colar ali também. **Nota: NÃO FAÇA COMMIT DESSE ARQUIVO NO GITHUB. ELE CONTÉM SUA CHAVE PRIVADA. VOCÊ PODE SER ROUBADO E HACKEADO. ESSA CHAVE PRIVADA É A MESMA QUE A DA MAINNET.** Nós vamos falar sobre variáveis `.env` depois e como mantê-las em segredo. @@ -152,27 +149,20 @@ Uma vez que você configurou o seu setup, estamos prontos para fazer o deploy co Rode esse comando pela raíz do seu diretório `epic-nfts`. ```bash -npx hardhat run scripts/deploy.js --network goerli +npx hardhat run scripts/deploy.js --network sepolia ``` Aqui está o que eu consigo: -```plaintext -Contrato implantado no endereço: 0x067f2Ac969091c285BcC1e537EC748aEdD779F02 -Mintou NFT #1 -Mintou NFT #2 -Mintou NFT #3 -Minted NFT #4 -Fim do deploy e mint! -``` +![Imgur](https://i.imgur.com/AbXDLLf.png) -Podemos ter certeza que tudo funcionou corretamente usando o [Goerli Etherscan](https://goerli.etherscan.io/) onde você copiar e colar o endereço do contrato que foi o output para ver o que aconteceu com ele. Aqui eu posso ver que tivemos **cinco** transações. **Uma** transação de criação de contrato e **quatro** transações onde mintamos NFT. Isso está certo :). +Podemos ter certeza que tudo funcionou corretamente usando o [Sepolia Etherscan](https://sepolia.etherscan.io/) onde você copiar e colar o endereço do contrato que foi o output para ver o que aconteceu com ele. Aqui eu posso ver que tivemos **cinco** transações. **Uma** transação de criação de contrato e **quatro** transações onde mintamos NFT. Isso está certo :). ![Untitled](https://i.imgur.com/hJtoYRp.png) -**Se acostume a usar muito o Etherscan do Goerli para debugar os deploys** porque é a maneira mais fácil de acompanhar os deployments e se algo der errado. Se não estiver mostrando no Etherscan, isso significa que está ou processando ou algo deu errado. Isso é o que eu consigo: +**Se acostume a usar muito o Etherscan do Sepolia para debugar os deploys** porque é a maneira mais fácil de acompanhar os deployments e se algo der errado. Se não estiver mostrando no Etherscan, isso significa que está ou processando ou algo deu errado. Isso é o que eu consigo: -Se funcionou - **INCRÍVEL VOCÊ ACABOU DE FAZER DEPLOY DE UM CONTRATO E MINTOU NFTS!!** +Se funcionou - **INCRÍVEL VOCÊ ACABOU DE FAZER DEPLOY DE UM CONTRATO E MINTOU NFTS!!** 👩‍💻 ### **🌊 Ver no OpenSea** @@ -196,40 +186,25 @@ Por exemplo: Nesse caso, o OpenSea renderizou todos os atributos dos personagens eficientemente! -O que é legal aqui é que se nós trocarmos o valor do HP da NFT do jogador para `150` ou qualquer valor, ele mudaria e atualizaria no OpenSea! **Isso é super legal porque a NFT segura dinamicamente o estado do personagem :).** Nós não precisamos de nenhum servidor centralizado para segurar aqueles dados. +O que é legal aqui é que se nós trocarmos o valor do HP da NFT do jogador para `150` ou qualquer valor, ele mudaria e atualizaria no OpenSea! **Isso é super legal porque a NFT segura dinamicamente o estado do personagem :).** Nós não precisamos de **nenhum servidor centralizado** para segurar aqueles dados. Isso é incrível porque agora quando nossos jogadores forem jogar o jogo e nós detectarmos sua NFT, vamos saber exatamente qual o estado do personagem da NFT dele no jogo! -_Nota: você vai perceber que nós mintamos 4 NFTs para a mesma carteira nesse caso - isso **não seria** permitido no nosso jogo porque cada jogador estaria permitido a ter apenas 1 NFT. Eu só queria testar. Também, nesse momento `nftHolders` pode apenas segurar um `tokenId` por endereço único. Então, cada vez que uma nova NFT é mintada para o mesmo endereço, o `tokenId` anterior é sobrescrito. Você poderiar retornar um erro se quisesse ao invés disso._ +> 💡**Nota:** você vai perceber que nós mintamos 4 NFTs para a mesma carteira nesse caso - isso **não seria** permitido no nosso jogo porque cada jogador estaria permitido a ter apenas 1 NFT. Eu só queria testar. Também, nesse momento `nftHolders` pode apenas segurar um `tokenId` por endereço único. Então, cada vez que uma nova NFT é mintada para o mesmo endereço, o `tokenId` anterior é sobrescrito. Você poderiar retornar um erro se quisesse ao invés disso. ### **🙀 "Ajuda, minhas NFTs não estão mostrando no OpenSea!"** -**Se suas NFTs não estiverem aparecendo no OpenSea** - espere alguns minutos, as vezes o OpenSea pode levar até 5 minutos. Aqui vai meu conselho, se já fazem mais de 5 minutos e seus metadados ainda se parecem com isso: +**Se suas NFTs não estiverem aparecendo no OpenSea** - espere alguns minutos, as vezes o OpenSea pode levar até 5 minutos. ![Untitled](https://i.imgur.com/dVACrDl.png) -**Use o Rarible ao invés do OpenSea.** Rarible é outro marketplace NFT como o OpenSea. Aqui está como configurá-lo: - -1. Vá para `goerli.rarible.com`. -2. Crie esse URL: `https://goerli.rarible.com/token/INSIRA_O_ENDEREÇO_DO_CONTRATO_AQUI:INSIRA_O_TOKEN_ID_AQUI.` - -Por exemplo, esse é o meu link: - -```plaintext -https://goerli.rarible.com/token/0xcec8593c046364f163926a4327dfce6f546d9f98:4 -``` - -Esse é a NFT do Zeca Pagodinho!! Meu `tokenId` é `4` porque foi o quarto mint feito daquele contrato. Sinta-se livre para tentar colocar outros Ids. - -**Basicamente, se você não vir sua NFT no OpenSea dentro de alguns minutos, tente o Rarible para ter certeza que está funcionando.** - ### 🤯 Porque isso é épico? -Vale a pena falar sobre o porque o que você acabou de fazer é grande coisa. +Vale a pena falar sobre o **porque o que você acabou de fazer é grande coisa**. -Basicamente, você criou uma NFT. Então, isso já é legal. As pessoas podem possuir um personagem do seu jogo em suas carteiras, yay! +Basicamente, **você criou uma NFT**. Então, isso já é legal. As pessoas podem possuir um personagem do seu jogo em suas carteiras, yay! -Mas, essas NFTs tem atributos também! Como ataque, vida, mana ou qualquer coisa que você adicionou. Então, isso significa que a NFT é mais do que só um JPG - tem outros elementos que a fazem mais interativa. +Mas, essas **NFTs tem atributos também!** Como ataque, vida, mana ou qualquer coisa que você adicionou. Então, isso significa que a NFT é mais do que só um JPG - tem outros elementos que a fazem mais interativa. O maior jogo NFT do mundo, Axie Infinity, funciona assim também. É um jogo baseado em turnos, estilo Pokemon onde você luta contra outros players 1v1. @@ -271,7 +246,8 @@ Em cima disso, como o criador das NFTs originais do Zeca Pagodinho - eu posso co Ok - vamos programar a lógica do jogo. -### 🚨 Reporte seu Progresso ! +### 🚨 Reporte seu Progresso + *Por favor, faça isso se não o yanluiz vai ficar triste :(* Poste uma screenshot em #progresso dos seus NFTs épicos no OpenSea. Faça um tweet sobre isso, espalhe pro mundo o que você fez, foi incrível! Marque a @Web3dev_ no twitter que a gente retweeta para você. Adoramos quando as pessoas interagem pelo twitter, é como uma dose de dopamina e motivação. Além do mais o seu tweet pode ajudar a divulgar a comunidade e a web3 para o mundo! From b2d3544fe61e21a94e69d1d17a9c6a6beb78bb72 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Mon, 15 Jan 2024 15:38:01 -0300 Subject: [PATCH 09/21] update: explicando sobre o dotenv mais cedo --- .../Section_1/Lesson_5_Deploy_To_Sepolia.md | 46 ++++++++++++++++++- .../Lesson_2_Finishing_Touches_Contract.md | 40 ---------------- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/NFT_Game/pt-br/Section_1/Lesson_5_Deploy_To_Sepolia.md b/NFT_Game/pt-br/Section_1/Lesson_5_Deploy_To_Sepolia.md index b37f05382..ac1d3884f 100644 --- a/NFT_Game/pt-br/Section_1/Lesson_5_Deploy_To_Sepolia.md +++ b/NFT_Game/pt-br/Section_1/Lesson_5_Deploy_To_Sepolia.md @@ -131,7 +131,7 @@ module.exports = { networks: { sepolia: { url: "SEU_URL_DA_API_ALCHEMY", - accounts: ["SUA_KEY_PRIVADA_DA_CONTA_SEPOLIA"], + accounts: ["SUA_KEY_PRIVADA_DA_CONTA"], }, }, }; @@ -140,7 +140,7 @@ module.exports = { Você pode conseguir URL da sua API no dashboard do Alchemy e colar ali mesmo. Depois, você vai precisar da sua chave **privada** do Sepolia (não o seu endereço público!) o qual você pode [pegar no metamask](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) e colar ali também. -**Nota: NÃO FAÇA COMMIT DESSE ARQUIVO NO GITHUB. ELE CONTÉM SUA CHAVE PRIVADA. VOCÊ PODE SER ROUBADO E HACKEADO. ESSA CHAVE PRIVADA É A MESMA QUE A DA MAINNET.** Nós vamos falar sobre variáveis `.env` depois e como mantê-las em segredo. +> ⚠️ **ATENÇÃO: NÃO FAÇA COMMIT DO `hardhat.config.js` NO GITHUB. ELE CONTÉM SUA CHAVE PRIVADA. VOCÊ PODE SER ROUBADO E HACKEADO. ESSA CHAVE PRIVADA É A MESMA QUE A DA MAINNET`Nós vamos falar sobre variáveis`.env` depois e como mantê-las em segredo.** Por quê você precisa dessa chave privada? Porque para realizar uma transação, como fazer deploy de um contrato, você precisa "logar" na blockchain e assinar / fazer deploy do contrato. E, o seu nome de usuário é o seu endereço público, e sua senha é sua chave privada. É como fazer login na AWS ou GCP para fazer deploy. @@ -246,6 +246,48 @@ Em cima disso, como o criador das NFTs originais do Zeca Pagodinho - eu posso co Ok - vamos programar a lógica do jogo. +### **🙉 Uma nota sobre o github** + +Se estiver fazendo upload para o Github, **não faça upload do seu arquivo `hardhat.config.js` com sua chave privada** para seu repositório. **Você vai ser roubado**. + +Eu uso o `dotenv` para isso. + +```javascript +npm install --save dotenv +``` + +```javascript +require("@nomicfoundation/hardhat-toolbox"); +require("dotenv").config(); + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + solidity: "0.8.19", + networks: { + sepolia: { + url: process.env.STAGING_ALCHEMY_KEY, + accounts: [process.env.PRIVATE_KEY], + }, + mainnet: { + chainId: 1, + url: process.env.PROD_ALCHEMY_KEY, + accounts: [process.env.PRIVATE_KEY], + }, + }, +}; +``` + +E o seu arquivo `.env` vai se parecer com isso: + +```javascript +STAGING_ALCHEMY_KEY=SEU_URL_DA_API_ALCHEMY_TESTNET; +PROD_ALCHEMY_KEY=SEU_URL_DA_API_ALCHEMY_PROD; +PRIVATE_KEY=SUA_KEY_PRIVADA_DA_CONTA_METAMASK; +``` + +> ⚠️ **ATENÇÃO:** **Não commite seu arquivo .env depois disso. +> Adicione ele no `.gitignore`** [aqui](https://www.atlassian.com/br/git/tutorials/saving-changes/gitignore) você pode entender melhor sobre e como usá-lo. + ### 🚨 Reporte seu Progresso *Por favor, faça isso se não o yanluiz vai ficar triste :(* diff --git a/NFT_Game/pt-br/Section_4/Lesson_2_Finishing_Touches_Contract.md b/NFT_Game/pt-br/Section_4/Lesson_2_Finishing_Touches_Contract.md index bbe4ad27a..5790b5346 100644 --- a/NFT_Game/pt-br/Section_4/Lesson_2_Finishing_Touches_Contract.md +++ b/NFT_Game/pt-br/Section_4/Lesson_2_Finishing_Touches_Contract.md @@ -1,43 +1,3 @@ -### **🙉 Uma nota sobre o github** - -**Se estiver fazendo upload para o Github, não faça upload do seu arquivo hardhat config com sua chave privada para seu repositório. Você vai ser roubado.** - -Eu uso o dotenv para isso. - -```javascript -npm install --save dotenv -``` - -```javascript -require("@nomiclabs/hardhat-waffle"); -require("dotenv").config(); - -module.exports = { - solidity: "0.8.0", - networks: { - goerli: { - url: process.env.STAGING_ALCHEMY_KEY, - accounts: [process.env.PRIVATE_KEY], - }, - mainnet: { - chainId: 1, - url: process.env.PROD_ALCHEMY_KEY, - accounts: [process.env.PRIVATE_KEY], - }, - }, -}; -``` - -E o seu arquivo .env vai se parecer com isso: - -```javascript -STAGING_ALCHEMY_KEY=BLAHBLAH; -PROD_ALCHEMY_KEY=BLAHBLAH; -PRIVATE_KEY=BLAHBLAH; -``` - -(não commite seu arquivo .env depois disso) - ### 🌎 Pegue seus assets de imagem no IPFS. Agora - as imagens do nosso boss e do personagem estão no Imgur. From d963727676eec40f151bbe9fb39a69d149041c18 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Mon, 15 Jan 2024 17:38:55 -0300 Subject: [PATCH 10/21] fix: atualizando texto --- .../Lesson_1_Build_Boss_And_Attack_Logic.md | 106 +++++------------- 1 file changed, 28 insertions(+), 78 deletions(-) diff --git a/NFT_Game/pt-br/Section_2/Lesson_1_Build_Boss_And_Attack_Logic.md b/NFT_Game/pt-br/Section_2/Lesson_1_Build_Boss_And_Attack_Logic.md index d4bf47156..6df1228c9 100644 --- a/NFT_Game/pt-br/Section_2/Lesson_1_Build_Boss_And_Attack_Logic.md +++ b/NFT_Game/pt-br/Section_2/Lesson_1_Build_Boss_And_Attack_Logic.md @@ -1,4 +1,4 @@ -### 🙀 Construindo nosso boss. +### 🙀 Construindo nosso boss Então, no nosso jogo o personagem NFT vai estar apto a atacar um boss. @@ -60,18 +60,18 @@ Finalmente, só mudamos `run.js` e `deploy.js` para passar em parâmetros para o ```javascript const gameContract = await gameContractFactory.deploy( ["Anitta", "Ronaldinho Gaúcho", "Zeca Pagodinho"], - [ - "https://i.imgur.com/gC5qXsl.png", - "https://i.imgur.com/0PvxtwP.png", - "https://i.imgur.com/Pj8lHpM.png", - ], - [100, 200, 300], - [100, 50, 25], - "Capitão Nascimento", - "https://i.imgur.com/yWpKMDt.png", - 10000, - 50 - ); + [ + "https://i.imgur.com/gC5qXsl.png", + "https://i.imgur.com/0PvxtwP.png", + "https://i.imgur.com/Pj8lHpM.png", + ], + [100, 200, 300], + [100, 50, 25], + "Capitão Nascimento", + "https://i.imgur.com/yWpKMDt.png", + 10000, + 50 + ); ``` Parece um pouco feio, mas, é isso! @@ -84,7 +84,7 @@ Seria bem divertido se o boss fosse seu cachorro, e ao invés de tentar destruí De qualquer jeito, seja criativo. Esse é o seu projeto :). -### 👾 Recuperando os atributos dos NFTs do jogador. +### 👾 Recuperando os atributos dos NFTs do jogador Nós vamos criar uma função `attackBoss`. Aqui está um início dela: @@ -118,7 +118,7 @@ Eu então pego os atributos do jogador usando `nftHolderAttributes[nftTokenIdOfP Em contraste, se fôssemos usar `memory` ao invés de `storage`, iria criar uma cópia local da variável dentro do escopo da função. Isso significa que se fizéssemos `player.hp = 0` seria desse jeito apenas na função e não mudaria o valor global da variável. -Em `run.js` você pode testar isso adicionando isso em qualquer lugar embaixo de `gameContract.deployed();`: +Em `run.js` você pode testar isso adicionando isso em qualquer lugar embaixo de `gameContract.deploy();`: ```javascript let txn; @@ -137,25 +137,15 @@ Então, fazemos `attackBoss()`. Quando rodo isso, isso é o que consigo: -```plaintext -Terminamos de incializar o boss Capitão Nascimento com HP 10000, img https://i.imgur.com/yWpKMDt.png -Terminamos de incializar o Anitta com HP 100, img https://i.imgur.com/gC5qXsl.png -Terminamos de incializar o Ronaldinho Gaúcho com HP 200, img https://i.imgur.com/NplQpes.png -Terminamos de incializar o Zeca Pagodinho com HP 300, img https://i.imgur.com/Pj8lHpM.png -Contrato deployado no endereço: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -NFT Mintado com tokenId 0 e characterId 2 - -Jogador com personagem Zeca Pagodinho ira atacar. Tem 300 de HP e 25 de PA -Boss Capitão Nascimento tem 10000 HP e 50 PA -``` +![Imgur](https://i.imgur.com/VTqAORU.png) Parece bom! `Zeca Pagodinho` está indo atacar nosso boss `Capitão Nascimento`. Tudo funcionou perfeitamente e estamos recuperando o estado das NFTs :). -### 🔍 Conferir algumas coisas antes de atacar. +### 🔍 Conferir algumas coisas antes de atacar Depois, nós só precisamos checar que o **personagem tenha HP**, se o personagem está morto ele não pode atacar! Nós vamos precisar ter certeza que o **boss tenha HP**. Não dá para atacar o boss se ele estiver destruído. -Algumas coisas para notar aqui - +Algumas coisas para notar aqui: - Você também vai notar a palavra chave especial `require` aqui. Sinta-se livre para ler mais [aqui](https://ethereum.stackexchange.com/questions/60585/what-difference-between-if-and-require-in-solidity). @@ -184,15 +174,16 @@ function attackBoss() public { } ``` -### 🔫 Ataque o boss!! +### 🔫 Ataque o boss Atacar, na verdade **não é** super fácil. -Basicamente, estamos trabalhando com `uint` agora. Isso é um "[unsigned integer](https://solidity-by-example.org/primitives/)" significando que não pode ser negativo! Isso é meio estranho. Digamos que o boss tenha 10 HP sobrando e nosso personagem tenha 50 de dano de ataque. Isso significa que precisaremos fazer `10 HP - 50 dano de ataque` para calcular o HP novo do boss, que seria `-40`. Mas, estamos trabalhando com `uint` então não podemos lidar com números negativos! +Basicamente, estamos trabalhando com `uint` agora. Isso é um "[unsigned integer](https://solidity.w3d.community/exemplos/linguagem-v0.8.3/tipos-de-dados-primarios.html)" significando que não pode ser negativo! Isso é meio estranho. Digamos que o boss tenha 10 HP sobrando e nosso personagem tenha 50 de dano de ataque. Isso significa que precisaremos fazer `10 HP - 50 dano de ataque` para calcular o HP novo do boss, que seria `-40`. Mas, estamos trabalhando com `uint` então não podemos lidar com números negativos! **Teríamos um erro de overflow ou underflow.** -Nós **poderíamos** usar `int` que permitiria armazenar números negativos. Mas, isso fica bagunçado porque a maioria das libraries como OpenZeppelin ou Hardhat não tem um suporte decente para `int` em suas funções de library. Por exemplo, nós umas `Strings.toString` que só funciona com `uint`. `console.log` também não funciona com `int` facilmente. +Nós **poderíamos** usar `int` que permitiria armazenar números negativos. Mas, isso fica bagunçado porque a maioria das libraries como OpenZeppelin ou Hardhat não tem um suporte decente para `int` em suas funções de library. +Por exemplo, nós umas `Strings.toString` que só funciona com `uint`. `console.log` também não funciona com `int` facilmente. Então, vale a pena ficar com `uint` só pela facilidade por agora. @@ -232,7 +223,7 @@ function attackBoss() public { `bigBoss.hp < player.attackDamage` só está checando se o boss vai ter seu HP reduzido para menos do que 0 no dano de ataque dos jogadores. Por exemplo, se `bigBoss.hp` fosse 10 e `player.attackDamage` fosse 30, então sabemos que o boss teria seu HP reduzido para menos que 0, o que causaria um erro! Então, vamos checar esse caso e configurar o hp do boss para 0 manualmente. Se não for para menos que 0, nós só fazemos `bigBoss.hp = bigBoss.hp - player.attackDamage` o que iria reduzir o HP do boss baseado em quanto dano o jogador dá! -### 🔪 Adicionando a lógica para o boss atacar o jogador. +### 🔪 Adicionando a lógica para o boss atacar o jogador Nós também precisamos ter certeza que o HP do jogador não se torne negativo também, porque o HP dos jogadores é um `uint` também. Então fazemos: @@ -294,26 +285,9 @@ await txn.wait(); Agora quando rodo `run.js` aqui está o que eu consigo: -```plaintext -Terminamos de incializar o boss Capitão Nascimento w/ HP 10000, img https://i.imgur.com/yWpKMDt.png -Terminamos de incializar o Anitta com HP 100, img https://i.imgur.com/gC5qXsl.png -Terminamos de incializar o Ronaldinho Gaúcho com HP 200, img https://i.imgur.com/NplQpes.png -Terminamos de incializar o Zeca Pagodinho com HP 300, img https://i.imgur.com/Pj8lHpM.png -Contrato deployado no endereço: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -NFT Mintado com tokenId 0 e characterId 2 - -Jogador com personagem Zeca Pagodinho ira atacar. Tem 300 de HP e 25 de PA -Boss Capitão Nascimento tem 10000 HP and 50 AD -Jogador atacou o boss. Boss ficou com hp: 9975 -Boss atacou o jogador. Jogador ficou com hp: 250 - -Jogador com personagem Zeca Pagodinho ira atacar. Tem 250 de HP e 25 de PA -Boss Capitão Nascimento tem 9975 de HP e 50 de PA -Jogador atacou o boss. Boss ficou com hp: 9950 -Boss atacou o jogador. Jogador ficou com hp: 200 -``` +![Imgur](https://i.imgur.com/qoUUT88.png) -**Está tudo funcionando?** Vamos ver. Parece que o `Zeca Pagodinho` atacou o `Capitão Nascimento` com `25 AD` e a saúde do Capitão Nascimento caiu de `10000` para `9975` o que está certo! Então o Capitão Nascimento ataca o Zeca Pagodinho com `50` de dano de ataque e a saúde do Zeca Pagodinho cai de `300` para `250`. Parece que tudo está funcionando bem :). +**Está tudo funcionando?** Vamos ver. Parece que o `Zeca Pagodinho` atacou o `Capitão Nascimento` com `25 PA` e a saúde do Capitão Nascimento caiu de `10000` para `9975` o que está certo! Então o Capitão Nascimento ataca o Zeca Pagodinho com `50` de dano de ataque e a saúde do Zeca Pagodinho cai de `300` para `250`. Parece que tudo está funcionando bem :). Você pode ver que quando atacamos uma segunda vez, os valores atualizados de HP são usados tanto para o personagem quanto para o boss :). @@ -321,34 +295,10 @@ Sinta-se livre para testar essa função tentando com um boss com `1 de HP` ou u Por exemplo, se eu dou ao jogador `1 HP`, aqui está o resultado: -```plaintext -Terminamos de incializar o boss Capitão Nascimento HP 10000, img https://i.imgur.com/yWpKMDt.png -Terminamos de incializar o Anitta com, img https://i.imgur.com/gC5qXsl.png -Terminamos de incializar o Ronaldinho Gaúcho com, img https://i.imgur.com/NplQpes.png -Terminamos de incializar o Zeca Pagodinho com, img https://i.imgur.com/Pj8lHpM.png -Contrato deployado no endereço: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -NFT Mintado com tokenId 0 e characterId 2 - -Jogador com personagem Zeca Pagodinho ira atacar. Tem 1 HP e 25 de PA -Boss Capitão Nascimento tem 10000 de HP e 50 de PA -Jogador atacou o boss. Boss ficou com hp: 9975 -Boss atacou jogador. Jogador ficou com hp: 0 - -Jogador com personagem Zeca Pagodinho ira atacar. Tem 0 de HP e 25 de PA -Boss Capitão Nascimento tem 9975 de HP e 50 de PA -Error: VM Exception while processing transaction: reverted with reason string 'Error: personagem precisa ter HP para atacar o boss.' - at MyEpicGame.attackBoss (contracts/MyEpicGame.sol:88) - at processTicksAndRejections (node:internal/process/task_queues:96:5) - at runNextTicks (node:internal/process/task_queues:65:3) - at listOnTimeout (node:internal/timers:526:9) - at processTimers (node:internal/timers:500:7) - at HardhatNode._mineBlockWithPendingTxs (/Users/flynn/Developer/epic-game/node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1582:23) - at HardhatNode.mineBlock (/Users/flynn/Developer/epic-game/node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:435:16) - at EthModule._sendTransactionAndReturnHash (/Users/flynn/Developer/epic-game/node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1494:18) -``` +![Imgur](https://i.imgur.com/lLUAoVx.png) Então, você pode ver que o primeiro ataque aconteceu de maneira correta, `Boss atacou jogador. Jogador ficou com hp: 0`. Incrível! Nossa função funcionou perfeitamente. O hp do nosso personagem ia ser negativo, mas foi configurado para `0`! Yay! -Mas, na segunda vez que atacamos, conseguimos um erro com: `Error: personagem precisa ter HP para atacar o boss`. O que está correto!!! Isso é basciamente como devolver um erro na nsosa API quando algo dá errado. +Mas, na segunda vez que atacamos, conseguimos um erro com: `Error: personagem precisa ter HP para atacar o boss`. O que está correto!!! Isso é basciamente como devolver um erro na nossa API quando algo dá errado. -Legal - nossa função `attackBoss` está basicamente feita. Vamos adicionar mais alguma mágica depois mas por agora estamos bem. Nós oficialmente temos nossa lógica de jogo **on-chain** :). \ No newline at end of file +Legal - nossa função `attackBoss` está basicamente feita. Vamos adicionar mais alguma mágica depois mas por agora estamos bem. Nós oficialmente temos nossa lógica de jogo **on-chain** :). From a4288ec452f9417dfa97791ef5cf4fe9d896a686 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Tue, 16 Jan 2024 11:29:44 -0300 Subject: [PATCH 11/21] update: atualizando imagens --- .../Lesson_2_Deploy_And_See_NFTs_Changing.md | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/NFT_Game/pt-br/Section_2/Lesson_2_Deploy_And_See_NFTs_Changing.md b/NFT_Game/pt-br/Section_2/Lesson_2_Deploy_And_See_NFTs_Changing.md index 860eac137..e4b7e51e3 100644 --- a/NFT_Game/pt-br/Section_2/Lesson_2_Deploy_And_See_NFTs_Changing.md +++ b/NFT_Game/pt-br/Section_2/Lesson_2_Deploy_And_See_NFTs_Changing.md @@ -2,7 +2,7 @@ Uma coisa que estamos fazendo que é super importante de se reconhecer é que es Por exemplo, quando fazmos `player.hp = player.hp - bigBoss.attackDamage;` estamos na verdade mudando o atributo de Health Points que aparece no OpenSea na NFT. Vamos testar isso para ter certeza que está funcionando como o esperado! -### 👻 Fazer deploy de novo e ver as NFTs mudando de valor. +### 👻 Fazer deploy de novo e ver as NFTs mudando de valor Copie tudo de `run.js` e sobrescreva o que está em `deploy.js`. Aqui está como o meu `run.js` se parece: @@ -12,18 +12,18 @@ const main = async () => { const gameContract = await gameContractFactory.deploy( ["Anitta", "Ronaldinho Gaúcho", "Zeca Pagodinho"], - [ - "https://i.imgur.com/gC5qXsl.png", - "https://i.imgur.com/0PvxtwP.png", - "https://i.imgur.com/Pj8lHpM.png", - ], - [100, 200, 300], - [100, 50, 25], - "Capitão Nascimento", - "https://i.imgur.com/yWpKMDt.png", - 10000, - 50 - ); + [ + "https://i.imgur.com/gC5qXsl.png", + "https://i.imgur.com/0PvxtwP.png", + "https://i.imgur.com/Pj8lHpM.png", + ], + [100, 200, 300], + [100, 50, 25], + "Capitão Nascimento", + "https://i.imgur.com/yWpKMDt.png", + 10000, + 50 + ); await gameContract.deployed(); console.log("Contrato deployado no endereço:", gameContract.address); @@ -61,7 +61,7 @@ De novo, eu só gosto de manter os dois separados já que `deploy.js` não muda Eu faço o deploy usando `npx hardhat run scripts/deploy.js --network goerli`. A partir daí, aqui está meu output: ```plaintext -Contrato deployado no endereço: 0x02f59Dc14666c4480Ae4b477eFfF15949970dfeA +Contrato deployado no endereço: 0x8c7925f549F055292cbC6cf61F0CDA06AeE2f69B ``` Uma vez que esperar alguns minutos, sites como o OpenSea ou o Rarible devem mostrar sua NFT com o HP atualizado. @@ -70,11 +70,11 @@ Então nesse caso, eu mintei um `Zeca Pagodinho` NFT e fiz ele atacar o `Capitã No OpenSea, aqui está como isso se parece pra mim: -![Zeca](https://i.imgur.com/cMM4CmP.png) +![Zeca](https://i.imgur.com/mlE7F9b.png) Está tudo funcionando como deveria!! Oba!! Zeca Pagodinho perdeu vida!! -Sinta-se livre para ver no Rarible também. Só saiba que o Rarible é um pouco mais lento para mostrar metadados atualizados! `https://goerli.rarible.com/token/INSERT_DEPLOY_CONTRACT_ADDRESS_HERE:INSERT_TOKEN_ID_HERE`. +Sinta-se livre para ver no Rarible também. Só saiba que o Rarible é um pouco mais lento para mostrar metadados atualizados! `https://testnet.rarible.com/token/INSERT_DEPLOY_CONTRACT_ADDRESS_HERE:INSERT_TOKEN_ID_HERE`. ![Zeca](https://i.imgur.com/LX0knuU.png) @@ -82,8 +82,8 @@ Sinta-se livre para ver no Rarible também. Só saiba que o Rarible é um pouco **Nota 2:** Eu devo mencionar que a NFT é atualizada imediatamente no contrato uma vez que `attackBoss` é minerado, mas esses third-party como OpenSea e o Rarible tem suas próprias mecânicas de caching. -### 👑 Você deixou cair isso. +### 👑 Você deixou cair isso VOCÊ CONSEGUIU! -Isso é uma grande coisa, conseguimos oficialmente construir uma **NFT interativa.** Coisa boa :). \ No newline at end of file +Isso é uma grande coisa, conseguimos oficialmente construir uma **NFT interativa.** Coisa boa :). From faca56852b30ae9a6f19c059a87760051e4afdb9 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Tue, 16 Jan 2024 11:44:36 -0300 Subject: [PATCH 12/21] =?UTF-8?q?update:=20atualizando=20bloco=20de=20c?= =?UTF-8?q?=C3=B3digo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Lesson_3_Adding_Utility_Functions.md | 67 ++++++++----------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/NFT_Game/pt-br/Section_2/Lesson_3_Adding_Utility_Functions.md b/NFT_Game/pt-br/Section_2/Lesson_3_Adding_Utility_Functions.md index fdbe03c8c..4a6ef9a8d 100644 --- a/NFT_Game/pt-br/Section_2/Lesson_3_Adding_Utility_Functions.md +++ b/NFT_Game/pt-br/Section_2/Lesson_3_Adding_Utility_Functions.md @@ -1,6 +1,6 @@ Abaixo eu vou passar por algumas funções. Elas não vão parecer muito úteis por agora, mas vão ser absurdamente úteis quando formos trabalhar no nosso web app. -### ✅ Construir função para checar se o usuário tem a NFT. +### ✅ Construir função para checar se o usuário tem a NFT Nós precisamos de uma maneira de checar se o usuário tem um personagem NFT que demos a ele, e depois recuperar os atributos da NFT se ela existir. Por quê? @@ -38,7 +38,7 @@ Por que fazemos `userNftTokenId > 0`? Bom, basicamente [não tem outro jeito](ht Esse é um problema para o usuário que tem a NFT com o tokenId `0`. Aí está o motivo do porque eu fiz `_tokenIds.increment()` antes no constructor! Dessa maneira, **ninguém está permitido a ter o tokenID 0.** Esse é um dos casos em que precisamos ser espertos para configurar nosso código por causa de algumas especificidades do Solidity :). -### 🎃 Recuperando os personagens padrão. +### 🎃 Recuperando os personagens padrão Nosso web app vai ter uma "tela de selecionar personagem" para novos jogadores para que eles possam escolher qual personagem NFT eles querem mintar! @@ -52,9 +52,9 @@ function getAllDefaultCharacters() public view returns (CharacterAttributes[] me Você deve estar se perguntando, "Porque estamos construindo funções para pegar variáveis sozinhas? Não podemos acessar elas diretamente do contrato?". Sim, você pode! Mas, é uma boa prática criar funções `get` :). Isso faz tudo organizado. -### 💀 Recuperando o boss. +### 💀 Recuperando o boss -Precisamos poder recuperar o boss. Por quê? Bom - quando nosso jogador estiver jogando o nosso jogo, o nosso ap vai precisar estar apto a mostrar coisas para ele, como o HP do boss, o nome, a imagem e etc! +Precisamos poder recuperar o boss. Por quê? Bom - quando nosso jogador estiver jogando o nosso jogo, o nosso Dapp vai precisar estar apto a mostrar coisas para ele, como o HP do boss, o nome, a imagem e etc! Essa também é uma função bem fácil de escrever: @@ -66,7 +66,7 @@ function getBigBoss() public view returns (BigBoss memory) { É isso! -### 🧠 Adicionando `Event` no nosso contrato. +### 🧠 Adicionando `Event` no nosso contrato Quando chamamos `mintCharacterNFT`, como vamos saber se foi **feito**? Quando fazemos: @@ -112,50 +112,41 @@ Tudo o que precisamos fazer é adicionar essa linha no final da função `attack emit AttackComplete(bigBoss.hp, player.hp); ``` -### ➡️ Fazendo Deploy das mudanças. +### ➡️ Fazendo Deploy das mudanças Muito bom! Agora adicionamos as funções que nosso web app vai usasr no nosso jogo! Estamos caminhando para um jogo incrível! Lembre-se que precisamos fazer o deploy do contrato de novo para usarmos essas funções. -Antes de irmos para o nosso web app, vamos precisar ter certeza de que temos um contrato limpo e pornto. Vamos ter certeza de que nosso arquivo de deploy não minte nenhum personagem ou faça algum ataque. +Antes de irmos para o nosso web app, vamos precisar ter certeza de que temos um contrato limpo e pronto. Vamos ter certeza de que nosso arquivo de deploy não minte nenhum personagem ou faça algum ataque. Aqui está meu arquivo `deploy.js` depois que removi as NFTs mintadas e os ataques do nosso último deploy: ```javascript -const main = async () => { +async function main() { const gameContractFactory = await hre.ethers.getContractFactory("MyEpicGame"); - const gameContract = await gameContractFactory.deploy( ["Anitta", "Ronaldinho Gaúcho", "Zeca Pagodinho"], - [ - "https://i.imgur.com/gC5qXsl.png", - "https://i.imgur.com/0PvxtwP.png", - "https://i.imgur.com/Pj8lHpM.png", - ], - [100, 200, 300], - [100, 50, 25], - "Capitão Nascimento", - "https://i.imgur.com/yWpKMDt.png", - 10000, - 50 - ); - - await gameContract.deployed(); - console.log("Contrato deployado no endereço:", gameContract.address); -}; - -const runMain = async () => { - try { - await main(); - process.exit(0); - } catch (error) { - console.log(error); - process.exit(1); - } -}; + [ + "https://i.imgur.com/gC5qXsl.png", + "https://i.imgur.com/0PvxtwP.png", + "https://i.imgur.com/Pj8lHpM.png", + ], + [100, 200, 300], // Pontos de vida + [100, 50, 25], // Dando de ataque + "Capitão Nascimento", + "https://i.imgur.com/yWpKMDt.png", + 10000, // Pontos de vida do boss + 50 // Dando de ataque do boss + ); + console.log("Contrato deployado no endereço:", gameContract.target); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); -runMain(); ``` -Tudo o que sobrou é fazer o deploy usando `npx hardhat run scripts/deploy.js --network goerli`. Lembre-se de salvar o endereço do seu contrato para a próxima seção. +Tudo o que sobrou é fazer o deploy usando `npx hardhat run scripts/deploy.js --network sepolia`. Lembre-se de salvar o endereço do seu contrato para a próxima seção. -É isso :). Vamos para o nosso web app! \ No newline at end of file +É isso :). Vamos para o nosso web app! From 0deeecb5f012ae011e1b744c003207f2393ba254 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Tue, 16 Jan 2024 21:09:52 -0300 Subject: [PATCH 13/21] update: atualizando links --- .../pt-br/Section_3/Lesson_1_Getting_The_Code.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/NFT_Game/pt-br/Section_3/Lesson_1_Getting_The_Code.md b/NFT_Game/pt-br/Section_3/Lesson_1_Getting_The_Code.md index cd73d2ca9..9c6484ceb 100644 --- a/NFT_Game/pt-br/Section_3/Lesson_1_Getting_The_Code.md +++ b/NFT_Game/pt-br/Section_3/Lesson_1_Getting_The_Code.md @@ -4,11 +4,11 @@ Aqui é onde a diversão **realmente** começa. Escrever e fazer o deploy do con Nós vamos usar **react.js** para construir nosso web app. Se você já estiver familiarizado com o React, isso vai ser fácil. Se você não fez muita coisa com React, não se preocupe! Você ainda pode passar por esse projeto, mas você pode sentir um pouco mais de dificuldade. Não desista! Quanto mais você luta mais você aprende 🧠. -Se você não tiver nenhuma experiência com React - [cheque essa série de introdução](https://scrimba.com/learn/learnreact) antes que você comece essa seção ou cheque essa [documentação de introdução](https://reactjs.org/docs/getting-started.html). Ou não faça nada especial, só vá em frente. O que funcionar pra você :). Você vai ser um mago do React depois desse projeto, se já não for agora 🧙‍♂! +Se você não tiver nenhuma experiência com React - [cheque essa série de introdução](https://scrimba.com/learn/learnreact) antes que você comece essa seção ou cheque essa [documentação de introdução](https://react.dev/learn). Ou não faça nada especial, só vá em frente. O que funcionar pra você :). Você vai ser um mago do React depois desse projeto, se já não for agora 🧙‍♂! -### ⬇️ Pegando o código. +### ⬇️ Pegando o código -Nós vamos estar usando essa coisa chamada [Replit](https://replit.com/~)! +Nós vamos estar usando essa coisa chamada [Replit](https://replit.com/)! É uma IDE baseada em navegador que nos deixa facilmente construir web apps e fazer o deploy deles a partir do navegador. É bem legítimo. Ao invés de configurar um ambiente local inteiro e escrever comandos para fazer deploy, é tudo dado para nós. @@ -16,12 +16,12 @@ Nota: **Você não tem que usar replit para construir + fazer deploy do seu site Crie uma conta no Replit antes de ir em frente. -Eu já criei um projeto básico em react que você pode fazer o **fork** no Replit. **[Nesse link](https://replit.com/@DanielCukier/nft-game-web3dev), e perto da direita você verá um botão de "Remix Project".** Esteja certo de estar logado, e clique nisso. +Eu já criei um projeto básico em react que você pode fazer o **fork** no Replit. **[Nesse link](https://replit.com/@viniblack/nft-game-web3dev), e perto da direita você verá um botão de "Remix Project".** Esteja certo de estar logado, e clique nisso. Você irá magicamente clonar meu repositório e a IDE inteira no seu navegador para trabalhar com o código. Uma vez que parar de carregar e mostrar algum código, clique em "run" na parte de cima e pronto. Pode levar de 2-4 minutos na primeira vez. -\*\*Nota: ao longo desse projeto, você pode notar que estamos referenciando arquivos `.js`. No Replit, se você estiver criando um arquivo JavaScript novo, você deve usar a extensão `.jsx` ao invés disso! O replit tem umas exigências chiques que precisam do arquivo `.jsx` :). +> 💡**Nota:** ao longo desse projeto, você pode notar que estamos referenciando arquivos `.js`. No Replit, se você estiver criando um arquivo JavaScript novo, você deve usar a extensão `.jsx` ao invés disso! O replit tem umas exigências chiques que precisam do arquivo `.jsx` :). Aqui está um vídeo rápido que fiz para um outro projeto passando por algumas coisas básicas do Replit: -[Loom](https://www.loom.com/share/4578eb9fba1243499a6913d214b21dc3) \ No newline at end of file +[Loom](https://www.loom.com/share/4578eb9fba1243499a6913d214b21dc3) From f6008e6bbec09a455abe392294f40c1b65e9223c Mon Sep 17 00:00:00 2001 From: Vini Black Date: Wed, 17 Jan 2024 11:43:30 -0300 Subject: [PATCH 14/21] update: atualizando gif --- ...Lesson_2_Building_Connect_Wallet_Button.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/NFT_Game/pt-br/Section_3/Lesson_2_Building_Connect_Wallet_Button.md b/NFT_Game/pt-br/Section_3/Lesson_2_Building_Connect_Wallet_Button.md index 65dc4dc73..6233da746 100644 --- a/NFT_Game/pt-br/Section_3/Lesson_2_Building_Connect_Wallet_Button.md +++ b/NFT_Game/pt-br/Section_3/Lesson_2_Building_Connect_Wallet_Button.md @@ -2,12 +2,12 @@ Então, para conseguir que o nosso site fale com a blockchain, precisamos de alguma maneira conectar nossa carteira nele. Uma vez que conectarmos nossa carteira no website, nosso site terá a permissão de chamar um contrato inteligente no nosso comportamento. **Lembre-se, é como fazer a autenticação dentro de um site.** -Vá para o seu código e entre em `App.js` embaixo de `src`. Aí é o ponto de entrada principal do nosso site será feito. +Vá para o seu código e entre em `App.jsx` dentro da pasta `src`. Aí é o ponto de entrada principal do nosso site será feito. Se estivermos logados no MetaMask, ele vai injetar automaticamente um objeto chamado `ethereum` dentro da nossa janela que tem alguns métodos mágicos. Vamos checar se temos isso primeiro: ```javascript -import React, { useEffect } from "react"; +import { useEffect } from "react"; import "./App.css"; import twitterLogo from "./assets/twitter-logo.svg"; @@ -50,7 +50,7 @@ const App = () => {
Monty Python Gif
@@ -87,7 +87,7 @@ Cheque o código abaixo: /* * Nós vamos precisar usar estados agora! Não esqueça de importar useState */ -import React, { useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import "./App.css"; import twitterLogo from "./assets/twitter-logo.svg"; @@ -146,7 +146,7 @@ const App = () => {

Junte os amigos e proteja o Metaverso!!

Nascimento Gif
@@ -180,7 +180,7 @@ Pronto para a experiência de login mais fácil da sua vida? /* * Nós vamos precisar usar estados agora! Não esqueça de importar useState */ -import React, { useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import "./App.css"; import twitterLogo from "./assets/twitter-logo.svg"; @@ -269,7 +269,7 @@ const App = () => {

Junte os amigos e proteja o Metaverso!!

Nascimento Gif {/* @@ -302,9 +302,8 @@ export default App; Clique seu novo botão chique e você deve ver sua extensão Chrome do Metamask aparecer. Boa! -![Untitled](https://i.imgur.com/8pJqLFd.png) +![Imgur](https://i.imgur.com/UgGfTei.png) - -## 🚨 Reporte seu Progresso! +## 🚨 Reporte seu Progresso Em #progresso, poste uma screenshot do seu site muito chique e não se esqueça de mudar seus GIFs e títulos para ficar algo mais a sua cara. Faça do SEU jeito! From 04389c7f8912add8ea7cf759dfbcca6a9476bf26 Mon Sep 17 00:00:00 2001 From: Vini Black Date: Wed, 17 Jan 2024 12:35:28 -0300 Subject: [PATCH 15/21] update: melhorando texto --- .../pt-br/Section_3/Lesson_1_Getting_The_Code.md | 2 +- .../Lesson_3_Setting_Up_Initial_App_State.md | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/NFT_Game/pt-br/Section_3/Lesson_1_Getting_The_Code.md b/NFT_Game/pt-br/Section_3/Lesson_1_Getting_The_Code.md index 9c6484ceb..43ca689f9 100644 --- a/NFT_Game/pt-br/Section_3/Lesson_1_Getting_The_Code.md +++ b/NFT_Game/pt-br/Section_3/Lesson_1_Getting_The_Code.md @@ -12,7 +12,7 @@ Nós vamos estar usando essa coisa chamada [Replit](https://replit.com/)! É uma IDE baseada em navegador que nos deixa facilmente construir web apps e fazer o deploy deles a partir do navegador. É bem legítimo. Ao invés de configurar um ambiente local inteiro e escrever comandos para fazer deploy, é tudo dado para nós. -Nota: **Você não tem que usar replit para construir + fazer deploy do seu site. Se você quiser trabalhar localmente no VSCode e usar Vercel/Heroku/AWS para fazer o deploy e está confiante de suas habilidades em desenvolvimento web -- isso está legal. [Aqui está o link](https://github.com/w3b3d3v/nft-game-web3dev) para o repositório base que você pode clonar e trabalhar localmente.** +> 💡**Nota:** **Você não tem que usar replit para construir + fazer deploy do seu site. Se você quiser trabalhar localmente no VSCode e usar Vercel/Heroku/AWS para fazer o deploy e está confiante de suas habilidades em desenvolvimento web -- isso está legal. [Aqui está o link](https://github.com/w3b3d3v/nft-game-web3dev) para o repositório base que você pode clonar e trabalhar localmente.** Crie uma conta no Replit antes de ir em frente. diff --git a/NFT_Game/pt-br/Section_3/Lesson_3_Setting_Up_Initial_App_State.md b/NFT_Game/pt-br/Section_3/Lesson_3_Setting_Up_Initial_App_State.md index 2c752bb51..a1ca36567 100644 --- a/NFT_Game/pt-br/Section_3/Lesson_3_Setting_Up_Initial_App_State.md +++ b/NFT_Game/pt-br/Section_3/Lesson_3_Setting_Up_Initial_App_State.md @@ -10,7 +10,7 @@ Essa seção vai te ajudar a entender como vamos renderizar cada estado do nosso Boa. Parece que nós temos três visões diferentes que precisamos criar! Nós vamos ver algumas coisas bem legais de React.js que podem ser novas pra você. Se você não entende isso completamente - **não se preocupe**! Faça algumas pesquisas e lembre-se o Google é seu amigo :). -### 🧱 Configurando o componente SelectCharacter. +### 🧱 Configurando o componente SelectCharacter Vamos começar criando nosso componente `SelectCharacter`! Vá para a pasta `src/Components/SelectCharacter` e crie um novo arquivo chamado `index.js`. Esse diretório terá a nossa lógica principal para o nosso componente `SelectCharacter` e seu estilo! Você deve ver um arquivo `SelectCharacter.css` com várias estilizações! @@ -38,7 +38,7 @@ export default SelectCharacter; Muito bom! Viu como foi fácil? Você já tem um componente pronto! Vamos em frente e configurar nossa renderização condicional para que possamos ver essa coisa. -### 👁 Mostrando o componente SelectCharacter. +### 👁 Mostrando o componente SelectCharacter Nós vamos precisar voltar para `App.js` e importar nosso novo componente. Logo abaixo de onde você importou `App.css`, adicione essa linha: @@ -75,7 +75,7 @@ const renderContent = () => { return (
Nascimento Gif