智能合约设计模式 - 紧急停止

本文为智能合约设计模式系列的一部分。

目的

在紧急情况时可以关闭合约关键功能

动机

即使是经过严格审核和测试的代码也可能包含bug或缺陷。智能合约也不例外。一般,这些漏洞只有在被攻击使才会发现,一旦发现bug,却很难被修复,因为不可变是区块链的核心原则之一。虽然有几个模式允许一定程度地升级代码(如代理模式),但这些解决方案通常需要大量的开发时间。在升级修复程序前,攻击者可能会盗走合约中的所有可用资金。

这种模式提供了阻止关键方法调用来暂停合约的可能性,从而防止攻击者持续攻击。当然,这个模式可以防止任何类型的bug攻击,不管是由被攻击发现还是主动发现,指导合约被修复或采取了其他措施。

适用性

在以下条件时使用紧急停止模式

  • 希望暂停合约
  • 希望保护关键功能被未暴露的bug攻击
  • 希望应对潜在的失败

参与者和协作

此模式有三个主要参与者:中心组件是一个状态变量,用于指示合约是否停止。每个重要方法检查此变量,在合约停止时,禁止执行或允许执行。第三个参与者是有权发布合约停止的调用者,它可能是合约所有人,也可能是大多数用户。

实现

合约停止或为停止,保存在布尔类型状态变量中,合约初始时该值为false。将其设为true就可在紧急情况是停止合约。建议通过方法调用,利用访问限制模式确保只有授权用户才可以调用此方法。防止恶意调用同时又兼顾去中心化的一个选择是制定一个触发规则。根据具体情况,可以采用各种规则(例如,最近一个小时提取了合约10%的金额)

状态变量一旦被设置为true,再次使用访问限制模式确保关键方法不能被调用,通过一个抛出异常的修饰符实现。在停止期间应该有可用方法,因为它们可以帮助解决这种情况,例如让用户提取存款,以相同方式保护。

另一个设计决策时,紧急停止是否可以恢复。如果合约应是可恢复的,例如采取了可升级预防措施,则通过将状态变量置回false来恢复合约。此方法和启动紧急停止方法类似,也应防止未授权调用。

代码示例

这个模式的具体实现依赖于底层智能合约的逻辑。重要问题,如是否可以恢复,哪些功能不可用,哪些可用等,应在部署合约前评估和仔细测试。

下面的代码展示了紧急停止模式的基本框架,并提供了两个受影响的示例方法。简便起见,省略具体业务逻辑。

// This code has not been professionally audited, therefore I cannot make any promises about
// safety or correctness. Use at own risk.
contract EmergencyStop {

    bool isStopped = false;

    modifier stoppedInEmergency {
        require(!isStopped);
        _;
    }

    modifier onlyWhenStopped {
        require(isStopped);
        _;
    }

    modifier onlyAuthorized {
        // Check for authorization of msg.sender here
        _;
    }

    function stopContract() public onlyAuthorized {
        isStopped = true;
    }

    function resumeContract() public onlyAuthorized {
        isStopped = false;
    }

    function deposit() public payable stoppedInEmergency {
        // Deposit logic happening here
    }

    function emergencyWithdraw() public onlyWhenStopped {
        // Emergency withdraw happening here
    }
}

第5行的布尔变量isStopped是一个状态变量,记录合约是否停止。两个修饰符检查它,分别是合约未停止(第7行)和合约停止(第12行),以限制它们修饰的方法调用。第17行的修饰符检查方法的调用者是否有权,例如可以通过require(msg.sender == owner)限定为合约所有者或增加投票机制。第22行和第26行中的两个方法使用它,通过将状态变量isStopped设置为truefalse,停止或恢复合约。

第30行的deposit方法是一个关键方法,一旦合约停止,它就不可访问。此限制是通过stoppedInEmergency修饰符实现。如果在停止期间调用此方法,则会引发异常。第34行的emergencywithdraw正好相反,只有在紧急停止时,它才可以访问。应该提供这样的紧急方法,使合约用户在停止期间能够访问他们的资金。否则,用户必须相信合约所有人不会擅自冻结资金。

结果

紧急停止模式给合约增加一个快速可靠的方法,当发现bug或安全问题时立即停止任何敏感方法。这将留下足够的时间权衡所有选项,并可能升级合约以修复安全漏洞。

此模式的负面结果是增加了合约的不可预测性。除非执行一个令人信服的规则集,否则授权者始终有可能滥用停止。因此,该模式实现的紧急停止只应作为最后手段,而不应被用作可预测事件的暂停机制,这种情况下,应采用具有定时转换的状态机模式,以便用户能够预测合约行为,并最小化系统的信任依赖。

已知应用

紧急停止模式最普遍的应用是OpenZeppelin库的可暂停合约。其它合约通过继承它使用此功能。好几个应用采用这个技术,一个例子是OmiseGO,一种旨在实现去中心化网络中金融包容和交互的代币。合约从第274行开始使用旧版本的可暂停合约。

另一个不太常见的可能是自己实现。这种方式的一个例子是百万以太网主页合约,它的主合约实现了紧急暂停模式,并使合同所有人能够在任意时间停止多个方法。

推而广之

如果你的智能合约或去中心化应用,需管理重要的数据,例如数据代表现实世界中的某种有价资产。不管它采用哪种链,公链还是联盟链,除非对所有节点有绝对的控制权,否则都建议使用本模式。至少它可以作为最后的措施避免更大的损失。本模式的一个关键点是如何确保它不被滥用,这使得它在联盟链中更容易被接受,身份机制和链下的信任联系保证了对其调用的监督以及滥用追查惩罚。

完整内容请查看智能合约设计模式系列

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,002评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,777评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,341评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,085评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,110评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,868评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,528评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,422评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,938评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,067评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,199评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,877评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,540评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,079评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,192评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,514评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,190评论 2 357

推荐阅读更多精彩内容