Hashtag Web3 Logo

Your First Smart Contract

10 min
beginner

Let's write a simple contract

We are going to look at a classic "Hello World" contract, but for blockchains: a simple Storage contract that lets anyone save a message and read the current message.

Anatomy of a Smart Contract pragma solidity Compiler version State Variables Stored on-chain Functions Read / write logic Modifiers Access control All wrapped inside: contract MyContract { ... }

Here is the entire contract:

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

contract SimpleStorage {
 // A state variable permanently stored on the blockchain
 string public message;

 // A function to update the message
 function setMessage(string memory _newMessage) public {
 message = _newMessage;
 }
}

Line-by-line breakdown

Let's tear this apart to understand exactly how Solidity works.

1. The License and Pragma

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

The first line is a machine-readable comment indicating the open-source license (MIT). The second line, the pragma, tells the compiler: "Only compile this code if you are using Solidity version 0.8.19 or higher." This prevents your code from breaking if future compiler versions change how things work.

2. Contract Declaration

contract SimpleStorage {

Think of contract exactly like class in Python or Java. It defines the blueprint. Everything inside the curly braces belongs to this contract.

3. State Variables

 string public message;

This is a state variable. Because it is declared inside the contract but outside any function, it is permanently stored on the Ethereum blockchain.

  • string: The data type. It holds text.
  • public: An access modifier. By declaring it public, Solidity automatically creates a hidden function that allows anyone in the world to read the value of message.
  • message: The name we gave the variable.

4. Functions

 function setMessage(string memory _newMessage) public {
 message = _newMessage;
 }

This is a function that allows users to change the message.

  • function setMessage(...): We name the function.
  • (string memory _newMessage): The parameters. We expect a string. The keyword memory tells the EVM to store this temporary variable in memory while the function executes, rather than saving it to the permanent blockchain storage.
  • public: Anyone can call this function.
  • message = _newMessage;: We take the input and overwrite our permanent state variable.

Adding Access Control

Right now, anyone can call setMessage. What if we only want the person who created the contract to change the message? We introduce msg.sender and a constructor.

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

contract OwnedStorage {
 string public message;
 address public owner;

 // Runs once when the contract is deployed
 constructor() {
 owner = msg.sender;
 }

 function setMessage(string memory _newMessage) public {
 // Require checks a condition. If false, it reverts the entire transaction.
 require(msg.sender == owner, "Only the owner can set the message");
 message = _newMessage;
 }
}

What changed?

  1. address public owner;: We added a state variable of type address to hold an Ethereum wallet address (like 0x123...).
  2. constructor(): This is a special function that runs only once, exactly when the contract is deployed. We set the owner variable to msg.sender.
  3. msg.sender: A global variable that always contains the address of the person calling the function. During deployment, msg.sender is the deployer.
  4. require(...): A gatekeeper. When someone calls setMessage, it checks if the caller (msg.sender) matches the owner. If it doesn't match, the transaction fails immediately, the error string is returned, and any state changes are reversed.

Key takeaways

  • pragma locks your compiler version.
  • State variables are permanently stored on the blockchain.
  • public variables automatically get read functions.
  • msg.sender identifies who is calling the contract.
  • require is used to enforce rules and access control.

Quiz: Your First Smart Contract

1 / 5

What does the 'pragma solidity' line do?