跳至主內容

簽吧。智能合約?

  • 智能合約是將合約條文程式化並寫進區塊鏈中。有別於傳統合約的是它無需第三方介入,當滿足合約條件時,程式便會自動執行合約,而且無法更改。

  • 過住有一些保安事故與智能合約有關,牽涉利用智能合約的程式設計漏洞。因此,不論是開發或使用智能合約時都要小心謹慎,以免程式執行結果與預期不同,同時要理解當中潛在的風險及相應的保安建議。

發佈日期: 2022年04月04日 6166 觀看次數

早前先後介紹了NFT 保存方法NFT 網絡攻擊,相信大家對區塊鏈及NFT 也有基本認識。除了NFT 外,區域鏈也可以應用於其他地方,其中一項核心技術是智能合約。可是,何謂智能合約?跟傳統合約有何區別?它的應用層面又是什麼?以及最重要的是有什麼網絡保安風險?接下來會向大家淺淡。

 

 

智能合約的起源

 

智能合約(Smart Contract)的概念源於1994由一位美國密碼學家兼電腦科學家Nick Szabo 提出,他提倡把合約數字化及程式化,意味著條款細則會以數字形式鑲嵌在特定區域中。可是,在區塊鏈出現前的社會迴響不大[1]

 

智能合約除了是區塊鏈的其中一項核心技術,亦是一種特殊協議。使用者可以把合約條文程式化寫進區塊鏈中。當滿足合約的一定條件後,便會觸發程式自動執行。

 

以自動售賣機為例,售賣機的合容條件就是當我投進了一定金額後,就會觸發程式執行出售一罐汽水。一切操作沒有涉及第三者及繁複手續,成本因而較少。

 

來源:https://www.nicepng.com/ourpic/u2w7y3t4w7a9e6i1_smart-contracts-in-insurance-policies-history-of-smart/[2]

 

 

傳統合約與智能合約的差異

 

日常生活中,大家會時常接觸傳統合約,例如購買房屋時需要經過地產中介接洽、銀行財務審批,及律師服務等程序。

 

傳統合約往往是以信任為基礎,牽涉第三方介入以作見證人,然後由簽署雙方各自履行合約上的義務,整個程序繁複和涉及額外費用。

 

智能合約的設計就是解決以上問題。除了可以省卻第三方的開支外,也能確保合約內容得以有效地執行。它是一項非以雙方信任為基礎的技術,而是建基於雙方協定的合約內容。

 

由於智能合約被程式化後會寫進區塊鏈,而區塊鏈有著不能篡改的特性,加上智能合約設定的條件一被滿足,內容亦會即時自動執行,保障雙方利益及節省了時間成本。

 

 

        
來源:https://kustard.io/blog/are-smart-contracts-really-smart/[3]

 

 

因此,智能合約具有下列特性:

 

  • 自動化

    當條件符合便自動執行內容。

  • 節省時間及成本低

    減少第三方的介入,從而減少當中牽涉的成本,例如時間成本及第三方開支。

  • 可靠的

    內容被寫進區塊鏈。因此,是以合約內容為基礎,而非雙方的信任。

 

常用智能合約編程語言

 

  • Vyper

  • Solidity

// SPDX-License-Identifier: GPL-3.0
pragma solidity >= 0.7.0;

contract Coin {
    // The keyword "public" makes variables
    // accessible from other contracts
    address public minter;
    mapping (address => uint) public balances;

    // Events allow clients to react to specific
    // contract changes you declare
    event Sent(address from, address to, uint amount);

    // Constructor code is only run when the contract
    // is created
    constructor() {
        minter = msg.sender;
    }

    // Sends an amount of newly created coins to an address
    // Can only be called by the contract creator
    function mint(address receiver, uint amount) public {
        require(msg.sender == minter);
        require(amount < 1e60);
        balances[receiver] += amount;
    }

    // Sends an amount of existing coins
    // from any caller to an address
    function send(address receiver, uint amount) public {
        require(amount <= balances[msg.sender], "Insufficient balance.");
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        emit Sent(msg.sender, receiver, amount);
    }
}

例子: Solidity編程的智能合約: https://ethereum.org/en/developers/docs/smart-contracts/languages/[4]

 

 

過去涉及智能合約的網絡保安事故

 

智能合約是由程式編寫而成,由以太虛擬機(Ethereum Virtual Machine)執行,很多保安事故都是因被黑客發現程式有漏洞有關。

 

