为何发送ERC20 Token 需要两次交易?

许多人可能对此感到疑问,透过本篇文章相信能充分为您解惑。上一节我们带大家一窥 以太坊 的架构全貌并为迄今为止七篇文章做了小结。我们将在这基础之上阐明发送ERC20 Token背后的技术解析。

发送以太币

发送以太币时其实蛮符合我们的直觉,就是把钱发给别人,别人收到这样。然而发送ERC20 代币却仿佛不是这么单纯,为什么呢?

ERC-20 代币的本质

首先回顾一下上一节提到的,ERC20代币只是用ERC20之智能合约底下的记忆体来储存记录各个地址持有数量的帐本。既然对象是个智能合约,就要再回顾一下第二节提到的,个人帐户(Externally Owned Account, EOA)与合约帐户(Contract Account)的不同,由于智能合约没有主观意识,动作皆需要由EOA发交易来触发。因此当合约地址收到ETH外的其它代币时,它并不会知道。因为更动的是「另一个智能合约底下的记忆体」!

我们实际来看一个范例:假设我想要透过去中心化交易所Uniswap 将我持有的82 颗cDAI 兑换成0.0092 颗ETH,在技术上是如何做到的呢?

先备知识: cDAI是我将DAI存入Compound放贷后,Compound发回给我的ERC20 Token。所以cDAI是由Compound管理的cDAI智能合约底下之记忆体(帐本)来记录追踪的。

我的Token Swap需求在常规逻辑上是:我把我的cDAI token发送给Uniswap,Uniswap把ETH发送给我。

不过事情并非这么单纯。由于Uniswap是去中心化,由智能合约来运作的。因此当Uniswap收到了cDAI token时,它不像人一样可以点开Metamask去查看是否有收到,确认有收到后再把ETH发送给我,因此需要用特殊的做法来实现这样的流程。

我们就直接开门见山讲答案

用比喻来说明的话,做法是:

1. 我先到银行(ERC20 Token的智能合约)开启授权,允许对方(第三方智能合约)能够到我的户头,提取钱(ERC20 Token),并设定「能够提取的额度」。

2. 接着我开给对方一张「写上金额的支票」,让对方拿着支票到银行中提领我帐户中的钱。

因为对象(智能合约)是一段程式码,如此做法方能让智能合约确认提取到Token并执行后续的合约逻辑操作。

因此,回到 区块链 的世界,必须透过以下两个交易步骤来进行:

Tx1: Approve(授权)

我必须先发一笔交易到「Compound cDAI Token智能合约」(银行),

授权「Uniswap的cDAI to ETH交易对智能合约」(对方)

可以到「Compound的cDAI Token智能合约」(银行)

提取我的「 cDAI Token」(钱)。

Tx2: Swap Token(兑换)

随后,我再发送一笔「将cDAI兑换为ETH」的交易(支票)

到「Uniswap的cDAI to ETH交易对智能合约」(对方)触发,

让「Uniswap的cDAI to ETH交易对智能合约」(对方)

至「Compound的cDAI Token智能合约」(银行)

提领我的82颗「cDAI Token」(钱)。

「Uniswap的cDAI to ETH交易对智能合约」(对方)提领到Token(钱)后再将0.0092颗ETH发送给我。

如下方示意图所示:

接着我们带大家实际走一次操作流程以搞懂背后技术逻辑。

Tx1: Approve(授权)

首先,当我们来到Uniswap交易所,选好Input与Output的

加密货币

种类并在Input输入欲兑换的数量,便可以在我欲兑换成ETH的cDAI Token旁边看到「Unlock」的按钮。这就是要求我进行「Tx1:授权」的操作。

点选「Unlock」按钮后,便会跳出「批准」的交易来让我签署。一但签署后,我便批准了Uniswap能够到Compound提领我的cDAI的权限。

这笔交易被确认后,我们便可以凭Txn Hash到Etherscan上找到这笔交易。可以发现这笔交易是发给「Compound的cDAI ERC20 Token智能合约」。

点进去这笔交易后,便可以看到呼叫的正是approve的function。我同意了「Uniswap的ETH-cDAI交易对」合约地址能够来提领我的cDAI,而授权的提领金额量为「最大」。

可能会有些人好奇为什么不把amount设成我要兑换的量:82就好。原因是为了便利于未来提领操作时不用再次授权,通常呼叫智能合约的approve函式时都会预设为开启最大值,这样未来再次需要提领时就不用再次进行approve的操作。

然而要注意的部分是:针对「可能存在漏洞或不被信任的智能合约」,若是仍按照预设将权限开至最大值,则将面临Token遭到窃取的风险。

在完成「Tx1:Approve授权」后,便可以看到「Unlock」的按钮消失,并且「Swap」按钮已能够点选。

Tx2: Swap Token

接着便能够来进行将我的cDAI 兑换成ETH 的Swap Token 动作。

同样透过Metamask来签署完成这笔交易后,我们到Etherscan上追縱这笔交易:能够发现这笔交易是从我的钱包发送给「Uniswap的ETH-cDAI交易对智能合约」。

点进去这笔交易后可以看到在这笔交易中执行了两件事:

1. 将82 cDAI 从「Compound 的cDAI 智慧合约」转至「Uniswap 的ETH-cDAI 交易对合约地址」中。

2. 将0.0092 ETH 从「Uniswap 的ETH-cDAI 交易对合约地址」中转给我。

接着我们可以在「Uniswap的ETH-cDAI交易对合约地址」的「Internal Txns」中看到0.0092 ETH转移至我的钱包地址;以及在「Erc20 Token Txns」中看到82 cDAI从「Compound的cDAI智能合约」转移至「Uniswap的ETH-cDAI交易对合约地址」中。

同时,这笔交易在「Compound 的cDAI 智能合约」中也可以查看到82 cDAI 被转移出的记录。

结论

1. 发送ETH与发送ERC20 Token给智慧合约有本质上的差异。ETH是push-based,单纯把ETH发过去就可以。ERC20 Token的发送则是pull-based,让合约去主动提取Token。

2. 必须先发送一笔交易至ERC20合约进行授权(Approve),允许某合约地址能够至ERC20智慧合约提取我持有的ERC20 Token。

3. 再发送一笔交易来触发合约地址进行提取ERC20 Token与后续的逻辑操作。

至此,相信读者都已充分理解发送ERC20 Token 给智慧合约背后的技术逻辑。

下一节我们将来介绍「Oracle(预言机)」,这个扮演真实世界与区块链间桥梁的技术,并带大家认识MakerDAO、Compound等大专案的实作方式。敬请期待!

以上若有任何

A. 不够清楚的地方

B. 撰写上改进的建议

C. 希望我能够撰写分享的区块链技术知识内容

根据国家《 关于防范代币发行融资风险的公告 》,大家应警惕代币发行融资与交易的风险隐患。

本文来自 LIANYI 转载,不代表链一财经立场,转载请联系原作者。