Die Ressourcen sind geladen. Beförderung...

Einfache Einführung in web3-Entwicklung auf Basis von Ethereum mit FMZ

Schriftsteller:Die Erfinder quantifizieren - Kleine Träume, Erstellt: 2023-03-28 13:32:48, Aktualisiert: 2024-11-11 22:28:24

Name: token,type:address],name:approveZeroThenMax,outputs:[],stateMutability:payable,type:bytefunction,{inputs:[stateMutability:payable,type:function},{inputs:[{internalType:payable,type:function},inputs:[internalType:address,name:token,type:address}],name:[approveZeroThenMaxMinusOne,outputs:[],stateMutability:payable,type:bytefunction,{inputs:[],[stateMutability:payable,type:type:type:type,type:type,type,type,type [inputs:[],stateMutability:nonpayable,type:constructor},{anonymous:true:false,inputs:[indexed:true,internalType:address,name:owner,type:address},{indexed:true,internalType:int24,stateMutability:nonpayable,type:int24},{anonymous:true,internalType:int24,name:addaddaddaddadd:true,internalType:address:address,name:owner,type:address:address:address:address:address:address:address:address:address:address: [{inputs:[],stateMutability:nonpayable,type:int24},{anonymous:false,inputs:[{indexed:true,internalType:uint24,name:fee,type:uint24},{indexed:true,internalType:int24,name:tickSpacing,type:int24},{addname:FeeAuntmobled,type:false,addaddaddaddaddaddaddaddaddinfalse:Created,inputs:addaddaddaddaddaddaddaddaddinfalse:indexed:

VerträgeV3FabrikAdresse = 0x1F98431c8aD98523631AE4a59f267346ea31F984 Der Wert der Verzögerung wird durch die Verzögerung der Verzögerung der Verzögerung der Verzögerung verringert.

Funktion toAmount ((s, Dezimalstellen) { Rückgabe Nummer (n) (BigDecimal (n) (BigInt (n)) / BigDecimal (n) (Math.pow (n)) (n), (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n) (n - Ich weiß.

Funktion toInnerAmount ((n, Dezimalstellen) { Rückgabe (BigDecimal(n) * BigDecimal(Math.pow(10, Dezimalstellen))).zu Festgesetzt(0) - Ich weiß.

Funktion main (() { // Registrierung der Uniswap-Werkverträgeexchange.IO("abi", VertragV3FactoryAdresse, abiFactory)

// 注册Uniswap路由合约的ABI
exchange.IO("abi", contractV3SwapRouterV2Address, abiRoute)

// 获取交易对的池地址
var tokenIn = {name : "1INCH", address: "0x111111111117dC0aa78b770fA6A738034120C302", decimals: exchange.IO("api", "0x111111111117dC0aa78b770fA6A738034120C302", "decimals")}
var tokenOut = {name : "WETH", address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", decimals: exchange.IO("api", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "decimals")}
var poolAddress = exchange.IO("api", contractV3FactoryAddress, "getPool", tokenIn.address, tokenOut.address, 10000)

// 注册池合约ABI
exchange.IO("abi", poolAddress, abiPool)

var slot0 = exchange.IO("api", poolAddress, "slot0")
Log("slot0:", slot0)

}


获取到兑换池的价格信息,打印出代码中```slot0```变量:

```javascript
{
    "feeProtocol":0,
    "unlocked":true,
    "sqrtPriceX96":"1128983883551457130720648561",
    "tick":"-85025",
    "observationIndex":5,
    "observationCardinality":6,
    "observationCardinalityNext":6
}

Die wichtigsten Preisinformationen werden insqrtPriceX96Das Feld, das zusammen mit den Token-Genauigkeitsdaten der Umtauschkombination benötigt wird, berechnet den aktuellen Preis des Umtauschpools, basierend aufUniswapDie Dokumentation beschreibt, wie wir eine Funktion implementieren, um zu berechnen:

function computePoolPrice(decimals0, decimals1, sqrtPriceX96) {
    // sqrtPriceX96 = sqrt(price) * 2^96
    [decimals0, decimals1, sqrtPriceX96] = [decimals0, decimals1, sqrtPriceX96].map(BigInt);
    const TWO = BigInt(2);
    const TEN = BigInt(10);
    const SIX_TENTH = BigInt(1000000);
    const Q192 = (TWO ** BigInt(96)) ** TWO;
    return (
        Number((sqrtPriceX96 ** TWO * TEN ** decimals0 * SIX_TENTH) / (Q192 * TEN ** decimals1)) /
        Number(SIX_TENTH)
    );
}

Mit dieser Funktion berechnen wir die Token-Kombination1INCH/WETHDie Preise für den Umtausch von 10.000 Pools liegen bei den aktuellen Preisen.

function computePoolPrice(decimals0, decimals1, sqrtPriceX96) {
    // sqrtPriceX96 = sqrt(price) * 2^96
    [decimals0, decimals1, sqrtPriceX96] = [decimals0, decimals1, sqrtPriceX96].map(BigInt);
    const TWO = BigInt(2);
    const TEN = BigInt(10);
    const SIX_TENTH = BigInt(1000000);
    const Q192 = (TWO ** BigInt(96)) ** TWO;
    return (
        Number((sqrtPriceX96 ** TWO * TEN ** decimals0 * SIX_TENTH) / (Q192 * TEN ** decimals1)) /
        Number(SIX_TENTH)
    );
}

function main() {
    var tokenIn = {name : "1INCH", address: "0x111111111117dC0aa78b770fA6A738034120C302", decimals: exchange.IO("api", "0x111111111117dC0aa78b770fA6A738034120C302", "decimals")}
    var tokenOut = {name : "WETH", address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", decimals: exchange.IO("api", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "decimals")}

    // 获取的slot0变量中"sqrtPriceX96":"1128983883551457130720648561",
    var price = computePoolPrice(tokenIn.decimals, tokenOut.decimals, "1128983883551457130720648561")
    Log("price:", price)
}

Variablen druckenpriceZeigt:price: 0.000203Ein 1 INCH ist für 0.000203 WETH.

Uniswap V3 Handelskatalog

Die Erfinder der quantitativen Handelsplattform veröffentlichen ein gut verpacktesUniswapSchablonenDie Funktionen zum Umtauschen, Erhalten von Preisen und Abfragen von Geldbeutelbalancen sind bereits realisiert. Es ist nicht mehr notwendig, den Code nach oben beschriebenen Inhalten zu schreiben. Es gibt viele Design-Details in der Template-Klasse, die es wert sind, gelernt zu werden:

  • Automatisierte Tokeninformationen Wenn Sie einen Code aus der Schablone ziehen, werden die Parameter der Schablone angezeigt.AutoFetchTokensWenn sie auf "true" gesetzt ist, wird der Vorlageprogramm automatisch zugegriffen.https://tokens.coingecko.com/uniswap/all.jsonLinking, Abrufen und automatische Verarbeitung aller Token. So kann man ohne manuelle Hinzufügung eines Tokens in der Strategiecode (wenn nicht, muss es verwendet werden)addToken(name, address)Das ist ein großartiges Projekt.

         if (AutoFetchTokens) {
              let res = JSON.parse(HttpQuery("https://tokens.coingecko.com/uniswap/all.json"))
              Log("fetch", res.tokens.length, "tokens from", res.name)
              res.tokens.forEach(function(token) {
                  if (token.chainId == chainId && token.symbol != "WETH") {
                      self.tokenInfo[token.symbol] = {
                          name: token.symbol,
                          decimals: token.decimals,
                          address: token.address
                      }
                  }
              })
          }  
    
  • Je nach Ketteneinstellung unterschiedliche Vertragsadressen Die Vorlage ist eingerichtet.ChainTypeParameter, die mehrere Ketten unterstützen:

      'https://rpc.ankr.com/eth',
      'https://arb1.arbitrum.io/rpc',
      'https://mainnet.optimism.io/',
      'https://rpc.ankr.com/avalanche',
      'https://polygon-rpc.com',
      'https://rpc.ankr.com/celo',
    

    Siehe auch:

          if (typeof(ChainType) === 'number') {
              let chainRpc = [
                  '',
                  'https://rpc.ankr.com/eth',
                  'https://arb1.arbitrum.io/rpc',
                  'https://mainnet.optimism.io/',
                  'https://rpc.ankr.com/avalanche',
                  'https://polygon-rpc.com',
                  'https://rpc.ankr.com/celo',
                  //'https://mainnet.aurora.dev',
                  //'https://bsc-dataseed.binance.org',
                  //'https://exchainrpc.okex.org'
              ][ChainType]
              if (chainRpc && chainRpc.length > 0) {
                  e.IO("base", chainRpc)
                  Log("change base rpc to", chainRpc)
              }
          }
    

    RPC-Methode für den Aufruf von Ethereumeth_chainIdNachfrage aktuellchainIdDas ist nicht wahr.chainIdIch habe die Adresse von WETH angepasst.UniswapSie haben eine Reihe von Adressen für Verträge.USDTEin Smart Contract kann auf verschiedenen Ketten unterschiedliche Anschriften haben.

    Siehe auch:

          // https://docs.uniswap.org/contracts/v3/reference/deployments
          let WETHAddress = {
              1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // Ethereum
              3: "0xc778417E063141139Fce010982780140Aa0cD5Ab", // Ropsten
              4: "0xc778417E063141139Fce010982780140Aa0cD5Ab", // Rinkeby
              5: "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", // Goerli
              42: "0xd0A1E359811322d97991E03f863a0C30C2cF029C", // Kovan
              10: "0x4200000000000000000000000000000000000006", // Optimism
              69: "0x4200000000000000000000000000000000000006", // Optimistic Kovan
              42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", // Arbitrum One
              421611: "0xB47e6A5f8b33b3F17603C83a0535A9dcD7E32681", // Arbitrum Rinkeby
              137: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", // Polygon
              80001: "0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889", // Polygon Mumbai
          }
    
          let chainId = e.IO("api", "ETH", "eth_chainId")
          if (chainId) {
              chainId = Number(chainId)
              Log("chainId: ", chainId)
              let addr = WETHAddress[chainId]
              if (addr) {
                  Log("Register WETH address", addr)
                  self.addToken("ETH", addr)
              }
              if (chainId == 42220) {
                  // Celo Address
                  ContractV3Factory = '0xAfE208a311B21f13EF87E33A90049fC17A7acDEc'
                  ContractV3SwapRouterV2 = '0x5615CDAb10dc425a742d643d949a7F474C01abc4'
                  self.addToken('CELO', '0x471ece3750da237f93b8e339c536989b8978a438')
              } else if (chainId == 42161) {
                  self.addToken('USDT', '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9')
              }
          } else {
              panic("get chain Id error")
          }
    
  • Mit der Uniswap V3 Exchange-Klasse

    In dieser Vorlage$.testUniswap()Die Funktion ist eine Funktion, die die Funktion eines Templates testet, und deren Code Anwendungsbeispiele für die Verwendung der Template enthält:

    $.testUniswap = function() {
        let ex = $.NewUniswapV3()
        Log("walletAddress: ", ex.walletAddress)
        let tokenAddressMap = {
            "USDT": "0xdac17f958d2ee523a2206206994597c13d831ec7",
            "1INCH": "0x111111111117dC0aa78b770fA6A738034120C302",
            "USDC": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
            "DAI": "0x6b175474e89094c44da98b954eedeac495271d0f",
        }
        for (let name in tokenAddressMap) {
            ex.addToken(name, tokenAddressMap[name])
        }
    
        Log(ex.getPrice('ETH_USDT'))
        Log(ex.getPrice('1INCH_USDT'))
    
        // swap 0.01 ETH to USDT
        Log(ex.swapToken('ETH', 0.01, 'USDT'))
        let usdtBalance = ex.balanceOf('USDT')
        Log("balance of USDT", usdtBalance)
    
        // swap USDT to DAI then DAI to ETH
        Log(ex.swapToken('USDT', usdtBalance, 'DAI,ETH'))
    
        Log("balance of ETH", ex.getETHBalance())
    
        // Log(ex.sendETH('0x11111', 0.02))
        
        // ...
    }
    

    Wenn eine Politik auf die "Uniswap V3 Transaktions-Klasse" verweist (wie man auf die Template-Klasse verweist, kann man in der FMZ-Plattformdokumentation lesen), kann man die Funktion aufrufen, die in dieser Template-Klasse verpackt ist.

    Erstellen Sie einexVariablen, die die Schablone "Uniswap V3 Transaktionslibrary" anrufen$.NewUniswapV3()Es gibt eine Art, ein Objekt zu erstellen, dem man einen Wert gibt.ex

    let ex = $.NewUniswapV3()
    

    NutzungexMitgliederfunktionen von ObjektenaddToken()Das bedeutet, dass Sie sich nicht mehr für die Nutzung des Tokens entscheiden müssen.

      let tokenAddressMap = {
          "USDT": "0xdac17f958d2ee523a2206206994597c13d831ec7",
          "1INCH": "0x111111111117dC0aa78b770fA6A738034120C302",
          "USDC": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
          "DAI": "0x6b175474e89094c44da98b954eedeac495271d0f",
      }
      for (let name in tokenAddressMap) {
          ex.addToken(name, tokenAddressMap[name])
      }
    

    Wenn Sie den Preis eines Tauschpools für ein Paar erhalten und drucken möchten, können SieexMitgliederfunktionen von ObjektengetPrice()Das kann man so schreiben:

      Log(ex.getPrice('ETH_USDT'))
      Log(ex.getPrice('1INCH_USDT'))
    

    Wenn Sie eine Umtauschoperation ausführen möchten, können SieexMitgliederfunktionen von ObjektenswapToken()Erstmals:

      // swap 0.01 ETH to USDT
      Log(ex.swapToken('ETH', 0.01, 'USDT'))
      let usdtBalance = ex.balanceOf('USDT')
      Log("balance of USDT", usdtBalance)
    
      // swap USDT to DAI then DAI to ETH
      Log(ex.swapToken('USDT', usdtBalance, 'DAI,ETH'))
    

Ersuchen

In diesem Kapitel werden wir lernen, wie man mit Hilfe der inventor-quantitative Handelsplattform die Veröffentlichungen von Smart Contracts liest, die in den Logs der Ethereum-Maschine gespeichert werden.

Eth_getLogs

Die Veröffentlichung von Smart Contract-Ereignissen erfordert die Verwendung der RPC-Methode von Ethereumeth_getLogsDas ist ein einfacher Weg, um die Logdaten auf der Kette zu erhalten, wie wir es in einem früheren Kurs erklärt haben. Zum Beispiel, wenn wirWETHDie Verträge können Code schreiben, der FMZ verwendet wird, um die Ereignisse zu erfassen.Debugging-ToolsTests, anhand derer die RPC-Nodes, an denen die Austauschobjekte konfiguriert sind, als Ethereum-Nodes aufgerufen werdeneth_getLogsWir haben drei Parameter für die Methode.fromBlocktoBlockaddressWir verwenden die Parameter fromBlock und toBlock, um Daten innerhalb eines Blocks zu querieren:

function toAmount(s, decimals) {
    return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}

function toInnerAmount(n, decimals) {
    return (BigDecimal(n) * BigDecimal(Math.pow(10, decimals))).toFixed(0)
}

function main() {
    // getBlockNumber
    var blockNumber = exchange.IO("api", "eth", "eth_blockNumber")
    Log("blockNumber:", blockNumber)

    // get logs
    var fromBlock = "0x" + (toAmount(blockNumber, 0) - 1).toString(16)
    var toBlock = "0x" + toAmount(blockNumber, 0).toString(16)
    var params = {
        "fromBlock" : fromBlock,
        "toBlock" : toBlock,
        "address" : "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"   // WETH合约的地址
    }
    var logs = exchange.IO("api", "eth", "eth_getLogs", params)

    // 由于数据量比较大,如果使用Log函数打印,数据会被截断。使用return将完整数据返回在页面「函数结果」编辑框中
    return logs   
}

Die Daten, die in den Logs eingegeben werden, sind viel größer, daher lassen wir einige davon aus:

[{
	"data": "0x00000000000000000000000000000000000000000000000001c1a55000000000",
	"topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x0000000000000000000000006b75d8af000000e20b7a7ddf000ba900b4009a80", "0x000000000000000000000000bcb095c1f9c3dc02e834976706c87dee5d0f1fb6"],
	"transactionHash": "0x27f9bf5abe3148169b4b85a83e1de32bd50eb81ecc52e5af006157d93353e4c4",
	"transactionIndex": "0x0",
	"removed": false,
	"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
	"blockHash": "0x847be24a7b159c292bda030a011dfec89487b70e71eed486969b032d6ef04bad",
	"blockNumber": "0x109b1cc",
	"logIndex": "0x0"
}, {
	"data": "0x00000000000000000000000000000000000000000000000008ea20cdea027c00",
	"logIndex": "0x5",
	"topics": ["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c", "0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d"],
	"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
	"blockHash": "0x847be24a7b159c292bda030a011dfec89487b70e71eed486969b032d6ef04bad",
	"blockNumber": "0x109b1cc",
	"removed": false,
	"transactionHash": "0xace3afa02e8af5d1ef6fc1635fbdf7bee37624547937ea5272c23968dd034c09",
	"transactionIndex": "0x1"
},

...

{
	"blockNumber": "0x109b1cd",
	"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
	"data": "0x00000000000000000000000000000000000000000000000002c053531ab8a000",
	"logIndex": "0xd3",
	"removed": false,
	"topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x0000000000000000000000001111111254eeb25477b68fb85ed929f73a960582", "0x000000000000000000000000252ba9b5916171dbdadd2cec7f91875a006955d0"],
	"transactionHash": "0x3012b82891f85b077cfe1c12cb9722b93c696ef2c37d67981ccddcc9c3396aca",
	"transactionIndex": "0x8d",
	"blockHash": "0xcd3d567c9bd02a4549b1de0dc638ab5523e847c3c156b096424f56c633000fd9"
}, {
	"topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x00000000000000000000000012b791bb27b3a4ee958b5a435fea7d49ec076e9c", "0x000000000000000000000000ef1c6e67703c7bd7107eed8303fbe6ec2554bf6b"],
	"transactionIndex": "0x91",
	"logIndex": "0xdb",
	"removed": false,
	"blockNumber": "0x109b1cd",
	"data": "0x0000000000000000000000000000000000000000000000000164f2434262e1cc",
	"transactionHash": "0x6aa8d80daf42f442591e7530e31323d05e1d6dd9f9f9b9c102e157d89810c048",
	"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
	"blockHash": "0xcd3d567c9bd02a4549b1de0dc638ab5523e847c3c156b096424f56c633000fd9"
}, {
	"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
	"blockHash": "0xcd3d567c9bd02a4549b1de0dc638ab5523e847c3c156b096424f56c633000fd9",
	"blockNumber": "0x109b1cd",
	"logIndex": "0xde",
	"removed": false,
	"topics": ["0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65", "0x000000000000000000000000ef1c6e67703c7bd7107eed8303fbe6ec2554bf6b"],
	"data": "0x0000000000000000000000000000000000000000000000000164f2434262e1cc",
	"transactionHash": "0x6aa8d80daf42f442591e7530e31323d05e1d6dd9f9f9b9c102e157d89810c048",
	"transactionIndex": "0x91"
}]

Sie können sehen, dass es eine Vielzahl von Ereignissen in den Logdaten gibt, wenn wir uns nur darum kümmern.TransferDie Daten müssen in die Veröffentlichung eingegliedert werden.TransferDer Vorfall wurde herausgefiltert.

Such-Logs

Das Ethereum-Log ist in zwei Teile unterteilt:topics2 Datendata

  • ThematopicsMiteth_getLogsDie Code-Run-out-Ergebnisse von Chapter-Tests sind ein Beispiel.topicsDie Daten in den Feldern sind:

    "topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x00000000000000000000000012b791bb27b3a4ee958b5a435fea7d49ec076e9c", "0x000000000000000000000000ef1c6e67703c7bd7107eed8303fbe6ec2554bf6b"],  
    

    Das hier.topicsDer Wert des (Theme) -Feldes ist eine Arraystruktur, die zur Beschreibung von Ereignissen verwendet wird. Es ist festgelegt, dass die Länge des ((Array)) nicht größer als 4 sein darf. Das erste Element ist der Signatur-Hashwert des Ereignisses. Wir nutzen eine Quantitative Trading Plattform für Erfinder.EncodeDie Funktion kann den Hash-Wert dieser Signatur berechnen, indem sie den folgenden Code verwendet:

    function main() {
        var eventFunction = "Transfer(address,address,uint256)"
        var eventHash = Encode("keccak256", "string", "hex", eventFunction)
        Log("eventHash:", "0x" + eventHash)
        // eventHash: 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
    }
    

    BerechnenTransfer(address,address,uint256)Diekeccak256Der Hash-Wert (hexcode) ist:0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

    topicsDie Werte der Felder sind eine Arraystruktur, wobei das zweite Element und das dritte Element:

    • Anschreibenfrom
    • Adresse der Empfängerto
  • Datendata

    dataDie Daten in den Feldern sind:

    "data": "0x0000000000000000000000000000000000000000000000000164f2434262e1cc",
    

    Einige Parameter in einem Ereignis (die Parameter in Solidity-Code für Smart Contracts, die keine indexierten Aussagen enthalten) werden in einem System gespeichert.dataIch bin ein großer Freund von Ihnen.

    Die Daten analysieren0x0000000000000000000000000000000000000000000000000164f2434262e1cc

    function toAmount(s, decimals) {
        return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
    }
    
    function main() {
        var value = "0x0000000000000000000000000000000000000000000000000164f2434262e1cc"
        Log(toAmount(value, 0) / 1e18)  // 0.10047146239950075
    }
    

    Das Ergebnis ist: 0.10047146239950075, was eine sehr schlechte Zahl ist.dataDie Daten entsprechen dem Betrag der Überweisungen.


Wenn Sie sich mit dem Thema beschäftigen, können Sie sich mit den folgenden Themen beschäftigen:

function toAmount(s, decimals) {
    return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}

function toInnerAmount(n, decimals) {
    return (BigDecimal(n) * BigDecimal(Math.pow(10, decimals))).toFixed(0)
}

function main() {
    // getBlockNumber
    var blockNumber = exchange.IO("api", "eth", "eth_blockNumber")
    Log("blockNumber:", blockNumber)

    // get logs
    var fromBlock = "0x" + (toAmount(blockNumber, 0) - 1).toString(16)
    var toBlock = "0x" + toAmount(blockNumber, 0).toString(16)
    var params = {
        "fromBlock" : fromBlock,
        "toBlock" : toBlock,
        "address" : "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
    }
    var logs = exchange.IO("api", "eth", "eth_getLogs", params)

    // 遍历logs
    var eventFunction = "Transfer(address,address,uint256)"
    var eventHash = "0x" + Encode("keccak256", "string", "hex", eventFunction)
    Log("eventHash:", eventHash)

    var counter = 0
    for (var i = logs.length - 1; i >= 0 && counter < 10; i--) {
        if (logs[i].topics[0] == eventHash) {
            Log("Event Transfer, data:", toAmount(logs[i].data, 0) / 1e18, ", blockNumber:", toAmount(logs[i].blockNumber, 0), ", transactionHash:", logs[i].transactionHash,
              ", log:", logs[i])
            counter++
        }
    }
}

In derhttps://etherscan.io/Nachfrage:

img

Das Ergebnis der Ausführung des Testcodes im FMZ Debugging Tool:

img

Sie können es auch nach Bedarf analysieren.fromtoDie Daten in den Feldern, zum Beispiel:

function main() {
    var from = "0x00000000000000000000000012b791bb27b3a4ee958b5a435fea7d49ec076e9c"
    var address = "0x" + exchange.IO("encodePacked", "address", from)
    Log("address:", address)
}

Das Ergebnis:

Adresse: 0x12b791bb27b3a4ee958b5a435fea7d49ec076e9c

Verhörverträge

AufgrundDebugging-ToolsDer Code kann nur kurzfristig getestet werden und erst nach der Ausführung des Codes ausgegeben werden, kann nicht in Echtzeit angezeigt werden. In diesem Abschnitt erstellen wir eine Echtplatte, die wir mit der quantitativen Handelsplattform der Erfinder testen.

Hier benutzen wir Ethereum, um abzuhören.USDTDer WährungskontraktTransfer(address,address,uint256)Wir entwarfen ein Beispiel, wie wir, basierend auf dem, was wir in der Vorlesung gelernt haben, ständig auf ein Smart-Contract-Ereignis hören:

function toAmount(s, decimals) {
    return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}

function toInnerAmount(n, decimals) {
    return (BigDecimal(n) * BigDecimal(Math.pow(10, decimals))).toFixed(0)
}

function addEventListener(contractAddress, event, callBack) {
    var self = {}
    self.eventHash = "0x" + Encode("keccak256", "string", "hex", event)
    self.contractAddress = contractAddress
    self.latestBlockNumber = 0
    self.fromBlockNumber = 0
    self.firstBlockNumber = 0
    /* TODO: test
    self.isFirst = true 
    */ 

    self.getBlockNumber = function() {
        var maxTry = 10
        for (var i = 0; i < maxTry; i++) {
            var ret = exchange.IO("api", "eth", "eth_blockNumber")
            if (ret) {
                return toAmount(ret, 0)
            }
            Sleep(5000)
        }
        throw "getBlockNumber failed"
    }

    self.run = function() {
        var currBlockNumber = self.getBlockNumber()
        var fromBlock = "0x" + self.fromBlockNumber.toString(16)
        var toBlock = "0x" + currBlockNumber.toString(16)
        var params = {

Mehr