Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

14.9. 面向對象編程

14.9.1. 可見性修飾符

Solidity對函數和狀態變數提供了四種可見性。分別是external,public,internal,private。其中函數預設是public。狀態變數預設的可見性是internal。

			
internal - 狀態變數預設為internal類型,函數只能通過內部訪問(當前合約或者繼承的合約),可在當前合約或繼承合約中調用。類似於Java的protected
public - public標識的函數是合約介面的一部分。可以通過內部,或者消息來進行調用。與Java的public含義一致。
external - external標識的函數是合約介面的一部分。函數只能通過外部的方式調用。外部函數在接收大的數組時更有效。Java中無與此對應的關鍵字。
private - 只能在當前合約內訪問,在繼承合約中都不可訪問。與Java中的private含義一致。

payable :可支付的函數修飾符,沒有該修飾符無法接受轉賬操作。
			
			

14.9.2. 錯誤處理





assert(bool condition):不滿足條件,將拋出異常

require(bool condition):不滿足條件,將拋出異常

revert() 拋出異常

			
if(msg.sender != owner) { revert(); }
assert(msg.sender == owner);
require(msg.sender == owner);			
			
			

14.9.3. interface 介面

介面是抽象的合約,介面中不能實現方法。

介面:

  • 不能繼承其他合約或介面

  • 不能定義構造方法

  • 不能定義變數

  • 不能定義結構體

  • 不能定義枚舉

		
pragma solidity ^0.4.11;

interface Token {
    function transfer(address recipient, uint amount) public;
}
		
			

14.9.4. library 庫

定義 library

		
pragma solidity ^0.4.25;

// This is the same code as before, just without comments
library Set {
  struct Data { mapping(uint => bool) flags; }

  function insert(Data storage self, uint value)
      public
      returns (bool)
  {
      if (self.flags[value])
        return false; // already there
      self.flags[value] = true;
      return true;
  }

  function remove(Data storage self, uint value)
      public
      returns (bool)
  {
      if (!self.flags[value])
          return false; // not there
      self.flags[value] = false;
      return true;
  }

  function contains(Data storage self, uint value)
      public
      view
      returns (bool)
  {
      return self.flags[value];
  }
}


		
			

調用庫中的函數

		
contract C {
    using Set for Set.Data; // this is the crucial change
    Set.Data knownValues;

    function register(uint value) public {
        // Here, all variables of type Set.Data have
        // corresponding member functions.
        // The following function call is identical to
        // `Set.insert(knownValues, value)`
        require(knownValues.insert(value));
    }
}
		
			

14.9.4.1. 使用庫來擴展數據類型

			
pragma solidity ^0.4.25;

library Search {
    function indexOf(uint[] storage self, uint value)
        public
        view
        returns (uint)
    {
        for (uint i = 0; i < self.length; i++)
            if (self[i] == value) return i;
        return uint(-1);
    }
}

contract C {
    using Search for uint[];
    uint[] data;

    function append(uint value) public {
        data.push(value);
    }

    function replace(uint _old, uint _new) public {
        // This performs the library function call
        uint index = data.indexOf(_old);
        if (index == uint(-1))
            data.push(_new);
        else
            data[index] = _new;
    }
}			
			
				

14.9.5. 繼承

例子 mortal 繼承 owned

				
pragma solidity ^0.4.11;  
  
contract owned {  
    function owned() { owner = msg.sender; }  
    address owner;  
  
    modifier onlyOwner {  
        require(msg.sender == owner);  
        _;  
    }  
}  
  
  
contract mortal is owned {  
    function close() onlyOwner {  
        selfdestruct(owner);  
    }  
}