美文网首页
智能合约设计模式 - 访问限制

智能合约设计模式 - 访问限制

作者: 李桐2000 | 来源:发表于2019-03-29 23:03 被阅读0次

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

目的

根据适当条件禁止访问合约功能

动机

由于区块链固有的公开性,无法保证合约的完全隐私。你无法阻止别人读取智能合约的状态,因为每个人都可以看到所有内容。但通过定义private状态,防止合约状态被其它合约读取。方法也可以声明为private,但这样就禁止一切外部调用。简单的声明称public,又会导致每个人都可以访问。一般来说,需要制定一些访问规则来限制合约访问。通常,方法访问权限被授予特定的实体,例如合约管理员。其它限制有在特定的时间点或访问者愿意为访问付费。所有这些限制,以及更多,都可以使用访问限制模式,来保护合约的安全性。

适用性

在以下条件时使用访问限制模式

  • 合约方法只能某些情况下被调用
  • 合约的多个方法都需要类似限制
  • 提高合约安全性,防止未授权的访问

参与者和协作

此模式参与者是方法的调用者和方法所属的合约。调用者可以是用户或合约,通过对合约地址发送事务来调用方法。被调用方的参与者是被保护的方法以及负责访问限制的附加组件。

实现

访问控制模式需要用到守卫检查模式。守卫检查模式检查调用方法是否满足规定要求,如果不满足就抛出异常。这里推荐采用 modifier 而非写到方法开头,因为这些检查经常要被多个方法复用。modifier 可以接受被保护方法的参数,也可以接受自己的参数。当然也可以将判断条件写死到 modifier 中,但这样会降低复用性。

modifier 结构通常遵守相同的规则:最开始检查规定条件,然后执行被修饰方法,_;在 modifier 中代表被修饰方法。如果需要在方法最后执行额外的动作,可以在_;后添加代码。通过这些方式,可以实现多种访问限制。

代码示例

下面示例改变自Solidity官方文档示例,它展示了3种访问限制方式。合约所有权既可以由所有人主动变更,也可以在上次购买变更一个月后由任何人以1以太币价格购买变更。

// This code has not been professionally audited, therefore I cannot make any promises about
// safety or correctness. Use at own risk.
pragma solidity ^0.4.21;

contract AccessRestriction {

    address public owner = msg.sender;
    uint public lastOwnerChange = now;
    
    modifier onlyBy(address _account) {
        require(msg.sender == _account);
        _;
    }
    
    modifier onlyAfter(uint _time) {
        require(now >= _time);
        _;
    }
    
    modifier costs(uint _amount) {
        require(msg.value >= _amount);
        _;
        if (msg.value > _amount) {
            msg.sender.transfer(msg.value - _amount);
        }
    }
    
    function changeOwner(address _newOwner) public onlyBy(owner) {
        owner = _newOwner;
    }
    
    function buyContract() public payable onlyAfter(lastOwnerChange + 4 weeks) costs(1 ether) {
        owner = msg.sender;
        lastOwnerChange = now;
    }
}

第7、8行声明状态变量ownerlastownerchange并初始化其为合约创建者和创建时间。第10行定义的onlyBy modifier 应用于第28行changeowner方法,确保本方法的调用者为合约的owner变量。如果其他人调用此方法就会触发异常。

第二个 modifier onlyAfter确保被附加的第32行方法只能在指定时间之后调用,本例为上次变更时间后4周(Solidity不支持月)。确保此方法至少经过4周才能调用一次。

第20行的最后一个 modifier cost具有一个金额入参,它确保调用者提交的金额不小于指定金额。这个 modifer 不同于前两个的之处在于,它在方法执行后(第22行的_代表方法执行)还有代码。从第23行开始,if语句检查提交金额是否大于指定金额,并返还多余金额给调用方。这个示例展示了多种 modifier。结合前面的 modifier,这个合约只有经过上次购买后4周才可以被再次购买,并且调用事物至少包含1个以太币。第32行buyContract方法的payable modifier 使此方法可以接受以太币。

需要注意的是,在上面示例中,我们可以不用 modifier 而直接在个方法体中实现相应的代码,功能完全一样,甚至更简单。但是,如果两个或多个方法包含相同或类似逻辑(如状态机模式),将它们实现到 modifier 中的好处就显而易见,因为 modifier 允许轻松复用。

