28 de fevereiro de 2023
O LayerZero ERC721 do OpenZeppelin cunhável com armazenamento URI (Uniform Resource Identifier ou identificador de recurso uniforme)
Depois de muitas tentativas fracassadas, muita pesquisa e um mergulho profundo nos exemplos de LayerZero Labs em Solidity, aprendi como implantar, cunhar e enviar um NFT ERC721 entre cadeias com o Remix. Em uma história anterior, criei um contrato ERC721 cunhável com armazenamento URI usando o Wizard de contrato do Openzepellin. Então, combinei esse contrato genérico com os requisitos do aplicativo de usuário do LayzerZero para criar um ERC72 LayerZero cunhável do Openzeppelin com armazenamento URI. O contrato está disponível no meu repositório no GitHub.
Para esta história, estarei usando a rede de teste Goerli da Ethereum e a rede de teste Mumbai da Polygon.
Primeiro, implante o contrato para a Goerli. Abaixo está um exemplo dos parâmetros requeridos pelo contrato.
BeachCryptoTestMintONFT721-V1, BCTMO1, 61174, 0xbfD2135BFfbb0B5378b56643c2Df8a87552Bfa23, 1, 5
Name (nome): BeachCryptoTestMintONFT721-V1
Symbol(símbolo): BCTMO1
Minimum gas to transfer (taxa de gás mínima para transferir): 61174
Layer Zero endpoint (ponto de extremidade do Layer Zero): 0xbfD2135BFfbb0B5378b56643c2Df8a87552Bfa23
Start mint id (id de início de cunhagem): 1
End mint id (id de final de cunhagem): 5
Aqui estou assumindo uma quantidade mínima de gás, 61174, retirada da documentação estimativa de custo de prova máximo como o parâmetro para o gás mínimo para transferir o argumento.
Em segundo lugar, implante no Remix para a Mumbai.
BeachCryptoTestMintONFT721-V1, BCTMO1, 61174, 0xf69186dfBa60DdB133E91E9A4B5673624293d8F8, 6, 10
Observe que eu mudei o ponto de extremidade (endpoint) do LayerZero, o ID de início de cunhagem (star mint id) e o ID de final de cunhagem (end mint id).
Em terceiro lugar, irei cunhar alguns tokens na rede de testes Goerli. Este contrato leva apenas o endereço da carteira como um parâmetro para a função de cunhagem. Cunharei alguns tokens para minha própria carteira.
A cunhagem foi bem sucedida.
Agora, quero verificar meu novo NFT na rede de teste do OpenSea.
Em quarto lugar, configure remotos confiáveis (Trusted Remotes). A fim de enviar um NFT ou token de uma blockchain como a Ethereum para outra como a Polygon, os contratos NFT em ambas as cadeias devem confiar um no outro. Aqui, posso fazer isso usando a função sendTrustedRemote integrada ao contrato, para permitir que meu contrato na Goerli saiba confiar no meu contrato na Mumbai.
Existem alguns processamentos que devem ser feitos para configurar nosso contrato para aceitar mensagem de outro contrato em uma blockchain diferente. Para configurar um confiável da Goerli para a Mumbai, tenho que passar dois parâmetros para a função setTrustedRemote, o ID da cadeia remota e o endereço do contrato remoto com o endereço do contrato local codificado.
O valor do segundo argument_path pode ser obtido usando uma função Javascript no Remix.
let remoteContractAddress = "0x95eb476accde4577df1c9f14678169ce16ff234d"
let localContractAddress = "0x44d979267f35dc80065fc4ac94125bda289ab424"
function generateTrustedRemotePath() {
let trustedRemote = ethers.utils.solidityPack(['address','address'],[remoteContractAddress, localContractAddress])
console.log(trustedRemote)
}
generateTrustedRemotePath();
Para configurar um remoto confiável da Goerli para a Mumbai, o argumento setTrustedRemote fica assim:
10109, 0x44d979267f35dc80065fc4ac94125bda289ab42495eb476accde4577df1c9f14678169ce16ff234d
Agora, faça o mesmo para configurar um remoto confiável da Mumbai para a Goerli.
let remoteContractAddress = "0x44d979267f35dc80065fc4ac94125bda289ab424"
let localContractAddress = "0x95eb476accde4577df1c9f14678169ce16ff234d"
function generateTrustedRemotePath() {
let trustedRemote = ethers.utils.solidityPack(['address','address'],[remoteContractAddress, localContractAddress])
console.log(trustedRemote)
}
generateTrustedRemotePath();
O argumento setTrustedRemote para configurar um remoto confiável da Mumbai para a Goerli se parecerá com isto:
10121, 0x95eb476accde4577df1c9f14678169ce16ff234d44d979267f35dc80065fc4ac94125bda289ab424
Uma vez que você finalizar, você pode usar uma função integrada chamada getTrustedRemoteAddress com o Remix para ver o endereço do contrato confiável na cadeia remota. A função leva o ID da cadeia remota como um argumento.
Em quinto lugar, defina um gás de destino mínimo com a função integrada setMinDstGas. Esta função definirá a quantidade mínima de gás requerida para a execução na cadeia de destino. A setMinDstGas recebe três argumentos.
uint16 _dstChainId,
uint16 _packetType,
uint256 _minGas
Para definir o gás de destino mínimo da Goerli para a Mumbai, o argumento se parece com este:
setMinDstGas(10109, 1, 150000)
Por último, enviarei o NFT da Goerli para a Mumbai usando a função integrada sendFrom. Em uma história anterior, entrei nesse processo em detalhes. Como herdamos e estendemos ONFT721Core.sol no nosso contrato, podemos aproveitar o sendFrom do LayerZero que nos dá a funcionalidade para enviar nosso NFT entre cadeias. A função fica assim:
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
*/
No meu caso, os argumentos são:
address _from = 0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516
uint16 _dstChainId = 10109
bytes calldata _toAddress = 0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516
uint _tokenId = 1
address payable _refundAddress = 0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516
address _zroPaymentAddress = 0x0000000000000000000000000000000000000000
bytes calldata _adapterParams = 0x00010000000000000000000000000000000000000000000000000000000000030d40
Enviarei o token de ID 1 da minha carteira na Goerli para minha carteira na Polygon. O ID da cadeia da Polygon é 10109. O endereço de reembolso é meu endereço, é aqui que o gás será enviado de volta se a transação tiver um obstáculo (hiccup). Do LayerZero:
”Resumo: toda transação custa uma certa quantidade de gás. Como o LayerZero entrega a transação de destino quando uma mensagem é enviada, ele deve pagar por este gás de destino. Um padrão de 200.000 gás é precificado na chamada para simplificar.”
Copiei a função de exemplo para calcular este valor e executei a função no Remix:
function getAdapterParam() {
let adapterParams = ethers.utils.solidityPack(
['uint16','uint256'],
[1, 200000]
)
console.log(adapterParams)
}
getAdapterParam();
O argumento final para a função sendFrom no meu contrato fica assim:
0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516,
10109, 0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516,
1,
0xda4e34F1cE6D36BDbf2Eb0e61FeB92b65E0FE516,
0x0000000000000000000000000000000000000000,
0x00010000000000000000000000000000000000000000000000000000000000030d40
Agora, usando esta função, posso enviar o ID do token da Goerli para a Mumbai:
Não se esqueça de adicionar o valor do gás em Wei através da interface Remix. Eu usei um valor de 6000000000000, baseado nos meus cálculos.
Agora, irei enviar:
Sucesso!
Antes:
Depois:
Implantei um contrato Omnichain LayerZero para as redes de teste Goerli e Mumbai, cunhei um token na Goerli e enviei esse token para a Mumbai.
Este contrato ainda precisa de muito trabalho! Agora que entendo os fundamentos do envio de um token de uma blockchain para outra, posso me concentrar na criação da funcionalidade principal do contrato.
Envie-me um comentário se tiver alguma dúvida ou sugestão para esta ou próximas histórias.
Esse artigo foi escrito por Beach Crypto e traduzido por Isabela Curado Nehme. Seu original pode ser lido aqui.
Oldest comments (0)