Your first contract

Write, compile, and deploy a simple smart contract — and understand what every line does.

The anatomy of a Solidity file

Every Solidity file starts with a license identifier and a pragma statement that tells the compiler which version to use.

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract SimpleStorage {
    uint256 private storedValue;

    function store(uint256 value) public {
        storedValue = value;
    }

    function retrieve() public view returns (uint256) {
        return storedValue;
    }
}

Let's walk through each part.

SPDX license identifier

This is a machine-readable license tag. MIT is common for open-source contracts. Omitting it produces a compiler warning.

pragma solidity

This pins the compiler version. The ^ means "this version or any compatible minor version." Using ^0.8.20 allows 0.8.20, 0.8.21, etc., but not 0.9.x.

contract

The contract keyword declares a new contract — similar to a class in object-oriented languages. The name should match the filename.

State variables

uint256 private storedValue declares a state variable. State variables are stored permanently on the blockchain. Reading them costs no gas; writing to them does.

Functions

The store function writes to state (costs gas). The retrieve function is marked view — it only reads state and is free to call.

Deploy to a local node

With your Hardhat node running (npx hardhat node), create an Ignition module to deploy:

javascript
// ignition/modules/SimpleStorage.js
const { buildModule } = require('@nomicfoundation/hardhat-ignition/modules');

module.exports = buildModule('SimpleStorageModule', (m) => {
  const simpleStorage = m.contract('SimpleStorage');
  return { simpleStorage };
});
bash
npx hardhat ignition deploy ignition/modules/SimpleStorage.js --network localhost

Interact with your contract

Open a Hardhat console and call your contract directly:

bash
npx hardhat console --network localhost
javascript
const SimpleStorage = await ethers.getContractFactory('SimpleStorage');
const deployed = await SimpleStorage.attach('YOUR_CONTRACT_ADDRESS');

// Store a value
await deployed.store(42);

// Read it back
const val = await deployed.retrieve();
console.log(val.toString()); // 42

That's your first deployed, called smart contract. From here, every concept builds on this foundation.

←   Setting up your dev environmentData types and variables   →