智能合约 -- solidity

  • 介绍


    image.png

数据类型

值类型

bool: false, true

  • 整型
    int/uint
  • 定长浮点型
    fixed / ufixed
    fixedMxN 中,M 表示该类型占用的位数,N 表示可用的小数位数。 M 必须能整除 8
fixed128x19 a = 1.1;
  • 地址类型
    address: 地址类型存储一个 20 字节的值(以太坊地址的大小)。 地址类型也有成员变量,并作为所有合约的基础
  • 定长字节数组
    bytes1, bytes2, bytes3, ..., bytes32。byte 是 bytes1 的别名
  • 变长字节数组
  • 枚举类型
    没有设置初始值,从0开始
    enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }
  • bytes 字节数组
bytes b = "abc"
b.push("4")
b.length;

string 特殊的字节数组


string str = "abc"
bytes memory b = string(b) // 可以相互转化
string memory str = bytes(b) // bytes 比string 更节省gas 

*. 函数

function (<parameter types>) {internal|external} [pure|constant|view|payable] [returns (<return types>)]

  1. 可见性

internal 表示函数或状态变量只能在当前合约内部访问,以及继承合约内部。
private 表示函数或状态变量只能在当前合约内部访问,不包括继承的合约。
external 表示函数只能被合约外部调用,不能在合约内部直接调用。
public 表示函数或状态变量可以被任何人访问,包括合约内部、继承的合约、其他合约和外部账户。

internal vs private: 主要区别在于 internal 可被继承合约访问,而 private 不可。
external vs public: 主要区别在于 external 只能被外部调用,而 public 可以被任何地方调用。

  1. 关键字

view 和 pure 是两种函数修饰符,用于声明函数的特性和行为。它们的主要区别在于函数对状态的影响以及允许的操作范围

  • view: 声明函数为 view 表明该函数仅从区块链上读取状态而不会修改任何状态
view:
可以读取合约的状态变量。
可以调用其他 view 或 pure 函数。
不能修改状态变量或调用不带 view 的函数。
适合于查询和访问函数,但不修改状态。
pure:
完全不访问合约的状态变量。
不能修改状态也不能读取状态。
只能返回基于输入参数的计算结果。
适合于执行纯粹的计算操作,如数学运算或字符串操作。

view 和 pure 函数通常用于纯粹的状态读取或计算操作,不涉及以太币的收发。
payable 函数用于接收以太币的支付,并可能修改合约状态。
view 和 pure 函数不消耗 gas,而 payable 函数会消耗 gas。
  1. 函数修饰器
  // 修饰器,用于限制只有合约所有者可以调用
    modifier onlyOwner {
        require(msg.sender == owner, "Only the owner can call this function");
        _; // 这里是修饰器逻辑执行完毕后,继续执行函数的地方
    } 
  1. 错误

require: 用于输入验证和前置条件检查,条件不满足时触发异常。
revert: 用于异常情况处理,可以包含自定义错误消息。
assert: 用于内部错误检查和不可能发生的情况,不应该被触发,如果触发则表示合约内部出现了严重错误。


image.png
  1. 事件
    使用事件有助于实现更透明和互操作的智能合约系统,主要有以下几点好处:

通知外部应用程序: 允许前端应用程序或其他合约监听合约内部的关键操作和状态变化。
日志记录: 提供合约操作的可验证记录,便于审计和跟踪。
成本效益: 相对于在区块链上存储大量的状态变化,事件提供了一种更经济和高效的方式来记录和传递信息。


image.png
// 定义事件
event Transfer(address indexed _from, address indexed _to, uint256 _value);

// 触发事件
function transfer(address _to, uint256 _value) public {
    require(_to != address(0), "Invalid address");

    // 执行转账逻辑

    emit Transfer(msg.sender, _to, _value);
}

引用类型
  • 映射
    ``
mapping(_KeyType => _ValueType) :  
mapping(address => uint) public balances;
// delete 删除值
delete balances["0x63c6e9f027947be84d390cfa7b2332d13b529353"]
  • 结构体
struct Funder {
        address addr;
        uint amount;
    }
  • 数组
 uint[] memory a = new uint[](7); // 不定长数组
uint[10] b ; // 定长数组
  • 数据位置

数据是保存在 内存memory 中还是 存储storage 中
函数参数(包括返回的参数)的数据位置默认是 memory, 局部变量的数据位置默认是 storage,状态变量的数据位置强制是 storage (这是显而易见的)

  • storage: 关键字用于声明永久存储在区块链上的数据
  • memory 是临时的数据存储位置,主要用于函数执行期间的临时变量
  • calldata 是用于存储外部调用函数时传入的参数和数据的位置

storage 用于永久存储在区块链上的状态变量,可读可写。
memory 用于临时存储函数内部的变量和参数,函数执行结束后清空。
calldata 用于存储外部调用函数时传入的参数和数据,只能读取不可修改。

变量和常量

  • immutable 可以在构造函数设置一个值,不可变
uint constant  NAME_ = 1; // 常量
uint immutable  amount = 1; // 
bool a = false;

  • 继承
  1. override 重写父合约方法

super. 调用父合约方法

image.png

image.png
  • 抽象


  • 接口


    image.png

image.png

全局变量

image.png

gas

image.png

参考资料

https://solidity-cn.readthedocs.io/zh/develop/types.html
https://www.bilibili.com/video/BV1eM4y1Q76Z/?spm_id_from=333.337.search-card.all.click&vd_source=5f155e9816129fc687a3807f7a9b1701

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容