越学越迷糊,于是准备再学一遍,进行总结。Solidity学习笔记一:基础语法与remix的使用
本人是一只前端程序猿,最近各种前端已死的言论甚嚣尘上,既然web2走不通了,那就去web3这条赛道瞧瞧
参加了登链社区技术集训营二期,又看了其他的教学视频,感觉是越学越迷糊
于是准备再学一遍,进行总结。如有错误,还请指正🫰希望各位大佬能够不吝赐教
Solidity:是一门面向合约的、为实现智能合约而创建的高级编程语言。
智能合约:是管理以太坊状态里账户行为的程序。
Solidity 是静态类型语言,支持继承、库和复杂的用户定义类型等特性。
万事开头难,我们先拿编辑器开个头
编写Solidity有很多种方式,我们先用浏览器的在线编辑器,比较简单,访问这个在线编辑器网站 Remix 编辑器
第一步就是先把其他的文件给删除掉,
第二步:新建自己的contracts文件夹 ,然后在里面新建一个以 .sol
结尾的文件
(智能合约的文件都是以.sol结尾的)
代码要先指明 solidity 使用的版本
pragma solidity 0.8.7; // 只是用这个版本
solidity版本也有几种不同的声明方式
pragma solidity 0.8.7; // 只是用这个版本
pragma solidity ^0.8.7; // 比0.8.7这个版本更新的都适用
pragma solidity >0.8.7; // 大于这个版本
pragma solidity >=0.8.7 <0.9.0; // 大于等于这个版本适用 0.9以上的不适用
重点: 每行代码都要使用
;
结尾
你以为 pragma solidity 0.8.7;
就是web3的第一行代码了吗?
no ! no ! no ! no ! no !
在开始写程序之前 需要先声明一下,否则在有的编辑环境下有可能会报错
它是定义一个代码规则和分享规则
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
在编辑器里,你写的代码就是这个样式
然后进行编译,点击Compile ...
是进行编译;没有语法错误编译成功时,1处就会有个绿色的对号
到这 已经把 Solidity
项目运行起来了,虽然好像什么都没有,但是确实 实实在在的编译成功了
接下来咱们继续,开始深入
俗话说:万事开头难,然后中间难;现在开始学习智能合约,开始填充合约内容
合约是使用 contract
进行声明的
它就像一个java语言的class一样,声明一个合约名
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract HelloWorld{
// 合约内容
}
在Solidity中的变量类型大概分为这几类
数值类型(Value Type) :包括布尔型,整数型等等,这类变量赋值时候直接传递数值。
引用类型(Reference Type) :包括数组和结构体,这类变量占空间大,赋值时候直接传递地址(类似指针)。
映射类型(Mapping Type) : Solidity
里的哈希表。
数值类型 最基础的有四种数据类型分别是 boolean , uint , int , address 等等
boolean // 布尔值类型 默认值为false
int // 可表示正数和负数 默认值为0
uint // uint是无符号整数 表示这个数字不是可正可负的,就只能表示正数 默认值为0
string // 表示一个单词,字符串,需要用 “”
address // 表示地址 比如数字钱包的地址 默认值为0的地址: 0x0000000000000000000000000000000000000000
enum //枚举
// SPDX-License-Identifier: MIT
pragma solidity 0.8.8;
contract HelloWorld {
// 定义一个变量名为 hasFavoriteNumber 的布尔值
bool hasFavoriteNumber = true;
}
uint是无符号整数 表示这个数字是正整数
而且 solidity里也没有小数
// SPDX-License-Identifier: MIT
pragma solidity 0.8.8;
contract HelloWorld {
// 定义一个变量名为 favoriteNumber 的正数
uint favoriteNumber; // 初始化值为0
uint favoriteNumber1 = 666;
// 我们可以给unit分配空间 uint8表示他有8个bit,uint就相当于uint256
uint8 favoriteNumber = 255;
uint favoriteNumber = 666; // 默认分配的空间大小就是256
uint256 favoriteNumber = 666;
}
但是如果我给 unit8 赋值一个比较大的数字,那么就会报错
因为赋值的数字已经超过了unit8
可以存储的范围
枚举(enum
)是solidity
中用户定义的数据类型。它主要用于为uint
分配名称,使程序易于阅读和维护,使用名称来代替从0
开始的uint
:
// 用enum将uint 0, 1, 2表示为Buy, Hold, Sell
enum ActionSet { Buy, Hold, Sell }
// 创建enum变量 action
ActionSet action = ActionSet.Buy;
可表示正数和负数 默认值为0
// SPDX-License-Identifier: MIT
pragma solidity 0.8.8;
contract HelloWorld {
// int
int favoriteInt = -5;
int256 favoriteNumber = 666;
}
表示一个字符串
// SPDX-License-Identifier: MIT
pragma solidity 0.8.8;
contract HelloWorld {
// string类型
string favoriteText = "dong";
}
表示地址 比如数字钱包的地址
// SPDX-License-Identifier: MIT
pragma solidity 0.8.8;
contract HelloWorld {
// address类型
address myAddress = 0xb2028c070948d7F42FB1e0465dcB70F0671A155d;
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.8;
contract HelloWorld {
// bytes类型 也可以制定大小 它通常存储以 0x开头后面跟一些随机数字和字母
bytes32 favoriteBytes = 0x3f89
// bytes 赋值字符串类型 会自动转化为bytes 32是它允许分配的最多的空间
bytes32 favoriteBytes = "cat"
}
常量: 在变量名前面 加上 constant 标识 , 常量名用大写字母表示
// SPDX-License-Identifier: MIT
pragma solidity 0.8.8;
contract HelloWorld {
address public constant MY_ADDRESS;
}
细心的同学可以发现,定义变量的时候在变量名前面有一个 public
public :表示这个变量公开了,任何与合约交互的人 都可以看到 变量中存储的值
我们定义两个变量,一个带有public,一个不带,接下来我们把它部署一下
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
// 第一个合约
contract SimpleStorage {
uint myNumber = 111;
uint public favoriteNumber = 666;
}
编译好后,我们点击 1 这个时候就进入编译的页面,按钮2:"Deploy" 就是部署
点击 Deploy 按钮 就会发现部署好后的操作区域,可以看到有public的显示在页面上,我们能看到,没有public标识的就没有公开
接下来点击一下它就能看到它的值
引用类型(Reference Type) :包括数组和结构体,这类变量占空间大,赋值时候直接传递地址(类似指针)。
数组: 如果你想建立一个集合,可以用 数组
这样的数据类型. Solidity 支持两种数组: 静态数组和 动态数组:
// 固定长度为2的 uint类型的静态数组:
uint[2] fixedArray;
// 固定长度为5的 string类型的 静态数组:
string[5] stringArray;
// 动态数组,长度不固定,可以动态添加元素:
uint[] dynamicArray;
struct
结构体:支持通过构造结构体的形式定义新的类型;声明一个自定义的类型
// 结构体
struct Student{
uint256 id;
uint256 score;
}
Student student; // 初始一个student结构体
以下是对数组和结构体的总结
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
contract MyContract{
// 定义一个类型,类型名为People
struct People{
uint256 favoriteNumber;
string name;
}
//
People public people=People({favoriteNumber:6,name:'dong'});
People public people1=People({favoriteNumber:61,name:'dong1'});
// 定义一个数组
People[] public peopleList;
// 向数组内添加数据
function addPerson(string memory _name,uint256 _favoriteNumber) public{
// 添加数据方式一
People memory newPerson = People({favoriteNumber:_favoriteNumber, name:_name});
peopleList.push(newPerson);
// 方式二
peopleList.push(People({favoriteNumber:_favoriteNumber, name:_name}));
}
}
Solidity
里的函数我觉得和JS的函数非常相似,他也是用function关键字声明的,但是多了一些修饰符
参数也需要声明类型
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
contract SimpleStorage {
uint256 public favoriteNumber; // 以0初始化变量
// 定义一个 store的函数 传入一个形参
function store(uint256 _favoriteNumber) public {
// 进行赋值
favoriteNumber = _favoriteNumber;
}
}
点击黄色的 Deploy进行部署合约,就会出现以下信息
部署合约就 是发送一个交易;区块链上做任何事情,修改任何状态 就是在发一个交易, 我们可以在 store 里输入一个数字,然后点击 store按钮,就会调用一次合约会消耗一些gas
在变量名favoriteNumber
前面添加一个 public 表示这个变量公开了,可以在外部访问到它,我们看看能不能赋值成功
点击favoriteNumber 可以看到已经赋值成功
public
表示公开,任何与合约交互的人 都可以看到 变量中存储的值(public会创建变量的getter函数,返回函数值)
private
表示只对合约内部可见;只能从本合约内部访问,继承的合约也不能用(也可用于修饰状态变量)。
uint[] numbers;
function _addToArray(uint _number) private { numbers.push(_number); }
- `external`表示只对合约外部可见;只能从合约外部访问(但是可以用`this.fn()`来调用,`fn`是函数名)
- `internal`表示只有这个合约或者继承它的合约可以读取;只能从合约内部访问,继承的合约可以用(也可用于修饰状态变量)。
### 函数权限/功能 关键字
- `payable`(可支付的)很好理解,带着它的函数,运行的时候可以给合约转入`ETH`
- `view` 表示这个函数只会读取这个合约的状态,view函数里面不允许修改任何状态
- `pure` 也不允许修改状态,而且pure也不允许读取区块链数据,不能读取变量;通常用于某个不需要读取数据的算法
> **合约里面的操作和计算越多,消耗的gas也越多**
### 函数输出
`Solidity`的函数输出需要有两个关键字:`return`和`returns`
- `returns`加在函数名后面,用于声明返回的变量类型及变量名;
- `return`用于函数主体中,返回指定的变量。
```js
// 返回多个变量
function returnMultiple() public pure returns(uint256, bool, uint256[3] memory){
return(1, true, [uint256(1),2,5]);
}
在 returns
里表明返回的变量名称,solidity
会自动初始化这些变量,并返回这些函数的值;并且不需要使用 return
// 命名式返回
function returnNamed() public pure returns(uint256 _number, bool _bool,
uint256[3] memory _array){
_number = 2;
_bool = false;
_array = [uint256(3),2,1];
}
英文 | 翻译 |
---|---|
Compile | 编绎;编译文件;编译 |
contract | 合同;合约;契约; |
private | 私有的;私人的;私用的; |
external | 外部的;外面的;外界的; |
internal | 里面的;体内的; |
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!