BEP-20/ERC20代币如何在转账时添加税费并转入指定地址?
实现方案
你的需求完全可以实现,只需修改_transfer函数中的扣税判定逻辑即可,你当前的代码仅针对卖币(向交易对地址转账)场景做了扣税,补充普通转账和买币的判定规则即可。
核心判定逻辑说明
首先明确三类场景的判断标准:
- 买币:转账发起方为交易对地址(
sender == pairAddress),按需求设置0手续费 - 卖币:转账接收方为交易对地址(
recipient == pairAddress),且转账发起方不在免税白名单中,扣除5%手续费 - 普通转账:既不属于买币也不属于卖币的场景,且转账发起方不在免税白名单中,扣除5%手续费
修改后完整_transfer函数代码
/** * @dev 从`sender`地址向`recipient`地址转账`amount`数量的代币 * * 该内部函数功能和{transfer}等价,可用于实现自动扣手续费、销毁机制等场景 * * 会触发{Transfer}事件 * * 前置要求: * - `sender`不能是零地址 * - `recipient`不能是零地址 * - `sender`余额不能小于转账数量`amount` */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: 不能从零地址转账"); require(recipient != address(0), "ERC20: 不能向零地址转账"); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: 转账金额超过账户余额"); unchecked { _balances[sender] = senderBalance.sub(amount); } bool takeFee = true; uint256 taxFee = 0; // 免税白名单判定 if (_isExcludedFromFee[sender]) { takeFee = false; } if(takeFee){ // 买币场景:发送方是交易对地址,0手续费 if(sender == pairAddress){ taxFee = 0; } // 卖币场景:接收方是交易对地址,扣5%手续费 else if(recipient == pairAddress){ // 税率单位为万分之一,5%对应数值500 taxFee = amount.mul(500).div(10000); } // 普通转账场景,扣5%手续费 else { taxFee = amount.mul(500).div(10000); } // 手续费转入指定税费地址 if(taxFee > 0){ _balances[taxAddress] = _balances[taxAddress].add(taxFee); emit Transfer(sender, taxAddress, taxFee); amount = amount.sub(taxFee); } } _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); }
补充注意事项
- 需确保合约中已提前定义好
pairAddress(DEX交易对地址)、taxAddress(税费收款地址)、_isExcludedFromFee(免税地址映射)变量,且配套的权限控制逻辑正常,避免交易对、税费地址等核心参数被恶意篡改 - 若后续需要灵活调整税率,可把代码中的固定税率500提取为公共状态变量,通过管理员权限接口修改即可,无需重写部署合约
内容的提问来源于stack exchange,提问作者Lloyd Ramos
相关产品推荐
相关产品推荐

