name:
var contractV3FactoryAddress =
hàm toAmount ((s, số thập phân) { trả về Số (s)) / BigDecimal (math.pow), số thập phân))).toString (s)) }
hàm toInnerAmount ((n, số thập phân) { trả về (BigDecimal(n) * BigDecimal(Math.pow(10, số thập phân))).toFixed(0) }
function main (() { // Đăng ký hợp đồng nhà máy Uniswapexchange.IO("abi", hợp đồngV3FactoryAddress, 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
}
Các thông tin về giá cả chính được ghi lại trênsqrtPriceX96
Các trường, cần tính toán giá hiện tại của bể trao đổi dựa trên dữ liệu độ chính xác token của bộ sưu tập trao đổiUniswap
Trong tài liệu mô tả, chúng tôi thực hiện một hàm để tính toán:
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)
);
}
Sử dụng hàm này để tính các token1INCH/WETH
Theo số liệu của các nhà phân tích, tỷ lệ này là 10.000 đồng tại mức giá hiện tại của hồ bơi.
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)
}
In biến sốprice
Hiển thị:price: 0.000203
(Một Inch đổi với 0.000203 WETH)
Các nhà phát minh của nền tảng giao dịch định lượng đã công bố một gói tốtUniswap
Mô hình, đã thực hiện các chức năng như trao đổi, lấy giá, truy vấn số dư ví, không cần phải viết lại mã dựa trên nội dung trong bài giảng ở trên, bạn có thể đọc mã nguồn của mẫu này để tìm hiểu sâu hơn, phát triển các ứng dụng theo hướng Web3.
Có rất nhiều chi tiết thiết kế đáng học trong thư viện mẫu:
Tự động lấy thông tin token
Chọn một trong những đoạn mã giải thích, khi tham số của mẫuAutoFetchTokens
Khi đặt thành đúng, trình duyệt mẫu sẽ truy cập tự độnghttps://tokens.coingecko.com/uniswap/all.json
Liên kết, lấy và xử lý thông tin về tất cả các token tự động.addToken(name, address)
Thêm mã thông báo) ^
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
}
}
})
}
Tùy theo các thiết lập chuỗi, các địa chỉ hợp đồng khác nhau được điều chỉnh
Mẫu đã được thiết lậpChainType
Các tham số hỗ trợ chuyển đổi nhiều chuỗi:
'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',
Mã chọn:
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)
}
}
Phương pháp gọi RPC trên Ethereumeth_chainId
Tìm kiếm hiện tạichainId
Và dựa trênchainId
Một người đàn ông người Việt Nam có thể tìm thấy một người đàn ông khác.Uniswap
Một số địa chỉ hợp đồng.USDT
Một hợp đồng thông minh có thể có địa chỉ hợp đồng khác nhau trên các chuỗi khác nhau.
Mã chọn:
// 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")
}
Sử dụng Uniswap V3
Trong mẫu này$.testUniswap()
Chức năng là một chức năng kiểm tra các chức năng mẫu, mã của nó cung cấp các ví dụ về cách gọi mẫu:
$.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))
// ...
}
Khi một chính sách trích dẫn thư mục giao dịch Uniswap V3 (như trong tài liệu nền tảng FMZ), bạn có thể gọi hàm được gói trong thư mục này.
Tạo một trang web tên làex
Các biến, gọi "Uniswap V3 Transaction Library" mẫu đóng gói chức năng giao diện$.NewUniswapV3()
Tạo một đối tượng để gán giá trịex
。
let ex = $.NewUniswapV3()
Sử dụngex
Các hàm thành viên của đối tượngaddToken()
Thêm thông tin về mã thông báo (đăng ký).
let tokenAddressMap = {
"USDT": "0xdac17f958d2ee523a2206206994597c13d831ec7",
"1INCH": "0x111111111117dC0aa78b770fA6A738034120C302",
"USDC": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"DAI": "0x6b175474e89094c44da98b954eedeac495271d0f",
}
for (let name in tokenAddressMap) {
ex.addToken(name, tokenAddressMap[name])
}
Nếu bạn muốn lấy và in giá của một cặp giao dịch, bạn có thể sử dụngex
Các hàm thành viên của đối tượnggetPrice()
Có thể viết như sau:
Log(ex.getPrice('ETH_USDT'))
Log(ex.getPrice('1INCH_USDT'))
Nếu bạn muốn thực hiện các hoạt động chuyển đổi, bạn có thể sử dụngex
Các hàm thành viên của đối tượngswapToken()
, thực hiện chuyển đổi:
// 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'))
Trong chương này, chúng ta sẽ học cách đọc các sự kiện phát hành hợp đồng thông minh bằng nền tảng giao dịch định lượng của nhà phát minh, các sự kiện phát hành hợp đồng thông minh được lưu trữ trong nhật ký của máy ảo Ethereum.
Tìm kiếm các sự kiện được phát hành bằng hợp đồng thông minh, cần sử dụng phương pháp RPC của Ethereumeth_getLogs
Trong các bài học trước đây, chúng tôi đã giải thích cách gọi các nút RPC của Ethereum.
Ví dụ, chúng ta lấyWETH
Các sự kiện hợp đồng có thể được viết mã, sử dụng FMZ.Công cụ chỉnh sửaThử nghiệm, các đối tượng giao dịch được cấu hình bởi các nút RPC là các nút trên mạng Ethereum, được gọieth_getLogs
Chúng ta chỉ định 3 tham số trong phương pháp.fromBlock
、toBlock
、address
Chúng tôi sử dụng từBlock và toBlock để truy vấn dữ liệu trong một khối:
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
}
Khi truy cập vào dữ liệu logs, chúng tôi bỏ qua một số nội dung vì nó chứa nhiều dữ liệu:
[{
"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"
}]
Bạn có thể thấy rằng có rất nhiều sự kiện trong dữ liệu nhật ký, nếu chúng ta chỉ quan tâm đếnTransfer
Các sự kiện sẽ cần phải đưa dữ liệu này vàoTransfer
Các tin tức đã được lọc ra.
Ethereum log được chia thành hai phần, phần 1, chủ đềtopics
; 2, dữ liệudata
。
Chủ đềtopics
vớieth_getLogs
Một ví dụ là kết quả chạy mã của bài kiểm tra chương.topics
Dữ liệu trong trường là:
"topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x00000000000000000000000012b791bb27b3a4ee958b5a435fea7d49ec076e9c", "0x000000000000000000000000ef1c6e67703c7bd7107eed8303fbe6ec2554bf6b"],
Cái này.topics
Giá trị của (subject) field là một cấu trúc matrix để mô tả sự kiện.
Chúng tôi sử dụng các nền tảng giao dịch định lượng của nhà phát minh.Encode
Các hàm có thể tính toán giá trị hash của chữ ký này bằng cách sử dụng mã sau:
function main() {
var eventFunction = "Transfer(address,address,uint256)"
var eventHash = Encode("keccak256", "string", "hex", eventFunction)
Log("eventHash:", "0x" + eventHash)
// eventHash: 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
}
Tính toánTransfer(address,address,uint256)
củakeccak256
Giá trị hash (hex mã hóa) là0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
。
topics
Giá trị của trường là một cấu trúc matrix, phần tử thứ hai và phần tử thứ ba là:
from
to
Dữ liệudata
data
Dữ liệu trong trường là:
"data": "0x0000000000000000000000000000000000000000000000000164f2434262e1cc",
Một số tham số trong sự kiện (những tham số trong mã Solidity của hợp đồng thông minh không có tuyên bố được lập chỉ mục) sẽ được lưu trữ trongdata
Những người khác cũng có thể làm điều đó.
Phân tích dữ liệu0x0000000000000000000000000000000000000000000000000164f2434262e1cc
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
}
Theo đó, số liệu này là: 0.10047146239950075,data
Dữ liệu là số tiền chuyển khoản tương ứng.
Sau khi thực hành, bạn đã sẵn sàng. Chúng ta có thể bắt đầu tìm kiếm nhật ký:
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++
}
}
}
Tronghttps://etherscan.io/
Tìm kiếm:
Kết quả của việc chạy mã thử nghiệm trên FMZ Debugging Tool:
Có thể phân tích theo nhu cầu khi truy cập.from
,to
Dữ liệu của các trường, ví dụ:
function main() {
var from = "0x00000000000000000000000012b791bb27b3a4ee958b5a435fea7d49ec076e9c"
var address = "0x" + exchange.IO("encodePacked", "address", from)
Log("address:", address)
}
Kết quả:
Địa chỉ: 0x12b791bb27b3a4ee958b5a435fea7d49ec076e9c
DoCông cụ chỉnh sửaChỉ có thể kiểm tra mã trong một thời gian ngắn và chỉ xuất ra nội dung sau khi mã được thực hiện, không thể hiển thị trong thời gian thực, xuất bản nhật ký.
Ở đây, chúng tôi sử dụng Ethereum để nghe lén.USDT
Các hợp đồng tiền tệ nàyTransfer(address,address,uint256)
Sự kiện, dựa trên những gì chúng tôi đã học trong lớp học trước, chúng tôi đã thiết kế một ví dụ về việc liên tục nghe lén một sự kiện hợp đồng thông minh:
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 = {