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();
关键注意点
- 部署合约时的
value参数作用于构造函数,你的合约构造函数无校验逻辑,所以不会触发回滚;只有调用enter函数时传递的value才会触发其内部的require校验。 - 原代码中
data: '0x0' + evm.bytecode.object多了一个冗余的0,修正为'0x' + evm.bytecode.object避免字节码格式错误。 - 若传入
web3.utils.toWei('0.0011', 'ether')这类大于0.001 ETH的值,就能成功调用enter函数,地址会被加入players数组。
内容的提问来源于stack exchange,提问作者Alfred Schmidt
相关产品推荐
相关产品推荐

