WEB3DEV

Cover image for Crie Um Contrato Inteligente ERC721 NFT De Staking + Web App
Banana Labs
Banana Labs

Posted on

Crie Um Contrato Inteligente ERC721 NFT De Staking + Web App

capa

Neste guia, mostraremos como criar e implantar um contrato inteligente de staking de NFT, onde as pessoas podem fazer stake de seus NFTs e ganhar recompensas.

Vamos percorrer este tópicos:

  1. Criando o contrato inteligente ERC721 NFT
  2. Criando o contrato inteligente de token ERC20
  3. Criando o contrato inteligente de staking
  4. Construindo um aplicativo web front-end para interagir com o contrato

Vamos começar!

Implante Um Contrato Inteligente Drop NFT ERC721

Se você ainda não possui um contrato inteligente de coleta de NFT, pode usar o guia abaixo para começar a usar uma coleta de NFT ERC721A otimizada para gás:

🔗https://blog.thirdweb.com/guides/how-to-create-and-setup-a-claimable-nft-drop-on-optimism/

💡 O guia acima usa o Optimism, mas você pode usar qualquer uma de nossas redes suportadas.

Os tokens (NFTs) neste contrato inteligente são o que os usuários apostarão para ganhar recompensas de token ERC20.

Implante um Contrato Inteligente De Token ERC20

Em seguida, vamos implantar um contrato inteligente de token ERC20, que representa o token que os usuários serão recompensados por apostar em seus NFTs!
Se você ainda não possui um contrato inteligente ERC20, vá para a página Explorar e clique no contrato Token. Clique em Deploy Now para iniciar o fluxo de implantação:

Token

Configure seu contrato inteligente com uma imagem, nome, descrição etc. e configure qual endereço de carteira receberá os fundos das vendas primárias e secundárias.

Certifique-se de implantar isso na mesma rede que sua coleção NFT.

Cunhagem da Oferta de Token ERC20

A maneira como o contrato inteligente NFTStake.sol funciona é transferindo tokens para o usuário quando ele reivindica suas recompensas. Por esse motivo, precisamos fornecer ao contrato inteligente de staking um suprimento de tokens para transferência.

Então, vamos cunhar alguns tokens em nosso contrato inteligente ERC20 e transferi-los para o contrato de staking agora. Para fazer isso, vá para a guia Tokens e clique em Mint.

Guia Tokens
Clique em "Mint" para criar um suprimento adicional de seu token.

Insira um valor e clique em Mint tokens:

Mint tokens

Implante um Contrato Inteligente NFT Staking

Agora, passaremos para a parte emocionante e implantaremos o contrato de staking propriamente dito!

Vá para a página de contrato inteligente do NFTStake e clique em Deploy Now:

NFTStake

Agora você precisará fornecer algumas configurações para o seu contrato de staking. Você pode usar as informações abaixo de cada campo para ajudá-lo a entender com quais valores você precisa preenchê-los.

Quando estiver pronto, clique em Deploy Now

Depositar Token ERC20

Volte para o seu contrato inteligente ERC20 e aprove tokens para o seu endereço de contrato inteligente recém-implantado para gastar.

Vá para a guia explorar em seu contrato de Token e clique na função approve. Vamos permitir que o contrato de staking gaste (quantidade) de tokens para que ele possa pagar recompensas aos stakers.

Insira o endereço do seu contrato de staking e um valor que considere adequado, clique em Execute e aprove a transação.

Aprove

Por fim, vá para a guia explore do contrato Staking.

Aqui, você verá uma função depositRewardTokens. Esta é a função que vamos usar para suprir nosso contrato de staking com fundos para distribuir como recompensas.

Adicione a quantidade de tokens que deseja depositar no endereço do contrato de staking.

Deposit

Uma vez feito clique em execute e você está pronto para seguir!

Criando um Aplicativo Web Staking

Agora vamos criar um aplicativo da web NFT staking onde os usuários podem conectar suas carteiras, fazer stake/retirar NFTs e reivindicar recompensas.

Antes de começarmos, você pode acessar o código-fonte completo deste modelo no GitHub.

Usando a CLI da thirdweb, crie um novo projeto Next.js & TypeScript com o React SDK pré-configurado para você, usando o seguinte comando:

npx thirdweb create app --next --ts
Enter fullscreen mode Exit fullscreen mode

Por padrão, a rede é Mainnet, você precisará alterá-la para a rede em que implantou seus contratos inteligentes dentro do arquivo _app.tsx.

// Este é o chainId em que seu dApp funcionará.
const activeChainId = ChainId.Goerli;
Enter fullscreen mode Exit fullscreen mode

Mostrando NFTs de Propriedade Da Carteira Conectada

Primeiro, mostraremos os NFTs que a pessoa possui e permitiremos que eles façam stake com um botão. Vamos editar a página index.tsx para adicionar essa lógica.

Obtendo os tokens:

const address = useAddress();
const { contract: nftDropContract } = useContract(
  nftDropContractAddress,
  "nft-drop"
);

