摘要:另外只能做狀態變量,不能做本地局部變量。語法聲明映射類型包括類型包括狀態變量報錯。可視度指的是,決定函數或者狀態變量的可以被哪些智能合約可見和調用。狀態變量可見性沒有。在中,通過來抽象出狀態變量自增的代碼,并修飾。
Mapping
映射(Mappings):類似于哈希表。mapping 中任何一個可能的 key 都對應著一個 value,它的默認值是default-value 。底層用的不是使用鏈表 + 數組實現的,不需要擴容。value 引用存儲在 keccak256(key) 表姐地址,在 storage 上存儲,理論無限大。這也導致了,無法原生地遍歷 mapping。另外 mapping 只能做狀態變量,不能做本地局部變量。
語法
// 聲明映射 // key 類型包括: bool, int/uint , address, string... // value 類型包括: any type mapping(address => uint) balances; // 狀態變量 function() { mapping(address => uint) balances; // 報錯。本地局部變量報錯。 } // 成員賦值 balances[0x1] = 1; // 成員取值 balances[0x1] // 1 balances[0x2] // 默認值 0 balances[0x3] // 默認值 0可視度
可視度(Visibility): 可視度不是說別人無法用肉眼無法看到,智能合約部署在區塊鏈上,代碼任何人都可以看見。可視度指的是,決定函數或者狀態變量的可以被哪些智能合約可見和調用。
public: 所有智能合約可見
external: 只能被外部合約或者外部調用者可見
internal: 外部合約不可見,當前合約內部和子類合約可見
private: 只有當前合約可見
可以用一個例子來解釋,什么是外部合約、外部調用者、當前合約內部、子類合約。
有三個合約,Child 、 Parent 和 OutSide。其中 Child 繼承 Parent, OutSide 和另外兩個合約沒有直接關系。
- 外部合約可見: `Child` 的函數可以調用 `OutSide` 的函數。 - 外部調用者可見: 在 remix 的 run 面板中 create `Child` 合約后,可以調用。 - 當前合約內部可見: `Child` 的函數可以調用 `Child` 自身的其他函數。 - 子類合約可見:`Child` 的函數可以調用 `Parent` 的函數。
Child 、 Parent 和 OutSide 都有以下四個函數:
function publicFunc() public {} function externalFunc() external {} function internalFunc() internal {} // 不可調用 function privateFunc() private {} // 不可調用 // `Child` 中的函數名都加了 `self` 前綴,和 Parent 中的函數做區分。
函數可見性:public(default) , external , internal , private。
具體示例代碼如下:
pragma solidity ^0.4.14; import "./parent.sol"; import "./outside.sol"; contract Child is Parent{ // 返回一個值 function testOutside() { Outside o = new Outside(); o.publicFunc(); o.externalFunc(); // o.internalFunc(); // 報錯。Child 不能調用 OutSide 的 internal 函數。 // o.privateFunc(); // 報錯。Child 不能調用 OutSide 的 private 函數。 } function testParent () { publicFunc(); // externalFunc(); // 報錯。Child 不能調用 Parent 的 external 函數。 internalFunc(); // privateFunc(); // 報錯。Child 不能調用 Parent 的 private 函數。 } function selfPublicFunc() public {} function selfExternalFunc() external {} function selfInternalFunc() internal {} // remix 不可見。外部調用者不能調用 internal 函數。 function selfPrivateFunc() private {} // remix 不可見。外部調用者不能調用 private 函數。 }
狀態變量可見性:public , internal(default) , private 沒有 external。
狀態變量可見度和函數可見度非常相似,只有一點需要特殊說明。當在狀態變量上添加可視度時,編譯器會給狀態變量添加個 getter 函數,方便外部直接獲取。
使用 remix 創建以下合約時,會出現一個 data 函數,點擊該函數就可以獲取到 data 的值。
<圖>
繼承(待補充...) 函數修飾器函數修飾器(Function Modifiers): 函數修飾器可以改變函數的行為。可通過 _ 來控制修飾器的執行時機。
在 Example1 中,通過 modifier 來抽象出檢查條件的代碼,并修飾 input2。讓 input2 實現和 inputs2 一樣的行為。其中 _ 可以簡單的理解為,do something 代碼在 modifier 之后執行。
contract Example1 { address owner; function Example() public { owner = msg.sender; } modifier onlyOwner { require(msg.sender == owner); _; } function inputs1() { require(msg.sender == owner); // do something... } function inputs2() onlyOwner {} }
例如:函數修飾器可以在執行自動執行指定語句。inputs1 和 inputs2 在行為上是等價的。
在 Example2 中,通過 modifier 來抽象出狀態變量自增的代碼,并修飾 input2。讓 input2 實現和 inputs2 一樣的行為。其中 _ 可以簡單的理解為,do something(不包括 return) 代碼在其之前執行。
contract Example2 { // 省略 ... uint output; modifier increase return(unit) { _; output++; } function change1() return(unit) { // do something... output++; return output; } function change2() increase { // do something... return output; } }Safe Math 和 Library(待完善...)
因為 Solidity 數字大多數是和錢有關的,所以在加減乘除的四則運算時,發生上溢或下溢是非常危險的。
contract Test { uint8 public a = 0; function set () { a -= 100; } function set2 () { unit8 c = a - 100; assert(c < a); a = c; } } ----- set() // a = 156 整型溢出
import "./SafeMath.sol"; // 引入 unit8 contract Test { uint8 public a = 0; function set () { a = SafeMath.sub(a, 100); } }
import "./SafeMath.sol"; // 引入 unit8 contract Test { using SafeMath for uint8; // 將 SafeMath 庫里的方法,賦予了 uint8 類型。 uint8 public a = 0; function set () { a = a.sub(100); // a = SafeMath.sub(a, 100); } }其他
函數(function)聲明:函數是合約內代碼的可執行單元。
contract SimpleStorage { function simpleFn() { } }
函數返回值
返回一個或多個參數
直接賦值返回的命名參數,并返回
// 返回一個值 function oneParameter() returns(uint){ return 1; } // 返回多個返回值 function twoParameters() returns(uint, uint) { return (1,2); } // 命名參數直接賦值 function namedParameter() returns(uint foo, uint bar) { foo = 1; bar = 2; } // 獲取返回值 function get() { uint one = oneParameter(); var (two1, two2) = twoParameters(); var (named1, named2) = namedParameter(); }
本文由【區塊鏈研習社】優質內容計劃支持,更多關于區塊鏈的深度好文,請點擊【區塊鏈研習社】簡書專欄:區塊鏈研習社簡書專欄
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/23995.html
摘要:和比特幣協議有所不同的是,以太坊的設計十分靈活,極具適應性。超級賬本區塊鏈的商業應用超級賬本超級賬本是基金會下的眾多項目中的一個。證書頒發機構負責簽發撤 showImg(https://segmentfault.com/img/bV2ge9?w=900&h=385); 從比特幣開始 一個故事告訴你比特幣的原理及運作機制 這篇文章的定位會比較科普,盡量用類比的方法將比特幣的基本原理講出來...
摘要:舍去小數位在以太坊中賬戶有兩種類型普通賬戶和智能合約賬戶。報酬是小額的以太幣,想要運行智能合約的人的需要支付報酬來使合約工作。涉及到以太坊智能合約的攻擊的問題。 智能合約可以簡單的理解為一段可執行的程序片段,具體的代碼經過 Solidity 編寫之后,發布到區塊鏈上。而以太坊的智能合約也可以理解為一個特殊的交易(包括可執行代碼的),被發送出去后會被礦工打包記錄在某一個區塊中,當需要調用...
摘要:錯誤檢查拋出異常。用于檢查內部錯誤,比如上溢和下溢。由于語言完善的問題,支持狀態變量之間的轉換,未來可能會取消該限制。注意,只能將變量賦值給狀態變量,而不是本地變量。因為我們只能在狀態變量中分配內存空間。 錯誤檢查 throw: 拋出異常。已被廢棄。 revert(): 拋出異常,并回滾到調用前的狀態。 require(bool): require(false) 拋出異常,并回...
摘要:以太坊協議的目的是普遍化,以使其核心特征能夠以任意方式結合。稱以太坊為一個生態系統再合適不過了核心協議由不同的基礎設施編碼和社群支持,他們共同構成了以太坊項目。 Web 3:去中心化應用平臺很多人相信像以太坊這樣一個公開、無需信任的區塊鏈平臺十分適合作為Web 3.0的共享后端,像Web3.0這樣去中心化、安全的互聯網,它的核心服務,比如DNS和數字身份是去中心化的,個體可以參與到經濟...
閱讀 2071·2021-10-12 10:12
閱讀 791·2021-09-24 09:47
閱讀 1191·2021-08-19 11:12
閱讀 3468·2019-08-29 13:06
閱讀 689·2019-08-26 11:43
閱讀 2571·2019-08-23 17:20
閱讀 1154·2019-08-23 16:52
閱讀 2601·2019-08-23 14:27