Pular para o conteúdo principal
Change page

ERC-721 Padrão de token não-fungível

Última atualização da página: 25 de fevereiro de 2026

Introdução

O que é um Token Não Fungível?

Um token não fungível (NFT) é utilizado para identificar algo ou alguém de uma forma única. Este tipo de token é perfeito para ser usado em plataformas que oferecem itens colecionáveis, acessar chaves, bilhetes de loteria, assentos numerados para concertos, jogos esportivos etc. Este tipo especial de token tem possibilidades incríveis, então merece um padrão adequado, o ERC-721!

O que é ERC-721?

O ERC-721 apresenta um padrão para NFT. Em outras palavras, este tipo de token é único e pode ter um valor diferente do que outro token do mesmo contrato inteligente, talvez devido a sua validade, raridade ou mesmo sua aparência. Um momento, aparência?

Sim! Todos os NFTs têm uma variável uint256 chamada tokenId, então, para qualquer Contrato ERC-721, o par contract address, uint256 tokenId deve ser globalmente único. Dito isso, um dapp pode ter um "conversor" que usa o tokenId como entrada e produz uma imagem de algo legal, como zumbis, armas, habilidades ou gatinhos incríveis!

Pré-requisitos

Body

O ERC-721(Ethereum Request for Comments 721), proposto por William Entriken, Dieter Shirley, Jacob Evans e Nastassia Sachs em janeiro de 2018, é um padrão de token não-fungível que implementa uma API para tokens em contratos inteligentes.

Oferece funcionalidades, como transferir tokens de uma conta para outra, para obter o saldo atual do token de uma conta e também a oferta total do token disponível na rede. Além disso, ele também tem algumas outras funcionalidades como aprovar que uma quantidade de token de uma conta pode ser gasta por uma conta de terceiros.

Se um contrato inteligente implementa os métodos e eventos a seguir, ele pode ser chamado de Contrato de token ERC-721 e, uma vez implantado, é responsável por fazer um acompanhamento dos tokens criados no Ethereum.

De EIP-721 (opens in a new tab):

Métodos

1 function balanceOf(address _owner) external view returns (uint256);
2 function ownerOf(uint256 _tokenId) external view returns (address);
3 function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
4 function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
5 function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
6 function approve(address _approved, uint256 _tokenId) external payable;
7 function setApprovalForAll(address _operator, bool _approved) external;
8 function getApproved(uint256 _tokenId) external view returns (address);
9 function isApprovedForAll(address _owner, address _operator) external view returns (bool);
Exibir tudo

Eventos

1 event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
2 event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
3 event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

Exemplos

Vejamos por que um padrão é importante e como ele simplifica o controle de qualquer contrato de token ERC-721 no Ethereum. Só precisamos da Interface Binária de Aplicativos (ABI, pela sigla em inglês) do contrato para criar uma interface com qualquer token ERC-721. Como você pode ver abaixo, usaremos uma ABI simplificada, para torná-la um exemplo de fácil compreensão.

Exemplo de Web3.py

Primeiro, certifique-se de que você instalou a biblioteca Python Web3.py (opens in a new tab):

