At a glance
- What the chain runs
- Not your source code but compiled bytecode for the Ethereum Virtual Machine. The language is a human convenience on top
- The default
- Solidity, a C and JavaScript-flavoured language that most contracts, tools, and audits are built around
- The alternative
- Vyper, a smaller, Python-flavoured language that trades features for readability and safety
- The low level
- Yul and inline assembly, used in small doses for optimisation and tricks the high-level language will not express
- Other chains
- Rust on Solana and NEAR, Move on Aptos and Sui. Different syntax, same core idea of programs holding state
The chain runs bytecode, not source
Ethereum does not understand Solidity, or any human-readable language. It runs the Ethereum Virtual Machine, a simple processor that executes low-level instructions called opcodes. A programming language is a comfortable way to write those instructions; a compiler turns your source into the bytecode that actually gets deployed. This matters for two reasons: any language that compiles to EVM bytecode works on Ethereum, and what an auditor ultimately reasons about is the compiled behaviour, not the pretty source.
Solidity, the default
The overwhelming majority of Ethereum contracts are written in Solidity. Its syntax borrows from C and JavaScript, so it feels familiar, and it has the deepest ecosystem: the most libraries, the most tooling, the most auditors, and the most example code to learn from. If you read one language in this space, read this one; every other guide in this section uses it.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Greeter {
string public greeting = "gm";
function setGreeting(string calldata g) external {
greeting = g;
}
}
Vyper, Yul, and assembly
Vyper is the notable alternative on Ethereum. It looks like Python and is deliberately minimal: it leaves out features such as inheritance and function overloading on the theory that fewer moving parts means fewer places to hide a bug. Some security-focused projects prefer it for exactly that reason. The same contract above, in Vyper, reads like this.
# the same idea, Python-flavoured
greeting: public(String[32])
@external
def set_greeting(g: String[32]):
self.greeting = g
Below both sits Yul, an intermediate language, and inline assembly, which lets a Solidity author drop down to raw EVM opcodes inside a function. These are used sparingly, to squeeze out gas or to do something the high-level language forbids. They are also where subtle bugs love to live, because the safety checks the compiler normally adds are exactly what you are stepping around.
Beyond Ethereum
Other blockchains run different virtual machines and so use different languages. Solana and NEAR contracts are commonly written in Rust. Aptos and Sui use Move, a language designed around safely representing digital assets so they cannot be accidentally copied or lost. The syntax and the tooling differ, but the mental model carries over cleanly: a program deployed on-chain, holding state, called by transactions, spending a fee to run. Learn the pattern once and each new chain is mostly a change of dialect.
The short version. The chain executes EVM bytecode, and a language plus a compiler is how humans produce it, so any language that compiles down will run. Solidity is the default and the one to learn first, thanks to its ecosystem. Vyper is the leaner, Python-like alternative, and Yul and inline assembly are the low-level escape hatch used in careful doses. Other chains use Rust or Move, with different syntax but the same underlying idea of programs that hold state and run on-chain.
References & further reading
- Solidity documentation, The Solidity language. The reference for the dominant language.
- Vyper documentation, The Vyper language. The Python-flavoured, minimal alternative.
- Ethereum community, The Ethereum Virtual Machine. What actually executes on-chain.
- Move documentation, The Move language. Assets as a first-class idea on other chains.