以太坊智能合約學習筆記(二)

錯誤檢查

  • throw: 拋出異常。已被廢棄。
  • revert(): 拋出異常,並回滾到調用前的狀態。
  • require(bool): require(false) 拋出異常,並回滾到調用前的狀態,並返回剩餘的 gas。用於檢查有效條件,好比檢查函數輸入和返回、檢查調用者(require(msg.sender == owner))。
  • assert(bool): 。assert(false) 拋出異常,並回滾到調用前的狀態,並消耗掉全部的 gas。用於檢查內部錯誤(internal errors),好比上溢和下溢。能夠利用消耗掉全部的 gas的特性,防止或者懲罰惡意攻擊。
if(true){
    // 拋出異常,不往下走
    throw;
}

if(true){
    // 拋出異常,不往下走
    revert();
}

// 拋出異常,不往下走
require(false);

// 拋出異常,不往下走
assert(false);

數組

數組(Arrays):相同類型的元素的集合所組成的數據結構。html

數組類型:數組

  • 固定長度數組。 uint[5] dynamicArr
  • 動態長度數組。 uint[] fixedArr

成員:數據結構

  • length 。 固定長度數組爲聲明時的長度,動態長度數組爲數組中含有多少元素。
  • push 。往動態長度數組中增長一個元素,固定長度數組沒有該方法。
// 聲明
uint[] dynamicArr;
uint[3] fixedArr;

// 建立數組
uint[] dynamicArr = new uint[](7); // 賦值長度爲 7 的動態長度數組
uint[3] fixedArr = new uint[3](); // 報錯
uint[3] fixedArr = [1, 2, 3]; // 賦值長度爲 3 的固定長度數組


// 成員賦值
dynamicArr[0] = 1; 
fixedArr[0] = 1; 
fixedArr[3] = 1; // 報錯

// push 新元素
dynamicArr.push(1); // 正確
fixedArr.push(1); // 報錯。fixedArr 沒有 push 屬性。

// 訪問元素
dynamicArr[1]; // 0
fixedArr[1]; // 2

// 獲取數組長度
dynamicArr.length; // push 新元素後,長度爲 7+1。
fixedArr.length // 3


// 改變數組長度
dynamicArr.length = dynamicArr.length - 1; // 正確
fixedArr.length = fixedArr.length - 1; // 報錯。不能改變固定長度數組的長度


// 遍歷數組
for(uint i; i < dynamicArr.length; i++){}
for(uint i; i < fixedArr.length; i++){}
// 固定長度數組轉換爲動態長度數組。因爲語言完善的問題,支持狀態變量之間的轉換,將來可能會取消該限制。
uint[] x = [1, 3, 4]; // 正確。
uint[] memory x = [1, 3, 4]; // 報錯。固定長度 memory 的數組,不能轉換爲動態長度 memory 的數組。

結構體

結構體(Structs): 結構體是一些元素的集合。合法元素類型包括:值類型、數組和映射等,包括:結構體。函數

// 聲明
struc Employee{ // 大寫 E
    address id;
    uint salary;
    uint lastPayDay;
}

// 建立結構體
Employee employee = Employee(0x1, 0, 0);


// 訪問成員
employee.id

數據存儲

  • storage 持久性
  • memory 臨時空間
  • calldata 相似 memory,執行完後被抹除

相同存儲空間賦值ui

  • 傳遞引用 reference(EVM 上的內存地址)。 storage = storage

不一樣存儲空間變量賦值spa

  • 拷貝
    memory a = storage ,b 在 memory 內存中從新開闢一個空間給 employee 類型,而且將 employee 這個值拷貝到 memory 內存空間中。將 memory 內存地址賦值給 memory 變量。因此 memory 變量內存地址並非指向 storage 內存地址,而是一個 memory 變量的全新的地址。一樣的將 memory 賦值給 storage 變量,也會進行一個拷貝。注意,只能將 memory 變量賦值給狀態變量,而不是本地 storage 變量。由於咱們只能在狀態變量中分配內存空間。

delete

delete 初始化變量、刪除數組中的內容3d

http://www.tryblockchain.org/...code

@黃敏之-助教; EVM的定義就是0值等同於回收,把一個storage設爲0是消耗負值的gashtm

clipboard.png

實驗結果: remove約等於remove2,同時遠遠小於remove3和4。且執行完remove12後下次remove34的gas消耗大大增長。這個頗有意思。1和2作的都是釋放內存的操做,因此有負gas的福利;釋放內存後若是要再賦值,須要從新申請內存,因此這樣會消耗更多的gas。blog

delete owner 
delete arr 初始化arr length =0
delete arr[i] 初始化 arr 的某個元素,但此時 arr[i]  還佔據空間,length 也沒有變。

// 所以須要如下兩步,真正的刪除元素
arr[i] = arr[arr.length - 1]
arr.lenght -= 1;

未完成,待更新...

相關文章
相關標籤/搜索