1pip install web3
1from web3 import Web3
2from web3._utils.events import get_event_data
3
4
5w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))
6
7ck_token_addr = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d" # Contrato CryptoKitties
8
9acc_address = "0xb1690C08E213a35Ed9bAb7B318DE14420FB57d8C" # Leilão de Vendas CryptoKitties
10
11# Esta é uma Interface Binária de Aplicação de Contrato (ABI) simplificada de um Contrato de NFT ERC-721.
12# Ela exporá apenas os métodos: balanceOf(address), name(), ownerOf(tokenId), symbol(), totalSupply()
13simplified_abi = [
14 {
15 'inputs': [{'internalType': 'address', 'name': 'owner', 'type': 'address'}],
16 'name': 'balanceOf',
17 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
18 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True
19 },
20 {
21 'inputs': [],
22 'name': 'name',
23 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],
24 'stateMutability': 'view', 'type': 'function', 'constant': True
25 },
26 {
27 'inputs': [{'internalType': 'uint256', 'name': 'tokenId', 'type': 'uint256'}],
28 'name': 'ownerOf',
29 'outputs': [{'internalType': 'address', 'name': '', 'type': 'address'}],
30 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True
31 },
32 {
33 'inputs': [],
34 'name': 'symbol',
35 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],
36 'stateMutability': 'view', 'type': 'function', 'constant': True
37 },
38 {
39 'inputs': [],
40 'name': 'totalSupply',
41 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
42 'stateMutability': 'view', 'type': 'function', 'constant': True
43 },
44]
45
46ck_extra_abi = [
47 {
48 'inputs': [],
49 'name': 'pregnantKitties',
50 'outputs': [{'name': '', 'type': 'uint256'}],
51 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True
52 },
53 {
54 'inputs': [{'name': '_kittyId', 'type': 'uint256'}],
55 'name': 'isPregnant',
56 'outputs': [{'name': '', 'type': 'bool'}],
57 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True
58 }
59]
60
61ck_contract = w3.eth.contract(address=w3.to_checksum_address(ck_token_addr), abi=simplified_abi+ck_extra_abi)
62name = ck_contract.functions.name().call()
63symbol = ck_contract.functions.symbol().call()
64kitties_auctions = ck_contract.functions.balanceOf(acc_address).call()
65print(f"{name} [{symbol}] NFTs em leilões: {kitties_auctions}")
66
67pregnant_kitties = ck_contract.functions.pregnantKitties().call()
68print(f"{name} [{symbol}] NFTs grávidos: {pregnant_kitties}")
69
70# Usando o ABI do Evento de Transferência para obter informações sobre os Kitties transferidos.
71tx_event_abi = {
72 'anonymous': False,
73 'inputs': [
74 {'indexed': False, 'name': 'from', 'type': 'address'},
75 {'indexed': False, 'name': 'to', 'type': 'address'},
76 {'indexed': False, 'name': 'tokenId', 'type': 'uint256'}],
77 'name': 'Transfer',
78 'type': 'event'
79}
80
81# Precisamos da assinatura do evento para filtrar os logs
82event_signature = w3.keccak(text="Transfer(address,address,uint256)").hex()
83
84logs = w3.eth.get_logs({
85 "fromBlock": w3.eth.block_number - 120,
86 "address": w3.to_checksum_address(ck_token_addr),
87 "topics": [event_signature]
88})
89
90# Observações:
91# - Aumente o número de blocos acima de 120 se nenhum evento de Transferência for retornado.
92# - Se você não encontrou nenhum evento de Transferência, também pode tentar obter um tokenId em:
93# https://etherscan.io/address/0x06012c8cf97BEaD5deAe237070F9587f8E7A266d#events
94# Clique para expandir os logs do evento e copie seu argumento "tokenId"
95recent_tx = [get_event_data(w3.codec, tx_event_abi, log)["args"] for log in logs]
96
97if recent_tx:
98 kitty_id = recent_tx[0]['tokenId'] # Cole o "tokenId" aqui do link acima
99 is_pregnant = ck_contract.functions.isPregnant(kitty_id).call()
100 print(f"{name} [{symbol}] NFT {kitty_id} está grávido: {is_pregnant}")
Exibir tudo

Contrato de CriptoKitties tem alguns eventos interessantes além dos padrões.

Vamos verificar dois deles, Pregnant e Birth.

