paint-brush
Codifique un contrato inteligente NFT minimalista en Solidity On Ethereum: una guía prácticapor@thebojda
8,380 lecturas
8,380 lecturas

Codifique un contrato inteligente NFT minimalista en Solidity On Ethereum: una guía práctica

por Laszlo Fazekas4m2021/05/22
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

El estándar NFT (EIP-721) se creó en 2018, pero después de CrptoKitties este campo permaneció relativamente silencioso. Los tokens NFT (no fungibles) también son "bases de datos" simples en la cadena de bloques. Cuando acuña un NFT para usted mismo, el contrato de token le asigna la ID de token única. Dirección. El problema con la complejidad es el alto costo de transacción. En este artículo, mostraré cómo puede crear un contrato NFT minimalista pero completamente funcional en el. Cadena de bloques de Ethereum.

Company Mentioned

Mention Thumbnail

Coin Mentioned

Mention Thumbnail
featured image - Codifique un contrato inteligente NFT minimalista en Solidity On Ethereum: una guía práctica
Laszlo Fazekas HackerNoon profile picture

NFT es una palabra de moda nueva/vieja del mundo blockchain. El estándar NFT ( EIP-721 ) se creó en 2018, pero después de CrptoKitties este campo permaneció relativamente silencioso.

Hoy en día, las NFT vuelven a estar de moda y todo el mundo quiere hacer NFT de todo. Puedes vender tus artes o tweets, o cualquier cosa que puedas imaginar en forma de NFT. Pero, ¿qué es esta cosa mística de NFT?

NFT no es gran cosa. Como tokens ERC20 (fungibles), NFT (tokens no fungibles) también son "bases de datos" simples en la cadena de bloques.

Mientras que un contrato de token ERC20 almacena saldos de direcciones de Ethereum, el contrato de NFT almacena una identificación única -> asignaciones de direcciones de Ethereum. Cuando acuña un NFT para usted mismo, el contrato de token asigna la ID de token única a su dirección de Ethereum.

Técnicamente, esta identificación única es el propio NFT.

Puede venderlo o comprar otros NFT, lo que es una reasignación de la identificación. Los metadatos se pueden asignar a la ID (mediante un URI) que representa lo que está detrás de la NFT (por ejemplo, una imagen, un tweet, etc.). Eso es todo. Fácil, ¿verdad? Le dije, NFT no es gran cosa...

Aunque un NFT no es algo complicado, un contrato de NFT puede ser bastante complejo. Si observa la implementación de 0xcert , encontrará una lógica de token compleja y muchas variables de estado internas.

El problema con la complejidad es el alto costo de transacción. En este artículo, mostraré cómo puede crear un contrato NFT minimalista pero completamente funcional en la cadena de bloques de Ethereum.

En primer lugar, eche un vistazo a algunas de las variables de estado de la implementación de 0xcert:

 mapping ( address => uint256[]) internal ownerToIds; mapping ( uint256 => uint256) internal idToOwnerIndex; mapping ( uint256 => address) internal idToOwner; mapping ( address => uint256) private ownerToNFTokenCount;

los

 ownerToIds
el mapeo contiene los identificadores de token que se asignan a la dirección de Ethereum,
 idToOwner
es una ID de token -> asignación de direcciones de Ethereum,
 idToOwnerIndex
asigna la identificación del token al índice de la matriz de tokens del propietario y, finalmente,
 ownerToNFTokenCount
asigna la dirección Ethereum de los propietarios al recuento de tokens (cuántos NFT son propiedad del propietario).

Como puede ver, esta estructura de datos es muy redundante, porque cada mapeo podría calcularse a partir de la primera estructura de ownToIds.

Todas estas asignaciones se almacenan en la cadena de bloques y todas deben administrarse en los métodos del contrato. Desafortunadamente, todos ellos son necesarios si queremos implementar el estándar de token ERC-721. Entonces, ¿qué podemos hacer para reducir la complejidad y el costo transaccional de las llamadas a métodos?

Si no se necesita la compatibilidad con ERC-721, podemos hacer un truco simple. En este caso, podemos almacenar en la cadena de bloques solo las cosas que son absolutamente necesarias.

