संसाधन लोड हो रहा है... लोड करना...

एफएमजेड के साथ आसान परिचय एथेरियम आधारित वेब 3 विकास

लेखक:आविष्कारक मात्रा - छोटे सपने, बनाया गयाः 2023-03-28 13:32:48, अद्यतनः 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 var abiPool = [inputs:[],stateMutability:nonpayable,type:constructor},{anonymous:true,internalType:int24,inputs:[indexed:true,internalType:address,name:owner,type:address},{indexed:true,internalType:inputs:[],stateMutability:nonpayable,type:int24},{anonymous:true,internalType:int24,inputs:[indexed:true,internalType:address:address:address:name:owner,type:address:address:address:address:address var abiFactory = [{inputs:[],stateMutability:nonpayable,type:int24},{anonymous:false,inputs:[{indexed:true,internalType:uint24,name:fee,type:uint24},{indexed:true,internalType:int24,name:tickSpacing,type:int24},{anonymous:FeeAuntmobled,type:false,inputs:{addaddaddaddaddaddaddaddadd:true,internalType:uint24,name:inputs,name:inputs:{addaddaddaddaddaddaddadd:true,internalType:uint24,type:inputs,

var contractV3FactoryAddress = 0x1F98431c8aD98523631AE4a59f267346ea31F984 var contractV3SwapRouterV2Address = 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45

फ़ंक्शन toAmount ((s, दशमलव) { रिटर्न नंबर (BigDecimal) (BigInt) (s) / (BigDecimal) (Math.pow) (१० दशमलव) (toString)) }

फ़ंक्शन toInnerAmount ((n, दशमलव) { रिटर्न (बिगडेसिमल ((n) *बिगडेसिमल ((Math.pow ((10, दशमलव))).toFixed(0) }

function main (() { // Uniswap कारखाने अनुबंध के लिए पंजीकृत एबीआईexchange.IO("abi", अनुबंधV3FactoryAddress, 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
}

इनमें से मुख्य मूल्य सूचना डेटाsqrtPriceX96एक क्षेत्र, जो विनिमय संयोजन के टोकन सटीकता डेटा के साथ-साथ विनिमय पूल के वर्तमान मूल्य की गणना करने की आवश्यकता है,Uniswapदस्तावेज़ में वर्णित है कि हम एक फ़ंक्शन को लागू करने के लिए गणना करते हैंः

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)
    );
}

इस फ़ंक्शन का उपयोग करके टोकन संयोजन की गणना करें1INCH/WETHइस तरह के एक और उदाहरण के रूप में, हम आपको बता रहे हैं कि हम क्या कर रहे हैं।

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)
}

मुद्रण चरpriceदिखाता हैःprice: 0.000203(1 INCH को 0.000203 WETH में बदला गया) ।

Uniswap V3 ट्रेडिंग लाइब्रेरी

आविष्कारकों ने क्वांटिफाइड ट्रेडिंग प्लेटफॉर्म पर एक अच्छी तरह से पैक की गई जानकारी का खुलासा कियाUniswapटेम्पलेटइस टेम्पलेट के स्रोत कोड को पढ़कर और अधिक गहराई से सीख सकते हैं और वेब 3 दिशा में अनुप्रयोगों का विकास कर सकते हैं। इस टेम्पलेट लाइब्रेरी में कई डिज़ाइन विवरण हैं जिन्हें सीखने की जरूरत हैः

  • स्वचालित रूप से टोकन जानकारी प्राप्त करें एक कोड का एक टुकड़ा निकालें, और उस टेम्पलेट के लिए पैरामीटर का वर्णन करेंAutoFetchTokensजब यह सही पर सेट किया जाता है, तो टेम्पलेट प्रोग्राम स्वचालित रूप से पहुँचता हैhttps://tokens.coingecko.com/uniswap/all.jsonलिंक, प्राप्त करें और स्वचालित रूप से सभी टोकन के बारे में जानकारी संसाधित करें. इस तरह आप नीति कोड में मैन्युअल रूप से किसी टोकन को जोड़ने की आवश्यकता के बिना उपयोग कर सकते हैं।addToken(name, address)टोकन जोड़ें) ।

         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
                      }
                  }
              })
          }  
    
  • चेन सेटिंग्स के आधार पर विभिन्न अनुबंध पते को अनुकूलित करें यह टेम्पलेट सेट हैChainTypeपैरामीटर, कई श्रृंखलाओं को स्विच करने के लिए समर्थनः

      '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',
    

    चयन कोडः

          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)
              }
          }
    

    एथेरियम को कॉल करने के लिए आरपीसी विधिeth_chainIdखोजें वर्तमानchainId..chainIdवेथ के पते के अनुरूप।Uniswapएक अनुबंध का पता।USDTएक स्मार्ट कॉन्ट्रैक्ट के विभिन्न चेन पर अलग-अलग कॉन्ट्रैक्ट एड्रेस हो सकते हैं।

    चयन कोडः

          // 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")
          }
    
  • Uniswap V3 लेनदेन श्रेणी संग्रह का उपयोग करना

    इस टेम्पलेट में$.testUniswap()एक फ़ंक्शन एक टेम्पलेट फ़ंक्शन का परीक्षण करता है, जिसका कोड टेम्पलेट का उपयोग करने के उदाहरण देता हैः

    $.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))
        
        // ...
    }
    

    जब कोई नीति "Uniswap V3 लेन-देन वर्ग सूची" (जैसा कि FMZ प्लेटफ़ॉर्म दस्तावेज़ में संदर्भित है) को संदर्भित करती है, तो आप इस टेम्पलेट श्रेणी सूची में शामिल फ़ंक्शन को कॉल कर सकते हैं।

    एक नाम बनायाexचर, "Uniswap V3 लेन-देन वर्गीकरण" टेम्पलेट को कॉल करने वाले इंटरफेस फ़ंक्शन के लिए तैयार$.NewUniswapV3()एक ऑब्जेक्ट बनाने के लिएex

    let ex = $.NewUniswapV3()
    

    उपयोगexऑब्जेक्ट के सदस्य फ़ंक्शनaddToken()यह एक बहुत ही दिलचस्प लेख है।

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

    यदि आप किसी लेन-देन जोड़ी के लिए एक्सचेंज पूल मूल्य प्राप्त करना और प्रिंट करना चाहते हैं, तो इसका उपयोग किया जा सकता हैexऑब्जेक्ट के सदस्य फ़ंक्शनgetPrice()यह इस तरह लिखा जा सकता हैः

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

    यदि आप रूपांतरण ऑपरेशन करना चाहते हैं, तो आप इसका उपयोग कर सकते हैंexऑब्जेक्ट के सदस्य फ़ंक्शनswapToken(), रूपांतरण करेंः

      // 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'))
    

