Skip to content

VoidChain Shanghai Setup

VoidChain contract development environment setup for EVM Shanghai.

Prerequisite: VoidChain mainnet has completed its Shanghai compatibility upgrade and supports PUSH0 (0x5f) on-chain.

Use compiler version 0.8.37 throughout and explicitly pin the EVM version to shanghai.

1. Version Matrix (Must Match)

ComponentVersion / ValueNotes
Solidity compiler0.8.37+commit.f401782dThe file may be named solc-0.8.7.exe; use the --version output as the source of truth
pragmapragma solidity 0.8.37;Pin the exact version; do not use ^
EVM versionshanghaiMust be explicitly specified; do not rely on defaults
Optimizerenabled: true, runs: 200Adjust as needed
LicenseGPL-3.0Be aware of copyleft obligations; do not copy directly into closed-source components

Why the EVM Version Must Be Explicitly Pinned

The default EVM version changes with the Solidity compiler version, and toolchains use different defaults:

Compiler / ToolDefault EVM
solc 0.8.20 – 0.8.24shanghai
solc 0.8.25 – 0.8.29cancun
solc ≥ 0.8.30prague
solc 0.8.37osaka
Hardhat (for Solidity 0.8.20 onward)paris (does not follow solc)
FoundryFollows solc

VoidChain targets Shanghai. Any drift in the default version can cause the following:

  • A newer default (cancun/prague/osaka) → generates MCOPY/TLOAD/TSTORE/BLOB* → deployment fails with invalid opcode.
  • An older default (paris/london) → does not generate PUSH0, missing out on gas savings.

Conclusion: explicitly set evmVersion: "shanghai" in every toolchain.

2. Compiler Installation (Windows)

  1. Open the Releases page.
  2. Find v0.8.37 → Assets → download solc-windows.exe.
  3. Move and rename it, for example to C:\Chain00\sol\solc-837.exe.
mkdir C:\Chain00\sol
cd C:\Chain00\sol
Invoke-WebRequest -Uri "https://github.com/ethereum/solidity/releases/download/v0.8.37/solc-windows.exe" -OutFile "solc-837.exe"
.\solc-837.exe --version

Expected output:

solc, the solidity compiler commandline interface
Version: 0.8.37+commit.f401782d

Optional: add the directory to PATH.

