文章阅读页通栏

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

来源: BlockTempo动区动趋 作者:Lai Jack赖彦廷
许多人可能对此感到疑问,透过本篇文章相信能充分为您解惑。上一节我们带大家一窥以太坊的架构全貌并为迄今为止七篇文章做了小结。我们将在这基础......
许多人可能对此感到疑问,透过本篇文章相信能充分为您解惑。上一节我们带大家一窥以太坊的架构全貌并为迄今为止七篇文章做了小结。我们将在这基础之上阐明发送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. 希望我能够撰写分享的区块链技术知识内容

关键词: ERC20  Token  
0/300