区块链-智能合约工程师第三篇:Solidity进阶

Posted 区块链市场观察家

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区块链-智能合约工程师第三篇:Solidity进阶相关的知识,希望对你有一定的参考价值。

文章目录

学习资料地址:WTF学院

合约库

库合约一般都是一些好用的函数合集(库函数),为了提升solidity代码的复用性和减少gas而存在。他和普通合约主要有以下几点不同:

  • 不能存在状态变量
  • 不能够继承或被继承
  • 不能接收以太币
  • 不可以被销毁

String库

String库合约是将uint256(大正整数)类型转换为相应的string类型的代码库,主要包含两个函数,toString()将uint256转为string,toHexString()将uint256转换为16进制,再转换为string。

library Strings 
	function toString(uint256 value) public pure returns (string memory) 
	
	function toHexString(uint256 value) public pure returns (string memory) 
	
	function toHexString(uint256 value, uint256 length) public pure returns (string memory) 

调用库函数

使用 using A for B; 语句:添加完指令后,A 库的函数会自动添加为 B 类型变量的函数成员,可以直接调用。(在调用时,B变量会被当作第一个参数传递给函数)

    // 利用using for指令
    using Strings for uint256;
    function getString1(uint256 myNumber) public pure returns(string memory)
        // 库函数会自动添加为uint256型变量的成员
        return myNumber.toHexString();
    

通过库合约名称调用库函数:

    // 直接通过库合约名调用
    function getString2(uint256 myNumber) public pure returns(string memory)
        return Strings.toHexString(myNumber);
    

常用的合约库

合约库说明
String将uint256转换为String
Address判断某个地址是否为合约地址
Create2更安全的使用Create2 EVM opcode
Arrays跟数组相关的库函数

import

solidity支持利用import关键字导入其他源代码中的合约,让开发更加模块化。

  1. 通过相对路径/绝对路径:import ‘./Yeye.sol’;
  2. 通过源文件网址导入网上的合约:import ‘https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol’;
  3. 通过npm的目录导入:import ‘@openzeppelin/contracts/access/Ownable.sol’;
  4. 通过全局符号导入特定的合约:import Yeye from ‘./Yeye.sol’;

引用(import)在代码中的位置为:在声明版本号之后,在其余代码之前。

问题:与声明版本号并列,还是在合约里导入?
回答:与声明版本号并列。

接收ETH

Solidity支持两种特殊的回调函数,receive()和fallback(),他们主要在两种情况下被使用:

  • 接收ETH
  • 处理合约中不存在的函数调用(代理合约proxy contract)

接收函数 receive()

receive() 函数只用于处理接收ETH,一个合约最多有一个receive()函数,声明方式与一般函数不一样,不需要function关键字。

声明规则:receive()函数不能有任何的参数,不能返回任何值,必须包含external和payable。

receive() external payable  ... 

我们可以在receive()里发送一个event:

    // 定义事件
    event Received(address Sender, uint Value);
    // 接收ETH时释放Received事件
    receive() external payable 
        emit Received(msg.sender, msg.value);
    

回退函数 fallback()

fallback()声明时不需要function关键字,必须由external修饰,一般也会用payable修饰,用于接收ETH:

fallback() external payable  ... 

定义一个fallback()函数,被触发时候会释放fallbackCalled事件,并输出msg.sender,msg.value和msg.data:

    // fallback
    fallback() external payable
        emit fallbackCalled(msg.sender, msg.value, msg.data);
    

二者的区别

receive和fallback都能够用于接收ETH,他们触发的规则如下,简单说就是:只有msg.data为空且存在receive()时,才会触发receive()

触发fallback() 还是 receive()?
           接收ETH
              |
         msg.data是空?
            /  \\
          是    否
          /      \\
receive()存在?   fallback()
        / \\
       是  否
      /     \\
receive()   fallback()

以上是关于区块链-智能合约工程师第三篇:Solidity进阶的主要内容,如果未能解决你的问题,请参考以下文章

区块链-智能合约工程师第二篇:Solidity入门

区块链-智能合约工程师第二篇:Solidity入门

区块链Solidity智能合约与Solidity介绍

区块链之智能合约 solidity踩坑 --上篇

区块链-智能合约工程师第一篇:某科技jd解读

区块链-智能合约工程师第一篇:某科技jd解读