Moonbase Alpha v2: Novos eventos de contrato e Pub / Sub

(Alberto Viera) (13 de outubro de 2020)

Com o lançamento do Moonbase Alpha v2 , que acaba de ser anunciado pela PureStake, estamos adicionando alguns recursos novos e interessantes que ajudam o Moonbeam a se aproximar de seu objetivo principal de fornecer uma experiência perfeita para projetos de Ethereum no ecossistema Polkadot. Um dos principais recursos adicionados é a capacidade de se inscrever em eventos de contratos inteligentes Ethereum e outras informações de blockchain.

Os eventos de contrato são uma parte superimportante dos dApps no Ethereum, pois facilitam a comunicação entre contratos inteligentes e suas interfaces de usuário. Os eventos podem ser considerados gatilhos assíncronos com dados. Quando um contrato emite um evento, isso pode subsequentemente resultar em uma ação no front-end.

Casos de uso para eventos

Um exemplo simples de um evento que você pode rastrear é um transferir. Digamos que uma transferência seja iniciada por um usuário usando o front-end de um dApp, onde um hash de transação é obtido assim que é enviado. Mas, para garantir ao usuário que o pagamento foi enviado, o dApp pode escutar um evento (emitido pelo contrato) quando a transação é confirmada no blockchain. Consequentemente, isso pode acionar uma mensagem de exibição para o usuário notificando-o de que sua ação foi bem-sucedida.

Outro caso de uso poderoso de eventos é o armazenamento mais barato. Em média, os logs custam 8 gás por byte, enquanto o armazenamento por contrato custa 20.000 gás por 32 bytes. Portanto, os eventos podem servir como uma ferramenta para salvar e recuperar informações necessárias, como registros de transferência também. No entanto, eles não podem ser usados ​​como armazenamento para todos os casos de uso, porque não podem ser acessados ​​por outros contratos inteligentes, por exemplo.

A importância do Pub / Sub

Dado todo esse contexto, agora estamos prontos para falar sobre pub / sub.

Publicar-assinar, ou pub / sub, é um serviço de mensagens assíncronas que atua como um middleware entre os editores de mensagens, e pessoas que os assinam. Em termos gerais, os editores categorizam essas mensagens em classes e as publicam sem realmente saber quem as assinou. Da mesma forma, os assinantes se inscrevem nas aulas de interesse, recebendo apenas mensagens associadas àquelas aulas, sem saber quem é o editor.

Com o lançamento de Moonbase Alpha v2 , um serviço pub / sub compatível com eventos de estilo Ethereum agora está disponível.

Tutorial: como usar o Pub / Sub no Moonbeam

Desde uma imagem vale mais que mil palavras, vamos pular para alguns exemplos para mostrar como pub / sub funciona no Moonbeam.

Para acompanhar esta demonstração, você precisará do seguinte:

Inscrevendo-se nos registros de eventos no Moonbase Alpha v2

Qualquer contrato que siga o padrão de token ERC-20 emite um evento relacionado a uma transferência de tokens, ou seja, event Transfer(address indexed from, address indexed to, uint256 value). Para este exemplo, iremos assinar os logs de tais eventos. Usando a biblioteca Web3 JS, precisamos do seguinte trecho de código:

const Web3 = require("web3");
const web3 = new Web3("wss://wss.testnet.moonbeam.network");

web3.eth.subscribe("logs", {
address: "ContractAddress",
topics: ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]
}, (error, result) => {
if (error)
console.error(error);
})
.on("connected", function (subscriptionId) {
console.log(subscriptionId);
})
.on("data", function (log) {
console.log(log);
});

Observe que estamos nos conectando ao endpoint WebSocket do Moonbase Alpha. Usamos o método web3.eth.subscribe("logs", options [, callback]) para assinar os logs, filtrados pelas opções fornecidas. No nosso caso, as opções são o endereço do contrato de onde os eventos são emitidos e os tópicos usados ​​para descrever o evento. Mais informações sobre os tópicos podem ser encontradas em (esta postagem do Medium). Se nenhum tópico estiver incluído, você se inscreve a todos os eventos emitidos pelo contrato. Mas para filtrar apenas o evento Transfer, precisamos incluir a assinatura do evento, calculada como:

EventSignature = keccak256(Transfer(address,address,uint256))

O resultado do cálculo anterior é o que é mostrado no trecho de código anterior. Voltaremos à filtragem por tópicos mais tarde. O restante do código lida com a função de retorno de chamada.Assim que executarmos este código, obteremos um ID de assinatura e o terminal aguardará qualquer evento por meio dessa assinatura:

A seguir, uma transferência de token ERC20 será enviada com os seguintes parâmetros:

  • Do endereço: 0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b
  • Para o endereço: 0xfcB0B397BB28046C01be6A3d66c7Eda99Fb0f344
  • Valor (tokens): 10000000000000000000 – isso é 10 com 18 zeros

