Skip to content

Commit 1a17150

Browse files
committed
Add study notes for 2025-08-19
1 parent b7dd3f7 commit 1a17150

1 file changed

Lines changed: 391 additions & 0 deletions

File tree

cmu-ruoyan-lgl.md

Lines changed: 391 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,397 @@ web2游戏大厂工作两年
1515
## Notes
1616

1717
<!-- Content_START -->
18+
# 2025-08-19
19+
20+
## solidity中的Gas优化方案
21+
22+
### 1. **变量声明优化**
23+
24+
#### 变量打包(Packing)
25+
```solidity
26+
// ❌ 浪费Gas:每个变量占用32字节
27+
contract Bad {
28+
uint256 a; // 32 bytes
29+
uint256 b; // 32 bytes
30+
uint256 c; // 32 bytes
31+
}
32+
33+
// ✅ 节省Gas:打包到同一槽位
34+
contract Good {
35+
uint128 a; // 16 bytes
36+
uint128 b; // 16 bytes
37+
uint256 c; // 32 bytes
38+
}
39+
```
40+
**Gas节省**:每个槽位节省约20,000 gas(存储操作)
41+
42+
#### 变量类型选择
43+
```solidity
44+
// ❌ 浪费Gas
45+
uint256 small = 1; // 32字节,浪费31字节
46+
47+
// ✅ 节省Gas
48+
uint8 small = 1; // 1字节,节省31字节
49+
```
50+
**Gas节省**:每个变量节省约5,000-15,000 gas
51+
52+
### 2. **循环优化**
53+
54+
#### 循环边界优化
55+
```solidity
56+
// ❌ 浪费Gas:每次循环都读取数组长度
57+
for (uint i = 0; i < array.length; i++) {
58+
// 操作
59+
}
60+
61+
// ✅ 节省Gas:缓存数组长度
62+
uint length = array.length;
63+
for (uint i = 0; i < length; i++) {
64+
// 操作
65+
}
66+
```
67+
**Gas节省**:每次循环节省约100 gas
68+
69+
#### 循环展开
70+
```solidity
71+
// ❌ 标准循环
72+
for (uint i = 0; i < 4; i++) {
73+
array[i] = i;
74+
}
75+
76+
// ✅ 循环展开(适用于小循环)
77+
array[0] = 0;
78+
array[1] = 1;
79+
array[2] = 2;
80+
array[3] = 3;
81+
```
82+
**Gas节省**:小循环可节省约500-1,000 gas
83+
84+
### 3. **函数优化**
85+
86+
#### 函数可见性
87+
```solidity
88+
// ❌ 浪费Gas:public函数自动生成getter
89+
uint256 public data;
90+
91+
// ✅ 节省Gas:明确指定可见性
92+
uint256 private data;
93+
```
94+
**Gas节省**:每个public变量节省约2,000 gas
95+
96+
#### 函数参数优化
97+
```solidity
98+
// ❌ 浪费Gas:使用storage引用
99+
function badFunction(uint[] storage arr) internal {
100+
uint[] storage temp = arr;
101+
}
102+
103+
// ✅ 节省Gas:使用calldata
104+
function goodFunction(uint[] calldata arr) external pure {
105+
// 直接使用arr,无需复制
106+
}
107+
```
108+
**Gas节省**:使用calldata可节省约5,000-20,000 gas
109+
110+
### 4. **存储操作优化**
111+
112+
#### 批量操作
113+
```solidity
114+
// ❌ 浪费Gas:多次存储操作
115+
function badBatch() external {
116+
data[0] = 1; // 20,000 gas
117+
data[1] = 2; // 20,000 gas
118+
data[2] = 3; // 20,000 gas
119+
}
120+
121+
// ✅ 节省Gas:使用结构体批量存储
122+
struct BatchData {
123+
uint256 a;
124+
uint256 b;
125+
uint256 c;
126+
}
127+
function goodBatch() external {
128+
BatchData memory batch = BatchData(1, 2, 3);
129+
// 一次性存储,节省gas
130+
}
131+
```
132+
**Gas节省**:批量操作可节省约10,000-30,000 gas
133+
134+
#### 存储位置选择
135+
```solidity
136+
// ❌ 浪费Gas:频繁修改storage
137+
uint256[] public storageArray;
138+
139+
// ✅ 节省Gas:使用memory处理后再存储
140+
function processArray() external {
141+
uint256[] memory tempArray = new uint256[](100);
142+
// 在memory中处理
143+
// 最后一次性存储到storage
144+
}
145+
```
146+
**Gas节省**:memory操作比storage便宜约15,000-25,000 gas
147+
148+
### 5. **事件优化**
149+
150+
#### 事件参数优化
151+
```solidity
152+
// ❌ 浪费Gas:过多indexed参数
153+
event BadEvent(
154+
address indexed from,
155+
address indexed to,
156+
uint256 indexed value, // 第三个indexed参数
157+
string message
158+
);
159+
160+
// ✅ 节省Gas:合理使用indexed
161+
event GoodEvent(
162+
address indexed from,
163+
address indexed to,
164+
uint256 value, // 非indexed,节省gas
165+
string message
166+
);
167+
```
168+
**Gas节省**:减少indexed参数可节省约375 gas
169+
170+
### 6. **Gas成本对比表**
171+
172+
| 操作类型 | Gas成本 | 优化建议 |
173+
|---------|---------|----------|
174+
| **存储写入** | 20,000 gas | 批量操作,减少存储次数 |
175+
| **存储读取** | 2,100 gas | 缓存变量,避免重复读取 |
176+
| **内存分配** | 3 gas/字节 | 使用calldata,减少内存复制 |
177+
| **函数调用** | 2,100 gas | 内联小函数,减少调用开销 |
178+
| **循环迭代** | 100-500 gas/次 | 循环展开,缓存边界值 |
179+
| **事件日志** | 375 gas + 数据gas | 减少indexed参数,优化数据结构 |
180+
181+
### 7. **实际优化示例**
182+
183+
```solidity
184+
// ❌ 未优化的合约
185+
contract Unoptimized {
186+
uint256 public value1;
187+
uint256 public value2;
188+
uint256 public value3;
189+
190+
function setValues(uint256 a, uint256 b, uint256 c) external {
191+
value1 = a;
192+
value2 = b;
193+
value3 = c;
194+
}
195+
196+
function processArray(uint256[] storage arr) external {
197+
for (uint i = 0; i < arr.length; i++) {
198+
arr[i] = arr[i] * 2;
199+
}
200+
}
201+
}
202+
203+
// ✅ 优化后的合约
204+
contract Optimized {
205+
// 变量打包
206+
uint128 public value1;
207+
uint128 public value2;
208+
uint256 public value3;
209+
210+
// 批量设置,减少存储操作
211+
function setValues(uint128 a, uint128 b, uint256 c) external {
212+
value1 = a;
213+
value2 = b;
214+
value3 = c;
215+
}
216+
217+
// 缓存数组长度,使用memory处理
218+
function processArray(uint256[] calldata arr) external pure returns (uint256[] memory) {
219+
uint256[] memory result = new uint256[](arr.length);
220+
uint256 length = arr.length;
221+
222+
for (uint i = 0; i < length; i++) {
223+
result[i] = arr[i] * 2;
224+
}
225+
return result;
226+
}
227+
}
228+
```
229+
230+
**总Gas节省**:优化后的合约可节省约40,000-80,000 gas(取决于操作复杂度)
231+
232+
### 8. **最佳实践总结**
233+
234+
1. **变量声明**:合理打包,选择合适类型
235+
2. **循环优化**:缓存边界值,考虑循环展开
236+
3. **函数设计**:减少storage操作,使用calldata
237+
4. **存储策略**:批量操作,减少存储次数
238+
5. **事件优化**:合理使用indexed参数
239+
6. **代码审查**:定期检查gas使用情况
240+
241+
通过这些优化,可以将合约的gas消耗降低20-40%,显著提升用户体验和成本效益。
242+
243+
---
244+
245+
## Gas费用与ETH换算关系
246+
247+
### 1. **基本换算公式**
248+
249+
```
250+
交易费用 = Gas使用量 × Gas价格
251+
```
252+
253+
其中:
254+
- **Gas使用量**:合约执行所需的计算资源(固定值)
255+
- **Gas价格**:用户愿意为每个Gas单位支付的ETH数量(可调整)
256+
257+
### 2. **Gas价格单位换算**
258+
259+
#### Wei(最小单位)
260+
```solidity
261+
1 ETH = 10^18 Wei
262+
1 Gwei = 10^9 Wei
263+
1 ETH = 10^9 Gwei
264+
```
265+
266+
#### 常用Gas价格范围
267+
| 网络拥堵程度 | Gas价格范围 | 说明 |
268+
|-------------|-------------|------|
269+
| **低拥堵** | 5-20 Gwei | 交易确认时间:1-2分钟 |
270+
| **中等拥堵** | 20-50 Gwei | 交易确认时间:2-5分钟 |
271+
| **高拥堵** | 50-100+ Gwei | 交易确认时间:5-15分钟 |
272+
| **极端拥堵** | 100-500+ Gwei | 交易确认时间:15分钟以上 |
273+
274+
### 3. **实际费用计算示例**
275+
276+
#### 简单转账交易
277+
```solidity
278+
// 标准ETH转账:21,000 gas
279+
Gas使用量 = 21,000 gas
280+
Gas价格 = 20 Gwei = 20 × 10^-9 ETH
281+
282+
交易费用 = 21,000 × (20 × 10^-9) = 0.00042 ETH
283+
// 约等于 $0.84(假设ETH = $2,000)
284+
```
285+
286+
#### 智能合约交互
287+
```solidity
288+
// 存储写入操作:20,000 gas
289+
Gas使用量 = 20,000 gas
290+
Gas价格 = 30 Gwei = 30 × 10^-9 ETH
291+
292+
交易费用 = 20,000 × (30 × 10^-9) = 0.0006 ETH
293+
// 约等于 $1.20(假设ETH = $2,000)
294+
```
295+
296+
#### 复杂合约操作
297+
```solidity
298+
// 批量操作:100,000 gas
299+
Gas使用量 = 100,000 gas
300+
Gas价格 = 25 Gwei = 25 × 10^-9 ETH
301+
302+
交易费用 = 100,000 × (25 × 10^-9) = 0.0025 ETH
303+
// 约等于 $5.00(假设ETH = $2,000)
304+
```
305+
306+
### 4. **Gas价格动态调整机制**
307+
308+
#### EIP-1559费用模型
309+
```solidity
310+
// 新费用结构
311+
总费用 = 基础费用 + 优先费用
312+
313+
其中:
314+
- 基础费用:被销毁,动态调整
315+
- 优先费用:给矿工的小费
316+
```
317+
318+
#### 基础费用计算
319+
```solidity
320+
// 基础费用根据区块使用率动态调整
321+
if (区块使用率 > 50%) {
322+
基础费用 += 12.5%
323+
} else if (区块使用率 < 50%) {
324+
基础费用 -= 12.5%
325+
}
326+
```
327+
328+
### 5. **不同网络Gas价格对比**
329+
330+
| 网络 | 平均Gas价格 | 特点 |
331+
|------|-------------|------|
332+
| **以太坊主网** | 15-50 Gwei | 安全性最高,费用较高 |
333+
| **Polygon** | 0.1-1 Gwei | 费用极低,确认快速 |
334+
| **BSC** | 3-10 Gwei | 费用适中,兼容性好 |
335+
| **Arbitrum** | 0.1-0.5 Gwei | 费用低,L2解决方案 |
336+
337+
### 6. **Gas费用优化策略**
338+
339+
#### 时间选择
340+
```solidity
341+
// 选择低峰期执行交易
342+
// 美国东部时间:凌晨2-6点
343+
// 欧洲时间:凌晨3-7点
344+
// 亚洲时间:下午2-6点
345+
```
346+
347+
#### 价格设置策略
348+
```solidity
349+
// 1. 设置Gas价格上限
350+
maxFeePerGas: 50 Gwei
351+
maxPriorityFeePerGas: 2 Gwei
352+
353+
// 2. 使用动态Gas价格
354+
// 根据网络拥堵程度自动调整
355+
```
356+
357+
### 7. **实际开发中的费用估算**
358+
359+
#### 使用Hardhat估算
360+
```javascript
361+
// 估算Gas使用量
362+
const gasEstimate = await contract.estimateGas.functionName(params);
363+
console.log(`预估Gas: ${gasEstimate.toString()}`);
364+
365+
// 估算费用
366+
const gasPrice = await ethers.provider.getGasPrice();
367+
const fee = gasEstimate.mul(gasPrice);
368+
console.log(`预估费用: ${ethers.utils.formatEther(fee)} ETH`);
369+
```
370+
371+
#### 使用Web3.js估算
372+
```javascript
373+
// 估算Gas
374+
const gasEstimate = await contract.methods.functionName(params).estimateGas();
375+
console.log(`预估Gas: ${gasEstimate}`);
376+
377+
// 获取当前Gas价格
378+
const gasPrice = await web3.eth.getGasPrice();
379+
const fee = gasEstimate * gasPrice;
380+
console.log(`预估费用: ${web3.utils.fromWei(fee, 'ether')} ETH`);
381+
```
382+
383+
### 8. **费用监控工具**
384+
385+
#### 实时监控网站
386+
- **Etherscan Gas Tracker**:实时Gas价格
387+
- **GasNow**:Gas价格预测
388+
- **ETH Gas Station**:详细费用分析
389+
390+
#### 开发工具集成
391+
```javascript
392+
// 在DApp中集成Gas价格显示
393+
async function getGasPrice() {
394+
const gasPrice = await provider.getGasPrice();
395+
const gwei = ethers.utils.formatUnits(gasPrice, 'gwei');
396+
return `${gwei} Gwei`;
397+
}
398+
```
399+
400+
### 9. **总结**
401+
402+
1. **Gas费用 = Gas使用量 × Gas价格**
403+
2. **1 ETH = 10^9 Gwei = 10^18 Wei**
404+
3. **标准转账:21,000 gas × 20 Gwei = 0.00042 ETH**
405+
4. **合约交互:20,000-100,000+ gas,费用因操作复杂度而异**
406+
5. **选择合适时机和Gas价格可显著降低交易成本**
407+
6. **使用工具监控和估算Gas费用,优化用户体验**
408+
18409
# 2025-08-18
19410

20411
整理开发快捷键

0 commit comments

Comments
 (0)