Your First Smart Contract
A contract that stores a message
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.
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
Read each declaration alongside the behavior it introduces.
1. The License and Pragma
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
The first line declares the MIT license. The pragma ^0.8.19 permits compiler versions from 0.8.19 up to, but not including, 0.9.0. Pin an exact compiler version in the build configuration for reproducible results.
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 ofmessage.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 keywordmemorytells 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?
address public owner;: We added a state variable of typeaddressto hold an Ethereum wallet address (like0x123...).constructor(): This is a special function that runs only once, exactly when the contract is deployed. We set theownervariable tomsg.sender.msg.sender: A global variable that always contains the address of the person calling the function. During deployment,msg.senderis the deployer.require(...): A gatekeeper. When someone callssetMessage, it checks if the caller (msg.sender) matches theowner. If it doesn't match, the transaction fails immediately, the error string is returned, and any state changes are reversed.
Key takeaways
pragmaspecifies an allowed compiler range; the build configuration selects the version used.- State variables are permanently stored on the blockchain.
publicvariables automatically get read functions.msg.senderidentifies who is calling the contract.requireis used to enforce rules and access control.
Quiz: Your First Smart Contract
1 / 5What does the 'pragma solidity' line do?