You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建简单Escrow托管合约时currentState未更新且调用报错的问题求助

问题诱因
  • 核心语法错误:两处状态赋值均误用相等比较运算符==,该运算符仅返回布尔值,单独作为语句执行时无链上状态变更效果:
    • confirmPayment函数中currentState == State.AWAITING_DELIVERY;仅做相等性判断,未执行赋值操作,函数调用后状态永远停留在初始值AWAITING_PAYMENT(枚举值0)
    • confirmDelivery函数中currentState == State.COMPLETE;存在同类语法错误,即使前置状态更新成功,也不会将状态置为完成态
  • confirmDelivery调用直接回退的原因:因currentState始终为0,inState(State.AWAITING_DELIVERY)修饰符内的require判断失败,触发回退。IDE提示的“需要添加payable修饰符”为通用误导提示,该函数本身无需接收ETH,不存在payable相关问题。
  • 潜在逻辑缺陷:0.4.21版本中address.send()为低级别调用,仅返回布尔值不触发异常,若转账失败不会自动回退交易,会出现资金未转出但状态已更新的资金安全问题。
修复方案
  1. 修正两处运算符错误:将==替换为赋值运算符=,确保状态更新逻辑生效
  2. 补充send返回值校验:转账失败时直接触发回退,避免资金损失
  3. 显式标记函数可见性、声明初始状态,提升代码可读性

修复后完整代码:

pragma solidity ^0.4.21;

contract Escrow {
    
    enum State {AWAITING_PAYMENT, AWAITING_DELIVERY, COMPLETE}
    
    State public currentState;
    
    address public buyer;
    address public seller;
    
    modifier buyerOnly() { require(msg.sender == buyer); _; } 
    modifier inState(State expectedState) { require(currentState == expectedState); _; }
    
    constructor(address _buyer, address _seller) public {
        buyer = _buyer;
        seller = _seller;
        currentState = State.AWAITING_PAYMENT; // 显式声明初始状态
    }
    
    function confirmPayment() public buyerOnly inState(State.AWAITING_PAYMENT) payable {
        currentState = State.AWAITING_DELIVERY; // 修正运算符错误
    }
    
    function confirmDelivery() public buyerOnly inState(State.AWAITING_DELIVERY) {
        // 校验转账结果,失败直接回退
        require(seller.send(this.balance));
        currentState = State.COMPLETE; // 修正运算符错误
    }
}
已部署旧合约的处理方式

如果已部署的旧合约中已经存入2ETH,无需重新部署,直接使用修复后的接口ABI调用confirmPayment方法(本次调用无需再转入ETH,资金已在合约内),状态即可更新为AWAITING_DELIVERY,后续即可正常调用confirmDelivery完成全流程。


内容的提问来源于stack exchange,提问作者Clifton Aurelius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 20:36:03