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)
總結
- storage可以接受memory的值
- memory的改動不影響storage
- 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)
總結
- storage可以接受memory的值
- memory的改動不影響storage
- 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");
}
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/281696.html
標籤:區塊鏈
下一篇:fsync操作
