Solidity 从入门到实战(六)

Solidity 从入门到实战(六)

注意:本专栏主要来自于https://www.bilibili.com/video/BV1St411a7Pk?p=11&spm_id_from=pageDriver的学习笔记以及https://blog.csdn.net/weixin_45067603/article/details/105751748

memory(内存存储)与storage(区块链存储)

具体的区别可访问:『0007』- Solidity状态变量、局部变量与memory 、storage之间的爱恨情仇

在这里插入图片描述

pragma solidity ^0.4.0;

contract memoryTest{
    uint[] arrx; //这个状态变量存储在区块链的网络之上
    //当我们调用此函数的时候,会创建一个可变数组,会在内存中为它分配空间
    function test(uint[] arry) returns(uint){
        
        arrx =arry;//将内存的arry拷贝给区块链的arrx变量
        
        //当我们在函数内部定义了一个可变长度的数组时,实际上,它默认的类型是storage类型,它指向了区块链的arrx,所以当我修改z的元素的时候,我实际上在操作区块链上的arrx
    
        uint []storage z =arrx;
        //通过指针实际上修改了区块链上arrx的长度,说明z和arrx是一样的,操作z的时候,会改变arrx的值
        z[0] =100;
        
        z.length =100;
    }
    //返回arrx第一个元素
    function test2() returns(uint){
        
        return arrx[0];
    }
    //返回arrx的长度
    function test3() returns(uint){
        
        return arrx.length;
    }
}

在这里插入图片描述

结构体

案例1

简单使用结构体

pragma solidity ^0.4.0;


contract structTest{
   //定义结构体 
    struct student{
        
        uint grade;
        string name;
    }
    
    struct student2{
        
        uint grade;
        string name;
        //student stu; 结构体内部不能包含自己本身,但是可以是动态长度的数组,也可以是映射
        student2[] stu; 
        
        mapping(uint =>student2) test;
    }
    //结构体初始化
    function init()view returns(uint,string){
        student memory s = student(100,"吴彦祖");
        return(s.grade,s.name);
    }
    //结构体初始化第二种方式
     function init2()view returns(uint,string){
        student memory s = student({grade:100,name:"吴彦祖"});
        return(s.grade,s.name);
    }
}

在这里插入图片描述

案例2

结构体中的mapping特性

pragma solidity ^0.4.0;

contract structTest{
    
    struct student{
        
        uint grade;
        string name;
        mapping(uint =>string) map;
    }
    
    student wyz;//默认为storage类型,只能够用storage类型来操作结构体中的mapping类型
    //memory的对象不能够直接操作struct结构体中的mapping
   function init() view returns(uint,string,string){
   //在初始化结构体的时候,忽略掉mapping类型
       student memory s = student(100,"吴彦祖");
       //将内存中的s对象赋值给wyz这样的storage对象
       wyz =s;
       //我们只能通过storage对象来操作mapping属性
       wyz.map[0] ="helloworld";
       
       return(s.grade,s.name,wyz.map[0]);
   }
}

在这里插入图片描述

案例3 (memory转storage)

总结

  1. storage可以接受memory的值
  2. memory的改动不影响storage
  3. storage的改动不影响memory
pragma solidity ^0.4.0;

contract structTest{
    
    struct student{
        
        uint grade;
        string name;
    }
    
    student stu;
    //函数的形参传递了指针引用
    //要是函数以结构体作为参数,那么函数修饰符必须有private/internal
    function test(student memory s)internal{
        //将s的值赋给了区块链上的stu
        stu =s;
        //修改函数形参s,只是修改内存中的空间,没有修改掉区块链上的空间,因为它们两个是完全独立的空间
        s.name="吴彦祖";
    }
    
    function test2(student memory s1)internal{
        stu =s1;
        //修改区块链中的值
        stu.name ="胡歌";
    }
  function call() returns(string){
      //tmp在内存中开辟空间,指向student
      student memory tmp = student(100,"tmp");
      
      test(tmp);
      return stu.name;
  }
  function call2() returns(string){
      
      student memory tmp = student(100,"tmp");
      
      test2(tmp);
      return tmp.name; //但是该值没有发生变化
  }
}

内存地址图

在这里插入图片描述

在这里插入图片描述

案例4(storage转memory)

总结

  1. storage可以接受memory的值
  2. memory的改动不影响storage
  3. storage的改动不影响memory
pragma solidity ^0.4.0;

contract structTest{
    
    struct student{
        uint grade;
        string name;
    }
    //定义结构体,并初始化
    student stu=student(100,"赵丽颖");
    //storage类型作为函数的参数
    function test(student storage s)internal view returns(string){
        
        student memory lina = s;
        
        lina.name="吴彦祖"; //改变内存中姓名,观察区块链中的姓名是否改变
        return s.name;
    }
    
    function test2(student storage s1)internal view returns(string){
        student memory liming  =s1;
        s1.name ="胡歌"; //改变区块链中的姓名,观察内存中的姓名是否改变
        return liming.name;
    }
  function call() view returns(string) {
      return test(stu); //没改变
  }
  function call2() view returns(string){
      
      return test2(stu); //没改变
    
  }
}

在这里插入图片描述

案例5(memory转memory)

pragma solidity ^0.4.0;


contract structTest{
    
    struct student{
        uint grade;
        string name;
    }
    
    student stu=student(100,"赵丽颖");
    //memory类型之间的转换,由于solidity的优化,是通过指针来传递的
    function test(student memory s)internal view returns(string){
        
        student memory lina = s;
        
        lina.name="吴彦祖";//都是在内存中,由于lina指向s,修改lina的name属性,相当于修改s的name属性
        return s.name; 
    }
    
    function test2(student memory s1)internal view returns(string){
        student memory liming  =s1;
        s1.name ="胡歌";//都是在内存中,由于liming指向s1,修改liming的name属性,相当于修改s1的name属性
        return liming.name;
    }
  function call() view returns(string) {
      return test(stu);//吴彦祖
  }
  function call2() view returns(string){
      
      return test2(stu);//胡歌
    
  }
}

在这里插入图片描述

案例6(storage转storage)

pragma solidity ^0.4.0;


contract structTest{
    
    struct student{
        uint grade;
        string name;
    }
    
    student stu=student(100,"赵丽颖");
    
    function test(student storage s)internal view returns(string){
        
        student storage lina = s;
        
        lina.name="吴彦祖";
        return s.name;
    }
    
    function test2(student storage s1)internal view returns(string){
        student storage liming  =s1;
        s1.name ="胡歌";
        return liming.name;
    }
  function call() view returns(string) {
      return test(stu);
  }
  function call2() view returns(string){
      
      return test2(stu);
    
  }
}

在这里插入图片描述

枚举

格式:enum 变量名{x,y,z} 没有分号

pragma solidity ^0.4.0;


contract enumTest{
    
   enum men{xiaoming,xiaowang,xiaozhang}
   
    men  studyMen = men.xiaoming;
   
  function getEnum()public pure returns(men){ 
      
      return men.xiaozhang;
  }
  
  function oneDayStudy()public payable  returns(string){//按照视频中所写的,会出现错误,用此种方式不出错
      
      require(studyMen == men.xiaoming);
      studyMen = men.xiaowang;
      return "oneDayStudy with xiaoming";

  }
  
  function twoDayStudy()public view returns(string){
      
     require(studyMen == men.xiaowang);
     return ("twoDayStudy with xiaowang");
  }
}

在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟逆袭之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值