从EtherEx到ERC20:标准代币API(approve/transferFrom)的起源与演进完整指南
【免费下载链接】etherexEtherEx is an open source, fully transparent, next generation decentralized exchange built on Ethereum.项目地址: https://gitcode.com/gh_mirrors/et/etherex
EtherEx 是 2014 年上线的最早一批以太坊开源去中心化交易所之一,它的合约代码第一次把approve、transferFrom、allowance、transfer、balanceOf这套接口组合固定了下来,成为后来 EIP-20 草案、乃至如今 ERC20 标准代币 API 的直接前身。本文将带你从一份真实的历史源码出发,拆解"授权转账"机制是如何诞生的,以及新手如何复现整套流程。
一、为什么去中心化交易所需要标准代币API?
传统交易所由平台统一托管用户资产,而 EtherEx 完全跑在链上:代币必须真实地躺在交易所合约里,交易撮合只在合约内部更新账本(见 contracts/etherex.se)。
这就引出一个经典难题:
- 代币合约属于用户(私钥在用户手里);
- 但交易所合约需要能"取走"用户批准过的那部分代币来完成充值(deposit)。
解法只有一个:用户先授权,交易所再代转。这个"授权 + 代转"两步式交互,就是approve/transferFrom标准代币 API 的雏形。
二、拆解 approve / transferFrom:授权转账的完整链路
EtherEx 附带了一个示例标准代币 ETX,用 Serpent 语言实现,源码仅 80 多行,是理解整套 API 最好的标本:contracts/etx.se
2.1 approve:把"取币额度"交给交易所
def approve(_spender, _value): self.accounts[msg.sender].custodians[_spender].maxValue = _value log(type=Approval, msg.sender, _spender, _value)用户调用 approve,等于在链上声明:"我允许地址_spender(交易所合约)最多转走我_value个代币"。这笔授权记在custodians字段里,并广播Approval事件。
配套只读方法 allowance 可随时查询剩余额度,钱包界面正是靠它显示"还可代转多少"。
2.2 transferFrom:交易所按额度代转
充值时,用户调用的是交易所的deposit,交易所合约再回头调用代币合约的 transferFrom:
if balance >= _value and _value <= custodians[msg.sender].maxValue: # 扣余额、加目标余额、扣减授权额度注意两个细节:msg.sender在这里是交易所合约,它只能动用用户预先批准、且未用完的额度;每转一次额度就自动递减。授权是"消耗型"的,额度用完即失效,这是与"无限授权"的关键安全差异。
2.3 deposit:用户视角只需一步
交易所侧的充值入口在 contracts/etherex.se:
def deposit(amount, market_id): if self.markets[market_id].contract.transferFrom(msg.sender, self, amount): # 更新用户在交易所的可用余额完整链路是:用户 approve → 用户调用交易所 deposit → 交易所 transferFrom 取币 → 交易所账本加余额。整个过程无需用户交出私钥,也没有中间托管方。
部署清单 contracts/EtherEx.yaml 里就记录了这条真实调用链:先approveOnce再deposit,是当年链上充值的标准姿势。
2.4 withdraw 与 balanceOf:标准 API 的另外半边
- 提现:交易所直接调用代币合约的 transfer 把币打回用户地址,对应交易所的 withdraw。因为交易所合约自己就持有代币,这一步不需要任何授权。
- 查余额:前端界面显示用户持仓依赖 balanceOf,前端 ABI 里也完整声明了这组接口(frontend/app/js/abi/sub.js)。
五个方法各司其职,构成了最早的"标准代币接口清单",README 中称其为Subcurrency API(README.md)。
三、add_market:交易所如何把"非标准代币"挡在门外
标准 API 的另一面是准入校验。交易所注册新市场时,会用空参数逐个试探代币合约的五个方法:
# Check Standard Token support if contract.allowance(msg.sender, self) != 0: return MARKET_NONSTANDARD_ALLOWANCE if contract.approve(self, 0) != 1: return MARKET_NONSTANDARD_APPROVE ...见 add_market 校验逻辑 与错误码定义 MARKET_NONSTANDARD_*(40~44)。任何方法签名、返回值不符合约定,市场注册直接失败——这是链上"接口标准"的第一道强制门槛,测试里甚至专门构造了返回-1的"非标准合约"来验证拒绝逻辑(tests/test_etherex.py)。
四、从 EIP-20 草案到 ERC20:一段 API 的演进史
| 阶段 | 时间 | 变化 |
|---|---|---|
| Subcurrency API | 2014–2015 | EtherEx 时代:approve/transferFrom/allowance/transfer/balanceOf,返回值用 0/1 表示成败 |
| EIP-20 草案 | 2015 | 社区标准化提案,接口基本定型,事件与布尔返回值开始被强调 |
| ERC20 标准 | 2018 | 正式编号:强制Transfer/Approval事件、totalSupply,规范布尔返回值 |
README 中有一句关键旁证:早期deposit曾依赖代币合约自定义方法,后被弃用,明确转向"标准化合约 API"(README.md)。这条从"各自实现"到"统一接口"的路径,正是 ERC20 诞生的缩影——你今天在 MetaMask 里点下的每一次 "Approve",走的都是这条 2014 年就铺好的路。
五、新手实践:如何本地复现 approve/transferFrom 全流程
- 克隆仓库
git clone https://gitcode.com/gh_mirrors/et/etherex- 安装依赖并运行测试(需要 pyethereum 测试框架)
pip install -r dev_requirements.txt py.test -vvrs- 推荐阅读的测试用例,它们就是标准 API 行为的"活文档":
- 授权→充值→额度清零的完整断言:test_deposit_to_exchange
- 连续两次 approve 的额度覆盖行为:test_approve_twice_then_transfer
跑通这些测试,你就亲手验证了一遍"标准代币 API 的起源"。
六、结语:五个小方法,定义了一个时代的代币标准
从 contracts/etx.se 的 80 行代码,到今天数以万计的 ERC20 代币,接口几乎没有变过:approve授权、transferFrom代转、allowance查额度、transfer直转、balanceOf查余额。EtherEx 的价值,正是最早用真实去中心化交易所证明:一套简洁的标准代币 API,足以让资产在无人托管的链上安全流转。读懂它,你就读懂了 ERC20 的地基。
【免费下载链接】etherexEtherEx is an open source, fully transparent, next generation decentralized exchange built on Ethereum.项目地址: https://gitcode.com/gh_mirrors/et/etherex
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考