Node.js环境下solc v0.8.15编译Solidity合约失败,求解决及保存输出
Solidity合约编译失败问题排查与解决
问题背景
尝试使用solc编译一个用于实现两账户间转账的中间人合约,但编译失败,同时需要将编译输出保存至文件。
合约代码
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.15; contract basic { modifier onlyOwner { require(msg.sender == owner); _; } address public owner; address public peer; address public lastSender; int public lastAmaunt; constructor(address p2){ owner=msg.sender; peer=p2; } // 查看合约余额 function getTotalBalance () public view returns (uint){ return address(this).balance; } // 仅合约所有者可从合约转出资金 function sentMoneyto (uint to,uint256 _value) public onlyOwner{ if(to==1){ (payable(peer)).transfer(_value); }else{ (payable(owner)).transfer(_value); } } // 接收任意地址转入的资金 function getMoneyFrom() public payable{ lastSender = msg.sender; lastAmaunt = int(msg.value); } function cangePeer(address newPeer) public onlyOwner{ peer=newPeer; } }
编译脚本代码
const path = require('path'); const fs = require('fs'); const solc = require('solc'); const inboxPath = path.resolve(__dirname, 'contracts', 'Inbox.sol'); const source = fs.readFileSync(inboxPath, 'utf8'); const input = { language: 'Solidity', sources: { 'Inbox.sol': { content: source, }, }, settings: { outputSelection: { '*': { '*': ['*'], }, }, }, }; compilesFiles = JSON.parse(solc.compile(JSON.stringify(input))).contracts[ 'Inbox.sol' ].Inbox; console.log(compilesFiles);
核心错误分析与修复
编译失败的核心原因是合约名称不匹配:你的合约定义为contract basic,但编译脚本中尝试读取.contracts['Inbox.sol'].Inbox,这里的Inbox是错误的合约名称,需替换为实际合约名basic。
同时,脚本缺少错误捕获逻辑,无法直观看到编译报错信息。以下是修复后的完整编译脚本:
const path = require('path'); const fs = require('fs'); const solc = require('solc'); const contractPath = path.resolve(__dirname, 'contracts', 'Inbox.sol'); const source = fs.readFileSync(contractPath, 'utf8'); const input = { language: 'Solidity', sources: { 'Inbox.sol': { content: source, }, }, settings: { outputSelection: { '*': { '*': ['*'], }, }, }, }; // 解析编译结果并检查错误 const compileResult = JSON.parse(solc.compile(JSON.stringify(input))); // 输出编译错误(如果有) if (compileResult.errors) { compileResult.errors.forEach(err => { console.error(err.formattedMessage); }); process.exit(1); } // 读取正确的合约实例(合约名为basic) const compiledContract = compileResult.contracts['Inbox.sol'].basic; // 将编译结果保存到文件 const outputPath = path.resolve(__dirname, 'compiled-contract.json'); fs.writeFileSync(outputPath, JSON.stringify(compiledContract, null, 2)); console.log('合约编译成功,结果已保存至:', outputPath);
额外优化建议
- 修正合约内拼写错误:
sentMoneyto改为sendMoneyTo、cangePeer改为changePeer、lastAmaunt改为lastAmount(规范命名提升可读性) - 确保solc版本与合约pragma声明匹配:合约使用
^0.8.15,安装对应版本solc:npm install solc@0.8.15 - 若合约文件名不为
Inbox.sol,需同步修改脚本中的路径和sources内的键名
内容的提问来源于stack exchange,提问作者Eyal Itzhak
相关产品推荐
相关产品推荐

