BokkyPooBah's Token Teleportation Service 复现
本文最后更新于 2023年12月20日 中午
先有鸡还是先有蛋?——当你只有 ERC-20 代币时,应该怎么支付 Gas 呢?
背景介绍
-
有一个非常现实的问题,如何从 ERC-20 代币冷启动——倘若你有 ERC-20 代币,却没有 Gas Token。这是一个很经典的但是又往往被忽视的问题,很多时候它非常好处理,但是在某些情况下会极其棘手。事实上,解决该类问题相关的想法倒是并不少,OpenZeppelin 就提过 Gas Station Network,以太坊 ERC-865: 以 Token 支付转账、ERC-1077 gas 中继接口、EIP965 授权操作 以及 ERC-1776 原生元交易 等提案都是与此极大相关。甚至,之前大火的账户抽象 ERC-4337 也能很好的解决这个问题。
-
不过,一般来说,此类提案不太容易受到重视。一方面遇到这类问题真正棘手的时候并不多,另一方面这类提案一定程度上会削弱 ETH 本身的影响力,所以很难有好的叙事。
-
BokkyPooBah’s Token Teleportation Service 是一个早期的 ERC-865 的实现,尽管较为粗糙,但是核心的交互思路和后续的方案是高度一致的。
复现环境
- 项目:BokkyPooBahsTokenTeleportationServiceSmartContract
- 部署合约:BTTSTokenFactory.sol
- 测试网络:BSC Testnet
- solidity 编译器:0.4.18,enable optimization & 200
- 参与账户
账户 | 地址 |
---|---|
合约部署账户 | 0x3240f8664Fcd0faF9bf7d231196C5696D20a0707 |
转账账户 | 0xD8182F419A20a7cB7c8DE66e07Eb192a1F972844 |
接收账户 | 0x67De25A51E8C6F03BAf4913c7AFDC7e2c26f7F7E |
服务提供账户 | 0xaaE80fEBBa1046168d6c462e685d513643dde9Fa |
服务获利账户 | 0x080F98C531280d8B6aB9395AbA8dC197dc5100fb |
复现目标
- 服务提供账户根据转账账户给出的签名,将 1 token 从转账账户发送到接收账户。完成后有一笔 0.01 的 fee 发送到服务获利账户。
实验流程
部署合约
- 合约部署账户直接部署 BTTSLIB,地址为:0x1f06a5c9551b437d0CfF28Fe2eA9A51BD0f6d219
- 合约部署账户直接部署 BTTSTokenFactory,地址为:0xe521c57F10421B5a855153748657B1829E1C07f9
- 合约部署账户调用 BTTSTokenFactory 的
deployBTTSTokenContract
函数,部署 BTTSToken,地址为:0xBFee159535A3b48ED2bF7eC8ed0CA92df982B57d(需要在返回值bttsTokenAddress
字段里找到)- 函数参数为:
- symbol = “EPTest”
- name = “EP Test”
- decimals = 18
- initialSupply = “10000000000000000000000000”
- mintable = true
- transferable = true
- 函数参数为:
获取 Token
-
合约部署账户调用 BTTSToken 的 Mint 函数,参数为:
- tokenOwner = 0xD8182F419A20a7cB7c8DE66e07Eb192a1F972844
- tokens = 1000000000000000000000000
- lockAccount = true
-
此时 call BTTSToken 的
balanceof
函数,可以返回 0xD8182F419A20a7cB7c8DE66e07Eb192a1F972844 的 token 为 1000000000000000000000000,0x67De25A51E8C6F03BAf4913c7AFDC7e2c26f7F7E 和 0x080F98C531280d8B6aB9395AbA8dC197dc5100fb 的 token 是零 -
调用 BTTSToken 的
unlockAccount
函数解锁账户 ,参数为:- tokenOwner = 0xD8182F419A20a7cB7c8DE66e07Eb192a1F972844
计算元交易
-
计算
-
call BTTSToken 的
signedTransferHash
,计算 signedTransferHash,参数是- tokenOwner = 0xD8182F419A20a7cB7c8DE66e07Eb192a1F972844
- to = 0x67De25A51E8C6F03BAf4913c7AFDC7e2c26f7F7E
- tokens = 1000000000000000000
- fee = 10000000000000000
- nonce = call BTTSToken 的 nextNonce(0xD8182F419A20a7cB7c8DE66e07Eb192a1F972844) 获得,这里是 0
-
返回 { “0”: “bytes32: hash 0x59d312d723b09d23fdaaefa542737fceb8fe80185b0b539c2923b49eeaabe755” }
-
用 0xD8182F419A20a7cB7c8DE66e07Eb192a1F972844 签名 0x59d312d723b09d23fdaaefa542737fceb8fe80185b0b539c2923b49eeaabe755,得到 0x141964af6113a974245236a31fb1a91107b4bf8f902b236fff0b33b6de356013641532ec6080fdecaccf3f7534ffa35c4dc4e0fbb82583244dd439d6dc20eba61b
-
call BTTSToken 的
signedTransferCheck
函数,检查元交易是否正确,参数为:- from = 0xD8182F419A20a7cB7c8DE66e07Eb192a1F972844
- to = 0x67De25A51E8C6F03BAf4913c7AFDC7e2c26f7F7E
- tokens = 1000000000000000000
- fee = 10000000000000000
- nonce = 0
- sig = 0x141964af6113a974245236a31fb1a91107b4bf8f902b236fff0b33b6de356013641532ec6080fdecaccf3f7534ffa35c4dc4e0fbb82583244dd439d6dc20eba61b
- feeAccount = 0x080F98C531280d8B6aB9395AbA8dC197dc5100fb
-
返回 0,说明元交易正确
执行元交易
-
调用 BTTSToken 的
signedTransfer
函数,参数为:- from = 0xD8182F419A20a7cB7c8DE66e07Eb192a1F972844
- to = 0x67De25A51E8C6F03BAf4913c7AFDC7e2c26f7F7E
- tokens = 1000000000000000000
- fee = 10000000000000000
- nonce = 0
- sig = 0x141964af6113a974245236a31fb1a91107b4bf8f902b236fff0b33b6de356013641532ec6080fdecaccf3f7534ffa35c4dc4e0fbb82583244dd439d6dc20eba61b
- feeAccount = 0x080F98C531280d8B6aB9395AbA8dC197dc5100fb
-
这笔交易的 Hash 为 0x94c2cd99bfdc0e350e63263cffbf930daca25d9a80bfc0309e41972d9c0adca3
检查结果
-
如图所示,结果和预期相符合,复现成功
-
转账账户
- 接收账户
-服务获利账户