文章目录
- Solidity极简入门
- HelloWorld
- 数值类型
- 三种函数类型
- 函数输出
- 变量作用域
- 引用类型
参考文章:一文速览2022十大智能合约开发工具
资料地址:WTF学院
Solidity极简入门
HelloWorld
remix:在线智能合约开发IDE(Integrated Development Environment,集成开发环境),可以在浏览器中快速部署测试智能合约。
合约HelloWorld:
// SPDX-License-Identifier: MITpragma solidity ^0.8.4;contract HelloWeb3{string public hi = "Hello World!";}
事项 | 说明 |
---|---|
代码所用的软件许可(license) | 不写许可的话编译时会警告(warning) |
声明源文件所用的solidity版本 | 将不允许小于 0.8.4 版本或大于等于 0.9.0 版本的编译器编译 |
Solidity语句分隔符 | 以 ; 结尾 |
在合约目录新建 HelloWorld.sol,点击编译然后再点击部署。部署在测试链上以后,点击我们的变量名就能调用成功。
数值类型
类型 | 说明 |
---|---|
数值类型 | 布尔型bool |
整数型 | 包括整数int、正整数uint、大正整数uint256 |
地址类型address和payable | 其中payable的地址拥有balance和transfer()两个成员 |
定长字节数组 | byte, bytes8, bytes32,其中数字是长度 |
枚举enum | 类似python的集合类型,enum ActionSet { Buy, Hold, Sell } |
– | 可以显式的和uint相互转换,并会检查转换的正整数是否在枚举的长度内 |
三种函数类型
[pure|view|payable]
:决定函数权限/功能的关键字。payable(可支付的)很好理解,带着它的函数,运行的时候可以给合约转入ETH。
合约的状态变量存储在链上,gas fee
很贵,如果不改变链上状态,就不用付gas。包含pure跟view关键字的函数是不改写链上状态的,因此用户直接调用他们是不需要付gas的(合约中非pure/view函数调用它们则会改写链上状态,需要付gas)。
在以太坊中,以下语句被视为修改链上状态:
- 写入状态变量。
- 释放事件。
- 创建其他合同。
- 使用selfdestruct.
- 通过调用发送以太币。
- 调用任何未标记view或pure的函数。
- 使用低级调用(low-level calls)。
- 使用包含某些操作码的内联汇编。
小结:
pure
类型的函数不能读取也不能写入存储在链上的状态变量,只能传入形参进行处理。view
类型的函数能读取但也不能写入状态变量,可以调用合约变量返回给一个新的变量。
函数输出
函数输出包括:返回多种变量、命名式返回、以及利用解构式赋值读取全部和部分返回值。
Solidity有两个关键字与函数输出相关:return和returns,区别在于:
- returns加在函数名后面,用于声明返回的变量类型及变量名;
- return用于函数主体中,返回指定的变量。
命名式返回:通过在 returns
标明返回变量的名称,solidity 会自动初始化并返回这些变量,无需 return 语句。
解构式赋值:solidity使用解构式赋值的规则,支持读取函数的全部或部分返回值。
变量作用域
引用类型(Reference Type):包括数组(array),结构体(struct)和映射(mapping),这类变量占空间大,赋值时候直接传递地址(类似指针)。由于这类变量比较复杂,占用存储空间大,我们在使用时必须要声明数据存储的位置。
solidity数据存储位置有三类:storage,memory和calldata。不同存储位置的gas成本不同。
storage类型的数据存在链上,类似计算机的硬盘,消耗gas多;memory和calldata类型的临时存在内存里,消耗gas少。大致用法:
- storage:合约里的状态变量默认都是storage,存储在链上。
- memory:函数里的参数和临时变量一般用memory,存储在内存中,不上链。
- calldata:和memory类似,存储在内存中,不上链。与memory的不同点在于calldata变量不能修改(immutable),一般用于函数的参数。
赋值规则:只有两种同类型变量的赋值是创建地址引用
- storage(合约的状态变量)赋值给本地storage(函数里的)时候,会创建引用,改变新变量会影响原变量。
- storage赋值给memory,会创建独立的复本,修改其中一个不会影响另一个;反之亦然。
- memory赋值给memory,会创建引用,改变新变量会影响原变量。
- 其他情况,变量赋值给storage,会创建独立的复本,修改其中一个不会影响另一个
变量的作用域:按作用域划分有三种,分别是状态变量(state variable),局部变量(local variable)和全局变量(global variable)
- 状态变量是数据存储在链上的变量,所有合约内函数都可以访问 ,gas消耗高。状态变量在合约内、函数外声明
- 局部变量是仅在函数执行过程中有效的变量,函数退出后,变量无效。局部变量的数据存储在内存里,不上链,gas低
- 全局变量是指 solidity 的预留关键字
引用类型
数组 Array 分为固定长度数组和可变长度数组两种:
- 固定长度数组:在声明时指定数组的长度。用T[k]的格式声明
- 可变长度数组(动态数组):在声明时不指定数组的长度。用T[]的格式声明
创建数组有一些固定规则:
- 对于memory修饰的动态数组,可以用new操作符来创建,但是必须声明长度,并且声明后长度不能改变,例如
new uint[](5)
- 数组字面常数(Array Literals)是写作表达式形式的数组,用方括号包着来初始化array的一种方式
数组成员:
length: 数组有一个包含元素数量的length成员,memory数组的长度在创建后是固定的。push(): 动态数组和bytes拥有push()成员,可以在数组最后添加一个0元素。push(x): 动态数组和bytes拥有push(x)成员,可以在数组最后添加一个x元素。pop(): 动态数组和bytes拥有pop()成员,可以移除数组最后一个元素。
结构体:
// 结构体struct Student{uint256 id;uint256 score; }