一、 编写第一个智能合约
智能合约也是由编程语言编写,学习编程语言需要掌握以下基本内容:
- 数据类型
- 控制语句
- 数据结构和算法
首先需要了解合约的声明方式和基本数据类型。
1.1 Solidity 声明合约
使用 contract
关键字声明合约:
Solidity 中声明变量的格式:类型 变量名 = 值;
同样的,在同一个智能合约中,不允许变量名重复;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
// 使用 contract 关键字声明合约
contract HelloWorld {
bool boolVar = true; // bool 值
}
1.2 Solidity 的基本数据类型
Solidity 中包含 4中基本数据类型:
- bool:布尔值
- unit:无符号整数
- byte:字节
- address:地址
1.2.1 bool 布尔值
bool 布尔值:在 Solidity 中,布尔值和其他语言中不同,其他语言中的 非 0
值表示 true,0
表示 false。
这一招在 Solidity 中不可用。这是因为智能合约部署在区块链上,一旦出现问题无法删除,因此设计的更为严谨。
bool boolVar = true; // bool 值
bool boolVar2 = false; // bool 值
1.2.2 uint 无符号整数
uint 无符号整数 ,u 表示 unsigned ,int 表示 integer 整数。uint 表示所有正数; 格式:unit 后面可以接位数, uint8 或者 unit256
-
unit8 能表示的是 (0-2^8-1) 的数字即 0-255,赋值小于0或者大于255的就会报错,uint8 varNum1 = 256 报错
-
uint256 常用,这个数字很大;一般 uint 和 uint256 等价
uint uintVarNum2 = 2555555; // 可以,但是一般不建议省略256,推荐显式声明
// int 整形:整数,可以存储有符号的整数,例如负数。int 表示 int256
int intVar = -1;
1.2.3 byte 字节
一个 byte 式 8 个 bit,一般存放字符串。solidity 中最大可以声明 bytes32,不能写 超过 32 的 bytes
bytes32 varChar = 'hello world';
注意 solidity 中也包含 bytes
但它是数组,是 bytes8/32/64的数组,不是默认的 bytes8
solidity 中也有 string
:某一种特殊的 bytes,自动分配空间的 bytes
string strVar = 'hello world';
思考:有了 uint256 还要 unit8 干啥?有了 string 还要 bytes 干啥? 答案:节约内存,提升效率;声明内存和位数的分配的内存不会超过声明的位数
1.2.4 address:地址
你的合约地址,注意 地址不用双引号
address addVar = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
区块链地址从 右边的 deploy 选项卡中 ACCOUNT 右边的小菜单中复制地址
二、 函数
2.1 函数的声明
语法: function 函数名 (入参) 标识符 view returns (string memory) { 函数体 }
-
函数名:函数的名称,驼峰?
-
入参:函数参数
-
标识符:函数可以被调用的范围,描述当前合约、子合约、外部合约、外部账户四类可以访问的函数和变量,共有4个标识符:
internal
:仅仅可以在合约内部和子合约调用external
:仅可以被外部合约和外部账户调用public
:内部合约、外部合约、子合约、外部账户均可private
:只能在当前合约内部调用
子合约:继承当前合约的合约 child contracts
外部合约和外部账户基本等同,允许外部合约的就允许外部账户,不允许的同理
- view: 表示当前函数仅仅读取状态,不会修改状态,建议只读取的函数加上这个 vivew,编译器会对函数逻辑进行检查;
- returns(string memory) 返回值声明,string 返回值类型,memory 表示的是返回值的存储状态
function sayHello () public view returns(string memory) {
return strVar;
}
2.2 编写合的函数
contract HelloWorld {
string strVar = "hello world";
function sayHello () public view returns(string memory) {
return strVar;
}
}
三、 部署合约
部署这个合约,通过 remix 的左边 Deploy 选项卡完成。当然,部署之前你的合约需要经过编译且编译不能有错误。
3.1 本地部署步骤
- 选择一个 RemixVM shanghai
- 选择一个账户 ACCOUNT,将会从这个账户扣除手续费?
- VALUE 写 0
- CONTRACT 选择你要部署的合约
- 点击橘黄色按钮 Deploy
3.2 区块链控制台中会有状态等信息:
-
status: 状态,mined 挖矿,本地部署不需要挖矿
-
transaction hash: 交易哈希,通过交易 hash 可以通过区块链浏览器在主网上面找到本次交易
-
block hash: block 的 hash,本次交易生成的 block 的hahs
-
block number : 区块的数量,1 是个假的数字,取决于你部署了几次,真实的区块链上的这个数字很大
-
合约中应该有个构造函数,但是不写的话 solidiy 会默认帮大家创建一个,所以本质上 contract 关键字等同于 class 关键字?
3.3 测试你的智能合约函数
在 Deploy 选项卡完成部署之后,在下面的 Deployed Contracts 菜单下将会有的你的合约,展开菜单你会看到如下的图片:
这就会出现一个蓝色的按钮,按钮的文案和你的合约中的方法名字相同,点击它,它下面将会透出你的智能合约方法的返回值。
在图上的 Deploy 按钮上一直在提示你 evm version: shanghai。这表示你的 Deploy 时选择 EVM Version 是 shanghai。
此时如果你的 Compiler 里面的 EVM version 选择的不是 shanghai 是不可否以的。即便能够部署成功,调用方法时也会提示你这两个地方不兼容。
四、编辑合约
我们可以编写一个 setHelloWorld 的方法,修改合约的数据,注意这里是在学习函数的声明。
编写 set 函数,即你想修改合约中的变量,由两点需要注意:
- 修改后的值是外面传入的,因此你需要定义一个形参,形参:
类型+存储方式+变量名
- 这个函数是否需要返回值,不需要就不用声明
returns
contract HelloWorld {
string strVar = "hello world";
function sayHello () public view returns(string memory) {
return strVar
}
function setHelloWorld(string memory newString) public {
strVar = newString;
}
}
五、总结
本章我们学习了 Solidity 的基本数据类型、函数定义、编写合约、部署合约、编辑合约:
- 数据类型;
-
- bool:布尔值,注意,1 和 0 这种值在 Solidity 中不能表示布尔值,不存在自动的类型转换;
-
- uint:无符号整数,由 uint8 和 unit256,不写位数默认 uint 256;
-
- byte:字节,byte8、bype32,最大可以声明 32 位的 byte,一般用来表示字符串;而 bytes 这个表示数组;
-
- string:字符串类型
-
- address:地址类型,注意这个没有引号,不是字符串,是一种特殊的类型1
-
- 函数声明
- 编写合约
- 部署合约
- 编辑合约