阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      对数据精度敏感的服务端不应该使用Infura

      Infura的优点

      在用Web3做以太坊相关的数据交互时候,需要节点来进行支撑,但是维护一个节点是非常占用资源和精力的;所以使用Infura这类开放平台的接口还是非常不错的;

      Infura的缺点

      接口限速

      因为是开放的API,所以限速也不算缺点,可以通过充钱进行解决

      接口数据精度不保证

      假设用户在昨天(2019-12-11)拿到的数据A,今天(2019-12-12)拿到的数据可能是B

      我在实际开发的过程中,遇到好多次这种情况;

      其中一个例子:某个Token转账,通过Infura当时拿到的值是2000000000000000000,但是隔了N天以后,我拿到的数据是2000000000000000012,两个时间的值不一样;

      所在HASH0x6ba281ff82f3e2ae5ce3b870e4cb712de99e1b629de2126afb0d47aa82aaa709;

      官方浏览器 https://etherscan.io/tx/0x6ba281ff82f3e2ae5ce3b870e4cb712de99e1b629de2126afb0d47aa82aaa709 显示的数据是正确的;

      也有几个第三方浏览器,比如 https://eth.tokenview.com/cn/tx/8869537/149 显示是2000000000000000000,猜测可能用的也是 Infura 接口;

      现在的数据解析

      现在已经是正确的数据了,下面只是一个解析的演示

      通过下面RPC参数获取数据

      {
          "jsonrpc":"2.0",
          "method":"eth_getLogs",
          "params":[
          {
          "address": "0x9eb7006b8b9010a9856f20611af462f872f6a40e",
          "fromBlock": "0x8756a1",
          "toBlock":"0x8756a1",
              "topics":["0x94fcee0b7b95ac21ec59ec2c5b2e99e75c909351baf99e93cd97e713d820627b"]
          }
          ],
          "id":1
       }
      

      拿到的结果是

      {
         "jsonrpc": "2.0",
         "id": 1,
         "result": [
             {
                 "address": "0x9eb7006b8b9010a9856f20611af462f872f6a40e",
                 "blockHash": "0x31ec3fc8987a2ae35b305f5aa837738e7253e82c7df10102119545a81861c206",
                 "blockNumber": "0x8756a1",
                 "data": "0x00000000000000000000000000000000000000000000000000000000000000600000000000000000000000001a762727adcfd0bf8895e5e10b9193269b89a7c5000000000000000000000000000000000000000000000000000000005dbfb58700000000000000000000000000000000000000000000000000000000000000202d1de569c149af4de8380d0792a1dc2a814377ca869ed3e12531a9cb4dbd0eaa",
                 "logIndex": "0x8a",
                 "removed": false,
                 "topics": [
                     "0x94fcee0b7b95ac21ec59ec2c5b2e99e75c909351baf99e93cd97e713d820627b",
                     "0x0000000000000000000000000000000000000000000000001bc16d674ec8000c"
                 ],
                 "transactionHash": "0x6ba281ff82f3e2ae5ce3b870e4cb712de99e1b629de2126afb0d47aa82aaa709",
                 "transactionIndex": "0x95"
             }
         ]
      }
      

      代码解析阶段

      这里是拿到的数据解析

      (async () => {
          const Web3 = require("web3")
          let config = {
              INFURA_URL: "https://rinkeby.infura.io/you_infura_key",
              INIT_BLOCK_NUM: 4655753,
              CONTRACT_ADDRESS: "0xA766d355Ef29502Ca68637F0BCb9Ff7284D1ace2"
          }
      
          const web3 = new Web3(config.INFURA_URL, { timeout: 1000 * 10 });
          const ABI = [
              {
                  type: 'bytes',
                  name: 'czrAccount'
              },
              {
                  type: 'address',
                  name: 'ethAddress'
              },
              {
                  type: 'uint256',
                  name: 'timestamp'
              },
              {
                  type: 'uint256',
                  name: 'value',
                  indexed: true
              }
          ];
      
          let item = {
              "address": "0x9eb7006b8b9010a9856f20611af462f872f6a40e",
              "blockHash": "0x31ec3fc8987a2ae35b305f5aa837738e7253e82c7df10102119545a81861c206",
              "blockNumber": "0x8756a1",
              "data": "0x00000000000000000000000000000000000000000000000000000000000000600000000000000000000000001a762727adcfd0bf8895e5e10b9193269b89a7c5000000000000000000000000000000000000000000000000000000005dbfb58700000000000000000000000000000000000000000000000000000000000000202d1de569c149af4de8380d0792a1dc2a814377ca869ed3e12531a9cb4dbd0eaa",
              "logIndex": "0x8a",
              "removed": false,
              "topics": [
                  "0x94fcee0b7b95ac21ec59ec2c5b2e99e75c909351baf99e93cd97e713d820627b",
                  "0x0000000000000000000000000000000000000000000000001bc16d674ec8000c"
              ],
              "transactionHash": "0x6ba281ff82f3e2ae5ce3b870e4cb712de99e1b629de2126afb0d47aa82aaa709",
              "transactionIndex": "0x95"
          };
          let decodeLogInfo = await web3.eth.abi.decodeLog(
              ABI,
              item.data,
              [item.topics[1]]
          );
          let insertLog = {
              timestamp: decodeLogInfo.timestamp.toString(10),
              eth_hash: item.transactionHash,
              eth_address: decodeLogInfo.ethAddress,
              block_number: item.blockNumber,
              value: decodeLogInfo.value.toString(10),
              status: 1
          }
          console.log(insertLog)
      })()
      

      Infura的使用场景

      这种的场景是用于前端的,比如网页,Chrome扩展(Matemask那种),轻钱包等等;这些会实时的获取数据,对精度不是那么的敏感;

      Infura不适合的场景

      不适合对精度要求非常敏感的服务端

      目录
      目录