Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Nov 6, 2024
2 parents 6cfeb7d + 5909cb9 commit 2061ada
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 14 deletions.
2 changes: 1 addition & 1 deletion 30_TryCatch/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ tags:

## `try-catch`

`Solidity`中,`try-catch`只能被用于`external`函数或创建合约时`constructor`(被视为`external`函数)的调用。基本语法如下:
`Solidity`中,`try-catch`只能被用于`external`函数或`public`函数或创建合约时`constructor`(被视为`external`函数)的调用。基本语法如下:

```solidity
try externalContract.f() {
Expand Down
26 changes: 13 additions & 13 deletions S08_ContractCheck/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@ tags:
很多 freemint 的项目为了限制科学家(程序员)会用到 `isContract()` 方法,希望将调用者 `msg.sender` 限制为外部账户(EOA),而非合约。这个函数利用 `extcodesize` 获取该地址所存储的 `bytecode` 长度(runtime),若大于0,则判断为合约,否则就是EOA(用户)。

```solidity
// 利用 extcodesize 检查是否为合约
function isContract(address account) public view returns (bool) {
// extcodesize > 0 的地址一定是合约地址
// 但是合约在构造函数时候 extcodesize 为0
uint size;
assembly {
size := extcodesize(account)
}
return size > 0;
// 利用 extcodesize 检查是否为合约
function isContract(address account) public view returns (bool) {
// extcodesize > 0 的地址一定是合约地址
// 但是合约在构造函数时候 extcodesize 为0
uint size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
```

这里有一个漏洞,就是在合约在被创建的时候,`runtime bytecode` 还没有被存储到地址上,因此 `bytecode` 长度为0。也就是说,如果我们将逻辑写在合约的构造函数 `constructor` 中的话,就可以绕过 `isContract()` 检查。

![](./img/S08-1.png)
![image1](./img/S08-1.png)

## 漏洞例子

Expand Down Expand Up @@ -109,14 +109,14 @@ contract NotContract {

## 预防办法

你可以使用 `(tx.origin == msg.sender)` 来检测调用者是否为合约。如果调用者为 EOA,那么`tx.origin``msg.sender`相等;如果它们俩不相等,调用者为合约。
你可以使用 `(tx.origin == msg.sender)` 来检测调用者是否为合约。如果调用者为 EOA,那么`tx.origin``msg.sender`相等;如果它们俩不相等,调用者为合约。[eip-3074](https://eips.ethereum.org/EIPS/eip-3074)中,这样检查合约的方式,会失效。

```
```solidity
function realContract(address account) public view returns (bool) {
return (tx.origin == msg.sender);
}
```

## 总结

这一讲,我们介绍了合约长度检查可以被绕过的漏洞,并介绍预防的方法。如果一个地址的 `extcodesize > 0`,则该地址一定为合约;但如果 `extcodesize = 0`,该地址既可能为 `EOA`,也可能为正在创建状态的合约。
这一讲,我们介绍了合约长度检查可以被绕过的漏洞,并介绍预防的方法。如果一个地址的 `extcodesize > 0`,则该地址一定为合约;但如果 `extcodesize = 0`,该地址既可能为 `EOA`,也可能为正在创建状态的合约。

0 comments on commit 2061ada

Please sign in to comment.