日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入理解Solidity 二

發(fā)布時(shí)間:2023/12/13 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解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)用,占用大量的資源
  • 代碼
pragma solidity ^0.4.0; contract C{uint[] public data1;uint[] public data2;function append1() public {append(data1);}function append2() public {append(data2);}function append(uint[] storage d)internal{d.push(23);} }
  • 界面

糾錯(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.

  • 如果修改代碼如下

pragma solidity ^0.4.0; contract C{uint public a=23;uint[] public data;function g(uint input)public{a = input;}function f() public {uint[] storage x;x.push(2);data=x;} }
  • 首先取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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。