1 數據類型
布爾值, 整型
true && false
# 常見uint 代表uint256
int8 & int256
uint8 & uint256
# 類型推斷
var i = 123 #uint
var s = "string" #自動轉string
#類型轉換,大轉小可能截斷
uint32 a = 0x12345678;
uint16 b = uint16(a); // b will be 0x5678 now
枚舉Enum
enum Direction {East, South, West, North}
Direction constant myDirection = Direction.South;
function getDirection()public pure returns (Direction) {
return myDirection;
}
常量constant
1.1 引用類型
字符串string,bytes
string str = "Hello";
bytes32 bts = "World";
function lenght() public view returns(uint){
// length 返回長度
return bts.length;
}
數組array
uint[] public intArray;
function add(uint val) public {
intArray.push(val);
}
function getInt(uint _index) public view returns (uint) {
assert(intArray.length > _index);
return intArray[_index];
}
// 動態數組
function memArr() public view returns (uint) {
uint[] memory a = new uint[](7);
uint[3] memory b = [uint(1), 2, 3];
}
結構struct
struct User {
string name;
uint age;
}
現在,教大家使用remix
首先運行
npm start
在http://localhost:8080打開remix
代碼寫好后,點擊compile,run,每個函數輸入輸出都可以看到
2 地址 address(實體類型*)
屬性:
<address>.balance, 地址的余額(單位為:wei)
<address>.transfer,發送以太幣(單位為:wei)到一個地址,如果失敗會停止并拋出異常。
函數:
send() // 相對于transfer,send的級別較低。如果執行失敗,當前合約不會因為異常而停止,但是send方法會返回false。
注意事項:
調用遞歸深度不能超1024。
如果gas不夠,執行會失敗。
所以使用這個方法要檢查成功與否。或為保險起見,貨幣操作時要使用一些最佳實踐。
如果執行失敗,將會回撤所有交易,所以務必留意返回結果。
call()
delegatecall()
callcode()
// call(),delegatecall(),callcode()都是底層的消息傳遞調用,最好不使用,會破壞安全性。
2.1 mapping映射類型
mapping (bytes32 => uint) balances;
function add(bytes32 key, uint amt) public {
balances[key] += amt;
}
function get(bytes32 key) public returns (uint) {
return balances[key];
}
輸出:
2.3 單位
Ether的單位關鍵字有wei, finney, szabo, ether
1 ether = 1 * 10^18 wei
1 ether = 1 * 10^6 szabo
1 ehter = 1* 10^3 finney
uint public balance;
function oneEther() public{
balance = 1 ether;
}
Time的單位關鍵字有seconds, minutes, hours, days, weeks, years
1 == 1 seconds
1 minutes == 60 seconds
1 hours == 60 minutes
1 days == 24 hours
1 weeks == 7 days
1 years == 365 days
uint time;
function setNow() public returns (uint) {
time = now;
return time + 100 seconds;
}
上面用到了交易屬性now,以下是一些常見的屬性
2.4 交易的屬性:
block.blockhash(uint blockNumber) returns (bytes32),給定區塊號的哈希值,只支持最近256個區塊,且不包含當前區塊。
block.coinbase (address) 當前塊礦工的地址。
block.difficulty (uint)當前塊的難度。
block.gaslimit (uint)當前塊的gaslimit。
block.number (uint)當前區塊的塊號。
block.timestamp (uint)當前塊的時間戳。
now (uint)當前塊的時間戳,等同于block.timestamp
msg.data (bytes)完整的調用數據(calldata)。
msg.gas (uint)當前還剩的gas。
msg.sender (address)當前調用發起人的地址。
msg.sig (bytes4)調用數據的前四個字節(函數標識符)。
msg.value (uint)這個消息所附帶的貨幣量,單位為wei。
tx.gasprice (uint) 交易的gas價格。
tx.origin (address)交易的發送者(完整的調用鏈)
地址常見的屬性:
<address>.balance (uint256):Address的余額,以wei為單位。
<address>.transfer(uint256 amount):發送給定數量的ether,以wei為單位,到某個地址。失敗時拋出異常。
<address>.send(uint256 amount) returns (bool):發送給定數量的ether,以wei為單位,到某個地址。失敗時返回false。
錯誤判斷:
assert(bool condition):如果條件不滿足,則拋出 - 用于內部錯誤。
require(bool condition):如果條件不滿足,則拋出 - 用于輸入或外部組件中的錯誤。
revert():中止執行并恢復狀態更改
selfdestruct(owner)
3 函數function
Enum上面就是函數寫法,四種作用域
public
private
internal
external
3.1 數據位置memory和storage
memory 存在于內存,可回收,calldata類似
storage 永遠存在
同位置的賦值傳引用,不同位置轉換會拷貝
強制的數據位置(Forced data location)
外部函數(External function)的參數(不包括返回參數)強制為:calldata
狀態變量(State variables)強制為: storage
默認數據位置(Default data location)
函數參數(括返回參數:memory
所有其它的局部變量:storage
3.2 函數修改器modifier
用于在函數執行前檢查某種前置條件。
修改器是一種合約屬性,可被繼承,可重寫
contract owned {
function owned() { owner = msg.sender; }
address owner;
modifier onlyOwner {
if (msg.sender != owner)
throw;
_;
}
}
contract mortal is owned {
function close() onlyOwner {
selfdestruct(owner);
}
}
constant 數將承諾自己不修改區塊鏈上任何狀態
3.3 回退函數fallback
每一個合約有且僅有一個沒有名字的函數。這個函數無參數,也無返回值。
1.調用合約時,沒有匹配上任何一個函數(或者沒有傳哪怕一點數據),就會調用默認的回退函數。
2.當合約收到ether時(沒有任何其它數據),也會調用默認的回退函數。
避免用過多gas:
寫入到存儲(storage),創建一個合約,執行一個外部(external)函數調用,發送ether
一個沒有定義一個回退函數的合約。如果接收ether,會觸發異常,并返還ether
4. 事件Event
pragma solidity ^0.4.0;
contract Transfer{
event transfer(address indexed _from, address indexed _to, uint indexed value);
function deposit() payable {
address current = this;
uint value = msg.value;
transfer(msg.sender, current, value);
}
function getBanlance() constant returns(uint) {
return this.balance;
}
/* fallback function */
function(){}
}
web3 提供事件回調
var event = myContract.transfer(function(error, result){
console.log("Event are as following:-------");
for(let key in result){
console.log(key + " : " + result[key]);
}
console.log("Event ending-------");
});
4.1 Indexed屬性
事件參數上增加indexed屬性,最多可以對三個參數增加這樣的屬性
增加了indexed的參數值會存到日志結構的Topic部分,便于快速查找。而未加indexed的參數值會存在data部分,成為原始日志。
4.2 view
函數可以被聲明為view,在這種情況下,它們承諾不修改狀態。
以下語句被認為是修改狀態:
寫入狀態變量。
發射事件。
創建其他合約。
使用selfdestruct。
通過調用發送Ether。
調用其他函數不被標記view或者pure。
使用低等級調用。
使用包含某些操作碼的內聯匯編。
除了上述狀態修改語句的列表外,以下是從狀態讀取的:
從狀態變量讀取。
訪問this.balance或.balance。
訪問block,tx,msg的任何成員(除了msg.sig和msg.data)。
調用任何未標記為pure的功能。
使用包含某些操作碼的內聯匯編。
4.3 pure
函數可以聲明為pure,在這種情況下,它們承諾不會從該狀態中讀取或修改該狀態。
4.4 payable
5 庫library
限制
無狀態變量(state variables)。
不能繼承或被繼承
不能接收ether。
5.1 using for
指令using A for B;用來附著庫里定義的函數(從庫A)到任意類型B。這些函數將會默認接收調用函數對象的實例作為第一個參數。