Você já se perguntou como encontrar o evento no contrato inteligente e como lê-los?
Neste artigo, apresentarei um passo a passo para encontrar o maior swap em USD na 1inch.
Se você ainda não ouviu falar de 1inch, 1inch é uma rede distribuída para protocolos descentralizados que permitem as operações mais lucrativas, rápidas e protegidas em DeFi.
Leia mais aqui e https://app.1inch.io/
Antes que possamos descobrir como isso é feito, alguns dados devem ser preparados de antemão, conforme listado abaixo:
- Endereço do contrato router da 1inch e sua ABI
- Nome de evento do swap
- Bloco inicial do swap
- Endereço do token de stablecoins
Sumário
1 . Preparar dados
..... . Endereço do contrato router da 1inch e ABI
..... . Nome de evento do swap
..... . Bloco inicial do evento Swapped
..... . Endereço de contrato de Stablecoins
2 . Encontre o maior swap na 1Inch v3
..... . Configure um projeto NodeJS
..... . Prepare os dados necessários
..... . Leia os eventos anteriores do contrato
..... . Filtre os eventos Swapped para as stablecoins
3 . Conclusão
Preparar dados
Endereço do contrato router da 1inch e ABI
Eu tenho o endereço do contrato router da 1inch ao tentar fazer um trade na 1inch e, em seguida, copiei o endereço de destino para a Metamask. Portanto, eu encontro o endereço do contrato router da 1inch que é: 0x11111112542D85B3EF69AE05771c2dCCff4fAa26
.
O contrato ABI pode ser encontrado no Etherscan
Nome de evento do swap
Precisamos do nome de evento do swap para filtrar os eventos acionados pelo contrato router da 1inch. Então, vou ler o contrato deles usando o Etherscan e, em seguida, procuro o evento do swap que pode ser encontrado na captura de tela abaixo.
evento Swapped no contrato AggregationRouterV3
Como você pode ver, o nome do evento é Swapped
.
Bloco inicial do evento Swapped
O primeiro bloco em que o evento Swapped
acontece deve ser conhecido porque não queremos perder nenhum evento. Eu encontrei ele pesquisando no google o artigo 1Inch publicado no Medium. A data de publicação é 16 de março de 2021
. Assim, podemos supor que não houve nenhum evento Swapped
significativo ocorrido antes disso.
O próximo problema é como encontrar o número do bloco em 16 de março de 2021
?
Temos boas notícias, podemos encontrá-lo facilmente utilizando a API Covalent! A API para este caso é a API Get block heights. Vamos tentar usá-la com curl
.
curl -X GET "https://api.covalenthq.com/v1/1/block_v2/2021-03-16/2021-05-20/?page-size=1&key=ckey_75720a8fd64c4f6f9c6acbabaf9" \
-H "Accept: application/json"
A resposta é essa
1 {
2 "data": {
3 "updated_at": "2021-05-19T18:21:35.275391530Z",
4 "items": [
5 {
6 "signed_at": "2021-03-16T00:00:09Z",
7 "height": 12046295
8 }
9 ],
10 "pagination": {
11 "has_more": true,
12 "page_number": 0,
13 "page_size": 1,
14 "total_count": 420106
15 }
16 },
17 "error": false,
18 "error_message": null,
19 "error_code": null
20 }
A altura do bloco em 16 de março de 2021 é 12046295
. Excelente! Graças à incrível API Covalent.
Endereço de contrato de Stablecoins
Neste artigo, vou me concentrar apenas no swap de Stablecoins porque posso omitir os serviços de alimentação de preços, que são mais complicados de medir o valor do swap. Para manter as coisas simples, vamos nos concentrar no swap de Stablecoins.
O endereço do contrato de tokens é fácil de encontrar. Ele pode ser encontrado no explorador de blocos ou em qualquer serviço agregador de dados cripto, por exemplo. Coingecko, Coinmarketcap, etc. Então as Stablecoins que vamos usar são:
Ethereum Chain
USDT = 0xdac17f958d2ee523a2206206994597c13d831ec7
USDC = 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
DAI = 0x6b175474e89094c44da98b954eedeac495271d0f
Binance Smart Chain
USDT = 0x55d398326f99059ff775485246999027b3197955
USDC = 0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d
DAI = 0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3
BUSD = 0xe9e7cea3dedca5984780bafc599bd69add087d56
Agora, tenho todos os dados necessários. A seguir, vamos ver como posso encontrar o maior swap na 1inch v3.
Encontre o maior swap na 1Inch v3
Configure um projeto NodeJS
Primeiro, criei um novo projeto Node.js com npm init
em uma pasta vazia com web3.js
como dependência.
Prepare os dados necessários
Depois de ter meu projeto pronto, crio um novo arquivo chamado index.js
. Em seguida, mantenha todos os dados que coletamos na seção anterior em variáveis. Por fim, crie o web3
e contract
do agregador 1inch v3.
const Web3 = require('web3')
const routerAbi = require('./abi/router.json')
// O mais comum geth rpc é infura.
const GETH_RPC_ENDPOINT = "YOUR_GETH_RPC_ENDPOINT"
// Primeiro bloco em 2021-03-16 na Ethereum
const fromBlock = "12046295"
// Contrato 1Inch's AggregatorRouterV3
const routerV3 = "0x11111112542D85B3EF69AE05771c2dCCff4fAa26"
async function printBiggestSwap() {
const web3 = new Web3(GETH_RPC_ENDPOINT)
const contract = new web3.eth.Contract(routerAbi, routerV3)
}
printBiggestSwap()
Leia os eventos anteriores do contrato
Esta etapa é a razão pela qual eu quero usar o web3. O Web3 pode ler todos os eventos para determinado endereço de contrato e o nome do evento. Portanto, meu código agora se parece com este abaixo.
const Web3 = require('web3')
// O mais comum geth rpc é infura.
const GETH_RPC_ENDPOINT = "YOUR_GETH_RPC_ENDPOINT"
// Primeiro bloco em 2021-03-16 na Ethereum
const fromBlock = "12046295"
// Contrato 1Inch's AggregatorRouterV3
const routerV3 = "0x11111112542D85B3EF69AE05771c2dCCff4fAa26"
async function printBiggestSwap() {
const web3 = new Web3(GETH_RPC_ENDPOINT)
const contract = new web3.eth.Contract(routerAbi, routerV3)
// Isso não funcionará se o contrato tiver mais de 10 milk eventos.
// Portanto, não escreva assim.
const _result = await contract.getPastEvents("Swapped", {
fromBlock
})
// Em vez disso, leremos eventos limitados por rodada até atingir o último bloco.
const eventsPerRound = 10000;
const latestBlock = await web3.eth.getBlockNumber();
const _toBlock = Math.min(fromBlock + eventsPerRound, latestBlock)
let events = []
while (_toBlock < latestBlock) {
const _events = await contract.getPastEvents("Swapped", {
fromBlock,
toblock: _toBlock
})
events = events.concat(_events)
}
}
printBiggestSwap()
Os eventos passados podem ser lidos como a linha 17 — 19
. Infelizmente, o serviço Geth RPC não permitirá que o cliente consulte eventos com mais de 10 mil eventos por chamada. Portanto, precisamos reduzir os eventos retornados por chamada e continuar inserindo-os gradualmente em um array. Ver linha 22 - 33
Se você quer saber como o objeto event é retornado a partir de getPastEvents
, veja abaixo:
{
address: '0x11111112542D85B3EF69AE05771c2dCCff4fAa26',
blockNumber: 5746136,
transactionHash: '0x3d838039c450b1af55ba1c57d667bf800177d69936d412e0c698e80b83099007',
transactionIndex: 48,
blockHash: '0x0928fdc5f83087bcdc97b4ae7bc769b4f91550e42e220722168f9e59c640508e',
logIndex: 233,
removed: false,
id: 'log_40e4073c',
returnValues: Result {
'0': '0x0D080A3c3290C98E755d8123908498BcE2C5620d',
'1': '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
'2': '0x55d398326f99059fF775485246999027B3197955',
'3': '0x0D080A3c3290C98E755d8123908498BcE2C5620d',
'4': '2000200000000000000000000',
'5': '2000031648518588335779396',
sender: '0x0D080A3c3290C98E755d8123908498BcE2C5620d',
srcToken: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
dstToken: '0x55d398326f99059fF775485246999027B3197955',
dstReceiver: '0x0D080A3c3290C98E755d8123908498BcE2C5620d',
spentAmount: '2000200000000000000000000',
returnAmount: '2000031648518588335779396'
},
event: 'Swapped',
signature: '0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8',
raw: {
data: '0x0000000000000000000000000d080a3c3290c98e755d8123908498bce2c5620d000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d5600000000000000000000000055d398326f99059ff775485246999027b31979550000000000000000000000000d080a3c3290c98e755d8123908498bce2c5620d00000000000000000000000000000000000000000001a78f0f2c56360820000000000000000000000000000000000000000000000001a785eed3b9d4df19ee44',
topics: [
'0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8'
]
}
}
Filtre os eventos Swapped para as stablecoins
Como nos concentramos apenas no evento swap que tem stablecoin pelo menos de um lado, nós precisamos filtrar e descartar aqueles eventos swap que não têm stablecoins.
Como podemos obter o endereço do contrato de token a partir da resposta? Felizmente, ele já está incluído no objeto event como acima. Então você pode ver dstToken
(Token de destino) e srcToken
(Token de origem) que significam:
-
dstToken
endereço de contrato do token que o remetente obterá após o swap -
srcToken
endereço de contrato do token que o remetente usa para o swap
Já temos o endereço de contrato de Stablecoins, então meu código evolui para este:
const Web3 = require('web3')
// O mais comum geth rpc é infura.
const GETH_RPC_ENDPOINT = "YOUR_GETH_RPC_ENDPOINT"
// Primeiro bloco em 2021-03-16 na Ethereum
const fromBlock = "12046295"
// Contrato 1Inch's AggregatorRouterV3
const routerV3 = "0x11111112542D85B3EF69AE05771c2dCCff4fAa26"
async function printBiggestSwap() {
const web3 = new Web3(GETH_RPC_ENDPOINT)
const contract = new web3.eth.Contract(routerAbi, routerV3)
// Isso não funcionará se o contrato tiver mais de 10 milk eventos.
// Portanto, não escreva assim.
const _result = await contract.getPastEvents("Swapped", {
fromBlock
})
// Em vez disso, leremos eventos limitados por rodada até atingir o último bloco.
const eventsPerRound = 10000;
const latestBlock = await web3.eth.getBlockNumber();
const _fromBlock = fromBlock
const _toBlock = Math.min(fromBlock + eventsPerRound, latestBlock)
let biggestSwap;
while (_toBlock < latestBlock) {
const _events = await contract.getPastEvents("Swapped", {
fromBlock: _fromBlock,
toblock: _toBlock
})
const filteredEvents = _events.forEach({ returnValues } => {
if(isStableCoins(returnValues.dstToken)) {
biggestSwap = Math.max(biggestSwap, parseInt(returnValues.returnAmount))
}
if(isStableCoins(returnValues.srcToken)) {
biggestSwap = Math.max(biggestSwap, parseInt(returnValues.spentAmount))
}
})
_fromBlock = _toBlock + 1
_toBlock = Math.min(_toBlock + eventsPerRound, latestBlock)
}
console.log(biggestSwap)
}
function isStableCoins(token) {
const USDT = "0xdac17f958d2ee523a2206206994597c13d831ec7"
const USDC = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
const DAI = "0x6b175474e89094c44da98b954eedeac495271d0f"
const stablecoins = [USDT, USDC, DAI]
return stablecoins.indexOf(token.toLowerCase()) > -1
}
printBiggestSwap()
Vamos dar uma olhada no código adicional da etapa anterior.
Linha 34 a 42
- Verifique se o evento é swap de Stablecoins
- Se for um swap de Stablecoins, atribua um evento de swap maior à variável
biggestSwap
Linha 45 a 46
- Incrementar blocos para consultar eventos passados.
Linha 49
- Imprima o maior swap
Linha 52–58
- Retorna true se o endereço do contrato de token fornecido for USDT, USDC ou DAI
E a linha final imprime a maior transação de swap.
O resultado está abaixo:
{
address: '0x11111112542D85B3EF69AE05771c2dCCff4fAa26',
blockHash: '0x7936392cd01131f7e21bdd353a4b5a7b96f8fd3bba0d02fa9e2afada1365c74e',
blockNumber: 12446903,
logIndex: 69,
removed: false,
transactionHash: '0x6b1594e1a7aa3f2dfa3b00f8913745d961579d7e7e97950364cce11c02459d56',
transactionIndex: 5,
id: 'log_bc980976',
returnValues: Result {
'0': '0xB66f8015E916e0d6590761Ed299BF4B3BDF40006',
'1': '0x6B175474E89094C44Da98b954EedeAC495271d0F',
'2': '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
'3': '0xB66f8015E916e0d6590761Ed299BF4B3BDF40006',
'4': '31407288037329481247334373',
'5': '8607683887337745631338',
sender: '0xB66f8015E916e0d6590761Ed299BF4B3BDF40006',
srcToken: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
dstToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
dstReceiver: '0xB66f8015E916e0d6590761Ed299BF4B3BDF40006',
spentAmount: '31407288037329481247334373',
returnAmount: '8607683887337745631338'
},
event: 'Swapped',
signature: '0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8',
raw: {
data: '0x000000000000000000000000b66f8015e916e0d6590761ed299bf4b3bdf400060000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000b66f8015e916e0d6590761ed299bf4b3bdf4000600000000000000000000000000000000000000000019fac07f003f6ee5459fe50000000000000000000000000000000000000000000001d29f9c4a11e3d3486a',
topics: [
'0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8'
]
}
}
Você pode ver os detalhes desta transação aqui. Vale cerca de $ 31 milhões e pagou 0,91 ETH pela taxa de gás.
Para a Binance Smart Chain, será um pouco diferente. Por exemplo, o nó BSC não permitirá consultas que retornem mais de 5.000 resultados e o nó Geth rpc fica inativo com bastante frequência. Portanto, você pode considerar reduzir eventsPerRound
e agrupar a chamada getPastEvent
com lógica de repetição. Se você está curioso para ver o resultado no BSC. O resultado está abaixo (o último bloco é 7601227
quando o script é executado)
{
address: '0x11111112542D85B3EF69AE05771c2dCCff4fAa26',
blockNumber: 7360052,
transactionHash: '0xd58b583ccc04c2502828bd1d20a7d31f61806a839108cdad6ff2b19ca9a36fd9',
transactionIndex: 116,
blockHash: '0xee0c3a305ed738ea0d7629af6d93e0fccd291fb80f1732f22c4dd329dbe07aec',
logIndex: 142,
removed: false,
id: 'log_bf221914',
returnValues: Result {
'0': '0x0426266CF573388100183343b6e26b8bf5e4FDBb',
'1': '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82',
'2': '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
'3': '0x0426266CF573388100183343b6e26b8bf5e4FDBb',
'4': '420189781342653493372938',
'5': '11524614549462974075302973',
sender: '0x0426266CF573388100183343b6e26b8bf5e4FDBb',
srcToken: '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82',
dstToken: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
dstReceiver: '0x0426266CF573388100183343b6e26b8bf5e4FDBb',
spentAmount: '420189781342653493372938',
returnAmount: '11524614549462974075302973'
},
event: 'Swapped',
signature: '0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8',
raw: {
data: '0x0000000000000000000000000426266cf573388100183343b6e26b8bf5e4fdbb0000000000000000000000000e09fabb73bd3ade0a17ecc321fd13a19e81ce82000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d560000000000000000000000000426266cf573388100183343b6e26b8bf5e4fdbb0000000000000000000000000000000000000000000058fa889fde44c0a9680a00000000000000000000000000000000000000000009886e9b48c7c6ff54f43d',
topics: [
'0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8'
]
}
}
Os detalhes da transação podem ser lidos aqui. São cerca de 420k $ CAKE trocados por $ 11,5 milhões $ BUSD. É um swap menor do que a transação na Ethereum. Portanto, a maior troca com Stablecoins desde que a 1inch v3 começou oficialmente é
https://etherscan.io/tx/0x6b1594e1a7aa3f2dfa3b00f8913745d961579d7e7e97950364cce11c02459d56 (Testado em 20 de maio de 2021)
Conclusão
As etapas para obter esses dados são bastante complicadas. Felizmente, casos de uso como esse se tornarão muito mais fáceis com a API Covalent. Ela suporta 1 milhão de blocos por chamada. Observe que ainda está na versão beta, se você encontrou algum bug, pode relatar a eles em seu canal no Discord #feedback-and-support
. Assim, podemos obter uma API ainda melhor para usar. Espero que este artigo ajude você a entender como ler o evento do contrato na blockchain mais facilmente. Saúde.
O código completo está hospedado aqui: https://github.com/npty/data-dungeon
Esse artigo é uma tradução feita por @bananlabs. Você pode encontrar o artigo original aqui
Latest comments (0)