对数据精度敏感的服务端不应该使用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不适合的场景
不适合对精度要求非常敏感的服务端