1# Usando o ABI dos eventos Pregnant e Birth para obter informações sobre novos Kitties.
2ck_extra_events_abi = [
3 {
4 'anonymous': False,
5 'inputs': [
6 {'indexed': False, 'name': 'owner', 'type': 'address'},
7 {'indexed': False, 'name': 'matronId', 'type': 'uint256'},
8 {'indexed': False, 'name': 'sireId', 'type': 'uint256'},
9 {'indexed': False, 'name': 'cooldownEndBlock', 'type': 'uint256'}],
10 'name': 'Pregnant',
11 'type': 'event'
12 },
13 {
14 'anonymous': False,
15 'inputs': [
16 {'indexed': False, 'name': 'owner', 'type': 'address'},
17 {'indexed': False, 'name': 'kittyId', 'type': 'uint256'},
18 {'indexed': False, 'name': 'matronId', 'type': 'uint256'},
19 {'indexed': False, 'name': 'sireId', 'type': 'uint256'},
20 {'indexed': False, 'name': 'genes', 'type': 'uint256'}],
21 'name': 'Birth',
22 'type': 'event'
23 }]
24
25# Precisamos da assinatura do evento para filtrar os logs
26ck_event_signatures = [
27 w3.keccak(text="Pregnant(address,uint256,uint256,uint256)").hex(),
28 w3.keccak(text="Birth(address,uint256,uint256,uint256,uint256)").hex(),
29]
30
31# Aqui está um evento Pregnant:
32# - https://etherscan.io/tx/0xc97eb514a41004acc447ac9d0d6a27ea6da305ac8b877dff37e49db42e1f8cef#eventlog
33pregnant_logs = w3.eth.get_logs({
34 "fromBlock": w3.eth.block_number - 120,
35 "address": w3.to_checksum_address(ck_token_addr),
36 "topics": [ck_event_signatures[0]]
37})
38
39recent_pregnants = [get_event_data(w3.codec, ck_extra_events_abi[0], log)["args"] for log in pregnant_logs]
40
41# Aqui está um evento Birth:
42# - https://etherscan.io/tx/0x3978028e08a25bb4c44f7877eb3573b9644309c044bf087e335397f16356340a
43birth_logs = w3.eth.get_logs({
44 "fromBlock": w3.eth.block_number - 120,
45 "address": w3.to_checksum_address(ck_token_addr),
46 "topics": [ck_event_signatures[1]]
47})
48
49recent_births = [get_event_data(w3.codec, ck_extra_events_abi[1], log)["args"] for log in birth_logs]
Exibir tudo
  • Etherscan NFT Tracker (opens in a new tab) lista os principais NFTs no Ethereum por volume de transferências.
  • CryptoKitties (opens in a new tab) é um jogo centrado em criaturas criáveis, colecionáveis e superadoráveis que chamamos de CryptoKitties.
  • Sorare (opens in a new tab) é um jogo de futebol fantasia global onde você pode colecionar itens colecionáveis de edição limitada, gerenciar suas equipes e competir para ganhar prêmios.
  • O Ethereum Name Service (ENS) (opens in a new tab) oferece uma maneira segura e descentralizada de endereçar recursos tanto dentro quanto fora da blockchain usando nomes simples e legíveis por humanos.
  • POAP (opens in a new tab) entrega NFTs gratuitos para pessoas que participam de eventos ou concluem ações específicas. Os POAPs são livres para criar e distribuir.
  • Unstoppable Domains (opens in a new tab) é uma empresa com sede em São Francisco que constrói domínios em blockchains. Domínios de blockchain substituem endereços de criptomoedas por nomes legíveis por humanos e podem ser usados para habilitar sites resistentes à censura.
  • Gods Unchained Cards (opens in a new tab) é um TCG na blockchain Ethereum que usa NFTs para trazer propriedade real para os ativos do jogo.
  • Bored Ape Yacht Club (opens in a new tab) é uma coleção de 10.000 NFTs únicos que, além de ser uma obra de arte comprovadamente rara, funciona como um token de associação ao clube, oferecendo vantagens e benefícios aos membros que aumentam com o tempo como resultado dos esforços da comunidade.

Leitura adicional

Este artigo foi útil?