主页 > imtoken钱包手机app > 以太坊C++源码分析(六)Ethereum The DAO Fork
以太坊C++源码分析(六)Ethereum The DAO Fork
刚刚写了一篇关于区块链同步的文章,发现有一些DAO fork代码无法绕过。 有必要专门写一篇文章,简单介绍一下以太坊历史上著名的分叉事件。
区块链分叉分为硬分叉和软分叉。 请谷歌搜索不同之处。 DAO 分叉是硬分叉。
DAO 是存在于以太坊区块链智能合约中的去中心化组织。 该机构于2016年4月30日通过合约发起众筹,仅28天就筹得了等值1.5亿美元的资金。 货币。 然而不幸的是,合约本身存在缺陷,更不幸的是,被一个(几个?)聪明的黑客利用以太坊分叉是怎么回事,他们(他们?)在 6 月 17 日从它那里窃取了价值 5000 万美元的以太币。
巨额亏损让 The DAO 和全球投资者难以承受。 以V神为代表的七人团决定采取反制措施。 软分叉还是硬分叉,在社区内一直存在争议,经过多方权衡,最终确定了硬分叉方案。
这个分叉本身也很有争议。 相当于网络游戏中的回滚。 直接宣告黑客拥有的以太坊无效。 简单粗暴,但违背了区块链上打包的交易任何人都不能篡改的原则。 ,人为干预区块链也违背了去中心化的精神。 因此,分叉后,以太坊分裂。 V神和大多数人支持的一种叫做以太坊(ETH),另一种叫做以太坊经典(ETC)。 由于缺乏官方支持,ETC处于弱势地位以太坊分叉是怎么回事,但仍有一批人坚守区块链精神维护它。
本次硬分叉计划如下:
58个DAO和sub-DAO合约账户共计12,001,961.845205763407115004 ETH转入区块1920000的退款合约账户。
这些转账并没有体现在区块交易中,而是直接写入了源代码!
你可以在 Etherscan 上找到这个区块:区块 1920000
我们来看看这个fork在源码中是如何体现的:
void Block::performIrregularModifications()
{
u256 const& daoHardfork = m_sealEngine->chainParams().daoHardforkBlock;
if (daoHardfork != 0 && info().number() == daoHardfork)
{
Address recipient("0xbf4ed7b27f1d666546e30d74d50d173d20bca754");
Addresses allDAOs = childDaos();
for (Address const& dao: allDAOs)
m_state.transferBalance(dao, recipient, m_state.balance(dao));
m_state.commit(State::CommitBehaviour::KeepEmptyAccounts);
}
}
这段代码判断如果当前区块高度为1920000,则遍历所有DAO账户,将所有余额转给接收方,即退款合约账户。
分叉的影响也影响到区块链同步模块:
// Before starting to exchange the data with the node, let's verify that it's on our chain
if (!requestDaoForkBlockHeader(_peer))
{
// DAO challenge not needed
syncPeer(_peer, false);
}
BlockChainSync::requestDaoForkBlockHeader() 函数实现为:
bool BlockChainSync::requestDaoForkBlockHeader(std::shared_ptr _peer)
{
// DAO challenge
unsigned const daoHardfork = static_cast(host().chain().sealEngine()->chainParams().daoHardforkBlock);
if (daoHardfork == 0)
return false;
m_daoChallengedPeers.insert(_peer);
_peer->requestBlockHeaders(daoHardfork, 1, 0, false);
return true;
}
对于主网来说,daoHardfork是1920000,所以首先需要向peer请求fork区块头。
if (m_daoChallengedPeers.find(_peer) != m_daoChallengedPeers.end())
{
if (verifyDaoChallengeResponse(_r))
syncPeer(_peer, false);
else
_peer->disable("Peer from another fork.");
m_daoChallengedPeers.erase(_peer);
return;
}
验证码位于 BlockChainSync::verifyDaoChallengeResponse() 函数中:
bool BlockChainSync::verifyDaoChallengeResponse(RLP const& _r)
{
if (_r.itemCount() != 1)
return false;
BlockHeader info(_r[0].data(), HeaderData);
return info.number() == host().chain().sealEngine()->chainParams().daoHardforkBlock &&
info.extraData() == fromHex("0x64616f2d686172642d666f726b");
}
可以看出验证方式很简单,就是看block header的extraData中的记录是否为dao-hard-fork(Hex: 0x64616f2d686172642d666f726b),如果是则说明是ETH,可以继续同步,否则就是ETC,禁用peer。
节点通过DAO挑战后,可以按照正常流程进行同步。