Skip to content

Commit 72d66e9

Browse files
committed
update lesson8; add lesson11,12
1 parent 6de84bc commit 72d66e9

File tree

3 files changed

+114
-8
lines changed

3 files changed

+114
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
/*
5+
@合约修改器modifier
6+
- 介绍
7+
用来修改函数的行为,作用类似装饰器。
8+
用法:
9+
- 先定义一个modifier 函数:modifier mustBeOwner() { ...; _; }
10+
- 修饰其他函数:withdraw() public mustBeOwner {}
11+
- 如此一来,执行withdraw函数时,会先执行mustBeOwner(),同时将withdraw的逻辑嵌入 mustBeOwner() 中 `_;` 的位置
12+
特点:
13+
- 可以给一个函数添加多个modifier
14+
- modifier可以接收函数参数
15+
*/
16+
17+
18+
// 测试1
19+
contract Example{
20+
address owner;
21+
22+
constructor () {
23+
owner = msg.sender;
24+
}
25+
26+
// 若没有参数可以省略括号
27+
modifier mustBeOwner virtual {
28+
require(owner == msg.sender, "no permission!");
29+
_; // 占位,用于存放被修饰函数的逻辑
30+
}
31+
32+
// 测试函数
33+
function transfer() public mustBeOwner {
34+
35+
}
36+
}
37+
38+
// 测试2
39+
// modifier可以被继承并重写
40+
contract LearnModifier is Example{
41+
uint a;
42+
modifier mustBeOwner override {
43+
require(owner == msg.sender, "no permission!");
44+
a ++; // 顺序1
45+
_; // 占位,用于存放被修饰函数的逻辑
46+
a ++; // 顺序4
47+
}
48+
49+
// 可以接收参数
50+
modifier limitNum(uint num) {
51+
require(num < 3, "num < 3 is must!");
52+
a ++; // 顺序2
53+
_;
54+
a ++; // 顺序3
55+
}
56+
57+
// 可以设置多个modifier,接收函数参数作为modifier参数
58+
// 注意这个函数实际的执行顺序:mustBeOwner(limitNum(transfer2)))
59+
function transfer2(uint num) public mustBeOwner limitNum(num) {
60+
require(a == 2);
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
/*
5+
@事件:event
6+
- 介绍
7+
是在合约中定义和触发的内容。
8+
特点:
9+
- 只能在storage区声明,通常是大写开头
10+
- 订阅:如名字那样,事件可以被app通过web3.js提供的RPC接口订阅和监听,然后在前端进行对应响应。
11+
- 在合约内无法读取事件
12+
- 经济:一个事件比一个状态变量更节省gas,前者是2000gas,后者是20000gas。事件用来记录合约函数被调用时的log,如转账等。
13+
- 匿名:允许定义匿名事件
14+
- 可查询:在区块链浏览器上查询交易对应的事件内容:https://rinkeby.etherscan.io/tx/0x8cf87215b23055896d93004112bbd8ab754f081b4491cb48c37592ca8f8a36c7#eventlog
15+
- indexed的字段将作为topic以便观察;topic 0是事件签名的keccak哈希,其他topic是indexed字段的keccak哈希,data字段是未索引的字段
16+
- 匿名事件不会记录事件名和参数名,因此也无法通过web3接口进行筛选查询/监听
17+
- 若indexed的字段是数组类型(包含bytes和string类型),则只会保存其keccak哈希到区块链上,即topic观察到的是哈希值
18+
使用场景:
19+
- 智能合约给用户的返回值
20+
- 异常触发
21+
- 更便宜的数据存储
22+
23+
*/
24+
25+
contract LearnEvent{
26+
// indexed 表示将该字段进行索引,以便在区块链浏览器上
27+
// 通过web3.js进行筛选后的监听:var event = myContract.Transfer({num: 100})
28+
event Transfer(address indexed from, address indexed to, uint num);
29+
event Transfer2(address indexed from, address indexed to, uint num) anonymous; // 匿名事件
30+
31+
function transfer(address from, address to, uint num) public {
32+
emit Transfer(from ,to , num);
33+
emit Transfer2(from ,to , num);
34+
}
35+
}

test_solidity/basic_exercises/lesson8_function_varScope.sol

+17-8
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ pragma solidity ^0.8.0;
66
- 介绍
77
- 函数可以定义在合约内、外
88
- 可以有多个入参和出参,出参可以命名
9-
构造函数:
10-
- 只在部署时运行一次的函数,没有function关键字
11-
- 用于初始化所有状态变量、部署时给合约注入以太币
12-
- 可以没有
139
函数可见性(必须表明):
1410
- private:限制性最强,函数只能在所属的合约内使用,继承合约不可以使用
1511
- internal:可以在定义和继承合约内使用
@@ -20,6 +16,7 @@ pragma solidity ^0.8.0;
2016
- view:只能读取状态
2117
- pure:不能读写
2218
- payable:调用函数可以给合约发送以太币
19+
函数重载:合约内可以定义多个同名但不同参数的函数,并且在合约内外有效!
2320
2421
@变量作用域
2522
- 介绍
@@ -31,9 +28,9 @@ pragma solidity ^0.8.0;
3128
*/
3229

3330
// v0.7.0版本开始支持合约外定义函数,不过只能被合约调用,不能直接部署
34-
function free(int a, int b) pure returns (int,int) {
35-
return (a,b); // 多返回值需要是tuple类型
36-
}
31+
function free(int a, int b) pure returns (int,int) {
32+
return (a,b); // 多返回值需要是tuple类型
33+
}
3734

3835
contract LearnFunction{
3936

@@ -76,7 +73,7 @@ contract VarScope{
7673
contract LearnVarScope {
7774
constructor() {
7875
VarScope vs = new VarScope(1);
79-
vs.v2(); // getter()形式访问public变量,solidity自动为public变量创建一个getter函数,方便外部访问其值。
76+
vs.v2(); // getter()形式访问public变量
8077
// vs.v1(); // 不能外部访问internal变量
8178
}
8279
}
@@ -87,4 +84,16 @@ contract LearnVarScope2 is VarScope(1) {
8784
require(v1 == 1); // 直接访问v1
8885
require(v1 == getV1()); // 可以调用internal函数
8986
}
87+
}
88+
89+
// 允许存在多个同名不同参数的函数,在合约内外可以同时使用
90+
contract LearnFuncOverloadding{
91+
function add(uint a, uint b) public pure {}
92+
// function add(uint a, uint c) public pure {} // 函数参数同数量时不能同类型
93+
function add(uint a, uint b, uint c) public pure {}
94+
95+
function test() public pure {
96+
add(1,2,3);
97+
add(1,2);
98+
}
9099
}

0 commit comments

Comments
 (0)