Solidity学习笔记

以太坊

共识协议有

  • pow(工作量证明)
  • pos(权益证明)

结点类型有

  • 普通节点:备份区块链数据
  • 矿工:创建区块链

加密算法使用的是ECC(椭圆曲线加密算法)

通信协议使用的是Whisper

存储平台使用的是Swarm

geth是以太坊,whipster和swarm节点的一个实现

solidity流程

Solidity代码 Solidity编译器 字节码 部署在EVM上执行

文件组成

Solidity文件,扩展名为.sol,由4个结构组成

  • 预编译指令
  • 注释
  • 导入
  • 合约/库/接口

使用下面指令指定编译器版本

go 复制代码
pragma Solidity <version number>

注释形式有

  • 单行注释 :用双斜线表示//
  • 多行注释 :用/*和*/表示
  • 以太坊自然规范:即三个斜杠///表示单行注释,多行注释用/**表示注释开始,*/表示注释结束

导入其它合约使用

go 复制代码
import "otherContract"

合约使用关键字contract,库使用关键字library,接口使用关键字interface

合约

合约结构包含

  • 状态变量
  • 结构定义:使用struct
  • 修改器定义:使用关键字modifier,修改器与函数绑定。修改器中的下划线_表示执行目标函数。payable是由Solidity提供的修改器,当应用于函数时允许函数接受以太币
  • 事件声明:使用关键字event来定义
  • 枚举定义
  • 函数定义:函数支持的限定符有external, payable(k只能接受以太币), view(常量函数别名),pure(既不能读取也不能写入,不能访问状态变量)

状态变量修饰符有

  • internal:在没有显示指定情况下,默认是internal
  • private
  • public
  • constant

数据类型支持的有

  • bool
  • uint/int:从8位到256位,没有指定位数时,表示的是256位
  • bytes
  • address
  • mapping
  • enum
  • struct
  • string

数据类型

值类型有

  • bool
  • uint/int
  • address
  • byte:是bytes1的别名,字节类型还支持1-32,即bytes1-bytes32
  • enum

引用类型有

  • 数组:有固定数组和动态数组,比如固定数组为int[5] age,动态数组int[] age。动态数组可以使用内联初始化或者使用new运算符初始化,内联形式为int[] age = [1, 2,3],new初始化形式为int[] age = new int[](5)。solidity中有特殊数组类型,即字节数组bytes和字符串数组string
  • 结构
  • 字符串
  • 映射

数据存储位置

存储位置支持有

  • 存储
  • 内存
  • 调用数据
  • 堆栈

字面量

字符串字面量用单引号或者双引号

十六进制字面量以前缀hex作为关键字,如hex "1A2B3F"

全局变量和函数

区块

blockhash(uint blockNumber) returns (bytes32):当 blockNumber是 256 个最新区块之一时,给定区块的哈希值;否则返回零
blobhash(uint index) returns (bytes32):与当前事务关联的索引第index个 Blob 的版本化哈希。版本化哈希由代表版本(当前0x01)的单个字节组成,后跟 KZG 承诺 (EIP-4844) 的 SHA256 哈希的最后 31 个字节。如果不存在具有给定索引的 blob,则返回零。
block.basefee (uint):当前区块的基本费用(EIP-3198 和 EIP-1559)
block.blobbasefee (uint):当前区块的 blob 基本费用(EIP-7516 和 EIP-4844)
block.chainid (uint):当前链 ID
block.coinbase (address payable):当前区块矿工地址
block.difficulty (uint):当前区块难度(EVM < Paris)
block.prevrandao (uint):信标链提供的随机数 (EVM >= Paris)
block.gaslimit (uint):当前块 gas限制
block.number (uint):当前区块编号
block.timestamp (uint):当前区块时间戳(自 Unix 纪元以来的秒数)

消息

msg.data (bytes calldata):完整的调用数据,与创建交易相关的函数及其参数信息
msg.sender (address):调用函数的地址
msg.sig (bytes4):函数标识符使用散列函数签名后的前四个字节
msg.value (uint):随消息发送的以太币数量,以wei为单位

交易

tx.gasprice (uint):交易的 gas 价格
tx.origin (address):交易的发送者(全调用链)

加密

keccak256(bytes memory) returns (bytes32):计算输入的 Keccak-256 哈希值,其基于SH3算法
sha256(bytes memory) returns (bytes32):计算输入的 SHA-256哈希值,基基于SH2算法

地址

<address>.balance (uint256):是address类型的内置全局变量,用于查询某个地址的ETH余额,单位为wei

全局函数有

  • <address payable>.transfer(uint256 amount):安全转换函数,向目标地址发送指定数量的ETH,若转帐失败,自动回滚当前交易。要求目标地址是address payable类型
  • <address payable>.send(uint256 amount) returns (bool):低级转账函数,但是转账失败,不会自动 回滚
  • <address>.call(bytes memory) returns (bool, bytes memory):通用低级调用函数,向目标地址发送一个自定义数据的调用请求
  • <address>.delegatecall(bytes memory) returns (bool, bytes memory):委托调用函数,与call类似,但是使用当前合约的上下文
  • <address>.staticcall(bytes memory) returns (bool, bytes memory):只读调用函数,禁止修改任何状态

合约

合约全局变量有

  • this:表示当前合约的类型,可以显示转换成地址address contractAddress = address(this);

合约全局函数有

  • selfdestruct(address payable recipient):销毁当前合约,并且把剩余的以太币余额转移到参数指定地址