当前位置:首页区块链以太坊EOA检查和漏洞是什么意思?

以太坊EOA检查和漏洞是什么意思?

分享一个外部账户 EOA 漏洞案例。

以太坊的账户类型分为 外部账户 和 合约账户 两种类型。所谓外部账户,又称为 EOA(External Owned
Account),是指由用户掌握私钥的地址(用户的钱包地址一般为这种类型),而合约账户是部署到链上创建出的合约地址(多签账户的地址一般为这种类型)。

看下面的这段合约代码:

contract OnForEOA {

uint public flag;

// bad

modifier isNotContract(address _a){

uint len;

assemb { len :=extcodesize(_a) }

require(len==0);

_;

}

function setFlag(uint i) public isNotContract(msg.sender){

flag=i;

}

}

extcodesize 操作符返回某个地址关联的代码(code)长度,如果代码长度为0,表示为外部地址。而大于0表示为合约地址。

这段代码的本意是只允许 EOA 账户对该合约进行操作,也就是说普通用户可以直接用外部地址发起合约调用,而不允许用另一个合约进行调用。

那么上面这些代码的漏洞在哪里呢?会智能合约编程的同学可以稍微思考几分钟,再往下看。

下面的我们来部署一个攻击合约:

contract FakeEOA {

constructor(address _a) public {

OnForEOA c=OnForEOA(_a);

c.setFlag(1);

}

}

在 FakeEOA 攻击合约中,我们传入 _a 一个合约地址(准确来说是一个尚未生成的合约地址)。因为该合约地址尚未生成,当代码检查其
extcodesize 时,其结果为0。这样合约地址也被 OnForEOA 所接受了,这就是 OnForEOA 的漏洞所在。

以太坊中,合约地址的产生是可以预先计算的。其计算逻辑为:根据发送者的地址,和交易 nonce 来确定。算法如下:

合约地址=address(uint160(uint256(keccak256(abi.encodePacked(byte(0xd6),
byte(0x94), _origin, byte(nonce))))))

讲解解决?

要解决这个问题,我们可以加上 tx.origin 的判断,如下:

require(tx.origin==msg.sender);

这样可以保证是外部账户直接调用。

另外对于 tx.origin 使用要注意相关可能的陷阱,详见之前的文章:安全|一段代码讲解偷走你的

免责声明: 文章源于会员发布,不作为任何投资建议,如有侵权请联系我们删除!

温馨提示:

文章标题:以太坊EOA检查和漏洞是什么意思?

文章链接:https://www.btchangqing.cn/457930.html

更新时间:2023年02月07日

本站大部分内容均收集于网络,若内容若侵犯到您的权益,请联系我们,我们将第一时间处理。

区块链

深入解析NFT交易与聚合领域的细微变化和未来发展

2023-2-7 21:18:17

区块链

区块链和人工智能是什么关系?

2023-2-7 21:24:02

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索