当前位置:   article > 正文

Advanced Solidity初学者教程

Advanced Solidity初学者教程

目录

Advanced Solidity

引言:

1. 数学和算术

2. 时间和时间单位

3. 结构体

4. 修饰器

5. 枚举

6. 继承

7. 抽象合约

8. 接口

9. 库

10. 存储位置


Advanced Solidity

Advanced Solidity(高级Solidity)是一种区块链编程语言Solidity的深入应用,通常用于构建智能合约和去中心化应用(DApps)。它涉及复杂的编程概念和技巧,旨在提高合约的安全性、效率和功能性。Advanced Solidity可以包括诸如优化gas消耗、实现高级的数据结构、使用库和接口、处理支付和资金流、实现权限控制和安全模式等方面的内容。

引言:

hello,欢迎来到我的 Solidity 高级特性系列!Solidity 是一种智能合约编程语言,专门用于在以太坊及其他以太坊虚拟机(EVM)兼容的区块链平台上编写智能合约。虽然初学者可以使用 Solidity 来编写简单的合约,但深入了解其高级特性可以使您的合约更加健壮、灵活且易于维护。在本系列中,我将通过我的学习与你深入探讨 Solidity 的各种高级特性,包括数学和算术、时间和时间单位、结构体、修饰器、枚举、继承、抽象合约、接口、库以及存储位置等。无论你是新手还是有经验的开发者,我相信这些内容都将为你提供一些帮助,帮助您编写更强大、更安全的智能合约。

1. 数学和算术

智能合约中经常涉及数学和算术运算。Solidity 语言提供了基本的算术运算符,如加(+)、减(-)、乘(*)、除(/)和余数(%)。此外,还有一系列的数学函数,如 `addMod` 和 `mulMod`,用于在模运算中进行加法和乘法运算,这在处理加密货币时非常有用。

如果你理解了,那让我们一起来看看下面这个合约吧:下面这个合约提供了四个基本的数学运算函数:加法、减法、乘法和除法。这些函数都是纯函数(`pure`),意味着它们不修改合约的状态,也不触发交易。除法函数中包含了一个`require`语句,用于防止除以零的操作。如果感兴趣不妨试着编译部署一下。

  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.0;
  3. contract MathOperations {
  4.     function add(uint256 a, uint256 b) public pure returns (uint256) {
  5.         return a + b;
  6.     }
  7.     function subtract(uint256 a, uint256 b) public pure returns (uint256) {
  8.         return a - b;
  9.     }
  10.     function multiply(uint256 a, uint256 b) public pure returns (uint256) {
  11.         return a * b;
  12.     }
  13.     function divide(uint256 a, uint256 b) public pure returns (uint256) {
  14.         require(b != 0, "Division by zero");
  15.         return a / b;
  16.     }
  17. }

2. 时间和时间单位

在智能合约中,时间是一个重要的概念。Solidity 提供了多种时间相关的函数,如 `block.timestamp`,它返回当前区块的时间戳。此外,还有 `now` 函数,它返回当前时间(秒数)。

还是老样子,让我们一起试着编译部署这个合约:

`TimeContract`合约使用`block.timestamp`来获取当前区块的时间戳,并设置了一个24小时后的截止时间。`hasTimedOut`函数用于检查当前时间是否已经超过了截止时间。

  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.0;
  3. contract TimeContract {
  4.     uint256 public deadline;
  5.     constructor() {
  6.         deadline = block.timestamp + 24 hours; // 设置一个24小时后的截止时间
  7.     }
  8.     function hasTimedOut() public view returns (bool) {
  9.         return block.timestamp >= deadline;
  10.     }
  11. }

3. 结构体

结构体在 Solidity 中用于定义自定义的数据类型。它们允许你将相关的数据组合在一起,使得合约的代码更加清晰和有组织。

这次我把解释写在下面了,你可以先试着理解一下。

  1. pragma solidity ^0.8.0;
  2. contract UserContract {
  3.     struct UserInfo {
  4.         string name;
  5.         uint256 age;
  6.         address wallet;
  7.     }
  8.     UserInfo public user;
  9.     function setUserInfo(string memory _name, uint256 _age, address _wallet) public {
  10.         user = UserInfo(_name, _age, _wallet);
  11.     }
  12. }

