深入理解Solidity 二
生活随笔
收集整理的這篇文章主要介紹了
深入理解Solidity 二
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Solidity數(shù)據(jù)位置
- 所有復(fù)雜的數(shù)據(jù)類型,即數(shù)組、結(jié)構(gòu)和映射類型,都會(huì)有一個(gè)額外屬性“數(shù)據(jù)位置”,用來指定數(shù)據(jù)的存儲(chǔ)位置,即數(shù)據(jù)是存儲(chǔ)在memory還是存儲(chǔ)在storage里面
- 根據(jù)上下文環(huán)境,IDE會(huì)自動(dòng)指定數(shù)據(jù)的默認(rèn)存儲(chǔ)位置,但是也可以通過在類型名字之后添加關(guān)鍵字stirage或者memory進(jìn)行修改
- 函數(shù)參數(shù)(包括返回的參數(shù))的數(shù)據(jù)位置默認(rèn)是memory,局部變量的數(shù)據(jù)存儲(chǔ)位置默認(rèn)是storage,狀態(tài)變量的數(shù)據(jù)位置強(qiáng)制是storage
- 另外還有第三種數(shù)據(jù)存儲(chǔ)位置,calldata,這個(gè)是一塊只讀的,不會(huì)永久存儲(chǔ)的位置,用來存儲(chǔ)函數(shù)的參數(shù)。外部函數(shù)的參數(shù)(非返回函數(shù))的數(shù)據(jù)位置會(huì)被強(qiáng)制指定為calldata,效果和memory差不多。
數(shù)據(jù)位置總結(jié)
強(qiáng)制
- 外部函數(shù)的參數(shù)(不包括返回的參數(shù)):calldata
- 狀態(tài)變量:storage默認(rèn)存儲(chǔ)位置
可變
- 函數(shù)參數(shù)(包括返回參數(shù)):memory
- 引用類型的局部變量:storage,例,動(dòng)態(tài)數(shù)組使用哈希表,要求很大的存儲(chǔ)空間,遍歷key和value是可能的,防止哈希碰撞。
- 值類型的局部變量:棧(stack)
特別要求
- 公開可見(publicly visible)的函數(shù)參數(shù)一定是memory類型,如果要求是storage類型,則必須是private或者internal函數(shù)。這個(gè)的目的是為了防止公開調(diào)用占用資源。
- memory和storage只要數(shù)據(jù)類型一致,就可以互相傳數(shù)值。如果是memory傳給storage,是對(duì)于數(shù)據(jù)的完整拷貝傳過去,不是簡簡單單的引用。同樣是storage,如果是狀態(tài)變量就會(huì)改寫原先內(nèi)容,相當(dāng)于拷貝,存儲(chǔ)到永久性區(qū)間里面。如果是局部變量,不管對(duì)方是狀態(tài)變量還是局部變量都是引用?
例子
- 講解
- 類型之間都是storage,那么就是引用,如果類型不同,就是復(fù)制然后操作。uint[] storage d是一個(gè)引用,相當(dāng)于C語言中的指針,指向data1和data2
- 函數(shù)參數(shù)默認(rèn)是memory,需要將其改成stroage類型
- 將public改成internal類型,防止公開調(diào)用,占用大量的資源
- 代碼
- 界面
糾錯(cuò)(1)
代碼
pragma solidity ^0.4.0; contract C{uint public a;uint[] public data;function f() public {uint[] storage x;x.push(2);data=x;} }界面
問題
-
a變成了一個(gè)計(jì)數(shù)器,這個(gè)是Solidity的缺陷,原因在于uint[] storage x;它是一個(gè)指針,如果沒有賦值,默認(rèn)指定合約地址的整個(gè)存儲(chǔ)空間的0位置,也就是uint public a 的位置。
-
uint[] storage x,指向變量a。每次調(diào)用f函數(shù),x 的長度就會(huì)增加,并且將存儲(chǔ)的長度存儲(chǔ)在變量a上,因此每次a的數(shù)值每次增加1.
-
如果修改代碼如下
- 首先取a的值,為23,點(diǎn)擊f函數(shù),再點(diǎn)擊a,得到a變成24,24之前的數(shù)據(jù)不可以訪問,但是24是存儲(chǔ)的2,由代碼x.push(2)來完成。g函數(shù)也是一樣的效果。
修正
- 給uint[] storage x;初始化指定默認(rèn)位置,比如改成uint[]?x = data;x.push(2);刪除data = x;這一句
總結(jié)
以上是生活随笔為你收集整理的深入理解Solidity 二的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++学习 高级编程
- 下一篇: 算法章节 递归、排序、⼆分查找