目錄
注意事項
編譯器選擇
一些說明
1. 變量
1.1 狀态變量
1.2 局部變量
2. 資料類型
2.1 值類型
2.1.1 布爾類型(Booleans):
2.1.2 整型(Integers):
2.1.3 定長浮點型(Fixed Point Numbers):
2.1.4 定長位元組數組(Fixed-size byte arrays)
2.1.5 有理數和整型常量(Rational and Integer Literals)
2.1.6 枚舉(Enums)
2.1.7 函數類型(Function Types)
修飾符
函數定義
函數傳回值
構造函數
2.1.8 位址類型(Address)
基礎知識
轉賬
2.2 引用類型
2.2.1 字元串
2.2.2 數組
2.2.3 結構體:
2.2.4 mapping:映射,
2.2.5 storage和memory
bytes1、bytes、string互相轉換
最後

Solidity是一種智能合約進階語言,運作在Ethereum虛拟機(EVM)之上。Solidity是以太坊的首選語言,它内置了Serpent的所有特性,它的文法接近于Javascript,是一種面向對象的語言,這降低了學習門檻,易于被掌握和使用,因為JavaScript是Web開發者的常用語言。是以,Solidity充分利用了現有數以百萬程式員已掌握JavaScript這一現狀。
以太坊智能合約程式設計語言,文法簡單,但是有不成熟不完善,有bug,沒有多線程
使用的是Remix IDE編譯器 下載下傳位址 —> Remix IDE下載下傳位址
這個編譯器對中文很不友好!吐槽一下!
一個 contract 裡面就是一個合約,沒有main函數,隻要合約部署就可以運作
一定要有頭部版本号申明:pragma solidity 0.4.24;
每一行結尾得有分号(;)結束
注釋:中文必須在外面寫好然後拷貝,不能直接在裡面寫中文注釋!對中文很不友好!
pragma solidity 0.4.24;
contract HelloWorld{
string public name; // 這個就是狀态變量,使用public修飾
function hello(string memory text) public pure returns(string memory) {
return text;
}
}
在合約之内,在函數之内,局部變量不能使用public
pragma solidity 0.4.24;
contract Hello{
function hello(string memory text) public pure returns(string memory) {
string name = "FanOne"; // 這個就是局部變量
return text;
}
}
狀态變量預設是私有的,可以使用public修飾
true或false,預設是false
!邏輯非
&& 邏輯與
|| 邏輯或
== 等于
!=不等于
pragma solidity 0.4.24;
contract DataType {
// bool public ok = true;
bool public ok; // def is false
function test() returns(string){
if (ok) {
return "this is true";
}else {
return "this is false";
}
}
}
int/uint: 表示有符号和無符号不同位數整數
以8位為區間,有int8,int16,int24,…,int256,int預設是int256,uint同理
int8 num;
int256 total = 120;
舉例:兩個數相加的結果
pragma solidity 0.4.24;
contract Add {
int8 i1 = 10;
int16 i2 = 11;
function add() returns (int8){
return i1 + int8(i2); // 類型強轉
}
fixed/ufixed: 表示有符号和無符号的固定位浮點數
還不完全支援,它可以用來聲明變量,但不可以用來指派
關鍵字有:bytes1, bytes2, bytes3, …, bytes32。
byte 代表 bytes1。bytes1存儲1個位元組,即8位,bytes2存儲2個位元組,步長為1位元組遞增
.length:表示這個位元組數組的長度(隻讀),傳回的是定長位元組數組類型的長度,而不是值的長度
長度不能修改
可以通過下标擷取
元素值不可修改,隻讀
pragma solidity 0.4.24;
contract TestBytes {
bytes1 public b0; // 位元組:0x00
bytes1 public b1 = "f"; // 0x66
bytes2 public b2 = "fa"; // 0x6661
bytes6 public b6 = "fanone";
bytes32 public b32 = "FanOne";
function getLen() returns(int256){
return b32.length;
}
function getByIndex() returns(bytes1){
return b1[0];
}
}
表達式中直接出現的數字常量:
整數,小數,科學計數都支援(9e30:6*200^10)
自定義類型
至少要有一個元素,預設位uint8,不要忘了花括号
enum Gender {
Male,
FeMale
}
// Gender為自定義類型,設定預設值
Gender default = Gender.Male
狀态變量:預設是private
函數:預設是public
public:公有,擁有以太坊的賬戶都可以調用,可以修飾狀态變量
private:私有,隻有合約内部可以調用,可以修飾狀态變量
view / constant:函數會讀取但是不會修改任何合約的狀态變量
pure:函數不适用任何合約的狀态變量
payable:調用函數需要付錢,錢付給了智能合約的賬戶
returns:傳回值函數聲明中使用
external:僅合約外部可以調用,合約内部需要使用this調用
internal:僅合約内部和繼承的合約可以調用
修飾符在returns聲明的前面,可以有多個修飾符
view、constant、pure的差別:都是針對狀态變量的
函數中通路了狀态變量,但是沒有修改,使用view或者constant
如果沒有使用狀态變量,則使用pure修飾
如果即通路了狀态變量,又修改了,則不要修飾即可。
注意坑:constant修飾的函數中,修改了狀态變量,編譯器不會報錯,但是運作是修改不成功的。
payable
想要轉錢,修飾符必須是payable
payable的修飾符,轉的錢到合約中了
function setMoney(string str) public payable returns(string) {
return str;
}
署的時候,交易金額給個值,會發現金額減少了,錢到了合約,注意交易金額的機關,用ether,不然看不到大的變化
擷取合約中的錢
function getMoney() public view returns(uint256){
return this.balance;
}
this代表目前合約本身,balance擷取目前合約的餘額
function 函數名稱(可選參數) 修飾符 傳回值{
函數體
}
例:
function Add(a int8) public view returns(int8){
return a
}
使用returns指定傳回的類型
傳回值聲明一定要放在最後
多個傳回值使用元組:使用括号括起來()
進入合約就執行,一般設定一些初始化後不變的資料
constractor() public {
owner = msg.sender;
}
public:共有,可以修飾函數,可以修飾狀态變量
provate:私有,可以修飾函數,可以修飾狀态變量
view/constant:用了狀态變量,但是沒有修改狀态變量,隻能修飾函數
pure:沒有使用狀态變量,隻能修飾函數
payable:隻能修飾函數,轉賬的話必須使用payable,錢從賬戶過來,錢到合約
returns:在函數最後,傳回值
狀态變量在函數中修改了,就不要使用(view\constant\pure)修飾符
位址是所有合約的基礎,所有合約都繼承位址對象
通過合約的位址串,調用合約内的函數,本質是uint160,可以進行加減,需要強轉
balance:擷取餘額
transfer:轉賬,推薦使用,誰調用就是給誰轉
send:轉賬,不安全,不推薦使用,合約餘額不夠需要自己手動處理,不會報錯
call:合約内部調用合約,調用底層代碼,别用
callcode:調用底層代碼,别用
delegatecall:調用底層代碼,别用
this指合約本身
address(this),直接使用this會有warning
賬戶–>賬戶:不支援
賬戶–合約:paybable
合約–賬戶:transfer,誰調用就是給誰轉
合約–合約 看進階用法
換算:1ether = 10**18wei (10^18),機關預設是wei
pragma solidity 0.4.24;
contract TransferDemo {
uint256 public a;
function constractGetMoney() public payable{
}
function getConstractBalance() public {
a = address(this).balance;
}
address to_addr = 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c;
function trans() public {
to_addr.transfer(5 * 10 ** 18 ); //define is wei
//need to transfer eth
}
}
這裡有很多位址可選擇
錢到哪去:向誰轉錢,就用誰調用transfer
錢從哪來:合約的錢(payable),合約的錢不夠transfer的時候會報錯
不支援索引
不支援length和push方法
可以修改,需要通過bytes轉換
string me = "fanone";
轉bytes,然後就可以使用bytes的特性了
bytes(me).length;
bytes轉string
string(bytes)
不定長位元組數組:bytes:
支援length,push(在最後追加)方法
可以修改
支援索引,如果未配置設定空間(new配置設定空間),使用下标會報角标越界,其他的會自動配置設定空間
以十六進制格式指派
bytes me = "fanone"
name.push("666")
内置數組:string、bytes、bytes1…bytes32
自定義定長數組:長度不可變,支援length,不支援push
uint256[5] public nums = [1,2,3,4,5];
自定義不定長數組:長度可變,内容可修改,支援length,push方法
uint256[] public nums = [1,2,3,4,5];
nums.push(6)
delete nums;
函數中使用new配置設定空間
uint8[] memory aa = new uint8[](10);// 10個長度的空間
函數不支援傳回結構體對象,可以把值放到元組中傳回(按個放到()中,傳回元組)
struct 結構體名稱{
類型 字段名;
}
struct Person {
string name;
uint age;
}
// 指定字段名,必須用()括起來,裡面是花括号
Person public p1 = Person({name:"hallen",age:18});
// 按順序初始化值,注意是括号()不是花括号{}
Person public p2 = Person("hallen",18);
// 結構體不定長數組
Person[] persons;
// 函數中可以往裡面添加值,類型必須是結構體初始化對象
persons.push(p1);
無法判斷是否存在某個key
不支援length
mapping(string=>string) map_data;
// 函數中指派
map_data["name"] = "hallen";
//擷取指定的key的值
string storage aa = map_data["name"];
storage:資料永遠儲存,引用傳遞,隻有引用類型的變量才可以顯示的聲明為storage。
memory:存在記憶體中,會被回收,資料會過期丢失,類似值類型
bytes1轉string要經過中間的bytes
角标用uint256類型,不然會類型不比對
小生凡一,期待你的關注。