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

Solc批量编译Solidity合约遇JSON解析错误,求技术支援

Solving Multi-Contract Compilation Error with solc@0.4.25 in React

Hey there, let's fix that solc compilation issue you've been stuck on! The JSON parsing error you're seeing is almost certainly because you're not passing the correct standard JSON input format that solc@0.4.25 expects, especially when compiling multiple files. Let's break this down step by step, with code fixes and explanations of the key logic.

Why the Error Happens

solc (from v0.4 onwards) requires a structured JSON object for compilation, not just raw source code strings. Your error message says the input isn't a valid JSON object/array—this means your solc.compile call is receiving malformed input. Remix works because it automatically handles this standard JSON structure under the hood.

Step-by-Step Fix & Key Logic Explanation

Let's rewrite your compile.js with the correct approach, and explain each critical part:

1. Basic Setup & File Reading

First, we'll read all .sol files from the contracts directory, then build the standard JSON input structure.

const fs = require('fs-extra');
const solc = require('solc');
const path = require('path');

// Define paths
const contractsDir = path.resolve(__dirname, 'contracts');
const buildDir = path.resolve(__dirname, 'build');

// Clear and rebuild build directory
fs.removeSync(buildDir);
fs.ensureDirSync(buildDir);

// Read all .sol files
const contractFiles = fs.readdirSync(contractsDir).filter(file => file.endsWith('.sol'));

2. Build the Standard JSON Input for solc

This is the most important part. The input must be a JSON object with language, sources, and settings keys:

  • sources: Maps each contract filename to its source code
  • settings: Tells solc what outputs to generate (ABI, bytecode, etc.)
const input = {
  language: 'Solidity',
  sources: {},
  settings: {
    outputSelection: {
      '*': {
        '*': ['abi', 'evm.bytecode'] // We need these for Ethereum transactions
      }
    }
  }
};

// Populate sources with contract code
contractFiles.forEach(file => {
  const filePath = path.resolve(contractsDir, file);
  const sourceCode = fs.readFileSync(filePath, 'utf8');
  input.sources[file] = { content: sourceCode };
});

3. Run Compilation Correctly

For solc@0.4.25, you need to pass the JSON string to solc.compile, or use solc.compileStandardWrapper (which handles the JSON parsing/stringifying for you). We'll use the standard wrapper for simplicity:

// Compile the contracts
const output = JSON.parse(solc.compileStandardWrapper(JSON.stringify(input)));

4. Process Compilation Output & Write to Build Directory

Now we'll check for errors, then extract the ABI and bytecode for each valid contract, writing them to individual JSON files in build:

// Handle errors first
if (output.errors) {
  // Write errors to errors.json (for debugging)
  fs.writeFileSync(path.resolve(buildDir, 'errors.json'), JSON.stringify(output.errors, null, 2));
  
  // Check if errors are fatal
  const fatalErrors = output.errors.filter(err => err.severity === 'error');
  if (fatalErrors.length > 0) {
    console.error('Fatal compilation errors:', fatalErrors);
    process.exit(1);
  }
}

// Extract and write valid contract artifacts
for (const fileName in output.contracts) {
  for (const contractName in output.contracts[fileName]) {
    const contract = output.contracts[fileName][contractName];
    const artifactPath = path.resolve(buildDir, `${contractName}.json`);
    
    // Write ABI and bytecode to the artifact file
    fs.writeFileSync(artifactPath, JSON.stringify({
      abi: contract.abi,
      bytecode: contract.evm.bytecode.object
    }, null, 2));
    
    console.log(`Successfully compiled ${contractName} from ${fileName}`);
  }
}

Key Logic Breakdown

  • Standard JSON Input: solc requires this structure to handle dependencies, imports, and output selection consistently—this is why your previous call failed (you were likely passing raw source instead of this structured JSON).
  • solc.compileStandardWrapper: This helper function takes the JSON string input, compiles it, and returns the parsed JSON output—saving you from manual stringify/parse steps and reducing errors.
  • Output Processing: We iterate over the compiled contracts (each file can have multiple contracts), extract the ABI (for interacting with the contract) and bytecode (for deploying), then write them to individual files in build—exactly what you need for your React app's Ethereum transactions.

Verify the Fix

  1. Run your compile script again—you should see success messages for each valid contract.
  2. Check the build directory: you'll have a .json file for each contract with the ABI and bytecode.
  3. In your React app, import these JSON files to access the ABI and bytecode when setting up contract instances (e.g., with web3.js or ethers.js).

Remember, since your contracts work in Remix, this fix should resolve the compilation issue without needing to switch to Truffle.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:38:53