1、solodity簡介
Solidity語言是一種以太坊智能合約高級編程語言,運行在以太坊(Ethereum)虛擬機(EVM)之上。
Solidity語言是一種語法類似JavaScript的高級編程語言。Solidity語言被設計成以編譯的方式生成以太坊虛擬機代碼。使用它很容易創建開發用于投票、眾籌、封閉拍賣、多重簽名錢包等以太坊智能合約。
但作為一種真正意義上運行在互聯網上的去中心化智能合約,它又有很多的不同,所以Solidity編程語言也很不同:
以太坊底層是基于帳戶,而非UTXO的,所以Solidity語言提供有一個特殊的Address類型。用于定位用戶賬號,定位智能合約,定位智能合約的代碼(智能合約本身也是一個帳戶)。
由于Solidity語言內嵌框架是支持支付的,并且提供了一些關鍵字,如payable,可以在Solidity語言層面直接支持支付,用起來十分簡單。
數據存儲是使用網絡上的區塊鏈,數據的每一個狀態都可以永久存儲,所以Solidity語言在開發時需要確定變量是使用內存,還是區塊鏈。
Solidity運行環境是在一個去中心化的網絡上,特別強調以太坊智能合約或函數執行的調用方式。因為原來一個簡單的函數調用變為了一個網絡上的節點代碼執行,完全是分布式的編程環境。
Solidity語言的異常機制也很不一樣,一旦出現異常,所有的執行都將會被回撤,這主要是為了保證以太坊智能合約執行的原子性,以避免中間狀態出現的數據不一致。
2、HelloWorld
目前學習Solidity語言編程最好的方式是使用基于瀏覽器的編譯器。
https://remix.ethereum.org/#optimize=false&version=soljson-v0.4.0+commit.acd334c9.js(需要翻墻)
pragma solidity >=0.4.22 <0.6.0;
contract HelloWorld{
string Myame = "kzhang";
function getName() public view returns(string){
return Myame;
}
function changeName(string newName) public{
Myame = newName;
}
3、數據類型
- 真假bool值
初始默認值為false。
pragma solidity >=0.4.22 <0.6.0;
contract BooleanTest{
bool _a ;
int num1 = 100;
int num2 = 200;
function getBool() returns(bool){
return _a; //返回false
}
function getBool2() returns(bool){
return !_a; //返回true
}
}
整形特性與運算
uint
int
注:特別需要注意整數溢出底層位運算
& 與
| 或
~ 取反
^ 異或
<< 左移 >> 右移整形字面量
solidity 中整形計算的時候,是只管計算的結果,只要結果滿足是整形,就不會保存(但可能溢出)。
//比如這種操作
function intergerTest() returns(uint){
uint num = 2/50 * 10000;
return num;
}
function intergerTest2() returns(uint){
uint num1 = 111111111112 - 111111111110;
return num2; //返回值是2
}
由于沒有float型,遇到小數,需要 轉成 整形處理,通過乘以 1000(可以有多個0)
- 固定長度字節數組
bytes1 ,bytes2 ,bytes3 ,bytes32。(以步長1遞增)
(bytes1等價于uint8 ; bytes32 等價于 uint256)
1、bytes1長度是固定的,一旦定義,是不可以再修改的。
pragma solidity >=0.4.22 <0.6.0;
contract ByteArray{
bytes1 public num1 = 0x7a;
bytes2 public num2 = 0x7a7b;
bytes8 public num3 = 0x7a7b7c7d7e7f7c7d;
function getLength() public returns(uint){
return num3.length;//獲取長度
}
}
2、說是字節數組,但是如果想要修改內部的數據,也是不能修改的,只能整體重新賦值
- 動態字節數組bytes
可以修改長度,也可以修改內存
pragma solidity >=0.4.22 <0.6.0;
contract DynamicByte{
bytes public name = new bytes(2);
function InitName(){
name[0] = 0x7a;
name[1] = 0x7b;
}
function getLength() view public returns(uint){
return name.length;
}
//修改內存
function changeName(){
name[0] = 0xaa;
}
//修改長度,是有數據右邊填充0
function changeLength(){
name.length = 5;
}
}
//添加數據到數組尾部,同時修改數組長度
function pushTest(){
name.push(0x99);
}
4、節約gas的利器——pure與view
在Solidity中constant、view、pure三個函數修飾詞的作用是告訴編譯器,函數不改變/不讀取狀態變量,這樣函數執行就可以不消耗gas了,因為不需要礦工來驗證。在Solidity v4.17之前,只有constant,后續版本將constant拆成了view和pure。view的作用和constant一模一樣,可以讀取狀態變量但是不能改;pure則更為嚴格,pure修飾的函數不能改也不能讀狀態變量,智能操作函數內部變量,否則編譯通不過。
pragma solidity >=0.4.22 <0.6.0;
contract HelloWorld{
string Myname = "kzhang";
function getName() public view returns(string){
return Myname;
}
function changeName(string newName) public{
Myname = newName;
}
function pureTest1(string _name) pure public returns(string){
return _name;
}
function pureTest2(string _name) pure public returns(string){
//return Myname;//編譯報錯!pure比constant和view都要嚴格,pure完全禁止讀寫狀態變量
return "123";
}
function viewTest() public view returns(string){
Myname = "123"; //view和constant效果一致,編譯會報warning,但是可以通過
return Myname; // return 123,但是!狀態變量age的值不會改變,仍然為"kzhang"!
}
}