2022年1月,有網絡保安公司的研究報告指出黑客透過創造欺詐代幣來引誘用戶購買[5]。由於黑客利用智能合約的錯誤設置及代碼漏洞,然後騙取智能合約中的資金,例如利用下圖中的emergencyWithdraw 函數從智能合約中進行了57次盜竊行為。

 

 

來源:https://research.checkpoint.com/2022/scammers-are-creating-new-fraudulent-crypto-tokens-and-misconfiguring-smart-contracts-to-steal-funds/ [5]

 

 

此外,報告亦提及下列四項代幣欺詐情況:

 

  • 一些代幣在購買費達99%時,黑客在購買階段騙走所以資金;

  • 一些代幣不允許買家轉售,只有代幣持有人可以轉售;

  • 一些代幣在售價達99%時,黑客在銷售階段騙走所以資金;

  • 一些代幣允許持有人創造更多代幣作銷售

2016年6月,智能合約平臺組織The DAO 由於在開發過程中代碼有誤,導致被黑客成功盜取約5,000萬美元的以太幣。

 

來源:https://www.wired.com/2016/06/50-million-hack-just-showed-dao-human/[6]

 

 

合約正常流程

 

  1. 要求DAO合約提取DAO Token
  2. 把DAO Token轉給使用者
  3. 更新DAO Token提取記錄

漏洞利用過程

 

  1. 要求DAO合約提取DAO Token
  2. 在更新DAO Token提取記錄前,再次要求提取DAO Token
  3. 不斷重複步驟2
  4. 合約最終只記錄了一次提取記錄,失去了期間的提取記錄

 

The DAO事件是一種「重入」(Reentrancy)攻擊,以下是攻擊程式碼的範例,手法類近The DAO該次事件。

mapping (address => uint) private userBalances;

function withdrawBalance() public {
    uint amountToWithdraw = userBalances[msg.sender];
    (bool success, ) = msg.sender.call.value(amountToWithdraw)(""); // At this point, the caller's code is executed, and can call withdrawBalance again
    require(success);
    userBalances[msg.sender] = 0;
}

「重入」攻擊範例: https://consensys.github.io/smart-contract-best-practices/attacks/reentrancy/[7]

 

 

以上例子可以看到當要用外部程式碼(external call) msg.sender.call.value(amountToWithdraw)("")前,沒有先將 userBalances[msg.sender] 重設為零,如果外部的是惡意程式,它便可以重覆調用 withdrawBalance(),不斷轉走相等於userBalances[msg.sender]數值的資產。

 

另外,2021年11月,多鏈去中心化交易所 MonoX 受到黑客入侵 [8]。黑客透過程式中的漏洞使智能合約把MONO 幣的價值提高,其後購買其他資產。最終MonoX 遭受3,100 萬美元的損失。

 

 

使用智能合約的注意事項

 

  1. 簽署智能合約時,要小心確認合約內容。若不確定簽署請求,應該使用官方渠道聯絡平台技術支援;
  2. 如對智能合約不是太熟悉,可使用規模較大的交易平台上的官方智能合約進行交易;
  3. 交易後,立即查看所持有的加密資產,檢查資產轉移數量是否正確、交易是否根據合約內容成功執行;
  4. 編寫智能合約時應參考最佳實踐指引[9],以避免常見的攻擊方式,如重入攻擊、阻斷服務攻擊等[10];以及
  5. 為智能合約進行保安評估或審計來檢查程式碼有否保安問題以便跟進。報告結果亦可供用戶查閱以增加透明度。

 

 

 

 

參考資料

[1] https://www.fisc.com.tw/Upload/b0499306-1905-4531-888a-2bc4c1ddb391/TC/9005.pdf  

[2] https://www.nicepng.com/ourpic/u2w7y3t4w7a9e6i1_smart-contracts-in-insurance-policies-history-of-smart/  

[3] https://kustard.io/blog/are-smart-contracts-really-smart/

[4] https://ethereum.org/en/developers/docs/smart-contracts/languages/

[5] https://research.checkpoint.com/2022/scammers-are-creating-new-fraudulent-crypto-tokens-and-misconfiguring-smart-contracts-to-steal-funds/

[6] https://www.wired.com/2016/06/50-million-hack-just-showed-dao-human/

[7] https://consensys.github.io/smart-contract-best-practices/attacks/reentrancy/

[8] https://arstechnica.com/information-technology/2021/12/hackers-drain-31-million-from-cryptocurrency-service-monox-finance/

[9] https://consensys.github.io/smart-contract-best-practices/

[10] https://consensys.github.io/smart-contract-best-practices/attacks/