const { data: ownedNfts } = useOwnedNFTs(nftDropContract, address);
Enter fullscreen mode Exit fullscreen mode

Renderizando:

<div>
  {ownedNfts?.map((nft) => (
    <div key={nft.metadata.id.toString()}>
      <ThirdwebNftMedia metadata={nft.metadata} />
      <h3>{nft.metadata.name}</h3>
      <Web3Button
        contractAddress={stakingContractAddress}
        action={() => stakeNft(nft.metadata.id)}
      >
        Stake
      </Web3Button>
    </div>
  ))}
</div>
Enter fullscreen mode Exit fullscreen mode

Estamos usando o componente ThirdwebNftMedia da thirdweb para exibir o NFT e também precisamos criar uma função stakeNft que solicitará que o usuário faça o stake do NFT:

const { contract, isLoading } = useContract(stakingContractAddress);

async function stakeNft(id: string) {
  if (!address) return;

  const isApproved = await nftDropContract?.isApproved(
    address,
    stakingContractAddress
  );
  if (!isApproved) {
    await nftDropContract?.setApprovalForAll(stakingContractAddress, true);
  }
  await contract?.call("stake", [id]);
}
Enter fullscreen mode Exit fullscreen mode

Mostrando os NFTs em stake

Agora que fizemos o stake de nosso NFT, também precisamos exibir os NFTs em stake, então, para isso, criaremos um novo componente. Portanto, crie um novo arquivo components/NFTCard.tsx e adicione o seguinte:

import {
  ThirdwebNftMedia,
  useContract,
  useNFT,
  Web3Button,
} from "@thirdweb-dev/react";
import type { FC } from "react";
import {
  nftDropContractAddress,
  stakingContractAddress,
} from "../consts/contractAddresses";

interface NFTCardProps {
  tokenId: number;
}

const NFTCard: FC<NFTCardProps> = ({ tokenId }) => {
  const { contract } = useContract(nftDropContractAddress, "nft-drop");
  const { data: nft } = useNFT(contract, tokenId);

  return (
    <>
      {nft && (
        <div>
          {nft.metadata && <ThirdwebNftMedia metadata={nft.metadata} />}
          <h3>{nft.metadata.name}</h3>
          <Web3Button
            action={(contract) => contract?.call("withdraw", [nft.metadata.id])}
            contractAddress={stakingContractAddress}
          >
            Withdraw
          </Web3Button>
        </div>
      )}
    </>
  );
};
export default NFTCard;
Enter fullscreen mode Exit fullscreen mode

Isso nos dá um bom cartão para mostrar nossos NFTs em stake. Agora, em pages/stake.tsx vamos pegar os stakedTokenIds e exibir isso:

const { data: stakedTokens } = useContractRead(
  contract,
  "getStakeInfo",
  address
);

<div>
  {stakedTokens &&
    stakedTokens[0]?.map((stakedToken: BigNumber) => (
      <NFTCard tokenId={stakedToken.toNumber()} key={stakedToken.toString()} />
    ))}
</div>
Enter fullscreen mode Exit fullscreen mode

Aqui, como você pode ver, estamos usando outra função chamada withdraw, então vamos escrever isso também:

async function withdraw(id: string) {
  await contract?.call("withdraw", [id]);
}
Enter fullscreen mode Exit fullscreen mode

Mostrar recompensas resgatáveis

const [claimableRewards, setClaimableRewards] = useState<BigNumber>();

useEffect(() => {
  if (!contract || !address) return;

  async function loadClaimableRewards() {
    const stakeInfo = await contract?.call("getStakeInfo", address);
    setClaimableRewards(stakeInfo[1]);
  }

  loadClaimableRewards();
}, [address, contract]);
Enter fullscreen mode Exit fullscreen mode

Isso obterá o stakeInfo do contrato e definirá as recompensas.

Para renderiza-lo, precisamos formatá-lo assim:

<p>
  {!claimableRewards
    ? "Loading..."
    : ethers.utils.formatUnits(claimableRewards, 18)}
</p>
Enter fullscreen mode Exit fullscreen mode

Reivindicando recompensas

Para permitir que os usuários reivindiquem as recompensas, criaremos um botão e anexaremos uma função a ele.

<Web3Button
  action={() => claimRewards([])}
  contractAddress={stakingContractAddress}
>
  Claim Rewards
</Web3Button>
Enter fullscreen mode Exit fullscreen mode

E obtenha a função do gancho useContractWrite:

const { mutateAsync: claimRewards } = useContractWrite(
  contract,
  "claimRewards"
);
Enter fullscreen mode Exit fullscreen mode

Conclusão

Este guia nos ensinou como permitir que seus usuários façam stake dos NFTs que possuem e ganhem recompensas pelo staking!
Se você fez o mesmo, dê um tapinha nas suas costas e compartilhe conosco no Discord da thirdweb! Se você quiser dar uma olhada no código, confira o Repositório do GitHub.


Esse artigo é uma tradução feita por @bananlabs. Você pode encontrar o artigo original aqui

Top comments (0)