Staking de NFTs en Solidity
Ahmed Castro
Posted on October 12, 2021
El Staking de NFTs es un trend que está conectando los nuevos proyectos de NFTs con el resto del ecosistema DeFi. El staking ha demostrado ser un mecanismo que incentiva comprar y holdear por lo que pienso que es bastante prometedor combinarlo con mundo de los NFTs.
Qué necesitas para este tutorial
Para este tutorial necetias tener instalado Metamask y tener fondos en Rinkeby que puedes conseguir desde el faucet.
1. Lanzamos un contrato de NFTs
Este es un ejemplo mínimo de colección de ERC-721 solo con fines únicamente educativos.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyNFTCollection is ERC721 {
uint256 token_count;
constructor() ERC721("My NFT", "MYNFT") {}
function mintNFT(address to) public
{
_mint(to, token_count);
token_count += 1;
}
}
2. Lanzamos el toquen que premia por Stakear
Asegurate de reemplazar 0x0000000000000000000000000000000000000000
por el address del contrato ERC-721.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import '@openzeppelin/contracts/token/ERC20/ERC20.sol';
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyNFTLiquidityPool is ERC20
{
mapping(address => uint256) public checkpoints;
mapping(address => uint256) public deposited_tokens;
mapping(address => bool) public has_deposited;
ERC721 public my_token;
uint public REWARD_PER_BLOCK = 0.1 ether;
constructor() ERC20("My Staking Token", "MYST"){
my_token = ERC721(0x0000000000000000000000000000000000000000);
}
function deposit(uint256 tokenId) external
{
require (msg.sender == my_token.ownerOf(tokenId), 'Sender must be owner');
require (!has_deposited[msg.sender], 'Sender already deposited');
if(checkpoints[msg.sender] == 0){
checkpoints[msg.sender] = block.number;
}
collect(msg.sender);
my_token.transferFrom(msg.sender, address(this), tokenId);
deposited_tokens[msg.sender] = tokenId;
has_deposited[msg.sender] = true;
}
function withdraw() external
{
require(has_deposited[msg.sender], 'No tokens to withdarw');
collect(msg.sender);
my_token.transferFrom(address(this), msg.sender, deposited_tokens[msg.sender]);
has_deposited[msg.sender] = false;
}
function collect(address beneficiary) public
{
uint256 reward = calculateReward(beneficiary);
checkpoints[beneficiary] = block.number;
_mint(msg.sender, reward);
}
function calculateReward(address beneficiary) public view returns(uint256)
{
if(!has_deposited[beneficiary])
{
return 0;
}
uint256 checkpoint = checkpoints[beneficiary];
return REWARD_PER_BLOCK * (block.number-checkpoint);
}
}
¡Gracias por ver este tutorial!
Sígueme en dev.to y en [Youtube]
(https://www.youtube.com/channel/UCNRB4tgwp09z4391JRjEsRA) para todo lo relacionado al desarrollo en Blockchain en Español.
Updates
23/06/2022 Gracias a Yerson corregimos la función calculateReward
Posted on October 12, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.