FMZ を使って簡単な入門 エーサインベースのweb3開発

作者: リン・ハーン発明者 量化 - 微かな夢作成日:2023-03-28 13:32:48,更新日:2024-11-11 22:28:24 更新日:2021-03-28 更新日:2021-01-11 更新日:2021-01-11 更新日:2021-01-11 更新日:2021-01-21 更新日:2021-01-21 更新日:2021-01-21 更新日:2021-01-21 更新日:2021-01-21 更新日:2021-01-21 更新日:2021-01-21 更新日:2021-01-21 更新日:2021-01-21 更新日:2021-01-21

name:token,type:address],name:approveZeroThenMax,outputs:[],stateMutability:payable,type:function,{inputs:[],stateMutability:payable,type:function},{inputs:[internalType:bytes,addminimumviewdata,lipp:addons},{inputs:[internalType:address,type:token,type:address}],name:approveZeroThenMaxMinusOne,outputs:[],stateMutability:payable,type:function,outputs:[inputs],stateMutability:[payable],type:type:function,type:type, var abiPool = [\\\inputs\:[],\stateMutability\:\\\nonpayable\,\\\\\type\:\\\constructor\,\\\\\\\\\anonymous\:\false,\\\inputs\:\\\\\\\\indexed\:true,\\\\internalType\:\inputs\:\inputs\:\:\inputs\:\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 var abiFactory = [\\inputs\:[],\stateMutability\:\\nonpayable\,\\\\type\:\\\constructor\,\\\\\\anonymous\:\false,\\inputs\:\\\\\indexed\:true,\\internalType\:\uint24\,\\\name\:\\\fee\,\\\type\:\uint24\,\\type\:\type\:\type\:\uint24\:\type\:\uint24\:type\:\uint:type\:\:\uint:type\:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\uanthr:\

契約V3ファクトリー アドレス = 0x1F98431c8aD98523631AE4a59f267346ea31F984 var contractV3SwapRouterV2Address = 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45

function toAmount ((s,小数点) { 返信番号 (大数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数 { \ pos (192,220) }

函数 toInnerAmount ((n,小数点) { return (BigDecimal ((n) * BigDecimal ((Math.pow ((10,小数点))).toFixed ((0) { \ pos (192,220) }

main ((() {の関数について //Uniswap工場契約のABIを登録する exchange.IO ((abi, contractV3FactoryAddress, 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池の現在の価格で1万の料金です.

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.0002031インチ×0.0203WETH) を換算します.

Uniswap V3 取引類データベース

発明家による量化取引プラットフォームの公開Uniswapテンプレートこのテンプレートのソースコードを読み,Web3方向のアプリケーションを開発することができます. このテンプレートのソースコードは,Web3方向のアプリケーションの詳細を学ぶことができます. 模範のデータベースには,学ぶ価値のあるデザインの詳細がたくさんあります:

  • トークン情報を自動的に取得する テンプレートのパラメータが表示される場合,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)
            }
        }

Ethereumを呼び出すRPC方法eth_chainId問い合わせの現在chainIdそして,chainIdWETHのアドレスをマッチします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()Function は,テンプレートの関数をテストする関数で,そのコードはテンプレートをどのように使うかを呼び出す例を示します:

  $.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 トランザクション データベース"を引用しているとき,このテンプレート データベースに包まれた関数を呼び出すことができます.

プロジェクトを立ち上げる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'))

検閲事件

この章では,発明者による量化取引プラットフォームを使用して,Ethereum仮想マシンログに保存されるスマートコントラクトリリースイベントを読み取ることを学びます.

eth_getLogs

スマートコントラクトのリリース事件の検索は,イーサリアムでのRPC方法を使用する必要があります.eth_getLogsチェーンのログデータを取得する,Ethereum RPCノードを呼び出す方法については,前のレッスンで説明しました. ビデオを撮ったときにWETH契約されたイベントのコードは FMZ を使って作成できます.デュージングツールテストでは,取引所のオブジェクトが設定されたRPCノードは,呼び出し中のイーサリアムネットワークのノードです.eth_getLogs方法として,この3つのパラメータを指定します.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事件はフィルタリングされた.

ログ検索

エーサリアムログは2つの部分,1つのテーマに分かれています.topics2 データはdata

  • テーマtopicsありがとうございました.eth_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このハッシュ値 (hex) は0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef


  - 发出地址```from```
  - 接收地址```to```

- 数据```data```
  
  ```data```字段的数据为:

  ```desc
  "data": "0x0000000000000000000000000000000000000000000000000164f2434262e1cc",

イベント内のいくつかのパラメータ (スマートコントラクトのSolidityコード内のパラメータは,インデックスされた宣言がない) は,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/検索結果:

使用FMZ轻松入门基于以太坊的web3开发

テストコードがFMZデビューツールで実行された結果:

使用FMZ轻松入门基于以太坊的web3开发

検索時に必要に応じて解析することもできますfromtoフィールドのデータ,例えば:

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

ランニング結果:

アドレス: 0x12b791bb27b3a4ee958b5a435fea7d49ec076e9c

盗聴契約事件

原因はデュージングツールコードを短時間テストするのみで,コードが実行された後にコンテンツを出力するのみで,リアルタイムで表示できない. 出力ログ. このセクションのコンテンツは,発明者の量化取引プラットフォームを使用して実盤を作成してテストする.

このビデオでは,Ethereumを使います.USDTこの通貨の契約はTransfer(address,address,uint256)事件は,前回のレッスンで学んだことに基づいて,スマートコントラクトのイベントを継続的に監視する例を設計しました.

`ジャバスクリプト function toAmount ((s,小数点) { 返信番号 (大数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数数 { \ pos (192,220) }

函数 toInnerAmount ((n,小数点) { return (BigDecimal ((n) * BigDecimal ((Math.pow ((10,小数点))).toFixed ((0) { \ pos (192,220) }

addEventListener (契約) アドレス,イベント,コールバック var self = {} self.eventHash = 0x + エンコード (keccak256, string, hex, イベント) self.contractAddress = 契約 アドレス self.latestブロック番号 = 0 self.fromブロック数 = 0 self.firstブロック番号 = 0 /* TODO:テスト 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 = {

もっと見る