第一集:Solidity語法講解
阿新 • • 發佈:2018-11-10
註釋
1.程式碼註釋
- 單行是//
- 多行是/**/
2.文件註釋
- 三斜槓///
- /** */
值型別和引用型別
1.值傳遞:簡單來說就是拷貝,不會對原資料造成影響
2.引用傳遞:不是拷貝,會對原有的資料產生影響
3.值型別
- 整形
- 布林
- 地址(address)
- 列舉
- 函式
- 定長位元組陣列 類似[32]byte
4.引用型別(在某些情況下,複雜型別佔用的空間比較大,在拷貝的時候也會佔用比較大的空間,所以這種情況可以考慮採用引用傳遞)
- 不定長位元組陣列
- 字串(string)
- 陣列(array)
- 結構體
整型
1.有符號和無無符號
2.步長為8,最大2^256
- 若沒有給定步長,系統預設最大的256
- 在使用整型過程中,如果在已經確定了資料大小的上限情況下,儘量使用與其最靠近的步長。節省公鏈資源
- EG:在add框中輸入 x ,y 點選add,獲得結果
- 和其他語言一樣,也會產生截斷
- Solidity中,轉化的時候不支援8進位制
- 整形的上溢和下溢
- 上溢:如果一個整形變數的值達到其型別的上限,再給他加上一個正數,最終結果會是變數值+正數-型別上限
- 下溢:如果一個整形變數的值達到其型別的下限,再給他減上一個正數,最終結果會是上限值-該正數的值
布林值bool
1.取值:true、false
2.運算子
- 比較
- 邏輯
地址型別(address)
-
代表以太坊地址、大小20個位元組、160位、所有地址都可以用uint160進行編碼
-
支援比較運算,不支援四則運算
-
地址型別擁有自己的成員
內鍵函式
- msg.sender 得到的是地址
- msg.value 得到的是值
屬性,balance:通過該屬性可以獲取指定地址的餘額,通過address(this).balance可以得到當前地址的餘額
方法
- 轉賬send():向某個指定的地址傳送貨幣
在Value處輸入要充值的數量
注意:Gas不夠執行會失敗
定長位元組陣列
- 表現形式:bytes
- 定長位元組陣列從bytes1開始一直到bytes32
- 步長是1
- bytes預設值表示bytes1
- 支援的運算子:位運算、比較運算
- 定長位元組陣列也擁有自己的屬性
- Length:獲取定長位元組陣列的長度
- Length:屬性不可以修改
字串
- 字串字面量不包含結束符
- 對字串的操作
- 通過bytes轉換可以獲取長度
- 通過bytes轉換可以獲取字串中指定的元素值
- 可以通過bytes轉換改變字串中指定下標的元素值
- 字串和位元組數
智慧推斷
- 使用var關鍵字的時候 ,在第一次賦值的時候,編譯器會自動推斷變數的型別,不能在函式引數中使用
- 在第一次變數型別已經確定之後,後面對該變數的賦值必須在這個類型範圍之內。
- Var可以把函式賦值給一個變數
- 注意 有時候var會推斷出一個錯誤的型別
16進位制
- 特點:以關鍵字hex開頭,後面根一些字串 EG: hex “00112233”
- 和字串一樣,16進位制也可以與bytes進行轉換,轉換完成後也能夠通過下標去獲取指定元素的值
常量和變數
-
常量:Solidity中,常量和其它語言沒有太大的區別,需要注意的是,不是所有型別都支援常量,當前只有值型別和string支援,另外,在solidity中,仍然需要在constant關鍵字前面指定一下常量的型別
-
變數-資料位置
①.位置分類,在solidity中,變數的位置分為兩類
- memory:儲存在記憶體中
- storage:storage修飾的資料會永久的儲存在區塊鏈上
- calldata: 不用在程式中去指定,該位置上的資料是隻讀的,不持久化到區塊鏈上,一般在外部函式才會指定
②.儲存位置說明
- 狀態變數預設儲存在storage中
- 函式中的區域性變數預設儲存位置是storage
- 函式引數和返回值預設的儲存位置是memory
③.變數轉換(資料位置)
- memory->memory 引用傳遞,會改變源資料的值
- memory->storage 不會改變源資料
- storage->storage 也會改變源資料
- storage->memory 資料拷貝 , 不會改變源資料的值
列舉
- 特點:使用者的自定義型別,列舉可以顯示的與整形進行轉換,顯式的轉換會在執行時檢測數值範圍,如果範圍不匹配會引發異常。列舉型別至少要有一個成員。
- 預設從0開始
結構體
- 結構體也是solidity中的自定義資料型別,在其中包含基本型別以及複雜
- 初始化方式
- 根據成員名稱進行初始化
- 根據成員順序進行初始化
- 注意:在solidity中不能直接返回結構體,只能返回成員
陣列
- 陣列分為定長和變長
- 注意對於storage陣列來說,元素型別可以是任意
- 對於memeory陣列來說,元素的型別的函式可見性有關,如果函式是外部可見的,函式引數不能是一個對映型別的陣列。
- 宣告方式
-
定長:ARRAY[length]
- 不定長:ARRAY[]
- 如果說狀態變數型別是一個數組,並且加了public標記,solidity會自動建立一個訪問器,可以直接通過下標進行訪問
- 初始化:對於變長陣列來說,可以能過關鍵字new進行初始化 ,通過new建立的memory陣列。不能通過.length長度的修改來修改陣列的大小屬性
- 陣列字面量:是指以表示式的方式隱式宣告一個數組,並作為一個數組變數的使用的方式,通過字面量只能建立memory的定長陣列。元素型別正好是能夠儲存的元素的長度
- 陣列的屬性和方法
陣列擁有.length屬性,表示當前的陣列長度
- 對於定長來說,不可修改
- 對於不定長陣列,length可以修改,如果當前的元素數量小於length,多餘的用0來補,如果改掉之後的length小於當前的元素數量,產生截斷
不定長陣列擁有push方法,通過push方法可以附加新的元素到陣列末尾,返回值是新的長度
-
二維陣列
- 陣列元素仍然是一個數組
- Uint[][5] X:代表X是一個有5行,每一行的列是一個動態陣列。
- Uint[3][5] X :代表X是一個5行3列的陣列
- 注意,在solidity中,二維陣列的行列位置與大多數程式語言(golang..)是相反的。前面是列,後面是行。
a[2][3],就是圖中a的位置,也就是最後一個數據
a[3][2],越界了,如果有4列可以進行修改。
對映
- 字典、鍵值對的對映關係儲存結構。Mapping(_keyType=>_keyValue)。
- 對映本身、動態陣列、合約、列舉、結構體都不能夠作為對映的鍵值,對映的值可以是任意型別。
- 在solidity中對映沒有長度,也沒有鍵集合(列表),值集合(列表)這樣的概念
- Delete對映中的一個key值,實際不是在刪除,而是在重置為初始值
- 在solidity中,map不支援遍歷
查詢中,若對映中沒有要查詢的key值,int型別返回0,其他型別返回代表對應空的值。
型別轉換
- 隱式型別轉換
- 如果運算子支援兩邊不同的型別,編譯器會嘗試進行自動轉換。
- 任何無符號的整數都可以轉換為相同或者更大大小的位元組值。比如任何一個可以轉換為uint160的變數都可以轉換為address型別。如果說uint160的資料沒有達到上限值,高位補0。
- 隱式型別轉換首先要考慮的是在轉換的過程中,防止資料丟失。
- 顯式型別轉換
- 在不允許型別轉換的情況下,確保可以轉換的前提下,進行強制轉換
- 注意,如果說由一個大型別(uint32)轉換為小型別(uint16),高位會被截斷。
控制語句
- Solidity中所支援的控制語句有
- for
- while
- do-while(後測試,會先執行一遍迴圈體中的程式碼)
- if-else
- 三目運算子
mulmod是內建函式,對x,y除以2取餘數。
全域性單位
1.貨幣單位
- Wei 1
- Kwei 1e3
- Mwei 1e6
- Gwei 1e9
- Mircroether 1e12
- Milliether(finney) 1e15
- Ether 1e18
2.時間單位(沒有month)
- 時間分類:Seconds,minutes,hours,days,weeks,years
3.內建的全域性變數
- 在solidity中,內建的全域性變數可以在合約指令碼的任何地方呼叫
- Msg的所有成員
- Sender:傳送者地址
- Value:傳送給合約的以太幣,預設單位是位
- Data:呼叫資料
- Gas:剩餘gas
- This的部分成員:Balance: 餘額
- Tx的部分成員
- Origin:交易傳送者的地址
- Gasprice:gas的價格
- Now :當前時間
- Block成員
- Number:區塊號
- Difficulty:當前區塊難度
- Coinbase:礦工地址
- Timestamp:時間戳
- Gaslimit():當前區塊的gaslimit
- Blockhash(num):給定區塊的雜湊值,只支援最近的256個區塊