以太坊(eth)交易所钱包开发 - 2 - 检测到账
文章目录
之前生成地址的时候不需要和Eth的节点交互,但是从到账检测开始就需要与Eth的RPC接口交互了。
Eth的钱包节点目前比较大众的两个实现分别是
个人推荐的是parity
但是为了快捷测试,避免部署节点占用资源,我们可以用一个线上的免费服务infura。注册完成后我们可以获得infura
提供的rpc接口地址https://mainnet.infura.io/v3/0b359d2406a6492fb53883d46921d775
Eth的RPC接口实际上是一个Http的调用,接口的参数内容可以在文档中找到https://github.com/ethereum/wiki/wiki/JSON-RPC
测试这些RPC接口的参数和返回内容我们可以用https://postwoman.io/来。
例如,我们想查询当前区块链最新的区块数字是多少,我们可以从wiki文档中找到这个接口的说明
在
postwoman
中调用,查看返回结果:
之后我们要理解一个概念叫确认数
。
在区块链中存在这样一种情况,两个矿工同时打包提交了一个block,之后的矿工会在这两个不同的block基础上继续打包,系统会判断最长的链有效,并废弃没在最长的链上的区块。那么如果我们检测到了那个被废弃的交易,并为用户做了到账处理,但是被废弃了,交易所就亏了。所以一般在15个确认之后才认为最终到账。
那么这个确认数
实际上就是当前最新的block number - 区块所在的block number的差值。
在配置表中添加配置字段block_confirm_num
设置在经过多少次确认之后才认为到账,暂时可以设置为15。
下面我们开始处理到账检测逻辑
我们需要在数据库中储存一个值,这个值为当前处理完成的block number,可以叫做seek_num。这是一个状态字段,我们创建一个表,用于存储程序的状态数据
|
|
检测收币的处理流程大概如下:
这里着重看一下的eth_getBlockByNumber
返回
|
|
result.transactions[].value如果是0,我们不用关心,一般这是合约交易,不涉及eth转账。
如果result.transactions[].value
不为0,我们则需取出result.transactions[].to
的内容与数据库中的冲币地址做比较,如果在地址中,我们则将信息存入待处理数据库。
数据库结构如下:
|
|
其中tx_id
为唯一索引,这样即使我们重复插入一个交易的数据,也不会产生多次到账。
而handle_status
为处理状态,因为在插入阶段,我们并不会给用户加资产,而是在另外的处理逻辑中,检测handle_status
为0的数据项,用事物的方式给用户加资产并重置handle_status
的状态。
在代码中,我们需要用golang调用eth rpc的接口, 官方有一个ethclient库https://pkg.go.dev/github.com/ethereum/go-ethereum/ethclient?tab=doc。但是这个库没有实现eth_blockNum接口,而且很难扩展,于是我直接把相关的源码下载下来,放到本地直接修改了。添加了eth_blockNum接口。
|
|
具体实现的代码已经传到了github https://github.com/moremorefun/go-dc-wallet
功能入口在 cmd/eth_block_seek/main.go
里面配置读取,数据库链接,日志已经加入,有兴趣的可以看一下具体代码。
这里主要是搞明白 eth rpc 的本质是什么以及有哪些接口。这就是需要去看一下我们上面提到的接口文档了。
文章作者 hao
上次更新 2020-04-17