WEB3DEV

Cover image for Um NFT que recebe um histórico de informações, como fazer em solidity?
Anderson Campolina
Anderson Campolina

Posted on • Atualizado em

Um NFT que recebe um histórico de informações, como fazer em solidity?

Olá terráqueos. Me surgiu uma ideia, e com ela uma proposta de trabalho. Descobri que com esforço, se realiza qualquer coisa. Recentemente descobri outra coisa: uma comunidade unida muda vidas. É muito gratificante poder compartilhar conhecimento e aprender no processo, não é verdade?

Pois bem, a minha ideia, que se refere ao título, foi humildemente colocada em prática pelo modesto código abaixo:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

contract Carteirinha {
    address public minter;
    struct Torcedor {
        uint256 cpf;
        string nome;
        string email;
    }

    struct Historico {
        string conquista;
    }

    // criando uma array do tipo objeto torcedor e historico.
    Torcedor[] public torcedor;
    Historico[] public historico;

    mapping(uint256 => address) public donoCarteirinha;
    mapping(address => uint256) public qtdCarteirinha;

    event Sent(address from, address to, uint256 _cpf);

    constructor() {
        minter = msg.sender; // Grava endereço de quem criou o NFT na variavel minter
    }

    function _exists(uint256 _cpf) internal view returns(bool) {
        address owner = donoCarteirinha[_cpf]; // adiciona o endereço do dono indicado pelo ID na variavel owner
        return owner != address(0); // retorna se este endereço NÃO é um address inválido ou vazio. (true or false)
    }

    function adicionarTorcedor(uint256 _cpf, string memory _nome, string memory _email) public {
        require(qtdCarteirinha[msg.sender] == 0, "ERRO: Carteirinha ja foi criada para esse ID"); // Limita a quantidade de carteirinhas por ID (CPF) para apenas uma.
        require(!_exists(_cpf), "ERRO: Carteirinha ja existe"); // verifica se o token ainda nao foi gerado pelo ID informado, pois so pode haver 1 por CPF
        require(msg.sender == minter); // Se o msg.sender é de fato quem criou o contrato
        donoCarteirinha[_cpf] = msg.sender; // quem está mintando a carteirinha será que receberá a carteirinha oficialmente
        qtdCarteirinha[msg.sender] += 1; // armazena a quantidade de NFTs que o endereço tem
        torcedor.push(Torcedor(_cpf, _nome, _email)); // adiciona os parametros passados na funcao para dentro da array Torcedor[]
    }

    function adicionarConquistaHistorico(string memory _conquista) public {
        historico.push(Historico(_conquista));
    }

    function _ownerOf(uint256 _cpf) internal view returns(address) {
        address owner = donoCarteirinha[_cpf];
        require(owner != address(0), "ERRO: Token invalido");
        return owner;
    }

    function send(address receiver, uint256 _cpf) public {
        require(_ownerOf(_cpf) == msg.sender);
        require(receiver != address(0), "ERRO: Receiver Invalido");
        donoCarteirinha[_cpf] = receiver;
        qtdCarteirinha[receiver] += 1;
        qtdCarteirinha[msg.sender] -= 1;
        emit Sent(msg.sender, receiver, _cpf);
    }
}
Enter fullscreen mode Exit fullscreen mode

O que eu precisava, era deixar esse código pronto para produção, com adaptações de segurança pelo @openzeppelin e outras libs, em padrão ERC721, com os dados dos torcedores imutáveis, e com um objeto/array de histórico de conquistas, como "comprou camisa" e "comprou ingresso" e um incremento de pontuação (bônus) para serem usados na webstore frontend posteriormente.

Também criei um outro contrato separado, para mintar esse NFT, e precisava buscar por ele tb, os dados que foram cadastrado em cada NFT e armazenado em uma Array com todos os endereços dos possuidores do NFT. Consegui concretizar tal código, porém, de maneira muito inicial e sem proteção. Por algum motivo, não consegui realizar as funções de leitura (get) dos dados do NFT dentro da array. Somente dentro de variáveis isoladas. Mas como preciso acessar a array do Historico[], me senti, e me sinto frustrado por ainda não ter conseguido realizar este simples código, que é de ler uma array de outro contrato.

Segue abaixo, o codigo em solidity deste outro contrato de mint:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.15;

//o objetivo do FabricaCarteirinha é fazer deploys e interações do contrato carteirinha.sol atravez de funções chamadas neste contrato.

// importando o contrato Carteirinha criado anteriormente:
import "./Carteirinha.sol";

//contract FabricaCarteirinha is Carteirinha { -> se colocar assim, herda todas as funçoes do Carteirinha() + as funcoes do FabricaCarteirinha() juntas.
contract FabricaCarteirinha {

    Carteirinha[] public carteirinhaArray;

    function criarCarteirinha() public {
        //fazendo deploy (gerando uma carteirinha) e ao mesmo tempo, declarando objeto do tipo Carteirinha para usar neste contrato:
        Carteirinha carteirinha = new Carteirinha();       
        //armazena o endereço do contrato criado que foi feito deploy, no ultimo lugar da lista, nesse caso, posiçao 0.
        //pensei em usar CPF como index, mas pode cer celular, email, etc...
        carteirinhaArray.push(carteirinha); // ISSO RETORNA O ENDEREÇO HASH DO NFT / CARTEIRINHA CRIADO - ARMAZENAR EM BANCO DE DADOS SQL
    }

    // passa os dados pelos parametros _simpleStoreIndex, que será 0 (posiçao da lista simpleStorageArray), e numero favorito, chamando a funçao '.store()' do contrato SimpleStorage(), e essa funcao pode ser publica
    function fcAdicionarTorcedor(uint256 _carteirinhaArrayIndex, uint256 _cpf, string memory _nome, string memory _email) public payable {
        //SimpleStorage(0xd840735F4B6a0d1AF8Fa48EcE560f4778c007397.adicionarTorcedor(01235546675, anso, rua araponga 50, 31986793422, [email protected]) - os dados são passados dando o numero do contrato  + "." + função, no caso, a .store.
        Carteirinha(address(carteirinhaArray[_carteirinhaArrayIndex])).adicionarTorcedor(_cpf, _nome, _email);   
    }

    function fcAdicionarHistorico(uint256 _carteirinhaArrayIndex, string memory _conquista) public payable {
        Carteirinha(address(carteirinhaArray[_carteirinhaArrayIndex])).adicionarConquistaHistorico(_conquista);   
    }
}
Enter fullscreen mode Exit fullscreen mode

Quero que saibam que, qualquer ajuda, terei uma gratidão enorme e pretendo ajudar a comunidade com o que puder. É a oportunidade da minha vida :-)

Top comments (0)