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:
- Criando o contrato inteligente ERC721 NFT
- Criando o contrato inteligente de token ERC20
- Criando o contrato inteligente de staking
- 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:
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.
Clique em "Mint" para criar um suprimento adicional de seu token.
Insira um valor e clique em 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
:
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.
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.
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
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;
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);
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>
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]);
}
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;
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>
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]);
}
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]);
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>
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>
E obtenha a função do gancho useContractWrite
:
const { mutateAsync: claimRewards } = useContractWrite(
contract,
"claimRewards"
);
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
Oldest comments (0)