Assim que enviarmos a transação, o log do evento emitido pela transação aparecerá no terminal:

Muitas informações são fornecidas nos logs, mas você pode se perguntar: onde estão as informações no evento emitido? E a resposta é: nos logs!

Nosso evento de destino envia duas informações indexadas, os endereços “de” e “para” (nessa ordem), que são tratados como tópicos. O outro dado compartilhado por nosso evento é o número de tokens, que não são indexados. Portanto, há um total de três tópicos (o máximo é quatro), que correspondem ao opcode LOG3:

Consequentemente, você pode ver que os endereços “de” e “para” estão contidos nos tópicos retornados pelos logs. Os endereços Ethereum têm 40 caracteres hexadecimais (1 caractere hexadecimal tem 4 bits, portanto, 160 bits ou formato H160). Assim, os 24 zeros extras são necessários para preencher a lacuna para H256, que tem 64 caracteres hexadecimais.

E quanto ao número de tokens? Dados não indexados são retornados no campo “dados” dos logs, mas são codificados em bytes32 / hex. Para decodificá-lo, podemos usar, por exemplo, esta ferramenta online e verificar se os “dados” são de fato 10 (mais 18 zeros).

Se o evento retornar vários valores não indexados, eles serão anexados um após o outro na mesma ordem em que o evento os emitir. Portanto, cada valor é obtido pela desconstrução dos dados em partes separadas de 32 bytes (ou 64 caracteres hexadecimais).

Este exemplo mostrou como poderíamos assinar apenas os logs de eventos de um contrato específico. Mas a biblioteca Web3 JS fornece outros tipos de assinatura que examinaremos nas seções a seguir.

Assinar transações pendentes de entrada

Para assinar transações pendentes, podemos usar o método web3.eth.subscribe("pendingTransactions", [, callback]), implementando a mesma função de retorno de chamada para verificar a resposta. Isso é muito mais simples do que nosso exemplo anterior e retorna o hash de transação das transações pendentes.

Podemos verificar se este hash de transação é o mesmo que o mostrado na MetaMask (ou Remix).

Assine os cabeçalhos de bloco de entrada

Outro tipo disponível na biblioteca Web3 JS é a assinatura de novos cabeçalhos de bloco. Para fazer isso, usamos o método web3.eth.subscribe("newBlockHeaders" [, callback]), implementando a mesma função de retorno de chamada para verificar a resposta. Esta assinatura fornece cabeçalhos de bloco de entrada e pode ser usada para rastrear alterações no blockchain.

Observe que apenas um cabeçalho de bloco é mostrado na imagem. Essas mensagens são exibidas para cada bloco produzido, para que possam preencher o terminal muito rapidamente.

Verifique se o nó está sincronizado com a rede

Com pub / sub também é possível para verificar se um nó específico, no qual você está inscrito, está atualmente sincronizado com a rede. Para isso, podemos aproveitar o método web3.eth.subscribe("syncing" [, callback]), implementando a mesma função de retorno de chamada para verificar a resposta. Esta assinatura retornará um objeto quando o nó for sincronizado com a rede.

Limitações atuais

A implementação pub / sub no Frontier ainda está em desenvolvimento ativo. Esta primeira versão permite que desenvolvedores dApp (ou usuários em geral) se inscrevam em tipos de eventos específicos, mas ainda existem algumas limitações. Nos exemplos anteriores, você deve ter notado que alguns dos campos não estão mostrando as informações adequadas, e isso é porque certas propriedades ainda não são suportadas pelo Frontier.

Outra limitação está relacionada aos logs do evento. No Ethereum, você pode usar curingas e passar vários endereços de entrada, por exemplo, para filtrar logs específicos. Digamos que gostaríamos de nos inscrever em todos os eventos de um contrato que tenham dois endereços específicos no campo “topic\_1” (lembre-se de que topic\_0 está reservado para a assinatura do evento)Então, poderíamos passar o seguinte tópico como entrada:

topics: [null, [address1, address2]]

Aqui, usando o curinga null no lugar para a assinatura do evento, estamos ouvindo todos os eventos emitidos pelo contrato que assinamos. Mas com essa configuração, também podemos usar um segundo campo de entrada, que é topic\_1, para definir um filtro por endereço, conforme mencionado anteriormente.

O A implementação do Frontier não oferece suporte a esses recursos. Como alternativa, você pode criar várias assinaturas para todos os eventos do contrato e os diferentes endereços, mas isso aumenta o número de operações a serem realizadas. No entanto, espera-se que isso seja suportado em versões futuras do Moonbase TestNet.

Fale conosco

Se você tiver algum comentário sobre o Moonbase Alpha v2, pub / sub ou qualquer outro Tópico relacionado ao Moonbeam, sinta-se à vontade para visitar nosso site ou entrar em contato por meio de nosso desenvolvimento oficial servidor Discord .

Originalmente publicado em https://www.purestake.com em 13 de outubro de 2020.