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

Solidity合约require校验Node部署未生效:与Remix表现不一致

解决Lottery合约enter函数校验在Node部署脚本中未生效的问题

你搞混了合约部署和调用enter函数这两个场景的value传递逻辑:

  • 你在部署脚本的send()里添加的value,是发给合约构造函数的,但你的合约构造函数完全没有对msg.value做校验,所以不管传多少都不会触发回滚。
  • enter函数里的require(msg.value > 0.001 ether)校验,只有在主动调用enter函数时才会生效,和合约部署操作没有任何关系。

修正后的脚本示例

先正常部署合约,再调用enter函数测试校验逻辑:

// 修正后的deploy.js
const HDWalletProvider = require('@truffle/hdwallet-provider');
const { Web3 } = require('web3');
const { abi, evm } = require('./compile');

const provider = new HDWalletProvider('你的助记词', '你的Infura节点URL');
const web3 = new Web3(provider);

const deployAndTest = async () => {
    try {
        const accounts = await web3.eth.getAccounts();
        console.log('从账户部署合约:', accounts[0]);

        // 1. 先部署合约,构造函数不校验value,无需传递
        const contractInstance = await new web3.eth.Contract(abi)
            .deploy({ data: '0x' + evm.bytecode.object }) // 原代码多写了一个0,修正为标准0x开头字节码
            .send({ gas: '1000000', from: accounts[0] });
        
        console.log('合约部署地址:', contractInstance.options.address);

        // 2. 测试调用enter函数,传入<=0.001 ETH的value,触发预期回滚
        console.log('测试调用enter函数,传入0.001 ETH...');
        await contractInstance.methods.enter().send({
            from: accounts[0],
            value: web3.utils.toWei('0.001', 'ether'),
            gas: '1000000'
        });
    } catch (error) {
        console.log('触发预期的回滚错误:', error.message);
    } finally {
        provider.engine.stop();
    }
};

deployAndTest();

关键注意点

  1. 部署合约时的value参数作用于构造函数,你的合约构造函数无校验逻辑,所以不会触发回滚;只有调用enter函数时传递的value才会触发其内部的require校验。
  2. 原代码中data: '0x0' + evm.bytecode.object多了一个冗余的0,修正为'0x' + evm.bytecode.object避免字节码格式错误。
  3. 若传入web3.utils.toWei('0.0011', 'ether')这类大于0.001 ETH的值,就能成功调用enter函数,地址会被加入players数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:22:02