1. 程式人生 > >solidity學習筆記(1)——智慧合約的執行與程式碼結構概述

solidity學習筆記(1)——智慧合約的執行與程式碼結構概述

智慧合約的程式碼結構

廢話不多說,先來一個智慧合約的例子:

pragma solidity ^0.4.4;
/*
pragma:版本宣告
Solidity:開發語言
0.4.4:當前合約的版本,0.4代表主版本,4代表修復bug的升級版本
^:代表向上相容,0.4.4 ~ 0.4.9可以對我們當前的程式碼進行編譯
*/

contract Person {
  uint _age;
  uint _height;
  address _owner; // 合約的擁有者

  constructor () public{
    _age = 29;
    _height = 180;
    _owner = msg.sender;
  }

  function owner() public constant returns (address){
    return _owner;
  }

  function getAge() public constant returns(uint) {
    return _age;
  }

  function getHeight() public constant returns(uint) {
    return _height;
  }

  function setAge(uint age) public {
    _age = age;
  }

  function setHeight(uint height) public {
    _height = height;
  }

  function kill() public {
    if(_owner == msg.sender){
      selfdestruct(_owner); // 摧毀擁有者的合約
    }
  }
}

註釋1:Contract

  • Contract是一個內建的物件,上面的語法就類似於class Person(子類) extends Contract(父類),意味著Person繼承於Contract。
  • 物件內有其建構函式constructor,用以對例項進行初始化。
  • 當合約部署的時候,就是產生一個合約的例項,來自同一個地址的相同合約只能部署一次,只有一個專有的合約地址。

註釋2:狀態變數

  • _age , _height都是狀態變數,在Contract中就相當於其屬性變數;
  • 在 Solidity 中,有兩個地方可以儲存變數 —— storage以及memory
  • Storage 變數是指永久儲存在區塊鏈中的變數。
     Memory 變數則是臨時的,當外部函式對某合約呼叫完成時,記憶體型變數即被移除。
  • 狀態變數(在函式之外宣告的變數)預設為“storage”形式,並永久寫入區塊鏈;而在函式內部宣告的變數預設是“memory”型的,它們函式呼叫結束後消失。
  • Storage 拿到的是引用/控制代碼/指標, memory 拿到的是一份拷貝。

註釋3:函式和狀態變數的可見性

因為Solidity有兩種函式呼叫:

  • 內部呼叫:不建立一個真實的EVM呼叫(也稱為“訊息呼叫”);
  • 外部的呼叫:要建立一個真實的EMV呼叫,

在智慧合約中,函式和狀態變數的可見性可以分為四種, public private internal

external ,函式預設可見性是 public ,狀態變數的預設可見性是 internal

  • public - (任意訪問,作為合約介面)可以通過內部呼叫或通過訊息呼叫。對公共狀態變數而言,會有的自動訪問限制符的函式生成。

  • private - (僅當前合約內)私有函式和狀態變數僅僅在定義該合約中可見, 在派生的合約中不可見。

  • internal - (僅當前合約及所繼承的合約)

    這些函式和狀態變數只能內部訪問(即在當前合約或由它派生的合約),而不使用(關鍵字)this 。
  • external - (僅外部訪問,也是合約介面)它們可以從其他合約呼叫, 也可以通過事務呼叫。外部函式f不能被內部呼叫(在內部也只能用外部訪問方式訪問,即 f()不執行,但this.f()執行)。

註釋4:函式的限制訪問

  • 在Solidity中  constant  view  pure 三個函式修飾詞的作用是告訴編譯器,函式不改變/不讀取狀態變數,這樣函式執行就可以不消耗gas了,因為不需要礦工來驗證。

  • 在Solidity v4.17之前,只有constant,後續版本將constant拆成了view和pure。view的作用和constant一模一樣,可以讀取狀態變數但是不能改;pure則更為嚴格,pure修飾的函式不能改也不能讀狀態變數,只能操作函式內部變數,否則編譯通不過。

註釋5:msg.sender 和 selfdestruct()

    在Contract中有一些全域性變數和函式,在我們編寫智慧合約的過程中可以直接呼叫,比如上面的 msg.sender selfdestruct() 

    msg的所有成員包括:

  1. msg.sender  :儲存訊息的傳送者,即部署智慧合約的賬戶地址
  2. msg.value :傳送的訊息的數量
  3. msg.gas :剩餘的gas
  4. msg.data:完整的calldata
  5. msg.sig :呼叫資料的前4個位元組 

    合約相關的方法:

  1. selfdestruct ( address recipient ) :摧毀目前的合同,將資金送到給定的地址
  2. suicide ( address recipient ):同上,是別名
  3. this:指當前合約,明確轉換為地址

全部的全域性變數和函式有很多,包括:

  1. Ether單元
  2. 時間單位
  3. 塊相關
  4. msg相關
  5. tx相關
  6. 當前時間戳
  7. 錯誤處理
  8. 數學和加密功能
  9. 地址相關
  10. 合約相關

具體有哪些全域性變數可見第二節。