Smart Contract Language Comparison: Solidity vs. Cadence vs. Move
When starting a new web3 project, it’s important to make the right choices about the blockchain and smart contract language
Join the DZone community and get the full member experience.
Join For FreeWhen starting a new web3 project, it’s important to make the right choices about the blockchain and smart contract language. These choices can significantly impact the overall success of your project as well as your success as a developer.
In this article, we'll compare three popular smart contract programming languages:
- Solidity: used in Ethereum and other EVM-based platforms
- Cadence: used in the Flow blockchain
- Move: used in the Sui/Aptos blockchain
We'll explain the concepts and characteristics of each language in simple terms, making it easier for beginners to understand. Let’s dive in.
Solidity: The Foundation of Ethereum Smart Contracts
Solidity is a high-level, object-oriented language used to build smart contracts in platforms like Ethereum. Initially, Solidity aimed to be user-friendly, attracting developers by resembling JavaScript and simplifying learning. While it still values user-friendliness, its focus has shifted to enhancing security.
Some Solidity features include:
- Syntax and simplicity: Solidity uses clear, explicit code with a syntax similar to JavaScript, prioritizing ease of understanding for developers.
- Security focus: Solidity emphasizes secure coding practices and highlights risky constructs like gas usage.
- Statically typed: The language enforces data type declarations for variables and functions.
- Inheritance and libraries: Solidity supports features like inheritance, libraries, and complex user-defined types.
Cadence: Empowering Digital Assets on Flow
Cadence is designed by Flow, a blockchain known for crypto games and NFT projects. It ensures secure, clear, and approachable smart contract development.
Some Cadence features include:
- Type safety: The language enforces strict type-checking to prevent common errors.
- Resource-oriented programming: Resources are unique types that can only move between accounts. They can’t be copied or discarded. If a function fails to store a Resource obtained from an account in the function scope during development, then semantic checks will show an error. The run-time enforces the same rules in terms of allowed operations. Contract functions that don’t handle Resources properly in scope before exiting will stop.
These Resource features make them perfect for representing both fungible and non-fungible tokens. Ownership is tracked according to where they are stored, and the assets can’t be duplicated or lost since the language enforces correctness.
- Capability-based security: Using Capabilities allows you to let others access your stored items remotely. If one person wants to access another person's stored items, the first person needs permission, called a Capability.
There are two types of Capabilities: public and private. If someone wants to allow everyone to access their items, they can share a public Capability. For example, an account can use a public Capability to accept tokens from anyone. On the other hand, someone can give private Capabilities to certain people, allowing them to access only certain features. For example, in a project with unique digital items, the project owner might grant an "administrator Capability" that lets those users create new items.
- Built-in pre- and post-conditions: Functions have predefined conditions for safer execution.
- Optimized for digital assets: Cadence's focus on resource-oriented programming makes it ideal for managing digital assets like NFTs.
- Freedom from msg.sender: To grasp the importance of these new ideas, let's take a quick look at some history. In 2018, the Dapper Labs team began working on Cadence as a new programming language. They faced challenges with Solidity because of its limitations. The main frustration in building decentralized apps came from the way contracts were accessed using addresses, making it difficult to combine contracts.
Composability in Web3
Now, imagine contracts as Lego building blocks. Composability in Web3 means one contract can be used as a foundation for others, adding their features together.
For instance, if a contract records game results on a blockchain, another contract can be built to show the best players. Another one could go even further and use past game results to predict future game odds for betting. But here's the catch: Because of how Solidity works, contracts can only talk to one another if the first contract has permission to access the second one, even if users can access both.
In Solidity, who can do what is controlled by protected functions in contracts? This means contracts know and check who is trying to access their protected areas.
Cadence changes how access works. Instead of using the old way where contracts need permission, it uses something called "Capabilities." When you have a Capability, you can use it to get to a protected item such as a function or resource. This means the contract no longer has to define who's allowed access. You can only get to the protected item if you have a Capability, which you can use with borrow()
. So, the old msg.sender
way isn't needed anymore!
The effects of composability are important. When contracts don't need to know beforehand who they're interacting with, users can easily interact with multiple contracts and their functions during a transaction if they have the right permissions (Capabilities). This also allows contracts to interact with one another directly without needing special permissions or preparations. The only condition is that the calling contract must have the required Capabilities.
Move: Safeguarding Digital Assets on Sui/Aptos
Move, used in the Sui/Aptos blockchain, addresses challenges posed by established languages like Solidity. It ensures scarcity and access control for digital assets.
Move's features include:
- Preventing double-spending: Move prevents the creation or use of assets more than once, ensuring robust blockchain applications.
- Ownership and rights control: Developers have precise control over ownership and associated rights.
- Module structure: In Move, a smart contract is called a module, emphasizing modularity and organization.
- Bytecode verifier: Move employs static analysis to reject invalid bytecode, enhancing security.
- Standard library: Move includes a standard library for common transaction scripts.
Creating Smart Contracts
Let's illustrate the differences by comparing a simple smart contract that increments a value in Cadence, Solidity, and Move.
Solidity Example
In Solidity, creating a contract that increments a value involves defining a contract, specifying the count variable, and creating functions to manipulate it. It uses explicit syntax for variable visibility and function declarations.
// SPDC-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Counter {
uint public count;
// function to get the current count
function get() public view returns (uint) {
return count;
}
// function to increment count by 1
function inc() public {
count += 1;
}
// function to decrement count by 1
function dec() public {
count -=1;
}
}
Cadence Example
Cadence's approach to incrementing a value is similar but emphasizes clarity. It utilizes a resource-oriented structure and straightforward syntax, making it easier for developers to create and manage digital assets.
pub contract Counter {
pub var count: Int
// function to increment count by 1
pub fun increment() {
self.count = self.count +1
}
// function to decrement count by 1
pub fun decrement() {
self.count = self.count – 1
}
pub fun get(): Int {
return self.count
}
init() {
self.count = 0
}
}
Solidity Versus Cadence Syntax Differences
In Solidity, the visibility keyword comes before or after variable/function names, whereas Cadence consistently follows the visibility-type-name sequence.
Scalability and Upgradability
Flow's network boasts higher transaction throughput than Ethereum, making Cadence more scalable. Additionally, Flow's support for contract updates enhances development.
Move Example
Move introduces new concepts like modules, resources, and ownership control. A Move module creates an Incrementer resource, requiring the owner's signature for operations.
module incrementer_addr::increment {
use aptos_framework::account;
use std::signer;
struct Incrementer has key {
count: u64,
}
public entry fun increment(account: &signer) acquires Incrementer {
let signer_address = signer::address_of(account);
let c_ref = &mut borrow_global_mut<Incrementer>(signer_address).count;
*c_ref = *c_ref +1
}
public entry fun create_incrementer(account: &signer){
let incrementer = Incrementer {
count: 0
};
move_to(account, incrementer);
}
}
Composite Types and Turing Completeness
All three languages support composite types, allowing complex types from simpler ones. All are Turing complete, meaning they can handle any computation given enough resources.
Resource-Oriented Versus Object-Oriented
While Solidity and Move require compilation, Cadence is interpreted. Cadence and Move employ a resource-oriented approach, securing digital ownership in one location.
Conclusion: Choosing the Right Programming Language
When selecting a programming language like Solidity, Cadence, or Move, consider the needs of your project.
- Solidity: Solidity is commonly used, but it might not be very easy to work with, and there could be security problems.
- Cadence: Mainly used for digital assets, Cadence is a newer language that focuses on security, is easy to understand, and provides developers with a superior experience.
- Move: Move is based on Rust, a more complex language. Rust can be more difficult to learn and understand. Move is a new language, and it doesn't have many tools, resources, or a big community. Languages that are interpreted, like Move, are usually slower than languages that are turned into computer code before running. At the time of this writing, no major blockchain uses Move, so it can't work with multiple blockchains.
Ultimately, your choice will impact your project's success, so make an informed decision and enjoy your journey as a web3 developer!
Published at DZone with permission of Michael Bogan. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments