If you want to build Web3 apps, the good news is that you have a lot of different blockchains and Web3 programming languages to choose from. In this article, we compare two popular Web3 programming languages—Clarity and Solidity—so you can make an informed decision on whether you want to build smart contracts on Bitcoin or on Ethereum respectively.
Clarity vs. Solidity: An Introduction
There are no Web3 applications without smart contracts—blockchain programs designed to run autonomously when predefined events or actions occur.
Blockchains differ in a number of respects, from which is the most decentralized and secure (Bitcoin) to which has the larger number of Web3 application users (Ethereum). But they also differ in the programming languages that developers create smart contract applications with.
How different can these languages be, you ask? Check out a workshop on that very subject from our Developer Advocate Max Efremov or read on below. Let’s get into it.
What Is Clarity?
Clarity is the programming language for creating smart contracts and dApps (decentralized applications) in the Bitcoin Web3 ecosystem. It was designed to make the handling of assets on a blockchain as safe, secure, and predictable as possible while also empowering developers to build the next generation of blockchain applications. It was created 6 years after Solidity, and incorporated many lessons learned in those early years of dApp development, namely the importance of secure, predictable smart contracts.
DApps written in Clarity are published on Stacks, the programming layer for Bitcoin. Bitcoin has limited scripting functionality by design, whereas Stacks is a fully expressive layer-1 blockchain capable of DeFi, NFTs, apps, smart contracts, and more. While it is a separate blockchain, Stacks natively integrates with Bitcoin through its unique consensus mechanism, so it inherits Bitcoin’s security, capital, and stability. Check out this overview of Bitcoin smart contracts if you want to learn more about the relationship between Bitcoin and Stacks.
Clarity was developed and is maintained by a multidisciplinary collaboration of engineers and scientists from the Stacks foundation, Hiro, Algorand, computer scientists at Princeton and Stanford, and others.
What Is Solidity?
Solidity was the first-ever smart contract programming language, and today it is the most widely used language in Web3. Solidity is the language for creating dApps on the Ethereum blockchain, and developers can also use it on any blockchain compatible with the Ethereum Virtual Machine (EVM), of which there are several.
Solidity was initially proposed by Ethereum co-founder Gavin Wood before it was fully developed by the Ethereum Core developers and what later became the Solidity team, led by Christian Reitwiessner.
Solidity gained popularity through its first-mover advantage as the first language to let developers build dApps, and its adoption accelerated during the 2017 ICO rush. Solidity has built a solid reputation as a programming language for building all kinds of decentralized applications, and today Solidity is the most popular Web3 language, with more than 4,000 monthly active developers using it on the Ethereum blockchain alone.
Building With Clarity vs. Building With Solidity
On one hand, you have Solidity, the most popular language in Web3 today. It has a strong developer community and robust documentation. The language is also compatible with a number of different blockchains, thanks to newer Web3 entrants building off Ethereum’s foundation.
On the other hand, you have Clarity, a much newer language that learned from Solidity’s flaws. Clarity takes a fundamentally different approach with its design and prioritizes security and predictability, and Clarity contracts settle on the Bitcoin blockchain itself—the most secure and decentralized blockchain in use today. Clarity was created to answer the question: How can a language empower developers to write the most secure and predictable smart contracts, given that these programs will be handling billions of dollars of real-world financial assets?
So how do these two languages stack up? Let’s take a look at the high-level similarities and differences between these two languages:
Clarity vs. Solidity: Security
Smart contracts manage billions of dollars in value—as much as $97 billion in November 2021— in DeFi apps on Ethereum alone. The open source nature of blockchain applications combined with the valuable assets they manage mean they are highly attractive targets for hackers.
Solidity, the pioneering smart contract language, came with several security blindspots that have since been exploited—the most infamous being the DAO hack in which 3.6 million ETH were stolen and the entire Ethereum chain state was reversed in a hard fork. However, the hacks did not stop, as Rekt’s leaderboard shows (the largest hack coming in 2022, worth over $600 million).
The staggering values these blockchain programs handle call for predictability and guarantees in execution.
Solidity is Turing complete, a technical term in computer science which describes a system that can theoretically solve any computation problem. More practically, it means Solidity is capable of things like executing infinite loops and conditional jumps.
This has important security ramifications because it means developers cannot predict all of the potential execution paths their code will take. If you can’t predict how your code will behave, that introduces new attack vectors and new bug possibilities that you didn’t anticipate during testing because you fundamentally cannot test for them.
Clarity, in contrast, is Turing incomplete. It is decidable. While theoretically this means it may be possible to build certain functionalities in Solidity that you can’t in Clarity, practically we have found this not to be the case.
Being decidable also comes with important benefits. Decidability means that developers can statically explore and analyze all outcomes of their code, and this has several ramifications:
- It is easier to debug your code when you can reason as to how the code will behave and analyze all of the possible execution outcomes.
- Certain classes of hacks and exploits are fundamentally impossible, such as reentrancy attacks
- You can predict contract termination as well as runtime costs. When you prompt users to execute a transaction, you can provide them with a precise gas and cost estimate, which you cannot do with the same degree of accuracy in Ethereum.
The Ethereum community has worked hard to empower developers to write secure vulnerabilities (for instance, there are smart contract security guidelines and dossiers on known attacks and vulnerabilities), but despite that work, those security concerns still exist because Solidity allows them. Clarity simply removes a lot of those vulnerabilities altogether.
To Compile, or Not to Compile
Clarity is an interpreted language and does not use a compiler. This means that the smart contract code on the blockchain is published publicly in a human-readable format (What You See Is What You Get). This has several benefits:
- It avoids any risk of compiler bugs, i.e. the process by which human-readable code is translated into machine code.
- It makes it easier for any developer or user to verify and validate the source code of the smart contract.
- It makes it easier for developers to learn from each other and boosts the overall composability of the ecosystem (developers can take the code of a smart contract, or part of it, and reuse it in a new application).
Clarity vs. Solidity: Syntax and Design Principles
At a high level, Clarity was designed with the principles of increased security, predictability, and transparency—principles chosen as a result of the lessons learned after the first 6 years of smart contract applications.
Let’s take a closer look at the two languages to see how those decisions play out.
Clarity is a functional programming language with syntactic similarities to LISP-like languages. Clarity requires precision and explicit composition. There is no inheritance, and developers must spell out what exactly the code should do. This brings the benefit of predictability and eases the auditing process. No cross-referencing inherited behavior from a 3rd-party library, which inherits behavior from a different 3rd-party library.
In the code examples provided below, the smart contract is a simple one that initializes a `counter` variable, has a “read” function, and allows users to increment and decrement.
An important differentiator between Clarity and Solidity is that Clarity offers post-conditions. Post-conditions protect users from hacks and bug exploits by ensuring that certain preset conditions are met before the finalization of a transaction.
If those conditions are not met, then the transaction aborts. For example, a post-condition could be setting a minimum or maximum value on a transfer (e.g. this transaction will transfer no more than 50 STX from the user’s wallet, or the transaction will abort), or ensuring that an NFT from a particular collection is transferred to your account. Post-conditions are human-readable ways for users to see the “terms” of the contract they are executing.
Solidity doesn’t offer post conditions, and so this specific type of user protection doesn't exist. Learn more about post-conditions here.
Reentrancy happens when a smart contract allows external contract calls to occur before the complete execution of the initial call. For example, Contract A calls into Contract B and is waiting for some condition to be met before updating its state, while Contract B calls back into Contract A (to, for instance, recursively withdraw or drain funds).
If you aren’t very careful with your contract design, reentrancy can make your code do things you never planned for, whether a bug or an exploit by a malicious actor. Solidity allows reentrancy and recently added an opt-in `noReentracy` guard that developers may or may not use, but the responsibility is on the developer. Clarity doesn’t allow for reentrancy at all.
In smart contracts, there are several types of permissions when it comes to functions: Private, Read-only, or Public. Private functions can only be called by the current contract; read-only functions can be called externally (but cannot change the chain state); and public functions can be called externally by another principal (i.e. another user or smart contract).
Solidity functions are public by default, which means that any external contract can call into them. Clarity functions, on the other hand, are private by default, and developers must explicitly state that any given function is public. This again imposes an intentional opt-out protection on developers, warding off less secure contract design.
Clarity vs. Solidity: Developer Ecosystem
We’ve talked about the differences between the two languages, but what kind of resources and support can you expect to find in each ecosystem as you learn a new programming language?
The Ethereum ecosystem has a large developer community in which 4,000+ developers are actively building hundreds of different decentralized projects using Solidity. 20% of all new Web3 developers join the Ethereum ecosystem. Other blockchains such as Cosmos, Fantom, Binance Smart Chain, and Avalanche are all Solidity-compatible, and developers have resources and support from those communities too.
The Bitcoin ecosystem has, by comparison, fewer developers, with 680 monthly active developers of its own. But that number is growing. A sizable fraction of Web3 developers build on top of Bitcoin thanks to projects such as Stacks, which is the largest and fastest-growing Web3 project on Bitcoin and has 120+ monthly active developers of its own as of 2022.
Dev Tooling and Resources
The large developer community in Ethereum provides you with access to a large library of developer resources for learning Solidity, as well as a wide variety of tooling, such as Hardhat, Truffle, Remix, and more. The ecosystem also offers a number of grant programs and with over $30 billion invested by VCs in Web3 in 2021, there is a lot of funding going around, whether in Ethereum or Bitcoin or a different ecosystem altogether.
If you choose to learn Clarity, the Clarity Language resource hub provides you with a compendium of tutorials, templates, free cohort-based learning groups you can join, and jobs for Clarity developers. Web3 developers that choose to learn Clarity will find a rich library of developer tooling from Hiro, which creates tools for building decentralized applications for Bitcoin, and they can turn to Stacks Grants for early funding.
Which Web3 Programming Language Offers More Opportunities?
Both the Bitcoin and Ethereum ecosystems are leading blockchain ecosystems, each with different pros and cons. In terms of smart contract programming languages, Solidity comes with a robust ecosystem of resources and community support, benefits that come with being the oldest smart contract programming language.
Clarity is a language optimized for secure and predictable applications. While much newer, in many ways, Clarity is better suited for the business of smart contracts.
Ultimately, the Web3 programming language you choose to learn is dependent on which blockchain you want to build on— a holistic decision, with many different factors, such as users, market shares, and funding. Now that you’ve learned about programming languages, are you ready to learn about the different ecosystems more broadly? Download our free guide.