(2.3)其他补充—— 二solidity 基础进阶《实战NFT web3 solidity(新版本0.8.+)》

Posted 1_bit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(2.3)其他补充—— 二solidity 基础进阶《实战NFT web3 solidity(新版本0.8.+)》相关的知识,希望对你有一定的参考价值。

《web3 solidity0.8.+版本(持续更新新版本内容) 基础到实战NFT开发》会及时更新新版本 solidity 内容,以及完成最终的 NFT 实战商业项目部分。

注:由于是付费专栏内容,若有错误请及时联系@1_bit,博客链接:https://blog.csdn.net/A757291228 ,或在文章下留言,收到后将会对错误进行改正,若是版本更新导致的问题也希望大家对错误进行提交,尽力去保证付费用户该得到的权益。

文章目录可查看:目录(文章更新中…)
更新内容将会在目录中更新…

友情提示:本系列文章读者最好学过一门编程语言,面向对象语言更佳,文章所有代码将会完整贴出。

一、字符串与 bytes

在 solidity 中 ,string 可以转化为 bytes,并且在转换时进行的是传址操作,例如:

// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
contract StringDemo
    function StringChange()public pure returns(string memory)
        string memory str="Hello";
        bytes memory byteData;

        byteData=bytes(str);
        byteData[1]='H';
        return str;
    

在以上合约中创建了一个方法 StringChange,返回 string 类型的数据,在方法中创建了一个 str 的 string 类型数据以及一个 bytes 类型的 byteData 数据,在接下来的代码中使用 bytes 对字符串进行了强转赋值给到 byteData,接着修改第 0 位的内容为 H,但是此时 return 的是转化之前的 str 变量,那么 str 字符串变量是否能够发生影响呢?

部署合约后我们可以查看结果:

二、循环

在 solidity 中可以使用 for 循环,for 循环的语法跟其他编程语言(例如C 等)语法相似在此不再讲解。

以下示例简单的释放了一个 for 循环的使用,由于过于简单不再赘述:

// SPDX-License-Identifier:MIT
pragma solidity ^0.8.0;
contract StringDemo
    uint[] arr=[1,2,3,4,5];
    function ForDemo()public view returns(uint)
        uint sum=0;
        for(uint i=0;i<arr.length;i++)
            sum+=arr[i];
        
        return sum;
    

以上代码此需要注意的是,我们在 ForDemo 方法中的修饰是 view,若你写错了改成了 pure 之类的,那么将会报错,因为在你修饰成了 pure 那么就表示你不会读取状态变量,那么你即使用了 arr那么也会报错,例如:

三、传参怎么传数组

在一些方法中,可能需要传入的参数是数组,那么在 remix 中我们测试时该怎么传入对应的数组参数呢?

以下是一个 solidity 代码的示例:

// SPDX-License-Identifier:MIT
pragma solidity ^0.8.0;
contract StringDemo
    function parameterDemo(uint[5] memory _arr)public pure returns(uint)     
        return _arr[1];
    

以上的 parameterDemo 方法接收一个固长数组,在此部署后如何进行传参呢?

我们只需要传入一个 [] 所包裹的值集合即可,记得一定要是长度为5的数组,例如传入数据 [1,3,2,5,9]:

四、方法重载

solidity中支持重载,注意,是重载而不是重写 override。

在 solidity 中的同名函数,但参数不同的函数为函数的重载,例如以下示例:

// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
contract  PayDemo
    function OverLoading(address)public pure returns(string memory)
        return "address";
    

    function OverLoading(uint256)public pure returns(string memory)
        return "uint256";
    

    function OverLoading(uint256[] memory)public pure returns(string memory)
        return "int256[]";
    

以上示例中分别创建了 3 个同名函数,但参数不同,通过不同的参数返回不同的值,部署合约后如下:

你会发现这样不就是体现了可以重名嘛,和传不同参数,本质上好像没啥区别。

这是因为这是重载在外部的可视化体现是这样的,若我们在合约中使用一个函数进行调用就不一样了,例如此时再合约中添加一个方法:

