Sitemap

Beyond the EVM: A Deep Dive into Solidity vs. Compact

5 min readJan 10, 2026

--

Press enter or click to view image in full size

The dominance of the Ethereum Virtual Machine (EVM) has established Solidity as the lingua franca of blockchain development. However, as the industry matures, the limitations of “radical transparency” have become a bottleneck for enterprise adoption, compliance, and user privacy.

Compact, the language of the Midnight Network. While Solidity was built for a world where every calculation is public, Compact is engineered for a Zero-Knowledge (ZK) paradigm where execution happens off-chain, and only the verification happens on-chain.

Get Timerr’s stories in your inbox

Join Medium for free to get updates from this writer.

This article dissects the architectural, syntactic, and execution differences between these two powerful languages, marking the shift from “Code is Law” to “Proof is Law.”

1. Architectural Core: The Execution Model

Press enter or click to view image in full size

The most profound difference between Solidity and Compact lies in where the code runs and who sees the data.

Solidity: The Global State Machine

Solidity operates on a Replicated State Machine model.

  • Execution: Every node in the network must re-execute every transaction to reach consensus on the new state.
  • Data Visibility: To validate a transaction, nodes must see the inputs. Consequently, all state variables and function arguments are public by default (even private variables are visible in the raw state trie).
  • Bottleneck: Because every node does every calculation, the network moves at the speed of its single slowest validator.

Compact: The Dual-State Model

Compact operates on a Privacy-First (ZK) Model.

  • Execution (Off-Chain): When a user interacts with a Compact contract, the logic executes locally on their device (or a private worker). The network does not see the inputs; it only sees a Zero-Knowledge Proof (ZKP) asserting that the state transition rules were followed.
  • Data Visibility (Dual-State): Compact splits state into two categories:
  1. Ledger State: Public data stored on the blockchain (e.g., a total vote count).
  2. Witness State: Private data known only to the user (e.g., who voted and what they voted for).
  • Verification (On-Chain): The nodes simply verify the ZK proof. This is computationally cheaper than re-running the logic, allowing for privacy without sacrificing integrity.

2. Syntax & Developer Experience (DX)

Solidity: The C++ / JavaScript Hybrid

Solidity feels familiar to C++ or Java developers but includes blockchain-specific primitives.

  • Ecosystem: It benefits from a decade of tooling maturity — Hardhat, Foundry, and Remix make testing and deployment seamless.
  • Key Concepts: Concepts like msg.sender (caller identity), payable (handling value), and mapping are intrinsic to the language.

Compact: TypeScript Roots

Compact is designed to lower the barrier to entry for Web2 developers by adopting a TypeScript-based syntax.

  • Philosophy: It abstracts the complexity of ZK circuits. You don’t write R1CS or arithmetic gates manually; you write high-level logic, and the compiler generates the proof circuits.

Key Concepts:

  • Circuits: Functions that define the rules of a state transition.
  • Witnesses: Variables that remain private to the prover.
  • Exports: Public interfaces callable by other contracts or wallets.

3. Code Comparison: The “Private Voting” Scenario

To illustrate the difference, let’s look at how both languages handle a simple voting mechanism. The goal: A user casts a vote, and the global tally updates.

Solidity Approach (Transparent)

In Solidity, to prevent double-voting, we must store who voted. This makes the voter’s identity and choice effectively public.

// Solidity: Everyone can see who voted
contract PublicVoting {
mapping(address => bool) public hasVoted;
uint256 public yesCount;

function vote(bool _vote) external {
// 1. Check if user already voted (Public check)
require(!hasVoted[msg.sender], "Already voted");

// 2. Record that they voted (Public state change)
hasVoted[msg.sender] = true;

// 3. Update tally
if (_vote) {
yesCount++;
}
}
}

Compact Approach (Private)

In Compact, we use a Nullifier pattern (often utilizing a Coin/UTXO model) to prevent double-voting without revealing identity, and we treat the vote itself as a witness (private input).

// Compact: The vote is a private witness
export circuit vote(
// 'witness' means this input is never revealed to the network
vote_choice: witness<boolean>,
// The coin represents the user's right to vote (a private token)
voting_coin: witness<Coin>
) {
// 1. Enforce that the coin is valid
// The network verifies the proof of ownership, not the coin itself
verify(voting_coin.is_valid());

// 2. "Spend" the coin to prevent double voting
// This creates a nullifier on the public ledger without linking to identity
consume(voting_coin);

// 3. Update public tally based on private input
// The network sees the count go up, but not which input caused it
if (vote_choice) {
ledger.yes_count.increment();
}
}

Note: In the Compact example, the network validates that yes_count incremented correctly according to the rules, but no observer can link the transaction to the specific voting_coin owner or see the vote_choice boolean.

4. Concurrency & Scalability

Solidity: Sequential & Blocking

Solidity uses the Account Model. Transactions modify global state directly. To prevent race conditions (e.g., two people spending the same balance), transactions must be ordered and executed sequentially within a block.

  • Impact: This limits parallel processing. If one contract is congested (e.g., a popular NFT mint), it can spike gas fees for the entire network.

Compact: Concurrent & UTXO-Based

Compact leverages a UTXO (Unspent Transaction Output) model, similar to Bitcoin or Cardano, but supercharged with ZK.

  • Impact: Transactions that touch different pieces of state (different UTXOs) can be processed concurrently.
  • Scalability: This architecture is naturally more scalable for high-throughput applications, as the state is fragmented rather than monolithic.

5. Use Cases: When to Use Which?

The choice between Solidity and Compact is not about which is “better,” but which fits the architectural requirement of the application.

Press enter or click to view image in full size

Final Thoughts

Solidity remains the gold standard for applications where public verifiability of data is the product. However, for the next wave of blockchain adoption involving sensitive financial data, enterprise logic, and personal identity, Compact offers the necessary bridge: the ability to verify rules were followed without revealing the data behind them.

--

--