Skip to content

Commit bcbbc09

Browse files
committed
Add study notes for 2025-08-17
1 parent 30ef967 commit bcbbc09

1 file changed

Lines changed: 117 additions & 0 deletions

File tree

SakuraTokoyomi.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,123 @@ web3萌新
1515
## Notes
1616

1717
<!-- Content_START -->
18+
# 2025-08-17
19+
20+
# 实践:Ethernaut闯关
21+
22+
~~打卡处上传不了图片,我上传到自己的博客中了~~
23+
24+
博客炸了维修ing。修好了补上链接
25+
26+
## 0.Hello Ethernaut
27+
28+
入门题,但是需要一些solidity或者其他语言的基础
29+
30+
根据教程在浏览器的Console中进行交互
31+
32+
33+
34+
最重要的是输入contract找到合约的api
35+
36+
37+
38+
这里有个password很显眼,输入contract.password()
39+
40+
41+
42+
得到密码ethernaut0,但是暂时还不知道怎么用
43+
44+
然后我将abi中的函数一个个进行输入,发现输入contract.method7123949()得到以下提示
45+
46+
47+
48+
将密码作为参数传入contract.authenticate("ethernaut0")
49+
50+
51+
52+
## 1.Fallbcak
53+
54+
```solidity
55+
// SPDX-License-Identifier: MIT
56+
pragma solidity ^0.8.0;
57+
58+
contract Fallback {
59+
mapping(address => uint256) public contributions;
60+
address public owner;
61+
62+
constructor() {
63+
owner = msg.sender;
64+
contributions[msg.sender] = 1000 * (1 ether);
65+
}
66+
67+
modifier onlyOwner() {
68+
require(msg.sender == owner, "caller is not the owner");
69+
_;
70+
}
71+
72+
function contribute() public payable {
73+
require(msg.value < 0.001 ether);
74+
contributions[msg.sender] += msg.value;
75+
if (contributions[msg.sender] > contributions[owner]) {
76+
owner = msg.sender;
77+
}
78+
}
79+
80+
function getContribution() public view returns (uint256) {
81+
return contributions[msg.sender];
82+
}
83+
84+
function withdraw() public onlyOwner {
85+
payable(owner).transfer(address(this).balance);
86+
}
87+
88+
receive() external payable {
89+
require(msg.value > 0 && contributions[msg.sender] > 0);
90+
owner = msg.sender;
91+
}
92+
}
93+
```
94+
95+
要求:拿到合约的拥有权和清空账户余额。
96+
97+
清空账户余额很简单,只需要以owner调用withdraw函数即可。
98+
99+
代码审计可得:
100+
101+
**初始状态**:部署者是 `owner`,并且给自己存了 `1000 ether` 的贡献值(`contributions[owner]`)。
102+
103+
**`contribute()`**:任何人可以贡献 `<0.001 ether`,并累加到自己的 `contributions`
104+
如果某人的贡献超过当前 `owner` 的贡献值,就会成为新的 `owner`
105+
106+
**`receive()`**:只要有人往合约转账(没有调用函数),如果:
107+
108+
- `msg.value > 0`
109+
- `contributions[msg.sender] > 0`
110+
那么 `owner = msg.sender`
111+
112+
**`withdraw()`**:只有 `owner` 能提取合约所有余额。
113+
114+
**await contract.contribute({value: 1});**
115+
116+
- 给合约打了一点钱(1wei)。
117+
- 此时有了 `contributions[player] = 0.0001 ether`,但因为 `contributions[owner] = 1000 ether`,还不是 owner。
118+
119+
**await contract.sendTransaction({value: 1});**
120+
121+
这一步是直接往合约地址打钱(没有调用函数),所以触发了 **`receive()`**
122+
123+
`receive()` 要求:
124+
125+
- `msg.value > 0`
126+
- `contributions[player] > 0` ✅ (之前已经贡献过)
127+
128+
条件满足,于是执行:`owner = msg.sender`
129+
现在已经变成了合约的 新 owner。
130+
131+
**await contract.withdraw()**
132+
133+
取出所有钱通关
134+
18135
# 2025-08-14
19136

20137
### 16.发送和接收 ETH

0 commit comments

Comments
 (0)