- Docs
- Smart Contracts
- Comparison with ethereum
Comparison with solidity contracts
CosmWasm and Ethereum's Solidity follow different paradigms for deploying and executing smart contracts. CosmWasm introduces a more modular and secure approach by breaking down the process into three distinct phases:
- Upload Code: In this step, you upload the optimized WebAssembly (Wasm) code to the blockchain. Unlike Solidity on Ethereum, you don't need to consider the state or contract address at this stage. This step is solely about getting the code onto the chain.
- Instantiate Contract: This phase involves creating an instance of the uploaded Wasm code. During instantiation, you define the initial state and generate a unique contract address. This separation allows for multiple instances of the same codebase with different configurations.
- Execute Contract: Once the contract is instantiated and live, it can process various calls depending on its design. Execution involves interacting with the contract's functions, potentially modifying its state or triggering further actions.
Similarities with Ethereum:
- Gas Requirements: Both CosmWasm and Solidity require gas for contract instantiation and execution. This is to cover the computational resources consumed by the operations.
- Token Transfers: In both platforms, the signer can send tokens to the contract alongside the transaction message during instantiation or execution.
Differences from Ethereum:
- Contract Execution: In CosmWasm, sending tokens directly to a contract (e.g., via SendMsg) does not trigger the contract code automatically. Contract execution must be explicitly requested. This design reduces the attack surface, unlike in Ethereum, where sending tokens to a contract triggers the fallback function, which can lead to vulnerabilities like reentrancy attacks.
Smart contract instantiation
In CosmWasm, uploading the contract code and instantiating the contract are treated as separate events, unlike in Ethereum, where they occur simultaneously. This separation allows multiple instances of a single contract template to exist, each with its own configuration.
Example: vesting contracts
A vesting contract in CosmWasm might be used to lock tokens and release them gradually over time. By varying the parameters during instantiation, you can create multiple instances of the same contract template, each tailored to different use cases:
// VestingContract.wasm{ "vesting_start_time": "1616678400", // Unix timestamp for vesting start time "vesting_duration": "31536000", // Vesting duration in seconds (1 year) "total_tokens": "1000000", // Total tokens to be vested "beneficiary_address": "archway1xyz" // Address of the beneficiary}
- Instance A: Vesting 1,000,000 tokens for Employee A over three years.
- Instance B: Vesting 500,000 tokens for Employee B over two years.
- Instance C: Vesting 250,000 tokens for Advisor A over one year with a six-month cliff.
This approach allows developers to create flexible and reusable contract templates that can be instantiated with different parameters to meet various requirements.
Avoiding reentrancy attacks
Reentrancy attacks are inherently avoided by CosmWasm's design. Reentrancy is a significant issue in Ethereum, responsible for many high-profile exploits. In Ethereum, a contract (Contract A) may call another contract (Contract B), which could call back into Contract A before its initial execution is complete. This can lead to vulnerabilities, such as double-spending, if not handled carefully.
In contrast, CosmWasm prevents such scenarios by disallowing direct contract-to-contract calls during execution. Instead, contracts in CosmWasm return a list of messages to be executed after the contract's execution is complete. This ensures that contracts finish their current operation before any other contract is called, thereby eliminating the risk of reentrancy. If any of the future messages fail, the entire transaction is reverted, ensuring atomic composition.
Resource limits
Smart contracts must operate within certain resource limits to prevent denial-of-service (DoS) attacks. CosmWasm leverages WebAssembly's tight sandboxing to enforce these limits.
- Memory Usage: CosmWasm allocates 32MB of RAM to each Wasm VM instance by default. This memory is used for storing the contract's bytecode, stack, and heap. This limit is designed to be sufficient for most contracts while ensuring minimal impact on blockchain performance.
- CPU Usage: The Wasmer Runtime used by CosmWasm injects metering logic into the Wasm code. This metering charges gas based on the computational complexity of operations, ensuring a deterministic gas price regardless of hardware variations. The contract execution is limited by the available gas, which is consumed according to a fixed conversion rate between Wasm gas and Cosmos SDK gas.
- Disk Usage: All disk access by contracts is mediated through the KVStore, and gas is charged for reads and writes. This ensures that contracts cannot monopolize storage resources, as the Cosmos SDK enforces these gas payments.
Lessons learned from Ethereum
CosmWasm has been designed with insights gained from Ethereum’s successes and challenges. Here’s how CosmWasm addresses some of the common vulnerabilities seen in Ethereum:
- Reentrancy: CosmWasm’s actor model and message-based communication ensure that contracts cannot fall prey to reentrancy attacks. The contract execution model guarantees that no volatile state exists when a contract calls another.
- Arithmetic Under/Overflows: In CosmWasm, the Rust programming language is used, which provides built-in protections against overflows. By enabling the
overflow-checks = true
setting in the Cargo manifest, any arithmetic overflow will cause the program to abort, eliminating the risk of silent overflows. - Delegate Call: CosmWasm does not support delegate calls. Instead, modules are linked together at compile time, allowing for comprehensive testing and eliminating the risks associated with runtime delegate calls.
- Default Visibilities: CosmWasm requires developers to explicitly define entry points for contract interactions. There is no automatic exposure of functions, reducing the risk of accidentally exposing critical logic.
- Short Address/Parameter Attack: This Ethereum-specific vulnerability related to RLP encoding and stack size does not apply to CosmWasm, which uses a type-checked JSON parser for handling data.
- Unchecked CALL Return Values: In CosmWasm, contracts cannot directly call other contracts. Instead, messages are dispatched through a router, which checks the results of all messages. If any message fails, the entire transaction is rolled back, preventing inconsistent states.
- Uninitialized Storage Pointers: CosmWasm contracts explicitly load variables from storage, and Rust enforces strict rules against uninitialized variables, making storage management explicit and safe.
- Floating Points and Precision: CosmWasm, like Solidity, does not support floating-point operations due to their non-deterministic nature. However, CosmWasm allows developers to import Rust packages, such as
rust_decimal
, which provide safe and precise fixed-point arithmetic for financial calculations. - Tx.Origin Authentication: CosmWasm does not expose
tx.origin
. Instead, contracts rely onparams.message.signer
, which represents the direct caller, ensuring clear and unambiguous authentication.