@@ -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