Remix EVM中NFT质押合约unstake函数交易回滚问题求助
问题描述
- 合约组件:包含Energy(ERC20)、Fuel(ERC721)、Generator(质押合约)三类合约,基于Remix EVM测试
- 正常功能:质押、代币转移操作均能正常执行
- 异常现象:调用
unstake函数时,交易因require条件不满足被回滚;但单独调用该require内的验证函数时,返回结果为true - 测试流程:部署Fuel和Energy合约 → 传入两者地址部署Generator合约 → 在Fuel合约中给Generator地址授权
approveForAll→ 铸造NFT并完成质押 → 调用unstake触发异常
排查建议与解决方案
- 检查
unstake函数内的条件执行顺序
确认require条件是否在函数执行过程中被提前修改的状态变量影响。比如是否在验证前就更新了质押状态、NFT归属等变量,导致实际验证时条件不成立,而单独调用验证函数时状态变量未被修改,结果为true。 - 确保调用上下文一致
单独验证require条件时,必须使用和调用unstake时相同的msg.sender地址。如果验证时用的是合约部署者,而实际unstake调用用的是NFT持有者地址,就会出现结果差异。 - 排查状态变量读写顺序
查看unstake函数是否存在先执行状态修改(比如调用transferFrom转移NFT)再做require验证的情况,这种顺序会导致验证时的状态已经和质押时不一致。 - 添加日志调试
在unstake函数内添加事件日志,输出require条件涉及的关键变量值,对比单独验证时的数值找差异。示例代码:
在Remix的交易日志中查看输出值,确认哪里不符合预期。event DebugUnstake(address caller, address currentStaker, bool stakeStatus); function unstake(uint256 tokenId) external { emit DebugUnstake(msg.sender, stakerOf[tokenId], isStaked(tokenId)); // 原函数逻辑 } - 验证授权有效性
调用Fuel合约的isApprovedForAll函数,传入用户地址和Generator合约地址,确认approveForAll的授权是否有效且未被撤销。 - 检查质押记录存储逻辑
确认质押函数是否正确将stakerOf[tokenId]等状态变量设置为质押者地址,unstake函数是否在require验证前就错误清空了这些记录。
内容的提问来源于stack exchange,提问作者yieniggu
相关产品推荐
相关产品推荐