后果

应用访问限制模式,必须注意几个后果。一个有争议的后果是代码可读性。一方面,modifier 是代码更容易理解,以为它在方法头中清楚标识,特别是当其名字有意义时。另一方面,代码执行从一行跳转到完全不同的其它行,使得难于跟踪和维护,从而容易导入引入歧义(甚至恶意)代码。因此,新的智能合约开发语言 Vyper 放弃了 modifier。

该模式的优点是:它能适应不同的情况和高复用性,同时提供了一种限制方法安全访问的方式,从而提高智能合约的安全性。

已知应用

这个模式最著名的应用可能是OpenZeppelin的Ownable合约

另个例子是CrytoKitties DApp的核心合约,它有3个所有者,CEO,CFO和COO,他们具有不同的安全级别,可以访问不同的功能。

推而广之

智能合约由于其公开透明去中心化的特质,导致安全成为影响它的重要问题之一。公开透明意味着源代码甚至合约状态谁都可以查看。去中心化意味着谁都可以调用合约的方法。以太坊、EOS等公链的匿名性更为黑客提供了肆无忌惮攻击的前期。联盟链提供的身份机制,从一定程度上缓解了安全问题(事后追查),但目前联盟链并不能设置方法级别的访问权限,也就是说无法阻止联盟中用户调用合约方法,况且有些方法从业务上就需要多个角色调用。因此对方法调用的安全保护成为智能合约开发的头等大事。

守卫检查模式着重于方法参数、方法返回等方面的安全。
访问限制模式着重于访问权限、合约状态等方面的安全。

本模式建议智能合约方法检查本次调用是否合法,一般有两大类检查,一是调用者是否有权利调用此方法,二是此方法是否处于可调用状态。

其它链并没有Solidity中修饰器,但它们都可以很容易地实现类似方式。至少可以把检查逻辑封装到单独的检查方法中,在智能合约暴露的方法里(一般是开始处)调用。另外,如果要进行调用者相关检查,必须获得调用者,各个链都有提供。EOS使用require_auth(account_name)确保当前调用者为指定账号。HyperLedger Fabric则提供了cid库获取调用者信息。

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

相关文章

  • 智能合约设计模式 - 访问限制

    本文为智能合约设计模式系列的一部分。 目的 根据适当条件禁止访问合约功能 动机 由于区块链固有的公开性,无法保证合...

  • 智能合约设计模式

    智能合约的开发不同于传统程序,具有一些自身的特点和规律。以前看到过一篇介绍Solidity模式的文章,感觉里面总结...

  • 智能合约设计模式 - 守卫检查

    本文为智能合约设计模式系列的一部分。 目的 保证智能合约的行为和入参符合预期 动机 就像法律合约一样,合约生效需要...

  • 基础设计模式:单例模式+工厂模式+注册树模式

    基础设计模式:单例模式+工厂模式+注册树模式 单例模式: 通过提供自身共享实例的访问,单例设计模式用于限制特定对象...

  • 智能合约设计模式 - 预言机

    本文为智能合约设计模式系列的一部分。 目的 访问区块链外的数据 动机 以太坊上的每个计算需要网络中的每个参与节点验...

  • 智能合约的设计模式

    概述 由于区块链运行机制的原因,智能合约的运行即使是异常运行都会在所有区块链节点上独立重复运行。因此,无论是在公有...

  • 智能合约-让区块链能做更多的事情

    智能合约 智能合约:智能合约是一种计算机协议,在以太坊中最重要的应用就是设计和部署只能合约。智能合约最早在1995...

  • MOAC墨客技术:异步合约调用

    概述 以太坊的同步智能合约调用,智能合约的返回和区块共识绑定在同一个区块,导致智能合约处理的总额受到区块时间限制。...

  • 智能合约设计模式 - 状态机

    本文为智能合约设计模式系列的一部分。 目的 确保合约不同状态暴露不同的功能 动机 合约的生命周期从初始状态开始,经...

  • Solidity开发模式

    前面写了智能合约开发模式总结了针对智能合约开发的通用模式,原文中还有一些模式只适用于Solidity开发,选出认为...

网友评论

      本文标题:智能合约设计模式 - 访问限制

      本文链接:https://www.haomeiwen.com/subject/wesdbqtx.html