常规的以太坊账户(EOA)有一个不幸的局限。来自 EOA 的每笔交易只能直接与单个地址或合同进行交互。在dapp交互中经常出现这种情况,例如“您必须先解锁X才能获得Y”之类的消息。
基于合约的账户(合约钱包)不受此限制,可以将交易分批处理到多个合约中,以提供更顺畅的用户体验。在用户眼中,“approve”步骤可以完全抽象掉,可以简单地执行他们想要的动作。
1. defi 的产品分类
我们可以构建的DeFi协议的数量每天都在增长,但主要分为以下几类:
- 交换 — Uniswap,dYdX,Kyber网络,0x
- 借贷 — compound,dYdX,Aave
- 综合资产 — Maker,Synthetix,FutureSwap
- 保险 — Nexus Mutual 和 Opyn
2. 合约钱包集成 dapp 思路
基于 sendTransactionBatch 实现一键交互
例如:我需要抵押 ETH 获得 DAI,授权 DAI 给 cDAI 的合约,然后拿 DAI 去铸币产生 cDAI,只有 cDAI 即可 生息。
传统的 EOA 钱包,只能一笔一笔交易,而且需要当前交易上链后,才能继续执行第二笔交易。操作的复杂度和交易手续费都大大增加了。
合约钱包,可以把三部操作,封装到一次调用里面,用户只需要一次交互即可完成。app 提供身份认证和签名,由 web 实现页面交互。
await provider.sendTransactionBatch([
deposit_ETH_and_get_DAI,
approveDai_to_cDAI,
mintCDaiTransaction
])
优势
- 体验更好:用户一键即可完成复杂的交互;UI 定制,和 app 风格统一
- 安全性:不需要部署新合约;解决 approve 的问题
- 功能更丰富:可随意组合多种 defi,想象空间更大
3. approve 问题
以使用 StarCoin 购买咖啡为例,
- 买一杯咖啡,用户需要 先 approve(BuyCoffee, fee),然后 buy(fee)。
- approve 后,dapp 合约有权操作钱包资产,可操作数量 <= fee
- 实际的场景中,很多 dapp 为了体验方便, 设置 fee 的值非常大 或者不受限制。可能由于合约升级,或者有漏洞时,作恶者接管钱包,用户的资金洗劫一空
解决办法:approveAndCall
- 需要使用多少,则授权多少金额
- 授权后,由于有每日限额,即使损失,金额也是可控
- 随时可以撤销授权,或者随时调整授权的金额
/**
* 设置帐户允许支付的最大金额
*
* 一般在智能合约的时候,避免支付过多,造成风险,加入时间参数,可以在 tokenRecipient 中做其他操作
*
* @param _spender 帐户地址
* @param _value 金额
* @param _extraData 操作的时间
*/
function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
}
demo
- approve:https://github.com/argentlabs...
- sendTransactionBatch: https://github.com/authereum/...
参考资料
- https://www.argent.xyz/blog/a...
- https://medium.com/argenthq/f...
- approve 介绍文章:https://segmentfault.com/a/11...
- batchTransaction 介绍:https://medium.com/authereum/...
- sendTransactionBatch 的实现:https://docs.authereum.com/we...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。