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

Solidity中含Fallback函数的钱包合约触发VM revert错误,原因何在?

为什么我的带Fallback函数的钱包合约触发revert错误?

你遇到的这个VM error: revert加上提示“Note: The constructor should be payable if you send value.”,问题出在合约部署阶段的转账处理,和你写的fallback函数没关系,我给你拆解清楚:

核心原因

在Solidity 0.4.x版本中,如果你没有显式定义构造函数,编译器会自动生成一个默认的无参构造函数,而这个默认构造函数是non-payable的。当你部署合约的时候,如果给合约发送了ETH,这笔转账会被交给构造函数处理,但因为构造函数不接受转账(non-payable),就会直接触发revert错误。

你写的payable fallback函数,是用来处理合约部署完成后的两种情况:

  • 调用合约中不存在的函数时
  • 直接给合约地址转账时(不是部署阶段的转账)
    所以部署时的转账根本轮不到fallback函数处理,这就是为什么你写了fallback还是报错。

解决方案

根据你的需求分两种情况处理:

情况1:部署合约时不需要转ETH

最简单的解决办法就是部署合约的时候,不要设置转账金额,直接部署即可,这样默认构造函数就能正常执行,不会触发revert。

情况2:部署时确实需要给合约转ETH

这时候你需要显式定义一个payable的构造函数,注意Solidity 0.4.x的版本差异:

  • 如果你用的是0.4.22及以上版本,可以用constructor关键字:
pragma solidity ^0.4.22;
contract MyWallet {
    struct account {
        uint balance;
        uint dailyLimit;
    }
    mapping (address =>account) _accounts;

    // 显式定义payable构造函数,处理部署时的转账
    constructor() payable public {
        // 把部署时转入的ETH存入部署者的账户
        _accounts[msg.sender].balance += msg.value;
    }

    // fallback函数处理部署后的转账
    function () payable {
        _accounts[msg.sender].balance += msg.value;
    }

    function getBalance() returns (uint){
        return _accounts[msg.sender].balance;
    }
}
  • 如果是0.4.22之前的版本,需要用和合约同名的函数作为构造函数:
pragma solidity ^0.4.0;
contract MyWallet {
    struct account {
        uint balance;
        uint dailyLimit;
    }
    mapping (address =>account) _accounts;

    // 和合约同名的payable构造函数
    function MyWallet() payable public {
        _accounts[msg.sender].balance += msg.value;
    }

    function () payable {
        _accounts[msg.sender].balance += msg.value;
    }

    function getBalance() returns (uint){
        return _accounts[msg.sender].balance;
    }
}

这样修改后,部署时的转账就能被构造函数正常接收,不会再触发revert错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:24:54