前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >天才程序员: "那些年我偷懒没敲的EOS代码, 让我失去了一切, 如果..."

天才程序员: "那些年我偷懒没敲的EOS代码, 让我失去了一切, 如果..."

作者头像
区块链大本营
发布2019-04-28 17:38:16
8220
发布2019-04-28 17:38:16
举报
文章被收录于专栏:区块链大本营区块链大本营

作者 | 红石

责编 | 乔治

出品 | 区块链大本营(blockchain_camp)

#今天是一篇技术文。

3月15日,mercatox 遭受(hard_fail)攻击,黑客获利数千 EOS,约合数万人民币。

3月11日,EOS DApp nkpaymentcap 被攻击,黑客成功获利 5 万 EOS,约合人民币100多万元。经分析发现,攻击者采用假转账通知攻击获取大量合约代币,又将代币通过 DApp 合约兑换成真 EOS 进行套现。

3月10日,EOS 竞猜类游戏 Vegas Town 被连续(hard_fail)攻击,黑客获利数千枚 EOS 。

3月9日,EOS 竞猜类游戏 Gamble EOS 遭受假转账攻击,黑客成功获利数千 EOS……

仅仅三月份,利用交易验证漏洞进行的攻击就已经有这么多起,损失达上千万人民币。

那么,什么是交易验证漏洞?为何 EOS 让你频频“丢钱”?BM告诉你,是你的代码“太笨”。

先说说交易验证,你不了解交易验证,但黑客了解。

因为在支付领域,这很重要。在区块链领域,无论做 DApp,还是接入数字货币支付,交易验证都是重要部分。

交易验证,说起来也简单:就是如何确认一笔金额已经到账。

说起来也不简单,因为会有无数黑客试图让并未成功的交易通过验证,从而空手套白狼。

比如最近针对 EOS 交易的 hard_fail 状态攻击,就是这样一种黑客攻击。

hard_fail 状态攻击

在 EOS 区块链上,每笔交易(transaction)都有一个状态(status)参数,只有当这个参数为 executed(已执行),才说明交易成功。但是因为一般来说,失败的交易都不会提交到链上,所以,一些不谨慎的交易所、DApp 甚至没有验证这个参数。

这才有了最近的 hard_fail 状态攻击。其实这个攻击手法的背后原理远比它的名字简单,就是黑客发起了注定失败的、但是又能上链的交易,专门攻击那些只要交易上链就视作交易成功的平台。

不试不知道,一试吓一跳,真的有很多平台没验证这个参数……

那么,EOS 交易验证到底需要验证些啥?

EOS 交易验证涉及的参数

EOS 交易验证,需验证:

1、交易 excuted,验证 transaction status 参数为 executed,验证这个参数可以有效避免 hard_fail 状态攻击;

说简单点,这一步是验证交易是否正常执行。

2、不可逆,即交易所在区块号低于当前最新不可逆块号,需要获得 transaction 所在区块的区块号,以及主网最新不可逆块的区块号(不可逆区块高度),判断:

block_num < last_irreversible_block_num;

说简单点,这一步是验证交易是否已经同步。

区块链是分布式账本,交易提交上去后,需要大多数节点记录了这笔交易,才能认为交易已上链并不可篡改。不然的话,比如如果只有一个节点有这笔交易,则只要这个节点的交易信息一改,这笔交易就变了。

3、合约账户和货币符号;

合约账户就是货币的智能合约账户。EOS 区块链转账都是基于智能合约的,比如 EOS 币的智能合约账户就是 eosio.token,每一次进行 EOS 币转账,都会调用这个合约。

假币攻击就是因为交易所没验证合约账户。

4、交易(action)类型为 transfer;

EOS 区块链上的交互都是以 transaction 进行,无一例外。所以,不是每一笔 transaction 都包含转账。EOS 一笔 transaction 可以有多个 action,只有类型为 transfer(转账)的 action,才是转账,才是需要做交易验证的。

5、From 和 to,即转入转出的账户需要再次确认。

交易(Transaction)同时满足这些条件,才能判断为交易成功,并执行下一步程序。而且,如果是通过公共 API 或 API 服务商提供的数据进行交易验证,需要使用不同服务提供商的 API 至少进行二次确认,以防止 API 信息出错导致问题。

那么问题又来了,如何通过公共 API 进行交易验证呢?

通过 EOSPark API 获取交易、进行交易验证

让我们以 EOSPark 的 API 服务做个基本示例。

EOSPark 本身是一个主流 EOS 区块浏览器,但他们也面向开发者提供 API、代码一致性校验、合约安全(SEC)、合约语义化等服务。

1、EOSPark API 官网: https://eospark.com/openapi 2、EOSPark API 官方文档: https://developer.eospark.com/api-doc/zh/https/

EOSPark API 服务思维导图:

EOSPark API 有四种查询 EOS 交易的方式。

根据账户查询:

HTTPS API get_account_related_trx_info Websocket API subscribe_account

根据 txID 查询:

HTTPS API get_transaction_detail_info HTTPS API get_transaction_action_info

以 HTTPS API get_account_related_trx_info 为例,这个接口能查询对应账户的进出交易,无论是收到的转账还是发起的转账,都可以一起查到:

get_account_related_trx_info 的基本查询语句如下:

https://api.eospark.com/api?module=account&action=get_account_related_trx_info&apikey= {这里放你的 API KEY}&account={这里放 EOS 账户名}&page=1&size=10

语句填好参数后可以直接在普通浏览器中打开查询信息,不过当然,我们更习惯用 IDE:

Node.js 代码示例:

返回 JSON 示例:

可以看到在 get_account_related_trx_info 返回的信息中,本来就包括交易所在区块号(block_num)和不可逆区块高度(last_irreversible_block_num)。

同时 status、code(合约账户)、symbol、From(这里是 sender)和 to(这里是 receiver)这些参数也一应俱全。(交易类型因为这个接口本身就是返回转账交易,所以这里可以不作验证。)

也就是说,使用这个接口,查询一次就可以直接验证获取到的交易。

那么问题又来了,也就是说,有些时候查询的信息不能直接进行交易验证?

很不幸,是滴。

获取不可逆区块高度和交易状态的补充方法

有些接口返回的交易信息不包含交易验证所需所有参数,需要再另外获取。最常见的就是不可逆区块高度的缺失,还有一些直接查询 actions 的接口有交易状态参数缺失。

不过处理起来都很简单。

同样以 EOSPark API 服务为例:

获取不可逆区块高度,使用 RPC 接口 get_info 就好,这是一个获取 EOS 主网基本信息的接口:

Node.js 代码示例:

返回 JSON 示例:

获取状态参数,可以使用 HTTPS 接口 get_transaction_detail_info,这是一个根据 txID 查询交易(transaction)详情的接口:

查询语句:

https://api.eospark.com/api?module=transaction&action=get_transaction_detail_info&apikey= {这里放你的API KEY}&trx_id={这里放查询的交易ID}

返回 JSON 示例:

至此,我们就简单说完了 EOS 区块链交易验证的一个基本思路。当然,具体情况具体分析,具体开发时验证的方式不一定按这样来。不过条条大路通罗马,思路是一样的,验证的参数也基本都是这些。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 区块链大本营 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
API 网关
腾讯云 API 网关(API Gateway)是腾讯云推出的一种 API 托管服务,能提供 API 的完整生命周期管理,包括创建、维护、发布、运行、下线等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档