Smart contracts can control large amounts of value and data while running immutable logic on a blockchain, which creates opportunities for attackers to exploit vulnerabilities. This guide offers a practical checklist for developers and teams to reduce those risks, drawing on Ethereum.org's smart contract security documentation. It focuses on access control, function visibility, and the irreversibility of deployed code.
Why smart contract security matters
Smart contracts are extremely flexible and capable of controlling large amounts of value and data, running immutable logic based on code deployed on the blockchain. This flexibility enables trustless and decentralized applications but also creates opportunities for attackers. Public blockchains like Ethereum further complicate security because deployed contract code usually cannot be changed to patch flaws, and stolen assets are extremely difficult to track and mostly irrecoverable. Although figures vary, it is estimated that the total amount of value stolen or lost due to security defects in smart contracts is easily over $1 billion. High-profile incidents include the DAO hack (3.6M ETH stolen, worth over $1B in today’s prices), the Parity multi-sig wallet hack ($30M lost to hackers), and the Parity frozen wallet issue (over $300M in ETH locked forever).
Checklist 1: Function visibility and access control
In smart contracts, functions marked public or external can be called by any externally owned accounts (EOAs) or contract accounts. Specifying public visibility is necessary if you want others to interact with your contract, but it can also expose sensitive operations. Functions marked private can only be called by functions within the smart contract, not external accounts. Giving every network participant access to contract functions can cause problems, especially if it means anyone can perform sensitive operations like minting new tokens. To prevent unauthorized use, implement secure access controls that restrict certain functions to approved entities, such as accounts responsible for managing the contract. Two common patterns are the Ownable pattern and role-based control.
- Review all public and external functions: are they intended to be callable by anyone?
- Apply access control (e.g., Ownable, role-based) to sensitive functions like minting, burning, or transferring ownership.
- Use private visibility for functions that should only be called internally.
Checklist 2: Upgradeability and immutability
Deployed contract code usually cannot be changed to patch security flaws, and assets stolen from smart contracts are extremely difficult to track and mostly irrecoverable due to immutability. This makes it crucial to invest effort in building secure, robust, and resilient smart contracts before deployment. If upgradeability is used, ensure that upgrade mechanisms are themselves secure and access-controlled.
- Decide early whether your contract needs to be upgradeable; if not, audit thoroughly before deployment.
- If upgradeable, secure the upgrade admin functions with strong access control.
- Test upgrade paths in a staging environment.
Checklist 3: Testing and audits
Because deployed contract code usually cannot be changed to patch security flaws, comprehensive testing and independent audits are essential. The Ethereum.org guide emphasizes that smart contract security is serious business and that every developer should learn it. While the source does not detail specific testing tools, it notes that developers should be familiar with the fundamentals of smart contract development before tackling security.
- Write thorough unit and integration tests covering all functions and edge cases.
- Consider independent audits before deploying contracts that hold significant value.
- Use testnets to simulate attacks and verify access controls.
Checklist 4: Stay informed and use resources
The Ethereum.org guide covers security considerations for Ethereum developers and explores resources for improving smart contract security. It advises developers to invest effort in building secure, robust, and resilient smart contracts. Although the source lists high-profile incidents, it does not provide a complete list of vulnerabilities or tools.
- Follow security best practices and stay updated on common vulnerabilities.
- Refer to additional resources like security-focused documentation and community forums.
- Conduct regular security reviews as your contract evolves.
Comparison: Ownable vs. role-based access control
| Pattern | Description | Use case |
|---|---|---|
| Ownable | Single owner account with special privileges | Simple contracts with one admin |
| Role-based | Multiple roles with distinct permissions | Complex contracts needing granular control |
Both patterns are mentioned in the source as useful for implementing access control. Choose based on your contract's complexity and the number of entities requiring special permissions.
Worked example: Hypothetical token contract
Suppose a team deploys a token contract with a public mint function. Without access control, anyone could mint new tokens, diluting value and potentially crashing the token price. By applying the Ownable pattern, only the owner can mint. Hypothetical: if the owner is a multisig wallet requiring three of five signatures, the risk of a single compromised key is reduced. This example illustrates the importance of restricting sensitive functions.
What the source does not say
The source does not provide a comprehensive list of vulnerabilities, specific testing tools, or detailed implementation steps for access control patterns. It also does not cover upgradeability patterns like proxies in depth, nor does it give quantitative risk assessments beyond the aggregate figure and incident examples. Readers should consult additional resources for complete security practices.