खोज की घटना

इस अध्याय में हम इनोवेटर क्वांटिफाइड ट्रेडिंग प्लेटफॉर्म का उपयोग करके स्मार्ट कॉन्ट्रैक्ट रिलीज़ की घटनाओं को पढ़ना सीखेंगे, जो एथेरियम वर्चुअल मशीन के लॉग में संग्रहीत हैं।

eth_getLogs

एथेरियम के आरपीसी तरीकों का उपयोग करके स्मार्ट कॉन्ट्रैक्ट रिलीज की घटनाओं की जांच करनाeth_getLogsहम पहले के पाठ में बताए गए एथेरियम आरपीसी नोड्स को कॉल करने के तरीके के बारे में जानते हैं। उदाहरण के लिए, हम प्राप्तWETHअनुबंधित घटनाओं के लिए कोड लिखा जा सकता है, और FMZ का उपयोग करडिबगिंग उपकरणपरीक्षण में, एक्सचेंज ऑब्जेक्ट को कॉन्फ़िगर किया गया आरपीसी नोड एथेरियम नेटवर्क नोड के रूप में कॉल किया गया थाeth_getLogsहम तीन मापदंडों को निर्दिष्ट करते हैं।fromBlocktoBlockaddress, हम fromBlock और toBlock पैरामीटर का उपयोग करके एक ब्लॉक के भीतर डेटा को सीमित करने के लिए पूछते हैंः

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   
}

