
请问您是否适合学习这门课?
智能合约是应用程序、购物网站、去中心化交易所、DeFi、GameFi...
区块就是存储数据的空间,可读可写,不能修改
什么是旷工?
交易费如何计算?
网路是由多个节点组成
节点必须有连接的能力,也就是发送和接受数据
账户是银行存折、交易所账户、客户端钱包
私钥是钱包唯一标识符,千万不能泄漏给他人
公钥由私钥生成
地址有公钥生成
密码是保护私钥
助记词是私钥另一种表现形式(注:由助记词生成私钥,而不是私钥生成助记词)
提案1559升级之前,Gas采用竞价收费方式
提案1559升级之后,Gas采用基础费+小费,它是如何计算?
首页功能介绍
工程目录workspace介绍
编译功能介绍
部署功能
创建自己workspace
代码校验
编码
调试
部署
工程文件结构
合约文件结构
License
注释
全局变量、局部变量
方法
License 参见: https://spdx.org/licenses/
//注释
/注解/ /// 参见: https://docs.soliditylang.org/en/v0.5.9/natspec-format.html#tags
; 结束符
大括号方法体
[]中括号
import 可以引入合约、抽象合约、类库、接口
import 可以引入Struct、错误信息、事件、等...
import 可以本地文件或是网络上可访问到的合约文件
【该课程不提供任何学习资料】
1、Remix工程文件是储存浏览器你额indexedDB数据里面
2、如果我们把浏览器的删除或清除浏览器数据,工程里面的文件也会被删除
3、我们需要把工程文件写入系统文件
4、当我把github上代码下载到系统文件后,就可以自己加载到remix的工程目录里,而不需要一个个文件复制粘贴
5、安装remixd插件与应用
5.1、 安装remixd插件npm i @remix-project/remixd
5.2、 映射系统文件夹工作目录到remix工作目录 remixd -s C:\Users\ALIENWARE\courses\uniswapv2\uniswap-v2-core
6、工作的使用一定要开启remixd应用
没有代码
有符号整数int
无符号整数uint
uint256/uint有多大
布尔是开关,或开或关,没有第三选项
布尔值运算符
布尔与整数转换
字符串定义
字符串比较
字符串字节码转换
Bytes是字节数组,可分为固定长度的数组和动态数组
字节以16进制为0 ~ 9,a ~ f 范围
字节操作
从业务层面来讲,Address 分为EOA(Externally Owned Account)钱包地址与合约地址
从代码层面来讲,Address 分为address 与 address payable。 它们的区别在于 address payable 拥有transfer和send方法
address 与 address payable直接转换
address的方法与属性
对于有相同属性的常量,比如订单状态尽量使用枚举表示
修改枚举的值
删除枚举的值
根据Key获取Value
根据Value获取Key
00:45 数组的定义
01:00 获取并返回数组
02:00 根据数组index获取相应的值
03:15 获取数组的长度
04:15 在数组后面追加数据push
05:00 删除数组末尾数据pop
05:50 根据数组index删除相应的值
07:00 内存(memory)数组的使用和主要事项
00:35 定义struct User对象
01:30 新增User对象
05:00 获取一个User
06:41 修改User
10:22 删除User
Mapping不能遍历里面的Key,也就是不知道Mapping有多少个key
Mapping以Key -> Value 形式储存
Mapping的Key是根据hash (Key + slot)产生的bytes32,所以Key是不会重复
Mapping的key,可以看作数据库表的主键
嵌套Mapping的key,可以看作数据库表的联合主键
获取int256最大值和最小值
获取合约的名称
获取合约的字节码与应用场景
获取合约运行时字节码
获取接口的Id与应用场景 ,根据合约地址判断代币的类型(ERC721、ERC1155)
值类型固定大小,定义变量时就分配内存,变量直接指向数据(Value)
引用类型没有固定大小,定义变量时分配指针地址(数据的引用),变量指向指针地址
memory、calldata与storage,它们只能修饰引用类型变量,比如字符串、数组、字节等...
memory 适用于方法传参、返参或在方法体内使用,使用完就会清除掉,释放内存
calldata 仅适用于方法传参,修饰该变量的值不能修改
storage 仅适用于方法体内,而且它的指针必须指向链上数据。使用完,链上数据将保存最新状态
constant 编译前已经确定,编译后不能再修改常量的值
constant 它不是状态变量,所以它不储存在插槽(Slot)里面,获取该常量的方法修饰必须是Pure,而不是View
immutable 它是状态变量,所以它储存在插槽(Slot)里,获取该变量的方法修饰必须是View,而不是Pure
immutable 必须在构造函数里面赋值,之后就不能再修改
全局变量Global, Solidity内部固有的变量,比如msg.sender、block.number、tx.origin,它在合约里任何地方都可以使用
状态变量State, 它是储存在链上的数据变量,永久存在。
局部变量Local, 它是方法体里临时定义的变量或是方法参数或是方法返回值,方法执行完就被删除释放内存
把智能合约看作对象,一切皆为对象
合约对象有属性、有动作行为,它们相互协同工作
为什么使用接口?
接口是一种编程规范,在面向对编程中起到非常大的作用
接口只能定义函数/方法,不能有方法体
不能包含状态变量
不能包含构造函数
所有方法都必须是external,需要暴露给外部调用
接口是可以继承的
实现(is)接口的合约必须实现接口里定义的所有方法
什么是抽象智能合约?
抽象的反义词是具体、详细、明确。我们需要把不明确的功能抽出来,让继承抽象合约的子合约去实现
使用抽象合约的场景?
一、强制用户必须执行某个业务逻辑方法
二、用户可选择的执行某个业务逻辑方法
工具类
不能继承
不能包含状态变量,可包含constant 修饰的变量
不能接收代币
不能构造函数
is 有俩个用途:1、is 可以用来实现接口;2、is 可以用来继承合约、抽象合约或接口。
为什么要有继续?
通用继承/简单继承
virtual,如果确认某个方法必定被子类继承,就应该使用 virtual 修饰该方法,它是修饰父类的方法
override,必须用override修饰的子类方法,它才能重写父类的virtual方法,它是修饰子类的方法
override,必须有一致的方法名和参数.
多重继承,有多个父类
函数是智能合约的灵魂,没有函数智能合约就没有自己的行为
函数必须放在合约、接口和类库里面
接口里的函数是没有方法体,由实现该接口的智能合约去完成函数/方法功能
为什么有的函数没有返回值
1、构造函数 ,是一种特殊的方法。主要用来在创建合约时初始化合约对象, 即为合约状态变量赋初始值
2、构造函数只能在创建合约时被调用一次。
3、Solidity只能有一个构造函数,其他语言可以都多个构造函数
4、构造函数的参数不能使用"引用类型"修饰符calldata,只能用Memory
5、创建合约的同时如果想转ETH给该合约,需要在构造函数后面加payable修饰符
摧毁合约原因如下:
不再使用该合约
强制用户迁移到新的合约
合约被攻击
销毁合约之前,把代币转移
public:在任何地方都能调用
internal:只有自己内部或子类才能调用
private:只有自己内部才能调用
external:只有外部才能调用,合约本身也不能调用
默认的方法既可访问也可修改链上数据(状态变量)
View 可以访问链上数据(状态变量),但不能修改链上数据
Pure 不能访问链上数据
外部调用View或Pure修饰的方法,不需要支付Gas,并不意味着EVM产生执行Gas(execution costs)
If 必须写在方法体里面
If 是控制程序的运行路径
If 只能与布尔值bool协作
if 语句 - 只有当指定条件为 true 时,我们会执行if相应的代码
if...else... 语句 - 当if条件为 true 时,会执行if相应的代码。当条件为 false 时会执行else的相应代码
if...else if...else if...else... 语句- 使用该语句来选择多条路径之一来执行
for 循环可以将代码块重复执行指定的次数
无符号整数uintfor 循环接收参数是整型
while(条件) { ...},只要条件为 true,while循环就可以一直重复执行指定的代码块{ ...}。
do {...}while(条件),先执行指定的代码块{ ...},再判断while(条件)是否成立,如果成立将继续重复指定的代码块{ ...}
for 可以实现while同样的功能
Break根据条件跳出循环体
Continue 根据点击跳过循环中的一个迭代
Require 输入值的校验
Require 接收两个参数:1、布尔值,2、字符串
Require 参数布尔值为false的时候,程序会抛出异常
Modifier主要修饰function方法,在执行function之前,先检查是否有modifier修饰符。如果有,先执行modifier修饰的方法.
Assert VS Require
Assert 主要适用于单元测试或内部测试,它会抛出致命异常Panic(uint256),开发人员不能定义错误信息
Require 主要适用于校验输入值是否满足业务需求,它抛出的错误信息是由开发人员定义
Assert 在任何地方都可能抛出异常,例如计算过程中出现溢出的情况,它是一个的明确Bug存在。
Require 用于在执行业务代码之前,对输入参数进行校验,它不是一个Bug。
Assert 抛出异常信息供内部(开发人员)参考 ,不需要用户了解。
Require 错误信息供外部用户参考,让用户了解是什么原因导致没能成功调用方法
revert 抛出异常,使程序直接回滚到最初的状态
error 是自定义错误信息,通常与Revert配合使用
在面向对象语言中, this 表示当前对象的一个引用
在Solidity语言中, this 表示本合约。确切地说,它不是本合约的对象
this有以下局限性:
1、不能访问本合约状态变量或常量
2、当this访问本合约方法时,它认为是外部调用本合约的方法,所以被调用的方法修饰符必须是public或external
最常用的是address(this),获取本合约地址
msg.sender,它是一个全部变量,在Solidity中任何一个地方都可以使用
msg.sender,它是一个地址(address),有可能是个人钱包地址(EOA),也有可能是合约地址
msg.sender,它是发起调用转账或调用他人合约的地址
该课程主要内容如下:(如果章节涉及到代码,都会附有源代码)
一、学习课程的预备知识
二、了解Remix开发工具与使用
三、了解Solidity语言的基本语法
四、了解Solidity语言的数据类型,值类型与应用类型
五、了解Solidity语言合约类、抽象类、接口与类库
六、了解Solidity语言的方法与修饰符
七、了解Solidity语言的控制流程
八、了解Solidity语言的关键字/保留字
九、深入了解ERC20通证
十、深入了解NFT/ERC721
十一、深入了解ERC1155
十二、了解真实案例,开发与部署自己的智能合约