当前位置:首页 > 资讯 > 区块链新闻 > 正文

科普 | 为什么使用提款(Withdrawal)模式?

发布:中币网   时间:2018-05-07 21:19:40   加入收藏 打赏

《建立以太坊支付通道》这篇文章引发了这样一个问题:为什么关闭一个支付通道要将资金增加到一个账户,而不是简单地将资金返还给通道参与者。这种机制被称为提款模式,这篇文章将解释其必要性。当一笔以太坊交易试图将资金释放到不受交易发起人控制的地址时,问题就出现了。一个非常简化的合约例子如下所示:contract BadSplitter { uint256 funds; address sender; add

《建立以太坊支付通道》这篇文章引发了这样一个问题:为什么关闭一个支付通道要将资金增加到一个账户,而不是简单地将资金返还给通道参与者。这种机制被称为提款模式,这篇文章将解释其必要性。

当一笔以太坊交易试图将资金释放到不受交易发起人控制的地址时,问题就出现了。一个非常简化的合约例子如下所示:

contract BadSplitter { uint256 funds; address sender; address recipient; // Deposit some funds in to the contract function deposit(address other) payable { funds = msg.value; sender = msg.sender; recipient = other; } // Split an amount of funds between the sender and the recipient function split() { // Can only be called by the recipient require(msg.sender == recipient); // Split the funds sender.transfer(funds / 2); recipient.transfer(funds / 2); }

(请注意,本智能合约纯粹是为了说明目的,完全不具有任何实用价值。)

本合约的运作方式如下:

  • 发送方发起一个 deposit() 事务,并附上接收方的地址。
  • 接收方发起一个 split() 事务,该交易将一半的存款发送给接收方,另一半发送回发送方。

或如图所示:

没有代码循环或限制条件,所以控制流程很容易遵循。那会出现什么问题呢?

问题在于,账户和合约都是交易的有效参与者,而作为交易的一部分,当这些合约收到资金时,合约会按照代码来执行。

当合约收到资金时,它会在合约上调用一个特殊的函数,称为回退(Fallback)函数。这允许合约控制调用它的交易的控制流程。

一个纯粹的恶意合约如下所示:

contract BadSender { // Forward funds to the splitter contract function forward(address other) payable { // This is the address of the splitter contract address splitterContract = 0xAe3aE77F5ab2490C46958D0b05f766871c17cA5e; BadSplitter splitter = BadSplitter(splitterContract); splitter.deposit.gas(200000).value(msg.value)(other); } // Purely malevolent fallback function () { revert(); } }

本合约的运作方式如下:

  • 发送方发起一个 forward() 事务,并附上接收方的地址。这将调用前面描述的恶意拆分合约(BadSplitter Contract)。
  • 当接收方试图在恶意拆分合约中调用拆分 split() 时,他们发现他们的交易失败了。这是因为恶意拆分引起 sender.transfer() 调用恶意拆分中的回退函数,该函数立即失效,并导致整个交易失效。

或如图所示:

重点是要明白:回滚(Reverting)交易会取消原交易采取的所有行动,所以回滚后以太坊的状态就好像从未发生过交易一样。如若没有这个 reverse() 方程,在发送者之前写一个简单的合约,向接受者发送资金就可以避免提款失败。

正如上面所提到的,这是一种纯粹的恶意合约,因为它会无条件地禁止接收者地址获得其资金。然而,鉴于智能合约是一个程序,一个更高级的恶意发送者(BadSender)可以根据时间、某个帐户的余额、一个内部标志等来允许或拒绝交易。恶意的可能性是无止境的,并且发送者还可以要求接收者支付赎金。

在支付通道的情境中,这会有负面的影响,因为当接受者试图关闭通道时,一个恶意发送者可能会回滚交易,不让接受者获得应得的资金。一旦通道在到期时间关闭,发送方可能会终止该通道、接收所有已存的资金,且永久地剥夺接收方所应得的资金。

解决这个问题的办法是使用提款模式。通过跟踪合约内部的余额,并迫使每个用户撤回自己的资金,从而在交易中的另一方可能是恶意合约的事实变得无关紧要。关于提款模式的更多细节可以在 solidity 官方文件中找到。

原文链接: https://medium.com/@jgm.orinoco/why-use-the-withdrawal-pattern-d5255921ca2a
作者: Jim McDonald
翻译&校对: Waterzeong & Elisa


本文由作者授权 EthFans 翻译及再出版。


来源:Butterfly




来源:中币网  https://www.zhongbi.net/news/blocknews/79144.html
声明:登载此文仅出于分享区块链知识,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不构成投资建议。投资者据此操作,风险自担。 此文如侵犯到您的合法权益,请联系我们3111859717@qq.com,我们将第一时间处理。