solidity智能合约开发五:内存、引用、持久化存储

1、内存与区块链——memory与storage区别

  • Storage变量
    • 是指永久存储在区块链中的变量;
    • 在函数之外声明的变量,也称之为状态变量,默认为“storage”形式,并永久写入区块链;
    • 拿到的是引用/句柄/指针;
  • Memory变量
    • 是临时的,当外部函数对某合约调用完成时,内存型变量即被移除;
    • 在函数内部声明的变量默认是“memory”型的,它们函数调用结束后消失;
    • 拿到的是一份拷贝;

2、结构体定义与初始化

pragma solidity >=0.4.22 <0.5.0;


contract structTest{
    //结构体定义
    struct student{
        uint grade;
        string name;
    }
    //结构体初始化
    function init() view public returns(uint,string){
        student memory s = student(88,"kzhang");
        return (s.grade,s.name);
    }
    
    
    //结构体初始化
    function init2() view public returns(uint,string){
        student memory s = student({grade:99,name:"kzhang"});
        return (s.grade,s.name);
    }
    
    //结构体定义
      struct student2{
        uint grade;
        string name;
//结构体内部可以包含动态长度的数组
        student2[] stu;
//也可以包含mapping映射
        mapping(uint=>student2)  map;
    }   
}

3、结构体中的mapping特性

      struct student2{
        uint grade;
        string name;
        mapping(uint=>string)  map;
    }
    //默认为storage类型,只能够用storage类型来操作我们的结构体中的mapping类型
     student2 stu2;

     function init3() view public returns(uint,string,string){
//memory的对象不能够直接的操作struct结构体中的mapping
      // student2 memory s2 = student2(100,"kzhang");
       // s2.map[0] = "helloworld";
        stu2 = student2(100,"kzhang");
        stu2.map[0] = "helloworld";
        return (stu2.grade,stu2.name,stu2.map[0]);
    }

4、结构体作为函数参数

结构体作为函数参数一定要用 internal 修饰

    
student2 stu2;
//结构体storage 作为参数
    function test1(student2 storage s2) internal{
        stu2 = s2;
        s2.name = "kzhang";
    }
//返回 "kzhang"
    function call1()  view returns(string){
        test1(stu2);
        return stu2.name;
    }
    
    /结构体memory作为参数,函数的形参,内存中开辟空间
    //默认情况下,形参都是memory类型,
//  function test2(student2 memory s2)  internal{ 等价
    function test2(student2 memory s2)  internal{
        //把s2的值赋值给了区块链上的stu2
        stu2 = s2;
//修改函数形参的s2,只是修改了其内存中的空间,没有修改掉区块链上的空间
//这是两个完全不同的空间
        s2.name = "kzhang";
    }

   //返回 空
    function call2() view returns(string){
        test2(stu2);
        return stu2.name;
    }
    
 //memory之间的传递,由于solidity的优化,是通过指针来传递的
    function test3(student2 memory s2) internal{
        student2 memory s = s2;
        s.name = "kzhang";
    }
    //返回 "kzhang"
    function call3() view returns(string){
        student2 memory ss = student2(100,"xiaoxiao");
        test3(ss);
        return ss.name;
    }

5、枚举体

1、enum必须要有成员对象
2、不能够有汉字
3、末尾不能有分号

contract enumTest{
    //初始化
    enum girl{a,b,c}
    
//返回值是从0开始递增的uint值
    function getEnum() view returns(girl){
        return dataGirl;
    }
    
    girl dataGirl = girl.a;
    //可以用来标识状态转移
//只有先和a约会了
    function oneNight()   returns(girl){
        require(dataGirl == girl.a);
        dataGirl = girl.b;
        return dataGirl;
    }
    //然后才能和b约会
    function secondNight()  returns(girl){
        require(dataGirl == girl.b);
        dataGirl = girl.c;
        return dataGirl;
    }
    
}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容