लॉग डेटा प्राप्त करने के लिए, हम डेटा की अधिक मात्रा के कारण इनमें से कुछ को छोड़ देते हैंः

[{
	"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"
}]

आप देख सकते हैं कि लॉग डेटा में कई प्रकार की घटनाएं हैं, अगर हम केवल ध्यान देंTransferघटनाओं को इन आंकड़ों में शामिल करने की आवश्यकता है।Transferघटना फ़िल्टर की गई है।

लॉग खोजें

एथेरियम लॉग को दो भागों में विभाजित किया गया है।topics; 2, डेटाdata

  • विषयtopicseth_getLogsउदाहरण के लिए, अध्याय परीक्षण के लिए कोड रन का परिणाम।topicsफ़ील्ड का डेटा हैः

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

    यहtopics(विषय) फ़ील्ड का मान एक सरणी संरचना है, जिसका उपयोग घटनाओं का वर्णन करने के लिए किया जाता है। यह निर्दिष्ट किया गया है कि इसका ((सरणी) लंबाई 4 से अधिक नहीं हो सकती है। पहला तत्व घटना का हस्ताक्षर हैश मान है। आविष्कारक क्वांटिफाइड ट्रेडिंग प्लेटफॉर्म पर, हम उपयोग करते हैंEncodeफ़ंक्शन इस हस्ताक्षर के हैश मान को निम्न कोड का उपयोग करके गणना कर सकता हैः

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

    गणना कीTransfer(address,address,uint256)काkeccak256हैश मान (हेक्स कोड)0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

    topicsफ़ील्ड का मान एक सरणी संरचना है, दूसरा तत्व, तीसरा तत्व क्रमशःः

    • पता भेजेंfrom
    • पता प्राप्त करेंto
  • आंकड़ेdata

    dataफ़ील्ड का डेटा हैः

    "data": "0x0000000000000000000000000000000000000000000000000164f2434262e1cc",
    

    घटना में कुछ पैरामीटर (जो स्मार्ट कॉन्ट्रैक्ट के सॉलिडिटी कोड में पैरामीटर हैं जिनमें इंडेक्स किए गए बयान नहीं हैं) में संग्रहीत किए जाते हैंdataइस लेख में

    इस डेटा का विश्लेषण करें0x0000000000000000000000000000000000000000000000000164f2434262e1cc

    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
    }
    

    यह आंकड़ा 0.10047146239950075 है।dataडेटा हस्तांतरण राशि के अनुरूप है।


एक बार जब हम पहले से ही इस विषय पर काम कर रहे हैं, तो हम पहले से ही इस विषय पर काम कर रहे हैं।

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++
        }
    }
}

मेंhttps://etherscan.io/पूछताछः

img

एफएमजेड डिबगिंग टूल में परीक्षण कोड के परिणामः

img

आप खोज के समय की आवश्यकता के आधार पर भी हल कर सकते हैंfromtoफ़ील्ड का डेटा, उदाहरण के लिएः

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

परिणामः

पताः 0x12b791bb27b3a4ee958b5a435fea7d49ec076e9c

जासूसी अनुबंध

कारणडिबगिंग उपकरणकोड का परीक्षण केवल थोड़े समय के लिए किया जा सकता है, और कोड निष्पादन पूरा होने के बाद ही सामग्री का उत्पादन किया जा सकता है, वास्तविक समय में प्रदर्शित नहीं किया जा सकता है, आउटपुट लॉग। इस अनुभाग में सामग्री का परीक्षण करने के लिए हम आविष्कारकों के क्वांटिफाइड ट्रेडिंग प्लेटफॉर्म का उपयोग करते हैं।

यहाँ हम एथेरियम का उपयोग कर रहे हैं, हम सुन रहे हैं।USDTइस मुद्रा अनुबंध केTransfer(address,address,uint256)घटनाओं के बारे में, हमने पिछले पाठ के आधार पर एक उदाहरण तैयार किया है जिसमें हम लगातार किसी स्मार्ट कॉन्ट्रैक्ट की घटना की निगरानी कर रहे हैंः

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 = {

अधिक