注释
1.代码注释
- 单行是//
- 多行是/**/
2.文档注释
- 三斜杠///
- /** */
值类型和引用类型
1.值传递:简单来说就是拷贝,不会对原数据造成影响
2.引用传递:不是拷贝,会对原有的数据产生影响
3.值类型
- 整形
- 布尔
- 地址(address)
- 枚举
- 函数
- 定长字节数组 类似[32]byte
4.引用类型(在某些情况下,复杂类型占用的空间比较大,在拷贝的时候也会占用比较大的空间,所以这种情况可以考虑采用引用传递)
- 不定长字节数组
- 字符串(string)
- 数组(array)
- 结构体
整型
1.有符号和无无符号
2.步长为8,最大2^256
- 若没有给定步长,系统默认最大的256
- 在使用整型过程中,如果在已经确定了数据大小的上限情况下,尽量使用与其最靠近的步长。节省公链资源
- EG:在add框中输入 x ,y 点击add,获得结果
- 和其他语言一样,也会产生截断
- Solidity中,转化的时候不支持8进制
- 整形的上溢和下溢
- 上溢:如果一个整形变量的值达到其类型的上限,再给他加上一个正数,最终结果会是变量值+正数-类型上限
- 下溢:如果一个整形变量的值达到其类型的下限,再给他减上一个正数,最终结果会是上限值-该正数的值
布尔值bool
1.取值:true、false
2.运算符
- 比较
- 逻辑
地址类型(address)
-
代表以太坊地址、大小20个字节、160位、所有地址都可以用uint160进行编码
-
支持比较运算,不支持四则运算
-
地址类型拥有自己的成员
内键函数
- msg.sender 得到的是地址
- msg.value 得到的是值
属性,balance:通过该属性可以获取指定地址的余额,通过address(this).balance可以得到当前地址的余额
方法
- 转账send():向某个指定的地址发送货币
在Value处输入要充值的数量
注意:Gas不够执行会失败
定长字节数组
- 表现形式:bytes
- 定长字节数组从bytes1开始一直到bytes32
- 步长是1
- bytes默认值表示bytes1
- 支持的运算符:位运算、比较运算
- 定长字节数组也拥有自己的属性
- Length:获取定长字节数组的长度
- Length:属性不可以修改
字符串
- 字符串字面量不包含结束符
- 对字符串的操作
- 通过bytes转换可以获取长度
- 通过bytes转换可以获取字符串中指定的元素值
- 可以通过bytes转换改变字符串中指定下标的元素值
- 字符串和字节数
智能推断
- 使用var关键字的时候 ,在第一次赋值的时候,编译器会自动推断变量的类型,不能在函数参数中使用
- 在第一次变量类型已经确定之后,后面对该变量的赋值必须在这个类型范围之内。
- Var可以把函数赋值给一个变量
- 注意 有时候var会推断出一个错误的类型
16进制
- 特点:以关键字hex开头,后面根一些字符串 EG: hex “00112233”
- 和字符串一样,16进制也可以与bytes进行转换,转换完成后也能够通过下标去获取指定元素的值
常量和变量
-
常量:Solidity中,常量和其它语言没有太大的区别,需要注意的是,不是所有类型都支持常量,当前只有值类型和string支持,另外,在solidity中,仍然需要在constant关键字前面指定一下常量的类型
-
变量-数据位置
①.位置分类,在solidity中,变量的位置分为两类
- memory:存储在内存中
- storage:storage修饰的数据会永久的存储在区块链上
- calldata: 不用在程序中去指定,该位置上的数据是只读的,不持久化到区块链上,一般在外部函数才会指定
②.存储位置说明
- 状态变量默认存储在storage中
- 函数中的局部变量默认存储位置是storage
- 函数参数和返回值默认的存储位置是memory
③.变量转换(数据位置)
- memory->memory 引用传递,会改变源数据的值
- memory->storage 不会改变源数据
- storage->storage 也会改变源数据
- storage->memory 数据拷贝 , 不会改变源数据的值
枚举
- 特点:用户的自定义类型,枚举可以显示的与整形进行转换,显式的转换会在运行时检测数值范围,如果范围不匹配会引发异常。枚举类型至少要有一个成员。
- 默认从0开始
结构体
- 结构体也是solidity中的自定义数据类型,在其中包含基本类型以及复杂
- 初始化方式
- 根据成员名称进行初始化
- 根据成员顺序进行初始化
- 注意:在solidity中不能直接返回结构体,只能返回成员
数组
- 数组分为定长和变长
- 注意对于storage数组来说,元素类型可以是任意
- 对于memeory数组来说,元素的类型的函数可见性有关,如果函数是外部可见的,函数参数不能是一个映射类型的数组。
- 声明方式
-
定长:ARRAY[length]
- 不定长:ARRAY[]
- 如果说状态变量类型是一个数组,并且加了public标记,solidity会自动创建一个访问器,可以直接通过下标进行访问
- 初始化:对于变长数组来说,可以能过关键字new进行初始化 ,通过new创建的memory数组。不能通过.length长度的修改来修改数组的大小属性
- 数组字面量:是指以表达式的方式隐式声明一个数组,并作为一个数组变量的使用的方式,通过字面量只能创建memory的定长数组。元素类型正好是能够存储的元素的长度
- 数组的属性和方法
数组拥有.length属性,表示当前的数组长度
- 对于定长来说,不可修改
- 对于不定长数组,length可以修改,如果当前的元素数量小于length,多余的用0来补,如果改掉之后的length小于当前的元素数量,产生截断
不定长数组拥有push方法,通过push方法可以附加新的元素到数组末尾,返回值是新的长度
-
二维数组
- 数组元素仍然是一个数组
- Uint[][5] X:代表X是一个有5行,每一行的列是一个动态数组。
- Uint[3][5] X :代表X是一个5行3列的数组
- 注意,在solidity中,二维数组的行列位置与大多数编程语言(golang..)是相反的。前面是列,后面是行。
a[2][3],就是图中a的位置,也就是最后一个数据
a[3][2],越界了,如果有4列可以进行修改。
映射
- 字典、键值对的映射关系存储结构。Mapping(_keyType=>_keyValue)。
- 映射本身、动态数组、合约、枚举、结构体都不能够作为映射的键值,映射的值可以是任意类型。
- 在solidity中映射没有长度,也没有键集合(列表),值集合(列表)这样的概念
- Delete映射中的一个key值,实际不是在删除,而是在重置为初始值
- 在solidity中,map不支持遍历
查找中,若映射中没有要查找的key值,int类型返回0,其他类型返回代表对应空的值。
类型转换
- 隐式类型转换
- 如果运算符支持两边不同的类型,编译器会尝试进行自动转换。
- 任何无符号的整数都可以转换为相同或者更大大小的字节值。比如任何一个可以转换为uint160的变量都可以转换为address类型。如果说uint160的数据没有达到上限值,高位补0。
- 隐式类型转换首先要考虑的是在转换的过程中,防止数据丢失。
- 显式类型转换
- 在不允许类型转换的情况下,确保可以转换的前提下,进行强制转换
- 注意,如果说由一个大类型(uint32)转换为小类型(uint16),高位会被截断。
控制语句
- Solidity中所支持的控制语句有
- for
- while
- do-while(后测试,会先执行一遍循环体中的代码)
- if-else
- 三目运算符
mulmod是内建函数,对x,y除以2取余数。
全局单位
1.货币单位
- Wei 1
- Kwei 1e3
- Mwei 1e6
- Gwei 1e9
- Mircroether 1e12
- Milliether(finney) 1e15
- Ether 1e18
2.时间单位(没有month)
- 时间分类:Seconds,minutes,hours,days,weeks,years
3.内建的全局变量
- 在solidity中,内建的全局变量可以在合约脚本的任何地方调用
- Msg的所有成员
- Sender:发送者地址
- Value:发送给合约的以太币,默认单位是位
- Data:调用数据
- Gas:剩余gas
- This的部分成员:Balance: 余额
- Tx的部分成员
- Origin:交易发送者的地址
- Gasprice:gas的价格
- Now :当前时间
- Block成员
- Number:区块号
- Difficulty:当前区块难度
- Coinbase:矿工地址
- Timestamp:时间戳
- Gaslimit():当前区块的gaslimit
- Blockhash(num):给定区块的哈希值,只支持最近的256个区块