[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Chain00\sol", "User")

Option B: Static Binary Repository (Comprehensive Versions with SHA256)

Option C: npm (Quick Verification Only)

npm install -g solc     # The command is solcjs, a JS implementation slower than the native binary

Not recommended as a production compiler.

Option D: Automatic Downloads with Hardhat / Foundry

The framework downloads the specified version into its cache. Simply specify the version in the configuration.

3. Source Code Guidelines

1. Use Consistent pragma Declarations

Update the header of every .sol file in the project to:

pragma solidity 0.8.37;

⚠️ The original pragma solidity >=0.7.0 <0.9.0; allows 0.7.x, which has no built-in overflow checks. Replace all occurrences. Updating only some files can cause compilation failures due to conflicting version constraints.

2. Do Not Introduce SafeMath

Solidity 0.8.x already provides built-in arithmetic overflow checks. Adding SafeMath is redundant and increases code size and gas usage.

3. Issues Requiring Manual Fixes After Upgrading

IssueDoes upgrading to 0.8 resolve it?
Arithmetic overflow / underflow✅ Resolved automatically
Tokens locked at the zero address via transfer(0x0)❌ Add require(_to != address(0))
Missing function authorization / overwriting shared state pointers❌ Use view, local variables, and permission checks
Array deletion without an existence check❌ Add require checks
Records consumed more than once / insufficient txid entropy❌ Fix the application logic

4. Compiler Configuration

Hardhat

// hardhat.config.js
module.exports = {
  solidity: {
    version: "0.8.37",
    settings: {
      evmVersion: "shanghai",
      optimizer: { enabled: true, runs: 200 }
    }
  },
  networks: {
    voidchain: {
      url: "https://<VoidChain RPC>",   // TODO: enter the actual RPC URL
      chainId: <chainId>,               // TODO: enter the actual chainId
      accounts: ["0x<private-key>"]
    }
  }
};
npx hardhat compile

Foundry

# foundry.toml
[profile.default]
solc_version = "0.8.37"
evm_version  = "shanghai"
optimizer    = true
optimizer_runs = 200
forge build

solc CLI (Windows PowerShell)

cd C:\Chain00\sol\dex
solc-837.exe --evm-version shanghai --optimize `
  --asm --bin --abi `
  -o C:\TChain00\sol\class `
  fullchain.sol

Parameters:

ParameterPurpose
--evm-version shanghaiRequired; pins the EVM target
--asmGenerates assembly for opcode verification
--bin / --abiGenerates bytecode and ABI
-o <dir>Writes output to a directory; stdout then contains only status messages

5. Understanding Compiler Output Files

When writing output to a directory with -o, the file extensions are:

ExtensionContents
.binDeployment bytecode (hexadecimal)
.bin-runtimeRuntime bytecode
.abiABI JSON
.evmAssembly mnemonics (the output of --asm, not .asm)

⚠️ Common misconception: --asm generates .asm files. In fact, solc uses .evm when writing to a directory specified by -o.

6. Required Opcode Checks

1. Check for Prohibited Post-Shanghai Opcodes

Select-String -Path C:\TChain00\sol\class\*.evm `
  -Pattern 'MCOPY|TLOAD|TSTORE|BLOBHASH|BLOBBASEFEE'

Expected result: no output.

Do not search only for COPY: that would also match valid instructions such as CODECOPY, EXTCODECOPY, CALLDATACOPY, and RETURNDATACOPY. Search for the full name MCOPY.

2. Confirm Shanghai Is Active (PUSH0)

Select-String -Path C:\TChain00\sol\class\*.evm -Pattern 'PUSH0' |
  Select-Object -First 3

Expected result: output confirming compilation for shanghai rather than a downgrade to paris/london.

PUSH0 is generated only when the compiler needs to push the constant 0. If the contract has no relevant operations, such as comparisons with address(0), no output may be normal. Also check the evmVersion metadata field described below.

3. Definitive Confirmation: Metadata Fields

solc-837.exe --evm-version shanghai --metadata fullchain.sol > meta.txt
Select-String -Path meta.txt -Pattern '"evmVersion":"[a-z]+"' -AllMatches |
  ForEach-Object { $_.Matches.Value } | Sort-Object -Unique

Expected output: exactly one unique line.

"evmVersion":"shanghai"

Also confirm the compiler version:

Select-String -Path meta.txt -Pattern '"version":"[0-9][^"]*"' -AllMatches |
  ForEach-Object { $_.Matches.Value } | Sort-Object -Unique

Expected: "version":"0.8.37+commit.f401782d"

7. Troubleshooting

1. findstr Finds Nothing, but the Editor Finds Matches

Cause: PowerShell's > redirection defaults to UTF-16LE (with \0 after each character), while findstr reads single bytes and fails to match.

Solution: use Select-String, which detects the encoding automatically; redirect through CMD (ANSI); or explicitly specify the encoding:

solc-837.exe --evm-version shanghai --metadata fullchain.sol |
  Out-File -Encoding utf8 meta.txt

2. asm.txt Contains Only Compiler run successful...

Cause: the command includes -o <dir>, so assembly is written to that directory and stdout contains only status messages.

Solution: to obtain a single file, remove -o and capture stdout with >:

solc-837.exe --evm-version shanghai --asm fullchain.sol > asm.txt

3. No Assembly Files Are Generated

Cause: --asm is missing. The --bin --abi options generate only bytecode and ABI.

4. Deployment Reports invalid opcode: opcode 0x5f not defined

0x5f is PUSH0. This means the compiler generated Shanghai bytecode, but the chain had not yet completed its Shanghai upgrade.

  • Before the VoidChain upgrade: downgrade to --evm-version london (or paris).
  • After the VoidChain upgrade (current): keep shanghai.

For other opcode errors, use the following downgrade table:

Opcode in ErrorNameIntroduced InDowngrade To
0x5fPUSH0Shanghaiparis
0x44PREVRANDAOParislondon
0x48BASEFEELondonberlin
0x46/0x47CHAINID/SELFBALANCEIstanbulistanbul

5. Error: unrecognised option '-Path'

Cause: the two commands in solc ... | Select-String -Path ... were pasted together and executed as one, causing solc to interpret -Path as its own argument.

Solution: run the two commands separately, pressing Enter after each; or use CMD's findstr.

6. Numbered Variants Appear, Such as BaseToken1.evm

This indicates conflicting contract names: multiple source files define contracts with the same name, or the same file is imported repeatedly through different paths.

Risk: ABI and bytecode ownership becomes ambiguous, and the wrong artifacts may be deployed. Remove duplicate imports.

7. Some .bin Files Are 0 KB

A 0 KB file indicates an abstract contract, an interface, or a pure library with no deployment bytecode.

If any of BaseToken, FullChain, Export, Import, MyChain, or MyToken is 0 KB, it has been declared abstract or has unimplemented functions. Resolve this before deployment.

Get-ChildItem C:\TChain00\sol\class\*.bin |
  Where-Object { $_.Length -eq 0 } | Select-Object Name

8. Pre-Deployment Checklist

  • Every .sol file starts with pragma solidity 0.8.37;.
  • solc --version outputs 0.8.37+commit.f401782d.
  • The evmVersion metadata value is shanghai, with no other values present.
  • No matches for MCOPY|TLOAD|TSTORE|BLOB* appear in .evm files.
  • Every .bin file intended for deployment is nonempty.
  • No duplicate contract variants with the same name exist.
  • Perform a trial deployment on VoidChain mainnet (successful local compilation does not guarantee on-chain execution).
  • Invariant tests: Σ balances == _totalSupply always holds after transfer / MapAssets / Payouts / GasPay (in 0.8, -= reverts instead of silently wrapping around).
  • Resubmit contract verification to the block explorer (the bytecode has changed, invalidating the previous verification record).

Deployed contracts cannot be upgraded in place. Bytecode changes require redeployment and state migration.

9. Quick Self-Check Script (Ready to Copy)

cd C:\Chain00\sol\dex
# 1. Version
solc-837.exe --version
# 2. Compile
solc-837.exe --evm-version shanghai --optimize --asm --bin --abi `
  -o C:\TChain00\sol\class fullchain.sol
# 3. Confirm metadata
solc-837.exe --evm-version shanghai --metadata fullchain.sol > meta.txt
Select-String -Path meta.txt -Pattern '"evmVersion":"[a-z]+"' -AllMatches |
  ForEach-Object { $_.Matches.Value } | Sort-Object -Unique
# 4. Prohibited opcodes (expect no output)
Select-String -Path C:\TChain00\sol\class\*.evm `
  -Pattern 'MCOPY|TLOAD|TSTORE|BLOBHASH|BLOBBASEFEE'
# 5. PUSH0 (expect output)
Select-String -Path C:\TChain00\sol\class\*.evm -Pattern 'PUSH0' |
  Select-Object -First 3
# 6. Check for empty bytecode
Get-ChildItem C:\TChain00\sol\class\*.bin |
  Where-Object { $_.Length -eq 0 } | Select-Object Name