uint256[] u256Arr=[1,2,3,4,5,6];
function CallOverLoading(uint256 _c)public view returns(string memory)
    string memory res;
    if(_c==1)
        res = OverLoading(0x7C4e30a43ecC4d3231b5B07ed082329020D141F3);
    else if(_c==2)
        res =  OverLoading(125);
    else if(_c==3)
        res = OverLoading(u256Arr);
    
    return res;
 

此时为了等下的传入数组,在这里参加农历 uint256 的数组,随后创建一个 方法 CallOverLoading 接收一个参数 _c,并且在方法中判断这个 _c 的值,从而给 OverLoading 传入不同的参数,看看是否会返回不一样的值,注意,在这里需要把 public 改为 private 会比较舒服一点,当然你不改也可以:

改了之后部署就会显示一个 方法,这样看起来比较爽:

接着输入不同的值:


这样就舒服多了。

五、constant

constant 在 solidity 中常量的修饰符,通过使用 constant 对变量修饰后,变量转为常量且不可变,若修改将会报错:

六、函数修改器 modifier

在 solidity 中有一个函数修改器可作为前置、中置或者后置方法,有点像 ASP.NET 中的母版页(最起码差不多十年不碰了,不懂还有没有这个概念),又有点像 Thinkphp 中的前置方法,可以在指定某个函数调用前、中执行该函数,下面是一个示例:

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.6;
contract ModifierTest

   modifier checkAge(uint val)
       require(val<10,"Age < 10");
       _;
   
   modifier checkHeight(uint val)
       require(val>260,"Height < 260");
       _;
   

   function osVal(uint age,uint height) external pure checkAge(age) checkHeight(height)
       age+=1;
   

以上代码中使用 modifier 创建了函数修改器,modifier 之后是对应的函数修改器名称,可以接收参数或者不接收参数,其中的 “_;” 表示使用这个修改器的函数代码位置,例如:

modifier checkHeight(uint val)
       require(val>260,"Height < 260");
       _;
   

在被 osVal 方法调用后,osVal 方法中代码的位置就等于在“_;”位置进行填充。在 osVal 中使用这些修改器只需要再其后说明即可,并且可以传入对应的参数,调用后效果如下:

“三明治”用法:

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.6;
contract ModifierTest
    uint public age=0;
    modifier sandwich()
        age+=1;
        _;
        age+=1;
    

    function osVal() external sandwich()
        age+=1;
    

三明治用法就是用于中间:

七、合约销毁

在 solidity 中,selfdestruct 是一个合约销毁方法,在部署时初始化函数中记录 msg.sender 后,通过一个方法使用 selfdestruct 传入 owner 即可对当前合约进行销毁:

// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
contract  selfdestructDemo
    address owner;
    constructor () 
        owner = msg.sender;
    
    function kill() public 
        require (msg.sender == owner);
        selfdestruct(payable(owner));
    


不过在此要注意,selfdestruct 传入 owner 参数时需要将 owner 通过 payable 类型强转,否则将会出现如下错误:

待完善补充 将 逐步完善(重要的知识点或在后面章节单章更新)

事件 /索引 indexed
自定义错误
abi.encode/abi.encodePacked
interface
keccak256

以上是关于(2.3)其他补充—— 二solidity 基础进阶《实战NFT web3 solidity(新版本0.8.+)》的主要内容,如果未能解决你的问题,请参考以下文章

(2.3)其他补充—— 二solidity 基础进阶《实战NFT web3 solidity(新版本0.8.+)》

区块链开发之Solidity编程基础

区块链开发之Solidity编程基础合约语句及函数修饰符

二solidity 基础进阶(2.1)—— library 库合约《实战NFT web3 solidity(新版本0.8.+)》

二solidity 基础进阶(2.1)—— library 库合约《实战NFT web3 solidity(新版本0.8.+)》

二solidity 基础进阶(2.1)—— library 库合约《实战NFT web3 solidity(新版本0.8.+)》