Este artículo es una traducción de Beach Crypto, hecha por Gabriella Martínez. Puedes encontrar el artículo original aquí.
Sería genial escucharte en nuestro Discord, puedes contarnos tus ideas, comentarios, sugerencias y dejarnos saber lo que necesitas.
Si prefieres puedes escribirnos a @web3dev_es en Twitter.
LayerZero, OpenZeppelin y ERC721 acuñables con Almacenamiento URI
Luego de muchos intentos fallidos, muchas investigaciones y una profundización en ejemplos de LayerZero Labs Solidity, aprendí cómo Desplegar, Acuñar y Enviar un NFT ERC721 a través de las cadenas con Remix. En una historia anterior, creé un ERC721 genérico acuñable con un contrato de Almacenamiento URI usando el Contrato Wizard de OpenZeppelin. Luego combiné este contrato genérico con los requisitos de la aplicación de usuario LayerZero para generar LayerZero OpenZeppelin y ERC721 acuñables con Almacenamiento URI. El contrato está disponible en mi repositorio de Github.
Para esta historia, estaré empleando la red de pruebas Goerli de Ethereum y la red de pruebas de Mumbai de Polygon.
Primero, despliega el contrato a Goerli. Abajo hay un ejemplo con los parámetros requeridos por el contrato.
BeachCryptoTestMintONFT721-V1, BCTMO1, 61174, 0xbfD2135BFfbb0B5378b56643c2Df8a87552Bfa23, 1, 5
Name: BeachCryptoTestMintONFT721-V1
Symbol: BCTMO1
Minimum gas to transfer: 61174
Layer Zero endpoint: 0xbfD2135BFfbb0B5378b56643c2Df8a87552Bfa23
Start mint id: 1
End mint id: 5
Aquí, estoy asumiendo el monto mínimo de gas, 61174, tomado de la documentación del Costo Estimado Máximo de la Prueba como el parámetro para el argumento de gas mínimo para la transferencia.
En segundo lugar, en Remix despliega a Mumbai
BeachCryptoTestMintONFT721-V1, BCTMO1, 61174, 0xf69186dfBa60DdB133E91E9A4B5673624293d8F8, 6, 10
Observa que cambié el endpoint de LayerZero, el comienzo del mind id y el final del ID acuñable.
Tercero, voy a acuñar algunos tokens a la red de pruebas de Goerli. Este contrato solo toma la dirección de la cartera como un parámetro a la función acuñable. Acuñaré algunos tokens a la cartera propietaria.
La acuñación fue exitosa
Ahora, quiero revisar mi nuevo NFT en la red de pruebas de OpenSea
En cuarto lugar, configura Trusted Remotes. Para poder enviar un NFT o token desde un blockchain como Ethereum a otro, como Polygon, el contrato del NFT, en ambas cadenas, debe confiar la una a la otra. Aquí, puedo hacerlo usando la función sendTrustedRemote
construida en el contrato para permitir que mi contrato en Goerli sepa confiar en mi contrato en Mumbai.
Aquí hay algunos procesos que deben hacerse antes de configurar tu contrato para aceptar mensajes desde otro contrato en un blockchain distinto. Para configurar un confiado desde Goerli a Mumbai, debo pasar dos parámetros a la función setTrustedRemote
, el ID de la cadena remota y la dirección del contrato remoto con la dirección del contrato local codificado.
El valor del segundo argumento _path
puede ser obtenido usando la función de JavaScript en Remix
let remoteContractAddress = "0x95eb476accde4577df1c9f14678169ce16ff234d"
let localContractAddress = "0x44d979267f35dc80065fc4ac94125bda289ab424"
function generateTrustedRemotePath() {
let trustedRemote = ethers.utils.solidityPack(['address','address'], [remoteContractAddress, localContractAddress])
console.log(trustedRemote)
}
generateTrustedRemotePath();
Para configurar un confiado remoto desde Goerli a Mumbai, el argumento setTrustedRemote
debe verse así
10109, 0x44d979267f35dc80065fc4ac94125bda289ab42495eb476accde4577df1c9f14678169ce16ff234d
Ahora, haz lo mismo para configurar un confiado remoto desde Mumbai a Goerli
let remoteContractAddress = "0x44d979267f35dc80065fc4ac94125bda289ab424"
let localContractAddress = "0x95eb476accde4577df1c9f14678169ce16ff234d"
function generateTrustedRemotePath() {
let trustedRemote = ethers.utils.solidityPack(['address','address'], [remoteContractAddress, localContractAddress])
console.log(trustedRemote)
}
generateTrustedRemotePath();
El argumento setTrustedRemote
para configurar un confiado remoto desde Mumbai a Goerli debe verse así
10121, 0x95eb476accde4577df1c9f14678169ce16ff234d44d979267f35dc80065fc4ac94125bda289ab424
Una vez que termines, puedes usar la función incorporada llamada getTrustedRemoteAddress
con Remix y ver la dirección del contrato confiado en la cadena remota. La función toma el id de la cadena remota como un argumento.
Quinto, configura el destino de gas mínimo con la función incorporada en setMinDstGas
. Esta función configurará la cantidad de gas mínimo requerida para la ejecución del destino de la cadena. setMinDstGas
toma tres argumentos
uint16 _dstChainId,
uint16 _packetType,
uint256 _minGas
Para configurar el destino de gas mínimo desde Goerli a Mumbai, el argumento debe verse así
setMinDstGas(10109, 1, 150000)
Por último, enviaré el NFT desde Goerli a Mumbai usando la función incorporada _sendFrom_
. En una historia anterior, detallé todo el proceso. Ya que hemos heredado y extendido ONFT721Core.sol en nuestro contrato, podemos aprovechar el _sendFrom_
desde LayerZero que nos da la funcionalidad para enviar nuestro NFT a través de las cadenas. La función se ve así:
function sendFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;
/**
* @dev send tokens `_tokenIds[]` to (`_dstChainId`, `_toAddress`) from `_from`
* `_toAddress` can be any size depending on the `dstChainId`.
* `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
* `_adapterParams` is a flexible bytes array to indicate messaging adapter services
*/
En mi caso, los argumentos son
address _from = 0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516
uint16 _dstChainId = 10109
bytes calldata _toAddress = 0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516
uint _tokenId = 1
address payable _refundAddress = 0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516
address _zroPaymentAddress = 0x0000000000000000000000000000000000000000
bytes calldata _adapterParams = 0x00010000000000000000000000000000000000000000000000000000000000030d40
Enviaré el token del id 1 desde mi billetera en Goerli a mi billetera en Polygon. El id de la cadena de Polygon es 10109. La dirección de retorno es mi dirección, aquí es donde el gas será enviado de vuelta si la transacción tiene algún fallo. Desde LayerZero:
”Abstracto: Cada transacción cuesta cierta cantidad de gas. Ya que LayerZero delibera la transacción de destino cuando el mensaje es enviado, debe ser pagado por ese destino de gas. Por defecto, el precio de 200,000 de gas en la llamada por simplicidad.”
Copié el ejemplo de función para calcular este valor y ejecuté la función en Remix.
function getAdapterParam() {
let adapterParams = ethers.utils.solidityPack(
['uint16','uint256'],
[1, 200000]
)
console.log(adapterParams)
}
getAdapterParam();
El argumento final para la función sendFrom
en mi contrato debe verse así
0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516,
10109, 0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516,
1,
0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516,
0x0000000000000000000000000000000000000000,
0x00010000000000000000000000000000000000000000000000000000000000030d40
Ahora, puedo usar esta función y puedo enviar el ID 1 del token desde Goerli a Mumbai
No te olvides de añadir el valor de gas en Wei a través de la interfaz de Remix. Usé un valor de 6000000000000 basado en mis cálculos.
Ahora lo enviaré
¡Éxito!
Antes
Después
He desplegado un contrato omnichain LayerZero a las redes de pruebas Goerli y Mumbai, acuñado un token en Goerli y enviar ese token a Mumbai.
¡Este contrato aún necesita mucho trabajo! Ahora que entiendo los fundamentos de enviar un token de una blockchain a otra, puedo enfocarme en construir el núcleo de la funcionalidad del contrato.
Envíame un comentario si tienes cualquier pregunta o sugerencia para esta u otras historias.
Discussion (0)