數(shù)據(jù)類型有Value Types值類型
和Reference Types引用類型
Value Types 值類型
Address 地址
長度:20 byte
注意:非address類型的數(shù)據(jù)也可以強(qiáng)制轉(zhuǎn)換成address
address的成員
balance變量氮块,獲取地址的eth余額(單位是wei)
transfer(uint256 amount)润歉,發(fā)送eth到一個(gè)地址洞慎,如果執(zhí)行失敗拋出異常糟趾,合約將停止執(zhí)行
send(uint256 amount)鸣皂,發(fā)送eth到一個(gè)地址滋早,如果執(zhí)行失敗返回false峡钓,合約繼續(xù)執(zhí)行
call, callcode and delegatecall 看不懂
address x = 0x123;
address myAddress = this;
if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);
Fixed-size byte arrays 固定大小字節(jié)數(shù)組
bytes1, bytes2, bytes3, …, bytes32
Enums 枚舉
Function Types 函數(shù)類型
函數(shù)類型定義如下:
function (<parameter types>) {internal|external} [pure|constant|view|payable] [returns (<return types>)]
函數(shù)類型即是函數(shù)這種特殊的類型巾遭。
- 可以將一個(gè)函數(shù)賦值給一個(gè)變量,一個(gè)函數(shù)類型的變量平道。
- 還可以將一個(gè)函數(shù)作為參數(shù)進(jìn)行傳遞睹欲。
- 也可以在函數(shù)調(diào)用中返回一個(gè)函數(shù)。
函數(shù)類型有兩類;可分為internal
和external
函數(shù)一屋。
若不寫類型窘疮,默認(rèn)的函數(shù)類型是internal
的。
注意:
this.f
訪問外部函數(shù)
f
訪問內(nèi)部函數(shù)
內(nèi)部函數(shù)的調(diào)用:在EVM會(huì)翻譯成簡單的跳轉(zhuǎn)指令冀墨。
外部函數(shù)的調(diào)用:不是EVM的跳轉(zhuǎn)指令闸衫,而是發(fā)起一個(gè)消息調(diào)用
內(nèi)部函數(shù)例子
pragma solidity ^0.4.16;
library ArrayUtils {
// internal functions can be used in internal library functions because
// they will be part of the same code context
function map(uint[] memory self, function (uint) pure returns (uint) f)
internal
pure
returns (uint[] memory r)
{
r = new uint[](self.length);
for (uint i = 0; i < self.length; i++) {
r[i] = f(self[i]);
}
}
function reduce(
uint[] memory self,
function (uint, uint) pure returns (uint) f
)
internal
pure
returns (uint r)
{
r = self[0];
for (uint i = 1; i < self.length; i++) {
r = f(r, self[i]);
}
}
function range(uint length) internal pure returns (uint[] memory r) {
r = new uint[](length);
for (uint i = 0; i < r.length; i++) {
r[i] = i;
}
}
}
contract Pyramid {
using ArrayUtils for *;
function pyramid(uint l) public pure returns (uint) {
return ArrayUtils.range(l).map(square).reduce(sum);
}
function square(uint x) internal pure returns (uint) {
return x * x;
}
function sum(uint x, uint y) internal pure returns (uint) {
return x + y;
}
}
內(nèi)部函數(shù)例子
pragma solidity ^0.4.22;
contract Oracle {
struct Request {
bytes data;
function(bytes memory) external callback;
}
Request[] requests;
event NewRequest(uint);
function query(bytes data, function(bytes memory) external callback) public {
requests.push(Request(data, callback));
emit NewRequest(requests.length - 1);
}
function reply(uint requestID, bytes response) public {
// Here goes the check that the reply comes from a trusted source
requests[requestID].callback(response);
}
}
contract OracleUser {
Oracle constant oracle = Oracle(0x1234567); // known contract
function buySomething() {
oracle.query("USD", this.oracleResponse);
}
function oracleResponse(bytes response) public {
require(
msg.sender == address(oracle),
"Only oracle can call this."
);
// Use the data
}
}
Reference Types 引用類型
引用類型的保存比值類型要昂貴的多。
Data location 數(shù)據(jù)存儲(chǔ)位置
- storage 永久存儲(chǔ)
- memory 內(nèi)存
- calldata 內(nèi)存只讀
強(qiáng)制數(shù)據(jù)存儲(chǔ)位置:
沒有返回參數(shù)的外部函數(shù): calldata
合約的狀態(tài)變量: storage
默認(rèn)數(shù)據(jù)存儲(chǔ)位置:
有返回值的函數(shù): memory
局部變量: storage
arrays 數(shù)組類型
成員
length變量
push方法
-
structs 結(jié)構(gòu)類型
案例如下:
pragma solidity ^0.4.11;
contract CrowdFunding {
// Defines a new type with two fields.
struct Funder {
address addr;
uint amount;
}
struct Campaign {
address beneficiary;
uint fundingGoal;
uint numFunders;
uint amount;
mapping (uint => Funder) funders;
}
uint numCampaigns;
mapping (uint => Campaign) campaigns;
function newCampaign(address beneficiary, uint goal) public returns (uint campaignID) {
campaignID = numCampaigns++; // campaignID is return variable
// Creates new struct and saves in storage. We leave out the mapping type.
campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0);
}
function contribute(uint campaignID) public payable {
Campaign storage c = campaigns[campaignID];
// Creates a new temporary memory struct, initialised with the given values
// and copies it over to storage.
// Note that you can also use Funder(msg.sender, msg.value) to initialise.
c.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value});
c.amount += msg.value;
}
function checkGoalReached(uint campaignID) public returns (bool reached) {
Campaign storage c = campaigns[campaignID];
if (c.amount < c.fundingGoal)
return false;
uint amount = c.amount;
c.amount = 0;
c.beneficiary.transfer(amount);
return true;
}
}
Mappings 映射類型
pragma solidity ^0.4.0;
contract MappingExample {
mapping(address => uint) public balances;
function update(uint newBalance) public {
balances[msg.sender] = newBalance;
}
}
contract MappingUser {
function f() public returns (uint) {
MappingExample m = new MappingExample();
m.update(100);
return m.balances(this);
}
}
Operators Involving LValues 運(yùn)算符
一般運(yùn)算符
a += e
-=, *=, /=, %=, |=, &= and ^=
a++ and a--
delete運(yùn)算符诽嘉,重置值/對(duì)象蔚出。
比如uint a = 10;delete a;
將a重置為0
pragma solidity ^0.4.0;
contract DeleteExample {
uint data;
uint[] dataArray;
function f() public {
uint x = data;
delete x; // sets x to 0, does not affect data
delete data; // sets data to 0, does not affect x which still holds a copy
uint[] storage y = dataArray;
delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also
// y is affected which is an alias to the storage object
// On the other hand: "delete y" is not valid, as assignments to local variables
// referencing storage objects can only be made from existing storage objects.
}
}
Conversions between Elementary Types 數(shù)據(jù)類型轉(zhuǎn)換
Implicit Conversions 隱式轉(zhuǎn)換
address
可以顯示轉(zhuǎn)為合約實(shí)例
,同時(shí)合約實(shí)例
也可以顯示轉(zhuǎn)換為address
MyContract contractInstance = MyContract(address mycontractAddress);
address mycontractAddress = address(contractInstance);
只能轉(zhuǎn)換成比自己位數(shù)大的數(shù)據(jù)類型虫腋,比如:
uint8 轉(zhuǎn) uint16
uint160轉(zhuǎn)address
Explicit Conversions 顯式轉(zhuǎn)換
int8 y = -3;
uint x = uint(y);
Type Deduction 未聲明類型
有些時(shí)候骄酗,定義變量時(shí)沒有聲明數(shù)據(jù)類型,使用默認(rèn)的悦冀。比如:
uint24 x = 0x123;
var y = x;
在這里趋翻,y使用var定義,它的類型將與x一致盒蟆,是uint
timestamp
私有鏈區(qū)塊時(shí)間戳案例:
- blockNumber: 0 timestamp: 0,
- blockNumber: 1 timestamp: 1526613702,
- blockNumber: 4993 timestamp: 1529483513,
- blockNumber: 4994 timestamp: 1529483514,
- blockNumber: 4995 timestamp: 1529544543,
- blockNumber: 4996 timestamp: 1529544712,
- blockNumber: 4997 timestamp: 1529544713,
block.timestamp (uint): 自 unix epoch 起始當(dāng)前區(qū)塊以秒計(jì)的時(shí)間戳
timestamp 以s為單位
- 1天 = 24h = 2460m = 2460*60s = 86400s
- 1小時(shí) = 3600s
- 1分鐘 = 60s