Trusted by Professionals for 10+ Years | Flat 20% OFF | Code: SKILL
Blockchain Council
smart contracts7 min read

Writing Your First Smart Contract: A Beginner-Friendly Solidity Tutorial

Suyash RaizadaSuyash Raizada
Writing Your First Smart Contract: A Beginner-Friendly Solidity Tutorial

This Solidity tutorial takes you from a blank Remix file to a deployed first smart contract on an Ethereum test network. You will write a small storage contract, compile it, deploy it with MetaMask, and call its functions without risking real ETH. Keep it simple. That is the point.

Solidity is the main programming language used for smart contracts that run on the Ethereum Virtual Machine, usually called the EVM. Its syntax looks familiar if you have seen JavaScript, C++, or Java, but the execution model is different. Every state change costs gas, every deployed contract is public, and mistakes can be expensive on mainnet.

Certified Artificial Intelligence Expert Ad Strip

What You Will Build

You will build a contract called MyFirstSmartContract. It stores a message on-chain and lets anyone update it. That sounds basic, but it teaches the parts you need before you touch ERC-20 tokens, NFT contracts, escrow logic, or DAO voting contracts.

  • Language: Solidity 0.8.x
  • IDE: Remix IDE
  • Wallet: MetaMask
  • Network: Ethereum Sepolia testnet
  • Contract type: simple storage and greeting contract

If you are learning with a structured path, this is the sort of foundation that fits well before moving into Blockchain Council's Certified Smart Contract Developer™ or Certified Blockchain Developer™ programs.

Key Solidity Concepts Before You Code

SPDX License and Pragma

Most Solidity files begin with two lines:

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

The SPDX line tells tools what license applies to the source code. The pragma line tells the compiler which Solidity versions are acceptable. Solidity 0.8.x is the standard choice for beginner tutorials because it includes built-in overflow and underflow checks, unlike older 0.7.x contracts.

A common beginner error in Remix is this one: ParserError: Source file requires different compiler version. It usually means your pragma says one thing and the compiler dropdown says another. Pick a compiler version that matches your pragma, such as 0.8.20 or newer for the code below.

State Variables

A state variable is stored on-chain. If you write string public message;, the value persists after deployment and can be read later. Solidity also creates a free getter function for public state variables, so you do not need to write a separate getMessage() function unless you want one for teaching clarity.

Functions and Visibility

Functions define what users can do with the contract. Visibility matters:

  • public: callable from inside and outside the contract
  • external: callable from outside the contract
  • internal: callable only inside this contract and derived contracts
  • private: callable only inside this contract

You will also see view and pure. A view function reads state but does not change it. A pure function neither reads nor changes contract state.

Step 1: Open Remix and Create a Solidity File

Go to the Remix IDE in your browser. Create a new file under the contracts folder and name it MyFirstSmartContract.sol. Remix is the right tool for your first contract because you do not need Node.js, Hardhat, Foundry, or a local RPC setup yet.

To be blunt, do not start with a DeFi protocol clone. Start with one file and one idea. You will learn faster.

Step 2: Write Your First Smart Contract

Paste this code into Remix:

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

contract MyFirstSmartContract {
    string public message;
    address public lastUpdatedBy;

    constructor(string memory initialMessage) {
        message = initialMessage;
        lastUpdatedBy = msg.sender;
    }

    function setMessage(string memory newMessage) external {
        message = newMessage;
        lastUpdatedBy = msg.sender;
    }

    function getMessage() external view returns (string memory) {
        return message;
    }
}

Here is what each part does:

  • contract MyFirstSmartContract defines the contract.
  • string public message stores text on-chain.
  • address public lastUpdatedBy stores the wallet address that last changed the message.
  • constructor runs once during deployment.
  • msg.sender is the address calling the function or deploying the contract.
  • setMessage changes state, so it costs gas.
  • getMessage reads state, so it can be called without sending a transaction.

Notice the memory keyword for strings passed into functions. Beginners often remove it and get a compiler error. Solidity needs to know where complex data types such as strings, arrays, and structs live during execution.

Step 3: Compile the Contract in Remix

Open the Solidity Compiler tab in Remix. Choose a compiler compatible with pragma solidity ^0.8.20;. Then click Compile MyFirstSmartContract.sol.

