Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed May 13, 2024
2 parents 1ff2f05 + a0deca0 commit 09070b1
Show file tree
Hide file tree
Showing 46 changed files with 538 additions and 138 deletions.
46 changes: 46 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Bug report (程序Bug报告)
title: "[Bug] [Class (章节)] Title(标题)"
description: Problems and issues with code of WTF-Solidity (报告WTF-Solidity中的程序Bug)
body:
- type: markdown
attributes:
value: >
Please make sure what you are reporting is indeed a bug with reproducible steps(请确保您所报告的是一个具有可重现步骤的错误), if you want to ask questions
or share ideas, you can head to our (如果你是想问一个问题或者分享一个主意,你可以通过以下方式)
[Discussions](https://github.com/AmazingAng/WTF-Solidity/discussions) tab, you can also
[join our discord](https://discord.gg/5akcruXrsk)
- type: textarea
attributes:
label: Details (细节)
description: Describe what happened.(描述一下发生了什么)
placeholder: >
Please provide the context in which the problem occurred and explain what happened(请提供问题发生的背景并解释发生的情况)
validations:
required: true


- type: textarea
attributes:
label: Environment (环境)
description: Tell us about your environment(告诉我们你的环境信息)
placeholder: >
Tell us what you're using it: Hardhat, Remix, etc. (告诉我们你使用的环境:Hardhat,Remix等等。)
- type: checkboxes
attributes:
label: Are you willing to submit PR?(你愿意提交PR吗?)
description: >
This is absolutely not required, but we are happy to guide you in the contribution process
especially if you already have a good understanding of how to implement the fix.
(这不是必须的,但是我们很高兴您能够提交PR)
options:
- label: Yes I am willing to submit a PR!(是的我愿意)



- type: markdown
attributes:
value: "Thanks for completing our form!(感谢填写表单!)"
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Ask a question or get support(提个问题或者获得支持)
url: https://github.com/AmazingAng/WTF-Solidity/discussions
about: Ask a question or request support for using WTF-Solidity (在使用WTF-Solidity时,遇到的问题或者需要获得帮助)
31 changes: 31 additions & 0 deletions .github/ISSUE_TEMPLATE/document.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Typo report(勘误报告)
description: Report a typo in the WTF-Solidity(报告WTF-Solidity中的勘误)
title: "[Doc][Module Name(模块)] Title(标题)"
body:
- type: markdown
attributes:
value: |
For better global communication, Please write in English.
If you feel the description in English is not clear, then you can use Chinese, thanks!
(为了更好的全球化的交流,请使用英文,如果觉得用英文无法清楚描述,可以使用中文)
- type: textarea
attributes:
label: Details(细节)
description: A short description what your find in our document.(简短的描述一下在文档中发现了什么错误)


- type: checkboxes
attributes:
label: Are you willing to submit a PR?(你愿意提交PR吗?)
description: >
This is absolutely not required, but we are happy to guide you in the contribution process
especially if you already have a good understanding of how to implement the fix.
(这不是必须的,但是我们很高兴您能够提交PR)
options:
- label: Yes I am willing to submit a PR!(是的我愿意)

- type: markdown
attributes:
value: "Thanks for completing our form!(感谢填写表单!)"
44 changes: 44 additions & 0 deletions .github/ISSUE_TEMPLATE/feature-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

name: Feature request(对此项目提出一个意见)
description: Suggest an idea for this project(对此项目提出一个意见)
title: "[Feature][Module Name(模块名称)] Title(标题)"
body:
- type: markdown
attributes:
value: |
For better global communication, Please write in English.
If you feel the description in English is not clear, then you can use Chinese, thanks!
(为了更好的全球化的交流,请使用英文,如果觉得用英文无法清楚描述,可以使用中文)
- type: textarea
attributes:
label: Details(细节)
description: Please describe your feature request in detail. (请详细描述您的功能请求。)

- type: textarea
attributes:
label: Motivation(动机)
description: Please describe your motivation in the feature request. (请描述您在功能请求中的动机。)
placeholder: >
Please describe your motivation in the feature request. (请描述您在功能请求中的动机。)
- type: checkboxes
attributes:
label: Are you willing to submit a PR?(你愿意提交PR吗?)
description: >
This is absolutely not required, but we are happy to guide you in the contribution process
especially if you already have a good understanding of how to implement the fix.
(这不是必须的,但是我们很高兴您能够提交PR)
options:
- label: Yes I am willing to submit a PR!(是的我愿意)



- type: markdown
attributes:
value: "Thanks for completing our form!(感谢填写表单!)"
31 changes: 31 additions & 0 deletions .github/ISSUE_TEMPLATE/improvement-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Improvement request (提升请求)
description: Suggest an improvement for this project (给WTF-Solidity提一个改进提升的请求)
title: "[Improvement][Module Name(模块名称)] Title(标题)"
body:
- type: markdown
attributes:
value: |
For better global communication, Please write in English.
If you feel the description in English is not clear, then you can use Chinese, thanks!
(为了更好的全球化的交流,请使用英文,如果觉得用英文无法清楚描述,可以使用中文)
- type: textarea
attributes:
label: Description
description: A short description why your find in our document.(简短的描述一下)


- type: checkboxes
attributes:
label: Are you willing to submit a PR?(你愿意提交PR吗?)
description: >
This is absolutely not required, but we are happy to guide you in the contribution process
especially if you already have a good understanding of how to implement the fix.
(这不是必须的,但是我们很高兴您能够提交PR)
options:
- label: Yes I am willing to submit a PR!(是的我愿意)

- type: markdown
attributes:
value: "Thanks for completing our form!(感谢填写表单!)"
Binary file modified 11_Modifier/img/11-1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified 11_Modifier/img/11-2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified 11_Modifier/img/11-3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 11_Modifier/img/11-4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 7 additions & 5 deletions 11_Modifier/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,19 @@ function changeOwner(address _newOwner) external onlyOwner{

`Owner.sol` 为例。

1. 在 Remix 上编译部署代码。
1. 在 Remix 上编译并部署代码,在合约部署时传入 initialOwner 变量。

![11-1](./img/11-1.jpg)
2. 点击 `owner` 按钮查看当前 owner 变量。

![11-1](img/11-1.jpg)
![11-2](./img/11-2.jpg)
3. 以 owner 地址的用户身份,调用 `changeOwner` 函数,交易成功。

![11-2](img/11-2.jpg)
![11-3](./img/11-3.jpg)
4. 以非 owner 地址的用户身份,调用 `changeOwner` 函数,交易失败,因为modifier onlyOwner 的检查语句不满足。

![11-3](img/11-3.jpg)
![11-4](./img/11-4.jpg)

## 总结

这一讲,我们介绍了`Solidity`中的构造函数和修饰符,并举了一个控制合约权限的`Ownable`合约。
这一讲,我们介绍了`Solidity`中的构造函数和修饰符,并写了一个控制合约权限的`Ownable`合约。
Binary file added 12_Event/img/12-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions 12_Event/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ keccak256("Transfer(address,address,uint256)")

### 在Etherscan上查询事件

我们尝试用`_transfer()`函数在`Rinkeby`测试网络上转账100代币,可以在`Etherscan`上查询到相应的`tx`[网址](https://rinkeby.etherscan.io/tx/0x8cf87215b23055896d93004112bbd8ab754f081b4491cb48c37592ca8f8a36c7)
我们尝试用`_transfer()`函数在`Sepolia`测试网络上转账100代币,可以在`Etherscan`上查询到相应的`tx`[网址](https://sepolia.etherscan.io/tx/0xb07dcd9943662e2e8b17c7add370f046401962ce24d0690a61bb249a385dc8c9#eventlog)

点击`Logs`按钮,就能看到事件明细:

![Event明细](https://images.mirror-media.xyz/publication-images/gx6_wDMYEl8_Gc_JkTIKn.png?height=980&width=1772)
![Event明细](img/12-4.png)

`Topics`里面有三个元素,`[0]`是这个事件的哈希,`[1]``[2]`是我们定义的两个`indexed`变量的信息,即转账的转出地址和接收地址。`Data`里面是剩下的不带`indexed`的变量,也就是转账数量。

Expand Down
15 changes: 9 additions & 6 deletions 17_Library/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ tags:
所有代码和教程开源在 github: [github.com/AmazingAng/WTFSolidity](https://github.com/AmazingAng/WTFSolidity)

---
这一讲,我们用`ERC721`的引用的库合约`String`为例介绍`Solidity`中的库合约(`Library`),并总结了常用的库合约。
这一讲,我们用`ERC721`的引用的库合约`Strings`为例介绍`Solidity`中的库合约(`Library`),并总结了常用的库合约。

## 库合约

Expand All @@ -34,9 +34,12 @@ tags:
3. 不能接收以太币
4. 不可以被销毁

## String库合约
需要注意的是,库合约重的函数可见性如果被设置为`public`或者`external`,则在调用函数时会触发一次`delegatecall`。而如果被设置为`internal`,则不会引起。对于设置为`private`可见性的函数来说,其仅能在库合约中可见,在其他合约中不可用。

`String库合约`是将`uint256`类型转换为相应的`string`类型的代码库,样例代码如下:

## Strings库合约

`Strings库合约`是将`uint256`类型转换为相应的`string`类型的代码库,样例代码如下:

```solidity
library Strings {
Expand Down Expand Up @@ -104,7 +107,7 @@ library Strings {

### 如何使用库合约

我们用`String`库合约的`toHexString()`来演示两种使用库合约中函数的办法。
我们用`Strings`库合约的`toHexString()`来演示两种使用库合约中函数的办法。

1. 利用using for指令

Expand Down Expand Up @@ -134,9 +137,9 @@ library Strings {
## 总结
这一讲,我们用`ERC721`的引用的库合约`String`为例介绍`Solidity`中的库合约(`Library`)。99%的开发者都不需要自己去写库合约,会用大神写的就可以了。我们只需要知道什么情况该用什么库合约。常用的有:
这一讲,我们用`ERC721`的引用的库合约`Strings`为例介绍`Solidity`中的库合约(`Library`)。99%的开发者都不需要自己去写库合约,会用大神写的就可以了。我们只需要知道什么情况该用什么库合约。常用的有:
1. [String](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/4a9cc8b4918ef3736229a5cc5a310bdc17bf759f/contracts/utils/Strings.sol):将`uint256`转换为`String`
1. [Strings](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/4a9cc8b4918ef3736229a5cc5a310bdc17bf759f/contracts/utils/Strings.sol):将`uint256`转换为`String`
2. [Address](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/4a9cc8b4918ef3736229a5cc5a310bdc17bf759f/contracts/utils/Address.sol):判断某个地址是否为合约地址
3. [Create2](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/4a9cc8b4918ef3736229a5cc5a310bdc17bf759f/contracts/utils/Create2.sol):更安全的使用`Create2 EVM opcode`
4. [Arrays](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/4a9cc8b4918ef3736229a5cc5a310bdc17bf759f/contracts/utils/Arrays.sol):跟数组相关的库合约
30 changes: 30 additions & 0 deletions 26_DeleteContract/DeployContract.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;

import "./DeleteContract.sol";

contract DeployContract {

struct DemoResult {
address addr;
uint balance;
uint value;
}

constructor() payable {}

function getBalance() external view returns(uint balance){
balance = address(this).balance;
}

function demo() public payable returns (DemoResult memory){
DeleteContract del = new DeleteContract{value:msg.value}();
DemoResult memory res = DemoResult({
addr: address(del),
balance: del.getBalance(),
value: del.value()
});
del.deleteContract();
return res;
}
}
Binary file added 26_DeleteContract/img/26-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 26_DeleteContract/img/26-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 26_DeleteContract/img/26-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 26_DeleteContract/img/26-6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
80 changes: 70 additions & 10 deletions 26_DeleteContract/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ tags:

`selfdestruct`命令可以用来删除智能合约,并将该合约剩余`ETH`转到指定地址。`selfdestruct`是为了应对合约出错的极端情况而设计的。它最早被命名为`suicide`(自杀),但是这个词太敏感。为了保护抑郁的程序员,改名为`selfdestruct`;在 [v0.8.18](https://blog.soliditylang.org/2023/02/01/solidity-0.8.18-release-announcement/) 版本中,`selfdestruct` 关键字被标记为「不再建议使用」,在一些情况下它会导致预期之外的合约语义,但由于目前还没有代替方案,目前只是对开发者做了编译阶段的警告,相关内容可以查看 [EIP-6049](https://eips.ethereum.org/EIPS/eip-6049)

然而,在以太坊坎昆(Cancun)升级中,[EIP-6780](https://eips.ethereum.org/EIPS/eip-6780)被纳入升级以实现对`Verkle Tree`更好的支持。EIP-6780减少了`SELFDESTRUCT`操作码的功能。根据提案描述,当前`SELFDESTRUCT`仅会被用来将合约中的ETH转移到指定地址,而原先的删除功能只有在`合约创建-自毁`这两个操作处在同一笔交易时才能生效。所以目前来说:

1. 已经部署的合约无法被`SELFDESTRUCT`了。
2. 如果要使用原先的`SELFDESTRUCT`功能,必须在同一笔交易中创建并`SELFDESTRUCT`

### 如何使用`selfdestruct`

`selfdestruct`使用起来非常简单:
Expand All @@ -34,7 +39,9 @@ selfdestruct(_addr);

其中`_addr`是接收合约中剩余`ETH`的地址。`_addr` 地址不需要有`receive()``fallback()`也能接收`ETH`

### 例子
### Demo-转移ETH功能

以下合约在坎昆升级前可以完成合约的自毁,在坎昆升级后仅能实现内部ETH余额的转移。

```solidity
contract DeleteContract {
Expand All @@ -60,16 +67,11 @@ contract DeleteContract {

部署好合约后,我们向`DeleteContract`合约转入1 `ETH`。这时,`getBalance()`会返回1 `ETH``value`变量是10。

当我们调用`deleteContract()`函数,合约将自毁,此时再次调用合约函数交互会失败。

### 注意事项

1. 对外提供合约销毁接口时,最好设置为只有合约所有者可以调用,可以使用函数修饰符`onlyOwner`进行函数声明。
2. 当合约被销毁后再次与合约函数交互会报error。
3. 当合约中有`selfdestruct`功能时常常会带来安全问题和信任问题,合约中的selfdestruct功能会为攻击者打开攻击向量(例如使用`selfdestruct`向一个合约频繁转入token进行攻击,这将大大节省了GAS的费用,虽然很少人这么做),此外,此功能还会降低用户对合约的信心。
当我们调用`deleteContract()`函数,合约将触发`selfdestruct`操作。**在坎昆升级前,合约会被自毁。但是在升级后,合约依然存在,只是将合约包含的ETH转移到指定地址,而合约依然能够调用。**

### 在remix上验证
#### 在remix上验证

##### 坎昆升级之前
1. 部署合约并且转入1ETH,查看合约状态

![deployContract.png](./img/26-1.png)
Expand All @@ -78,6 +80,64 @@ contract DeleteContract {
![deleteContract.png](./img/26-2.png)
从测试中观察合约状态可以发现合约销毁后的ETH返回给了指定的地址,在合约销毁后再次调用合约函数进行交互则会失败。

##### 坎昆升级之后
1. 部署合约并且转入1ETH,查看合约状态

![deployContract2.png](./img/26-3.png)
2. 销毁合约,查看合约状态

![deleteContract2.png](./img/26-4.png)
从测试中观察合约状态可以发现合约包含的ETH已经清零(返回给了指定的地址),再次调用合约函数进行交互依然可以成功。




### Demo-同笔交易内实现合约创建-自毁

根据提案,原先的删除功能只有在`合约创建-自毁`这两个操作处在同一笔交易时才能生效。所以我们需要通过另一个合约进行控制。

```solidity
contract DeployContract {
struct DemoResult {
address addr;
uint balance;
uint value;
}
constructor() payable {}
function getBalance() external view returns(uint balance){
balance = address(this).balance;
}
function demo() public payable returns (DemoResult memory){
DeleteContract del = new DeleteContract{value:msg.value}();
DemoResult memory res = DemoResult({
addr: address(del),
balance: del.getBalance(),
value: del.value()
});
del.deleteContract();
return res;
}
}
```
#### 在remix上验证
1. 部署`DeployContract`合约并且转入1ETH调用`demo`方法,查看合约状态,显示`DeleteContract`已被正确部署,且在`selfdestruct`后ETH已转移到`DeployContract`

![deployContract3.png](./img/26-5.png)
2. 选择导入返回值中的地址为`DeleteContract`。显示该地址不存有ETH,且调用合约函数进行交互均失败。

![deleteContract3.png](./img/26-6.png)


### 注意事项

1. 对外提供合约销毁接口时,最好设置为只有合约所有者可以调用,可以使用函数修饰符`onlyOwner`进行函数声明。
2. 当合约中有`selfdestruct`功能时常常会带来安全问题和信任问题,合约中的selfdestruct功能会为攻击者打开攻击向量(例如使用`selfdestruct`向一个合约频繁转入token进行攻击,这将大大节省了GAS的费用,虽然很少人这么做),此外,此功能还会降低用户对合约的信心。


## 总结

`selfdestruct`是智能合约的紧急按钮,销毁合约并将剩余`ETH`转移到指定账户。当著名的`The DAO`攻击发生时,以太坊的创始人们一定后悔过没有在合约里加入`selfdestruct`来停止黑客的攻击吧。
`selfdestruct`是智能合约的紧急按钮,销毁合约并将剩余`ETH`转移到指定账户。当著名的`The DAO`攻击发生时,以太坊的创始人们一定后悔过没有在合约里加入`selfdestruct`来停止黑客的攻击吧。在坎昆升级后,`selfdestruct`的作用也逐渐发生了改变,什么都不是一成不变的,还是要保持学习。
Loading

0 comments on commit 09070b1

Please sign in to comment.