以太坊Solidity型別介紹+實戰
Solidity 語法的介紹會是一系列文章,本文是第一篇:介紹 Solidity 的變數型別。
本文前半部分是參考 Solidity0.4.20 版本官方文件(當前最新版本)進行翻譯,然後是實際合約程式碼例項說明型別的使用。
型別
Solidity 是一種靜態型別語言,意味著每個變數(本地或狀態變數)需要在編譯時指定變數的型別(或至少可以推倒出型別)。Solidity提供了一些基本型別可以用來組合成複雜型別。
Solidity 型別分為兩類
§ 值型別(Value Type) - 變數在賦值或傳參是,總是進行值拷貝。
§ 引用型別(Reference Types)
值型別(Value Type)
值型別包含:
§ 布林型別(Booleans)
§ 整型(Integers)
§ 定長浮點型(Fixed Point Numbers)
§ 定長位元組陣列(Fixed-size byte arrays)
§ 有理數和整型常量(Rational and IntegerLiterals)
§ 字串常量(String literals)
§ 十六進位制常量(Hexadecimal literals)
§ 列舉(Enums)
§ 函式(Function Types)
§ 地址(Address)
§ 地址常量(Address Literals)
布林型別(Booleans)
布林(bool):可能的取值為常量值true和false。
布林型別支援的運算子有:
§ !邏輯非
§ && 邏輯與
§ || 邏輯或
§ == 等於
§ != 不等於
注意:運算子&&和||是短路運算子,如f(x)||g(y),當f(x)為真時,則不會繼續執行g(y)。
整型(Integers)
int/uint: 表示有符號和無符號不同位數整數。支援關鍵字uint8 到 uint256 (以8步進),
uint 和 int 預設對應的是 uint256 和 int256。
支援的運算子:
§ 比較運算子: <=, < , ==, !=, >=,> (返回布林值:true 或 false)
§ 位操作符: &,|,^(異或),~(位取反)
§ 算術操作符:+,-,一元運算-,一元運算+,,/, %(取餘數), \**(冪), << (左移位), >>(右移位)
說明:
1. 整數除法總是截斷的,但如果運算子是字面量(字面量稍後講),則不會截斷。
2. 整數除0會拋異常。
3. 移位運算的結果的正負取決於操作符左邊的數。x << y 和 x * 2\*y 是相等, x >> y 和 x / 2\y 是相等的。
4. 不能進行負移位,即操作符右邊的數不可以為負數,否則會丟擲執行時異常。
注意:Solidity中,右移位是和除等價的,因此右移位一個負數,向下取整時會為0,而不像其他語言裡為無限負小數。
定長浮點型(Fixed Point Numbers)
注意:定長浮點型 Solidity(發文時)還不完全支援,它可以用來宣告變數,但不可以用來賦值。
fixed/ufixed: 表示有符號和無符號的固定位浮點數。關鍵字為ufixedMxN 和 ufixedMxN。
M表示這個型別要佔用的位數,以8步進,可為8到256位。
N表示小數點的個數,可為0到80之前
支援的運算子:
§ 比較運算子: <=, < , ==, !=, >=,> (返回布林值:true 或 false)
§ 算術操作符:+,-,一元運算-,一元運算+,*,/, %(取餘數)
注意:它和大多數語言的float和double不一樣,M是表示整個數佔用的固定位數,包含整數部分和小數部分。因此用一個小位數(M較小)來表示一個浮點數時,小數部分會幾乎佔用整個空間。
定長位元組陣列(Fixed-size byte arrays)
關鍵字有:bytes1, bytes2,bytes3, ..., bytes32。(以步長1遞增)
byte代表bytes1。
支援的運算子:
§ 比較符: <=, <, ==, !=, >=,> (返回bool)
§ 位操作符: &, |, ^ (按位異或),~(按位取反), << (左移位), >> (右移位)
§ 索引(下標)訪問: 如果x是bytesI,當0 <= k < I ,則x[k]返回第k個位元組(只讀)。
移位運算和整數類似,移位運算的結果的正負取決於操作符左邊的數,且不能進行負移位。
成員變數:
.length:表示這個位元組陣列的長度(只讀)。
變長(動態分配大小)位元組陣列(Dynamically-sized byte array)
§ bytes:動態分配大小位元組陣列, 參見Arrays,不是值型別!
§ string:動態分配大小UTF8編碼的字元型別,參看Arrays。不是值型別!
根據經驗:
bytes用來儲存任意長度的位元組資料,string用來儲存任意長度的(UTF-8編碼)的字串資料。
如果長度可以確定,儘量使用定長的如byte1到byte32中的一個,因為這樣更省空間。
有理數和整型常量(Rational and Integer Literals)
也有人把Literals翻譯為字面量
整型常量是有一系列0-9的數字組成,10進製表示,比如:8進位制是不存在的,前置0在Solidity中是無效的。
10進位制小數常量(Decimal fraction literals)帶了一個.,在.的兩邊至少有一個數字,有效的表示如:1., .1 和 1.3.
科學符號也支援,基數可以是小數,指數必須是整數,有效的表示如: 2e10, -2e10, 2e-10, 2.5e1。
數字常量表示式本身支援任意精度,也就是可以不會運算溢位,或除法截斷。但當它被轉換成對應的非常量型別,或者將他們與非常量進行運算,則不能保證精度了。
如:(2\800 + 1) - 2\800的結果為1(uint8整類) ,儘管中間結果已經超過計算機字長。另外:.5 * 8的結果是4,儘管有非整形參與了運算。
只要運算元是整形,整型支援的運算子都適用於整型常量表示式。
如果兩個運算元是小數,則不允許進行位運算,指數也不能是小數。
注意:
Solidity對每一個有理數都有一個數值常量型別。整數常量和有理數常量從屬於數字常量。所有的數字常表示式的結果都屬於數字常量。所以1 + 2和2 + 1都屬於同樣的有理數的數字常量3
警告:
整數常量除法,在早期的版本中是被截斷的,但現在可以被轉為有理數了,如5/2的值為 2.5
注意:
數字常量表示式,一旦其中含有常量表示式,它就會被轉為一個非常量型別。下面程式碼中表示式的結果將會被認為是一個有理數:
1. uint128 a = 1;
2. uint128 b = 2.5 + a + 0.5;
上述程式碼編譯不能通過,因為b會被編譯器認為是小數型。
字串常量是指由單引號,或雙引號引起來的字串("foo" or 'bar')。字串並不像C語言,包含結束符,"foo"這個字串大小僅為三個位元組。和整數常量一樣,字串的長度型別可以是變長的。字串可以隱式的轉換為byte1,...byte32 如果適合,也會轉為bytes或string。
字串常量支援轉義字元,比如\n,\xNN,\uNNNN。其中\xNN表示16進位制值,最終轉換合適的位元組。而\uNNNN表示Unicode編碼值,最終會轉換為UTF8的序列。
十六進位制常量(Hexadecimal literals)
十六進位制常量,以關鍵字hex打頭,後面緊跟用單或雙引號包裹的字串,內容是十六進位制字串,如hex"001122ff"。
它的值會用二進位制來表示。
十六進位制常量和字串常量類似,也可以轉換為位元組陣列。
列舉(Enums)
在Solidity中,列舉可以用來自定義型別。它可以顯示的轉換與整數進行轉換,但不能進行隱式轉換。顯示的轉換會在執行時檢查數值範圍,如果不匹配,將會引起異常。列舉型別應至少有一名成員。下面是一個列舉的例子:
pragma solidity ^0.4.0;
contract test {
enum ActionChoices { GoLeft, GoRight,GoStraight, SitStill }
ActionChoices choice;
ActionChoices constant defaultChoice =ActionChoices.GoStraight;
functionsetGoStraight(){
choice = ActionChoices.GoStraight;
}
// Sinceenum types are not part of the ABI, the signature of "getChoice"
// willautomatically be changed to "getChoice() returns (uint8)"
// for allmatters external to Solidity. The integer type used is just
// largeenough to hold all enum values, i.e. if you have more values,
// `uint16`will be used and so on.
functiongetChoice()returns (ActionChoices){
returnchoice;
}
functiongetDefaultChoice() returns(uint) {
returnuint(defaultChoice);
}
}
程式碼例項
下面我們用一個真實的合約程式碼來理解下各個型別及操作符。
pragma solidity ^0.4.18;
contract testType{
functionadd(uintx, uint y) public returns (uint z){
z = x + y;
}
functiondivide(uintx, uint y ) public returns (uint z){
z = x / y;
}
functionleftshift(intx, uint y) public returns (uint z){
z = x << y;
}
functionrightshift(intx, uint y) public returns (uint z){
z = x >> y;
}
functioninterLiteral() public returns(uint, uint) {
return((2**800+ 1) - 2**800, 0.5*8);
}
functionhexLiteralBytes() public returns(bytes2, bytes1, bytes1) {
bytes2 a = hex"aabb";
return(a, a[0], a[1]);
}
}
執行
1. 開啟browser-solidity,把程式碼拷貝到編輯器。
2. 選擇環境建立合約
3. 傳引數呼叫
4. 點Details 檢視結果
上一張截圖大家就明白了。
建議根據自己對型別的理解,修改程式碼,使用不同的引數進行呼叫以增強對型別的理解。
如:執行hexLiteralBytes()檢視輸出結果,十六進位制常量可轉化為位元組陣列。
參考文件
相關文章
- Solidity 教程系列2 - 地址型別介紹Solid型別
- 以太坊開發實戰學習-高階Solidity理論 (五)Solid
- 以太坊虛擬機器介紹虛擬機
- 以太坊的擴容方案介紹
- 以太坊Solidity程式語言開發框架————1、Truffle簡介Solid框架
- 以太坊原始碼分析(53)以太坊測試網路Clique_PoA介紹原始碼
- 以太坊學習筆記————6、以太坊客戶端選擇與介紹筆記客戶端
- 以太坊簡介
- 智慧合約語言 Solidity 教程系列1 – 型別介紹Solid型別
- 以太坊學習筆記————10、錢包、以太幣、Gas介紹筆記
- Solidity陷阱:以太坊的隨機數生成Solid隨機
- 以太坊:Dapp及相關開發工具介紹APP
- 以太坊開發框架Truffle基礎使用介紹框架
- 以太坊常見合約型別及其用途型別
- 以太坊Solidity程式語言開發框架————5、移植Solid框架
- 以太坊原始碼分析(2)go ethereum 目錄大概介紹原始碼Go
- string型別介紹型別
- 以太坊Solidity程式語言開發框架————9、控制檯Solid框架
- 區塊鏈2.0以太坊智慧合約solidity之helloworld區塊鏈Solid
- 區塊鏈2.0架構:以太坊區塊鏈的介紹區塊鏈架構
- 介紹一個 GitHub 上的 Laravel 以太坊包 Laravel-ethereumGithubLaravel
- 以太坊Solidity程式語言開發框架————10、外部指令碼Solid框架指令碼
- 以太坊Solidity程式語言開發框架————11、工作流Solid框架
- 以太坊Solidity程式語言開發框架————13、配置檔案Solid框架
- 以太坊Solidity程式語言開發框架————15、構建流程Solid框架
- 以太坊Solidity程式語言開發框架————16、Truffle命令指南Solid框架
- 以太坊開發實戰學習-合約安全(八)
- 以太坊Solidity程式語言開發框架————3、建立一個工程Solid框架
- 以太坊Solidity程式語言開發框架————4、編譯合約Solid框架編譯
- 以太坊Solidity程式語言開發框架————6、構建應用Solid框架
- 以太坊Solidity程式語言開發框架————7、合約互動Solid框架
- 以太坊Solidity程式語言開發框架————8、測試合約Solid框架
- 區塊鏈2.0以太坊配置solidity編譯器sublime詳解區塊鏈Solid編譯
- 以太坊智慧合約開發第五篇:字串拼接—Solidity字串Solid
- postgreSQL 索引(二)型別介紹SQL索引型別
- 【Redis】資料型別介紹Redis資料型別
- SQL | JOIN 型別使用介紹SQL型別
- http代理型別格式介紹HTTP型別