If you see a red error, read the first line carefully. Remix errors are usually specific. A missing semicolon can cause a ParserError. A misspelled variable name can cause DeclarationError: Undeclared identifier. Fix one error at a time, then compile again.

When compilation succeeds, Remix generates two important outputs:

  • ABI: the interface used by wallets and dApps to call your contract
  • Bytecode: the compiled EVM instructions deployed to the network

Step 4: Set Up MetaMask and Sepolia Test ETH

Install MetaMask if you have not already. Create a wallet, store the recovery phrase safely, and switch to the Sepolia test network. Sepolia is widely used for Ethereum testing. Older tutorials may mention Ropsten, but Ropsten has been deprecated, so skip it.

You need Sepolia ETH from a faucet to deploy. It has no mainnet value, but it pays testnet gas. Use a reputable faucet, request a small amount, then wait for the transaction to appear in MetaMask.

Never deploy your first contract directly to Ethereum mainnet. Ethereum mainnet uses chain ID 1 and real ETH. Test first. Always.

Step 5: Deploy from Remix

In Remix, open Deploy & Run Transactions. For Environment, choose Injected Provider - MetaMask. MetaMask will ask you to connect Remix to your wallet.

Then:

  1. Confirm that MetaMask is on Sepolia.
  2. Select MyFirstSmartContract in the contract dropdown.
  3. In the constructor input field, enter a string such as "Hello, Ethereum".
  4. Click Deploy.
  5. Approve the transaction in MetaMask.

After the transaction confirms, Remix will show your deployed contract under Deployed Contracts. Expand it. You should see buttons for message, lastUpdatedBy, getMessage, and setMessage.

Step 6: Interact With the Contract

Click getMessage. Remix should return the initial message. This is a read operation, so it does not create a transaction.

Now enter a new value beside setMessage, such as "My first smart contract works", and click the button. MetaMask will prompt you to confirm a transaction because this function changes blockchain state. Once confirmed, call message or getMessage again. The stored text should update.

This distinction matters in real projects. Reading is usually free for users. Writing costs gas. If your contract design writes to storage too often, users will feel it immediately.

Common Mistakes Beginners Make

  • Using the wrong compiler: match the Remix compiler to your pragma line.
  • Forgetting constructor arguments: this contract needs an initial string during deployment.
  • Confusing calls and transactions: read functions are calls, state changes are transactions.
  • Testing on mainnet too early: use Sepolia until you understand gas, deployment, and contract behavior.
  • Copying complex code: contracts involving lending, staking, or swaps need security review and proper tests.

Where This First Contract Leads Next

A greeting contract is not production software, but the pattern is real. Storage contracts appear in protocol settings, identity records, metadata systems, and admin configuration. Once you understand this small example, add features one at a time:

  • Add an onlyOwner modifier so only the deployer can update the message.
  • Emit an event each time the message changes.
  • Replace the string with a mapping(address => string) so each wallet has its own message.
  • Move from Remix to Hardhat or Foundry and write unit tests.

If your goal is professional smart contract work, learn testing early. Foundry is excellent for Solidity-native tests, while Hardhat is still common in JavaScript and TypeScript teams. Remix is best for the first hour. It is not where you should audit a treasury contract.

Security Mindset From Day One

Solidity 0.8.x protects you from basic integer overflow issues, but that does not make contracts safe by default. Access control, reentrancy, unchecked external calls, and bad assumptions about token behavior still cause real losses.

For now, remember three rules:

  1. Keep the contract small enough to reason about.
  2. Know exactly who can call each function.
  3. Test every state change before deploying beyond a testnet.

The official Solidity documentation and Solidity by Example are good next references. For a guided learning path, consider Blockchain Council's Certified Smart Contract Developer™ if you want to build and review Solidity contracts, or Certified Blockchain Developer™ if you want broader blockchain development coverage.

Final Step: Build One More Version

Do not stop after this Solidity tutorial. Open Remix again and change the contract so only your wallet can call setMessage. Then add an event named MessageChanged. Those two changes will teach access control and event logs, which are far closer to real smart contract development than another passive reading session.

Related Articles

View All

Trending Articles

View All