“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情”
solidity
作为一个区块链开发者,solidity是一项必备的技能。那么solidity是什么呢?solidity是一门用于编写智能合约的高级语言在以太坊平台上,solidiy编写的智能合约会运行在以太坊虚拟机EVM之上,变成字节码运行。本文先从基本语法和solidity内置对象来介绍。
基本语法
(一)基本类型
| 类型名 | 解释 | 实例 |
|---|---|---|
| string | 字符串型 | "hello world" |
| bool | 布尔类型 | true,false |
| int | 有符号整数型 | 7,10,99,-100 |
| uint | 无符号整数型,不能为负 | 22,66,89 |
| address | 地址,用于表示账户或者合约 | 0x1234567890123456789012345678901234567890 |
注:uint8,uint16,uint24….uint256,以8位为步长,其中uint相当于uint256,int类似,相当于int256。
(二)引用类型
| 类型名 | 解释 | 备注 |
|---|---|---|
| Type[8] | 定长数组 | 固定长度 |
| Type[] | 动态数组 | Length表示数量,push推入 |
| struct | 结构体 | 结构体中可以包含大量的数据类型 |
| Mapping(type=>type) | 映射表 | Mapping(int=>address) |
| bytes32 | 字节数组 |
(三)存储方式
| 方式名 | 解释 | 备注 |
|---|---|---|
| storage | 成员变量 | 永久保存在状态树中(付费) |
| memory | 局部变量 | 临时存储(值传递) |
| calldata | 函数参数变量 | 临时存储的一个数据位置 |
内置对象
(一)block
- Block 在调用某个方法的时候,solidity会提供一个block的变量,把当前块的信息返回
| 方法名 | 返回类型 | 返回信息 |
|---|---|---|
| blockhash(uint blockNumber) | bytes32 | 指定区块的哈希值 |
| Block.coinbase | address | 当前区块的矿工地址 |
| Block.difficulty | uint | 当前区块难度 |
| Block.limit | uint | 当前区块gas消耗限制 |
| Block.number | uint | 当前区块编号 |
| Block.timestamp | uint | 当前区块时间戳 |
- Now是一个uint类型,指的是当前块的时间戳,与block.timestamp一样
(二)msg
- msg 在调用某个方法的时候,solidity会传递一个msg的属性,用来传递消息
| 方法名 | 返回类型 | 返回信息 |
|---|---|---|
| msg.gas | uint | 剩余的gas |
| msg.sender | uint | 该消息的发送者 |
| msg.sig | uint | 数据的前四个字节 |
| msg.value | uint | 发送的消息的数量 |
(三)内建函数
- Solidity,内置了一些函数用于高效计算solidity中的一些变量的计算 | 函数名 | 返回类型 | 返回信息 | | --- | --- | --- | | addmod(uint x, uint y, uint k) | uint | 计算(x + y)%k | | mulmod(uint x, uint y, uint k) | uint |计算(x * y)%k | | keccak256(bytes memory s) | bytes32 | 计算数据的keccak256 | | sha256(bytes memory s) | bytes32 | 计算数据的sha256| | ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) | addres | 恢复与公钥关联的地址(椭圆曲线算法)|
(四)abi解码工具函数
- 合约应用程序二进制接口(ABI)是在以太坊生态系统中与合约进行交互的标准方法,既可以从区块链外部进行,也可以用于合约间的交互
| 函数名 | 返回类型 | 备注 |
|---|---|---|
| abi.decode(bytes memory encodedData, (...)) | (...) | (uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes)) |
| abi.encode(...) | bytes memory | 对给定的参数进行Abi编码 |
| abi.encodePacked(...) | bytes memory | 对给定的参数进行A压缩编码 |
| abi.encodeWithSelector(bytes4 selector, ...) | bytes memory | 从第二个开始对给定的参数进行ABI编码,并在给定的四字节选择器之前添加 |
| abi.encodeWithSignature(string memory signature, ...) | bytes memory | 等价于abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...) |
注: keccak256(abi.encodePacked(a, b))是一种计算hash值的方式,比如对于一个函数,如果输入输出不同,最终的结果都不一样。
(五)内置调试函数
| 函数名 | 备注 |
|---|---|
| assert(bool condition, string memory reason) | 自信某条件一定成立,用于安全设计使用;如果不成立,扣光所有gas |
| require(bool condition, string memory reason) | 温和认定某条件成立,如果不满足,退回剩余的gas |
| revert(string memory reason) | 终止合约执行,并还原状态变更 |
注:
-
建议多用require,少用assert
-
Assert多用于判断非状态变量
-
Assert可以考虑放在函数结尾部分用于验证之前的操作结果正确
-
revert是主动退回gas,用于if/else判断后使用
(六)随机数
random = uint(keccak256(abi.encodePacked(msg.sender ,block.difficulty, now)));
注:
- 任何随机数生成方法,生成的都是伪随机数。
- Solidity是面向对象的,内部有this。
觉得写的不错的小伙伴点点赞点点关注,solidity系列我会持续更新下去。