使用工厂提高智能合约安全性

使用工厂模式的利与弊

> * 原文:https://consensys.net/diligence/blog/2019/09/factories-improve-smart-contract-security/ > * 译文出自:[登链翻译计划](https://github.com/lbc-team/Pioneer) > * 译者:[翻译小组](https://learnblockchain.cn/people/412) > * 校对:[Tiny 熊](https://learnblockchain.cn/people/15) > * 本文永久链接:[learnblockchain.cn/article…](https://learnblockchain.cn/article/2297) 智能合约可以部署其他智能合约,通常称为[工厂模式](https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)),让你不是创建一个合约跟踪很多事情,而是创建多个智能合约,每个合约只跟踪各个的事情。 使用这种模式可以简化合约代码,减少某些类型的安全漏洞的影响。 在这篇文章中,我将带你了解一个例子,这个例子是基于最近的一次审计中发现的一个关键漏洞修改而来。 如果使用了工厂模式,这个漏洞就不会那么严重了。 ## 一个错误的智能合约 下面是一个智能合约,通过一个相当简单的接口来出售 WETH。 如果你有WETH,你只需要 `approve(授权) `这个智能合约来出售你的代币,它将确保你得到正确的金额。 只要批准了足够的代币,任何人都可以向你购买WETH 。 合约采用[提现模式](https://learnblockchain.cn/docs/solidity/common-patterns.html#withdrawal-pattern)向卖家交付出售所得的ETH,但合约作者却犯了严重错误,代码如下: ```javascript // 技术上可以实现出售任何代币,但这个例子仅出售 WETH 。 // 因为这里不想关注价格. 1 WETH = 1 ETH. contract WETHMarket { IERC20 public weth; mapping(address => uint256) public balanceOf; constructor(IERC20 _weth) public { weth = _weth; } // 从指定的seller购买 WETH . seller 需要先授权 WETH. function buyFrom(address seller) external payable { balanceOf[seller] += msg.value; require(weth.transferFrom(seller, msg.sender, msg.value), "WETH transfer failed."); } // 出售者调用,提取ETH function withdraw(uint256 amount) external { require(amount <= balanceOf[msg.sender], "Insufficient funds."); // Whoops! Forgot this: // balanceOf[msg.sender] -= amount; (bool success, ) = msg.sender.call.value(amount)(""); require(success, "ETH transfer failed."); } } ``` 如果你想知道为什么代码使用`.call`而不是`.transfer`,请阅读[停止使用transfer()](https://learnblockchain.cn/article/2191))。 由于卖方的余额永远不会减少,所以,一...

  • 原文:https://consensys.net/diligence/blog/2019/09/factories-improve-smart-contract-security/
  • 译文出自:登链翻译计划
  • 译者:翻译小组
  • 校对:Tiny 熊
  • 本文永久链接:learnblockchain.cn/article…

智能合约可以部署其他智能合约,通常称为工厂模式,让你不是创建一个合约跟踪很多事情,而是创建多个智能合约,每个合约只跟踪各个的事情。 使用这种模式可以简化合约代码,减少某些类型的安全漏洞的影响。

在这篇文章中,我将带你了解一个例子,这个例子是基于最近的一次审计中发现的一个关键漏洞修改而来。 如果使用了工厂模式,这个漏洞就不会那么严重了。

一个错误的智能合约

下面是一个智能合约,通过一个相当简单的接口来出售 WETH。 如果你有WETH,你只需要 approve(授权)这个智能合约来出售你的代币,它将确保你得到正确的金额。 只要批准了足够的代币,任何人都可以向你购买WETH 。

合约采用提现模式向卖家交付出售所得的ETH,但合约作者却犯了严重错误,代码如下:

 // 技术上可以实现出售任何代币,但这个例子仅出售  WETH 。
  // 因为这里不想关注价格. 1 WETH = 1 ETH.
 contract WETHMarket {
     IERC20 public weth;
     mapping(address => uint256) public balanceOf;

     constructor(IERC20 _weth) public {
         weth = _weth;
     }

    // 从指定的seller购买 WETH . seller 需要先授权 WETH.
    function buyFrom(address seller) external payable {
        balanceOf[seller] += msg.value;
        require(weth.transferFrom(seller, msg.sender, msg.value),
            "WETH transfer failed.");
    }

    // 出售者调用,提取ETH
    function withdraw(uint256 amount) external {
        require(amount &lt;= balanceOf[msg.sender], "Insufficient funds.");

        // Whoops! Forgot this:
        // balanceOf[msg.sender] -= amount;

        (bool success, ) = msg.sender.call.value(amount)("");
        require(success, "ETH transfer failed.");
    }
}

如果你想知道为什么代码使用.call而不是.transfer,请阅读停止使用transfer())。

由于卖方的余额永远不会减少,所以,一...

使用工厂提高智能合约安全性插图

剩余50%的内容订阅专栏后可查看

  • 单篇购买 10学分
  • 永久订阅专栏 (90学分)
  • 发表于 2021-03-23 12:13
  • 阅读 ( 1214 )
  • 学分 ( 35 )
  • 分类:智能合约
  • 专栏:全面掌握Solidity智能合约开发

评论