Estándar de token no fungible ERC-721
Última actualización de la página: 17 de septiembre de 2025
Introducción
¿Qué es un token no fungible?
Una ficha no funcional (NFT) se utiliza para identificar algo o a alguien de una manera única. Este tipo de token es perfecto para ser usado en plataformas que ofrecen artículos recolectables, acceder a llaves, boletos de lotería, asientos numerados para conciertos y partidos deportivos, etc. Este tipo especial de token tiene unas posibilidades asombrosas, por lo que merece un estándar adecuado, el ERC-721 vino a solucionarlo.
¿Qué es el ERC-721?
El ERC-721 introduce una norma para NFT, en otras palabras, este tipo de ficha es único y puede tener un valor diferente que otra ficha del mismo contrato inteligente, tal vez debido a su antigüedad, rareza o incluso a algo como su visualidad. Espera, ¿visual?
¡Sí! Todos los NFT tienen una variable uint256 llamada tokenId, por lo que para cualquier contrato ERC-721, el par
dirección del contrato, tokenId uint256 debe ser único a nivel mundial. Dicho esto, una dapp puede tener un "convertidor" que
utilice el tokenId como entrada y genere una imagen de algo genial, como zombis, armas, habilidades ¡o gatitos increíbles!
Requisitos previos
Cuerpo
El ERC-721 (Ethereum Request for Comments 721), propuesto por William Entriken, Dieter Shirley, Jacob Evans, Nastassia Sachs en enero de 2018, es un Estándar de Token No Fungible que implementa una API para tokens dentro de Smart Contracts.
Proporciona funcionalidades como transferir tokens de una cuenta a otra, obtener el saldo de tokens actual de una cuenta, obtener el propietario de un token específico y también el suministro total del token disponible en la red. Además de estos también tiene otras funcionalidades como aprobar que una cantidad de token de una cuenta puede ser gastada por una cuenta de terceros.
Si un contrato inteligente implementa los siguientes métodos y eventos, se puede llamar un Contrato de Token ERC-721, y una vez desplegado será el responsable de llevar un seguimiento de los tokens creados en Ethereum.
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);Mostrar todoEventos
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);Ejemplos
Vamos a ver la importancia de un estándar para que inspeccionemos fácilmente cualquier contrato de token de ERC-721 en Ethereum. Sólo necesitamos la Interfaz binaria de aplicaciones de contrato (ABI) para crear una interfaz a cualquier Token ERC-721. Como puedes ver a continuación, usaremos una ABI simplificada, para que sea un ejemplo de fricción bajo.
Ejemplo de Web3.py
Primero, asegúrese de que ha instalado la librería de Python Web3.pyopens in a new tab:
1pip install web31from web3 import Web32from web3._utils.events import get_event_data345w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))67ck_token_addr = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d" # Contrato de CryptoKitties89acc_address = "0xb1690C08E213a35Ed9bAb7B318DE14420FB57d8C" # Subasta de ventas de CryptoKitties1011# Esta es una Interfaz Binaria de Aplicación (ABI) de Contrato simplificada de un Contrato NFT ERC-721.12# Expondrá solo los 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': True19 },20 {21 'inputs': [],22 'name': 'name',23 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],24 'stateMutability': 'view', 'type': 'function', 'constant': True25 },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': True31 },32 {33 'inputs': [],34 'name': 'symbol',35 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],36 'stateMutability': 'view', 'type': 'function', 'constant': True37 },38 {39 'inputs': [],40 'name': 'totalSupply',41 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],42 'stateMutability': 'view', 'type': 'function', 'constant': True43 },44]4546ck_extra_abi = [47 {48 'inputs': [],49 'name': 'pregnantKitties',50 'outputs': [{'name': '', 'type': 'uint256'}],51 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True52 },53 {54 'inputs': [{'name': '_kittyId', 'type': 'uint256'}],55 'name': 'isPregnant',56 'outputs': [{'name': '', 'type': 'bool'}],57 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True58 }59]6061ck_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}] NFT en subastas: {kitties_auctions}")6667pregnant_kitties = ck_contract.functions.pregnantKitties().call()68print(f"{name} [{symbol}] NFT preñados: {pregnant_kitties}")6970# Usando el ABI del evento de transferencia para obtener información sobre los 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}8081# Necesitamos la firma del evento para filtrar los registros82event_signature = w3.keccak(text="Transfer(address,address,uint256)").hex()8384logs = 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})8990# Notas:91# - Aumente el número de bloques a partir de 120 si no se devuelve ningún evento de Transferencia.92# - Si no encontró ningún evento de Transferencia, también puede intentar obtener un tokenId en:93# https://etherscan.io/address/0x06012c8cf97BEaD5deAe237070F9587f8E7A266d#events94# Haga clic para expandir los registros del evento y copie su argumento "tokenId"95recent_tx = [get_event_data(w3.codec, tx_event_abi, log)["args"] for log in logs]9697if recent_tx:98 kitty_id = recent_tx[0]['tokenId'] # Pegue el "tokenId" aquí desde el enlace de arriba99 is_pregnant = ck_contract.functions.isPregnant(kitty_id).call()100 print(f"El NFT {name} [{symbol}] {kitty_id} está preñado: {is_pregnant}")Mostrar todoEl contrato de CryptoKitties tiene algunos eventos interesantes aparte de los estándar.
Revisemos dos de ellos, Pregnant y Birth.
1# Usando los ABI de los eventos Pregnant y Birth para obtener información sobre los nuevos 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 }]2425# Necesitamos la firma del evento para filtrar los registros26ck_event_signatures = [27 w3.keccak(text="Pregnant(address,uint256,uint256,uint256)").hex(),28 w3.keccak(text="Birth(address,uint256,uint256,uint256,uint256)").hex(),29]3031# Aquí hay un evento Pregnant:32# - https://etherscan.io/tx/0xc97eb514a41004acc447ac9d0d6a27ea6da305ac8b877dff37e49db42e1f8cef#eventlog33pregnant_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})3839recent_pregnants = [get_event_data(w3.codec, ck_extra_events_abi[0], log)["args"] for log in pregnant_logs]4041# Aquí hay un evento Birth:42# - https://etherscan.io/tx/0x3978028e08a25bb4c44f7877eb3573b9644309c044bf087e335397f16356340a43birth_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})4849recent_births = [get_event_data(w3.codec, ck_extra_events_abi[1], log)["args"] for log in birth_logs]Mostrar todoNFT populares
- Etherscan NFT Trackeropens in a new tab enumera los principales NFT de Ethereum por volumen de transferencias.
- CryptoKittiesopens in a new tab es un juego centrado en criaturas criables, coleccionables y muy adorables que llamamos CryptoKitties.
- Sorareopens in a new tab es un juego de fútbol de fantasía global en el que puedes coleccionar coleccionables de edición limitada, gestionar tus equipos y competir para ganar premios.
- El Servicio de nombres de Ethereum (ENS)opens in a new tab ofrece una forma segura y descentralizada de direccionar recursos tanto dentro como fuera de la cadena de bloques, utilizando nombres sencillos y legibles por humanos.
- POAPopens in a new tab entrega NFT gratuitos a las personas que asisten a eventos o completan acciones específicas. Los POAP se pueden crear y distribuir de forma gratuita.
- Unstoppable Domainsopens in a new tab es una empresa con sede en San Francisco que crea dominios en cadenas de bloques. Los dominios de cadena de bloques reemplazan las direcciones de criptomoneda con nombres legibles por humanos y se pueden utilizar para habilitar sitios web resistentes a la censura.
- Gods Unchained Cardsopens in a new tab es un TCG en la cadena de bloques de Ethereum que utiliza NFT para otorgar propiedad real a los activos del juego.
- Bored Ape Yacht Clubopens in a new tab es una colección de 10.000 NFT únicos que, además de ser una obra de arte de rareza demostrable, actúa como un token de membresía para el club, proporcionando ventajas y beneficios para los miembros que aumentan con el tiempo como resultado de los esfuerzos de la comunidad.