《web3 solidity0.8.+版本(持續更新新版本內容) 基礎到實戰NFT開發》會及時更新新版本 solidity 內容,以及完成最終的 NFT 實戰商業項目部分。
注:由于是付費專欄內容,若有錯誤請及時聯系@1_bit,博客鏈接:https://blog.csdn.net/A757291228 ,或在文章下留言,收到后將會對錯誤進行改正,若是版本更新導致的問題也希望大家對錯誤進行提交,盡力去保證付費用戶該得到的權益。
文章目錄可查看:目錄(文章更新中…)
更新內容將會在目錄中更新…
友情提示:本系列文章讀者最好學過一門編程語言,面向對象語言更佳,文章所有代碼將會完整貼出。
一、字符串與 bytes
在 solidity 中 ,string 可以轉化為 bytes,并且在轉換時進行的是傳址操作,例如:
// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
contract StringDemo{function StringChange()public pure returns(string memory){string memory str="Hello";bytes memory byteData;byteData=bytes(str);byteData[1]='H';return str;}
}
在以上合約中創建了一個方法 StringChange,返回 string 類型的數據,在方法中創建了一個 str 的 string 類型數據以及一個 bytes 類型的 byteData 數據,在接下來的代碼中使用 bytes 對字符串進行了強轉賦值給到 byteData,接著修改第 0 位的內容為 H,但是此時 return 的是轉化之前的 str 變量,那么 str 字符串變量是否能夠發生影響呢?
部署合約后我們可以查看結果:
二、循環
在 solidity 中可以使用 for 循環,for 循環的語法跟其他編程語言(例如C 等)語法相似在此不再講解。
以下示例簡單的釋放了一個 for 循環的使用,由于過于簡單不再贅述:
// SPDX-License-Identifier:MIT
pragma solidity ^0.8.0;
contract StringDemo{uint[] arr=[1,2,3,4,5];function ForDemo()public view returns(uint){uint sum=0;for(uint i=0;i<arr.length;i++){sum+=arr[i];}return sum;}
}
以上代碼此需要注意的是,我們在 ForDemo 方法中的修飾是 view,若你寫錯了改成了 pure 之類的,那么將會報錯,因為在你修飾成了 pure 那么就表示你不會讀取狀態變量,那么你即使用了 arr那么也會報錯,例如:
三、傳參怎么傳數組
在一些方法中,可能需要傳入的參數是數組,那么在 remix 中我們測試時該怎么傳入對應的數組參數呢?
以下是一個 solidity 代碼的示例:
// SPDX-License-Identifier:MIT
pragma solidity ^0.8.0;
contract StringDemo{function parameterDemo(uint[5] memory _arr)public pure returns(uint) { return _arr[1];}
}
以上的 parameterDemo 方法接收一個固長數組,在此部署后如何進行傳參呢?
我們只需要傳入一個 []
所包裹的值集合即可,記得一定要是長度為5的數組,例如傳入數據 [1,3,2,5,9]
:
四、方法重載
solidity中支持重載,注意,是重載而不是重寫 override。
在 solidity 中的同名函數,但參數不同的函數為函數的重載,例如以下示例:
// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
contract PayDemo{function OverLoading(address)public pure returns(string memory){return "address";}function OverLoading(uint256)public pure returns(string memory){return "uint256";}function OverLoading(uint256[] memory)public pure returns(string memory){return "int256[]";}
}
以上示例中分別創建了 3 個同名函數,但參數不同,通過不同的參數返回不同的值,部署合約后如下:
你會發現這樣不就是體現了可以重名嘛,和傳不同參數,本質上好像沒啥區別。
這是因為這是重載在外部的可視化體現是這樣的,若我們在合約中使用一個函數進行調用就不一樣了,例如此時再合約中添加一個方法:
uint256[] u256Arr=[1,2,3,4,5,6];
function CallOverLoading(uint256 _c)public view returns(string memory){string memory res;if(_c==1){res = OverLoading(0x7C4e30a43ecC4d3231b5B07ed082329020D141F3);}else if(_c==2){res = OverLoading(125);}else if(_c==3){res = OverLoading(u256Arr);}return res;
}
此時為了等下的傳入數組,在這里參加農歷 uint256 的數組,隨后創建一個 方法 CallOverLoading 接收一個參數 _c,并且在方法中判斷這個 _c 的值,從而給 OverLoading 傳入不同的參數,看看是否會返回不一樣的值,注意,在這里需要把 public 改為 private 會比較舒服一點,當然你不改也可以:
改了之后部署就會顯示一個 方法,這樣看起來比較爽:
接著輸入不同的值:
這樣就舒服多了。
五、constant
constant 在 solidity 中常量的修飾符,通過使用 constant 對變量修飾后,變量轉為常量且不可變,若修改將會報錯:
六、函數修改器 modifier
在 solidity 中有一個函數修改器可作為前置、中置或者后置方法,有點像 ASP.NET 中的母版頁(最起碼差不多十年不碰了,不懂還有沒有這個概念),又有點像 ThinkPHP 中的前置方法,可以在指定某個函數調用前、中執行該函數,下面是一個示例:
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.6;
contract ModifierTest{modifier checkAge(uint val){require(val<10,"Age < 10");_;}modifier checkHeight(uint val){require(val>260,"Height < 260");_;}function osVal(uint age,uint height) external pure checkAge(age) checkHeight(height){age+=1;}
}
以上代碼中使用 modifier 創建了函數修改器,modifier 之后是對應的函數修改器名稱,可以接收參數或者不接收參數,其中的 “_;
” 表示使用這個修改器的函數代碼位置,例如:
modifier checkHeight(uint val){require(val>260,"Height < 260");_;}
在被 osVal 方法調用后,osVal 方法中代碼的位置就等于在“_;”
位置進行填充。在 osVal 中使用這些修改器只需要再其后說明即可,并且可以傳入對應的參數,調用后效果如下:
“三明治”用法:
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.6;
contract ModifierTest{uint public age=0;modifier sandwich(){age+=1;_;age+=1;}function osVal() external sandwich(){age+=1;}
}
三明治用法就是用于中間:
七、合約銷毀
在 solidity 中,selfdestruct 是一個合約銷毀方法,在部署時初始化函數中記錄 msg.sender 后,通過一個方法使用 selfdestruct 傳入 owner 即可對當前合約進行銷毀:
// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
contract selfdestructDemo{address owner;constructor () {owner = msg.sender;}function kill() public {require (msg.sender == owner);selfdestruct(payable(owner));}}
不過在此要注意,selfdestruct 傳入 owner 參數時需要將 owner 通過 payable 類型強轉,否則將會出現如下錯誤:
待完善補充 將 逐步完善(重要的知識點或在后面章節單章更新)
事件 /索引 indexed
自定義錯誤
abi.encode/abi.encodePacked
interface
keccak256