区块链技术与应用 - P23 - The DAO Incident

Posted by raftale on October 6, 2024

The DAO

DAO

上一节讲了重入攻击的原理。这节讲一个真实的案例,这个案例在以太坊的历史上赫赫有名,造成了以太坊的分裂。

因为比特币实现了去中心化的货币、以太坊实现了去中心化的合约,所以有人提出一个概念:Decentralized Everything。DAO这个概念就是在这个背景下产生的。

DAO的全称是Decentralized Autonomous Organization,区块链上,组织的规则制度是写在代码里面的,通过区块链的共识协议来维护规则制度的正常执行。

The DAO

2016年5月的时候,出现了一个致力于众筹投资的DAO,它的名字是The DAO

The DAO是一个去中心化的众筹投资基金,注意与DAO的含义是不一样的。

跟普通的风投基金的区别是,The DAO是一个民主式的风投基金,一个月的时间就筹集到了1.5亿美元的以太币,它的众筹速度和规模都是罕见的。

The DAO的工作原理

The DAO的工作原理:

  1. 工作原理:众筹的投资基金,投资的钱的来源是在区块链上众筹的,本质上是运行在以太坊上的智能合约。
  2. 投资哪个项目:参与投资是将以太币发给这个智能合约换回The DAOtoken,需要投资哪个项目是用The DAOtoken来投票决定的。
  3. 投资收益分配:按照智能合约的规章制度来分配的。

SplitDAO

SplitDAO是The DAO的一个特性,SplitDAO的作用:

  1. 可以帮助建立Child DAO:一部分人认为某个项目值得投,但得不到大多数的人的认可。这种情况下他们可以用拆分的方法从dao中独立出来,成立自己的Child DAO,拆分的时候这部分代币会被换成以太币,留在child dao中。拆分之后的有28的锁定期(这个也为后来的攻击的补救措施留了下缓冲时间)。
  2. 帮助投资者取回收益:The DAO没有直接换回eth的函数,通过SplitDAO成立的child dao,投资自己就可以取回资金。

黑客攻击

遗憾的是The DAO因为黑客攻击只存活了三个月。

黑客的攻击利用了SplitDAO的实现漏洞。

function splitDAO(
  uint _proposalID,
  address _newCurator
) noEther onlyTokenholders returns (bool _success) {
  ...
  // Burn DAO Tokens
  Transfer(msg.sender, 0, balances[msg.sender]);
  withdrawRewardFor(msg.sender);
  totalSupply -= balances[msg.sender];
  balances[msg.sender] = 0; 
  paidOut[msg.sender] = 0;
  return true;
}

SplitDAO代码中是先转账,然后再把账户清零。这个就是上一节讲的重入攻击漏洞,黑客就是利用这个漏洞进行了重入攻击。

正确的做法是:先把账户清零,然后再转账。

补救措施

社区的意见分为两派:

  1. 回滚交易:基于维护投资者利益的角度,以太坊团队支持补救措施。
  2. 不应该回滚交易:一部分人认为区块链不可篡改;以太坊本身没有问题,只是智能合约出了问题。

以太坊社区选择了回滚交易,补救措施是先通过软分叉禁止相关交易,再通过硬分叉回滚交易。

  1. 软分叉:通过升级软件增加了一个判断的规则,凡是跟The DAO基金上的账户有关的都不允许作任何交易
    • 但软分叉升级之后的软件有一个bug。判断交易非法时没有收取gas fee,结果造成了低成本的攻击。于是又回滚了版本,软分叉宣告失败。
  2. 硬分叉:将The DAO的代币转到一个新的智能合约上面,这个合约只有一个功能,将代币转换为ETH。挖到第192万个区块的时候,自动执行这个转账交易。
    • 因为旧矿工是无法认可这个交易的,所以这是硬分叉。

支持硬分叉和反对硬分叉的人进行了投票,最终选择了硬分叉,但是最后反对硬分叉的人仍然拒绝硬分叉,选择在旧链上继续运行。

硬分叉后,新链继承了以太币(ETH)的符号,而旧链上的以太币被称为以太经典(ETC)。

因为新旧链共享同一套历史账本和私钥,所以两条链上的交易可以进行重放攻击,于是用了一个chainID来区分新旧链。