Todo lo demás se puede almacenar en una base de datos externa. Si almacenamos los saldos de tokens, las listas de tokens, etc. en un almacenamiento externo (sin cadena de bloques), entonces no necesitamos las asignaciones redundantes. El contrato será más sencillo y las transacciones serán más baratas. Después de la teoría, echemos un vistazo al código:

Sólo 24 líneas de código. Nada mal. Pero, ¿es realmente un contrato NFT completamente funcional? Vamos a ver. Tiene 2 métodos: menta y transferencia. El método mint crea un nuevo token NFT. tiene 2 parametros

 _to
y
 _ipfsHash
. El primer parámetro es la dirección de Ethereum de destino que poseerá el token recién acuñado.

El segundo parámetro es un hash único que apunta a los metadatos en IPFS . En la especificación ERC-721 original, los metadatos se señalan con un

 tokenURI
. ¿Por qué usamos un hash de IPFS en su lugar? Hay muchas razones.

Un hash IPFS tiene solo 32 bytes, por lo que escribirlo en la cadena de bloques es más económico que una cadena URI. La segunda razón es que IPFS es inmutable. El contenido no se puede cambiar, porque si cambia el hash de IPFS también cambiaría. Por lo tanto, almacenar los datos en IPFS y escribir el hash en la cadena de bloques es algo así como escribir los datos en sí mismos en la cadena de bloques, pero es mucho más económico.

El método mint lee el valor actual del

 tokenCounter
variable para obtener un identificador de token único. El método incrementa esta variable en cada llamada, por lo que la identificación del token será absolutamente única. El método almacena la identificación del token: la asignación de dirección de Ethereum en el
 idToOwner
mapping, que es el único que mapea lo que almacenamos en la cadena de bloques. En el último paso, el método emite un evento Mint, que será muy importante más adelante.

El método de transferencia tiene dos parámetros.

 _to
y
 _tokenId
. El primer parámetro es la dirección de destino que poseerá el NFT, y el segundo parámetro es la ID del token. La primera línea del método verifica la propiedad del token usando el
 idToOwner
cartografía. Solo el propietario del token puede llamar al método de transferencia. Si el token es propiedad de la persona que llama, el método modifica la asignación en la asignación y emite un evento de transferencia.

Estos dos métodos son suficientes para un NFT completamente funcional. Pero, ¿qué pasa con los saldos, consultas de titularidad, etc.? Aquí viene la base de datos externa. Cuando un contrato emite un evento , se almacenará en la cadena de bloques en los registros.

Estos registros están disponibles a través de la API de JSON-RPC directamente, o puede usar la API de JavaScript para leerlos. Estos registros contienen el historial completo de transacciones, por lo que contienen toda la información necesaria. Dado que se almacenan en la cadena de bloques, en cada momento se puede crear una base de datos a partir de ellos que contiene la propiedad del token, los saldos y todos los demás datos que se necesitan.

Para mostrar esto, revisemos los métodos ERC-721 y cómo una base de datos externa puede proporcionar los datos.

 balanceOf
,
 ownerOf
- Estos se pueden calcular fácilmente a partir de eventos Mint y Transfer

 approve
,
 setApprovalForAll
,
 getApproved
,
 isApprovedForAll
- Nuestro NFT minimalista no proporciona una lógica de aprobación, solo el propietario puede transferir los tokens. Si es necesario, esta característica se puede implementar mediante una segunda asignación.

 safeTransferFrom
,
 transferFrom
- La seguridad de la transferencia se puede verificar externamente, y el parámetro from no tiene sentido aquí, porque nuestros tokens solo pueden ser transferidos por el propietario.

 tokenURI
- El URI del token se puede generar a partir de la parte hash de IPFS del evento Mint.

 totalSupply
,
 tokenByIndex
,
 tokenOfOwnerByIndex
- Estos se pueden calcular fácilmente a partir de los eventos Mint y Transfer.

Como puede ver, nuestro token NFT minimalista puede hacer todo lo que puede hacer un token ERC-721 excepto la lógica de aprobación, pero puede implementarse si es necesario.