UserContract`合约定义了一个`UserInfo`结构体,用于存储用户的名称、年龄和钱包地址。`setUserInfo`函数允许外部设置这些信息。

4. 修饰器

修饰器是一种特殊的函数,它可以在其他函数之前或之后执行。修饰器可以用于多种目的,如验证函数调用者的身份、记录事件或检查合约的状态。

  1. pragma solidity ^0.8.0;
  2. contract ModifierContract {
  3.     address public owner;
  4.     constructor() {
  5.         owner = msg.sender;
  6.     }
  7.     modifier onlyOwner {
  8.         require(msg.sender == owner, "Only the owner can call this function");
  9.         _;
  10.     }
  11.     function changeOwner(address newOwner) public onlyOwner {
  12.         owner = newOwner;
  13.     }
  14. }

`ModifierContract`合约展示了如何使用修饰器`onlyOwner`来限制只有合约所有者才能调用某些函数。


到这里为止,剩下的合约我不会在进行解释,是的,我要偷懒了,不好意思,如果你问我为什么?

5. 枚举

枚举是一种数据类型,它允许你定义一组命名的整数常量。在智能合约中,枚举通常用于表示状态、选项或类型。

  1. pragma solidity ^0.8.0;
  2. contract StatefulContract {
  3.     enum ContractState { Active, Inactive, Terminated }
  4.     constructor() {
  5.         state = ContractState.Active;
  6.     }
  7.     function setState(ContractState _state) public {
  8.         state = _state;
  9.     }
  10.     ContractState public state;
  11. }

6. 继承

继承是 Solidity 中的一种机制,允许一个合约从另一个合约继承状态变量和函数。这使得代码重用和模块化变得更加容易。

  1. pragma solidity ^0.8.0;
  2. contract BaseContract {
  3.     function baseFunction() public {
  4.         // 基础功能
  5.     }
  6. }
  7. contract DerivedContract is BaseContract {
  8.     function derivedFunction() public {
  9.         // 派生功能
  10.         baseFunction(); // 调用基类函数
  11.     }
  12. }

7. 抽象合约

抽象合约不能被直接实例化,它们通常用于定义接口或规范。抽象合约可以包含纯虚函数(没有实现的函数),这些函数必须在派生合约中实现。

  1. pragma solidity ^0.8.0;
  2. abstract contract AbstractContract {
  3.     function abstractFunction() public virtual;
  4. }
  5. contract ConcreteContract is AbstractContract {
  6.     function abstractFunction() public override {
  7.         // 具体实现
  8.     }
  9. }

8. 接口

接口定义了一组函数,但不包含它们的实现。它们用于指定其他合约应遵循的协议。

  1. pragma solidity ^0.8.0;
  2. interface IERC20 {
  3.     function totalSupply() external view returns (uint256);
  4.     function balanceOf(address account) external view returns (uint256);
  5.     function transfer(address recipient, uint256 amount) external;
  6.     // 其他 ERC20 标准函数
  7. }
  8. contract MyToken is ERC20 {
  9.     // 实现 ERC20 接口的函数
  10. }

9. 库

库是一组可重用的函数,它们可以被其他合约导入和使用。与合约不同,库不能接收交易或拥有状态变量。关键字——library,在solidity中,库也是一种合约,没有存储,不存储以太币没payable,也没有fallbace函数,库可以部署,但不能够直接访问其中的函数

  1. library SafeMath {
  2. function add(uint256 a, uint256 b) internal pure returns (uint256) {
  3. return a + b;
  4. }
  5. function sub(uint256 a, uint256 b) internal pure returns (uint256) {
  6. require(b <= a, "SafeMath: subtraction overflow");
  7. return a - b;
  8. }
  9. }
  10. contract MyContract {
  11. using SafeMath for uint256;
  12. function calculateSomething(uint256 a, uint256 b) public view returns (uint256) {
  13. return a.mul(b).add(1); // 使用 SafeMath 库进行安全的乘法和加法
  14. }
  15. }

10. 存储位置

在 Solidity 中,了解数据的存储位置对于优化智能合约的 gas 成本至关重要。状态变量可以存储在存储(storage)、内存(memory)或调用数据(calldata)中。内存和调用数据是临时的,而存储则与合约的生命周期相同。

  1. pragma solidity ^0.8.0;
  2. contract StorageExample {
  3.     uint256 public storedValue; // 存储在 storage
  4.     constructor(uint256 initialValue) {
  5.         storedValue = initialValue;
  6.     }
  7.     function returnMemoryValue() public pure returns (uint256) {
  8.         return 42; // 返回存储在 memory 中的值
  9.     }
  10.     function returnCalldataValue() public view returns (uint256) {
  11.         uint256 calldataValue = 42; // 存储在 calldata 中
  12.         return calldataValue;
  13.     }
  14. }

是的,又被我水了一个博客!下期再见,byebye。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/478351
推荐阅读
  

闽ICP备14008679号