A minimal Solidity contract is easiest to understand by following its stored data and the functions that can change it. The example below focuses on one rule: only the address that created the contract may update a stored message. It is a learning aid, not audited or deployment-ready code; before deployment, test the intended behavior and obtain review appropriate to the project’s purpose.
What this Solidity example demonstrates—and what it does not
A smart contract is code and data deployed through cryptographically signed transactions on a blockchain network. On Ethereum, a smart contract is a reusable program deployed into blockchain state and invoked through transaction requests. These definitions describe what a contract is; they do not establish that any particular program is correct or secure. source source
This example demonstrates a small state transition: an authorized caller changes a stored message, while an unauthorized caller is rejected. It does not handle funds, external data, or any broader business process. In particular, the contract cannot directly obtain off-chain facts that are not present in blockchain state without an oracle or transaction mechanism. That capability is deliberately outside this example. source
The code is intentionally limited so a reader can trace the access rule and state update. It should not be treated as a template that is safe to reuse unchanged. A contract’s suitability depends on its intended behavior and project-specific review; passing a few example tests is not a substitute for that work.
Smart contract code example Solidity: the annotated contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract MessageBox {
address public owner;
string public message;
constructor(string memory initialMessage) {
owner = msg.sender;
message = initialMessage;
}
function setMessage(string memory newMessage) public {
require(msg.sender == owner, "Only owner");
message = newMessage;
}
}
The SPDX line labels the source file with a license identifier; the identifier shown is part of this example, so a developer adapting the code should choose a license that matches the project’s needs. The pragma sets a compiler-version constraint: ^0.8.20 permits compatible versions at or above 0.8.20 within the same major version. A pragma constrains acceptable versions; it does not select which compiler is run. For reproducible review, record the compiler actually used rather than assuming the source line selects it.
MessageBox names the contract. Its owner and message variables are state: their values persist as contract data. The public visibility on each variable makes the compiler provide a way for callers to read it. Here, owner stores the address that deploys the contract, and message stores the initial text or a later update.
The constructor runs when the contract is created. Its initialMessage parameter is kept in memory for the constructor call. msg.sender identifies the caller in the current execution; here it becomes the owner. The constructor assigns that address and the initial message to persistent state.
setMessage accepts a new string. Before changing state, it checks whether the caller’s address equals owner. If not, require stops the call with the reason Only owner. If the condition passes, the function assigns newMessage to message. The access check is part of this specific example’s behavior, not a general access-control system for every application.
The code has no explicit event, payment, transfer, or recovery function. Its visible result is the updated message value. If an application needs additional behavior, that requirement changes the contract and its review scope; do not infer capabilities that are absent from the code.
Trace state changes and expected failures
Suppose the contract is created with initialMessage set to Hello. After successful creation, the stored owner is the creating address and the stored message is Hello. A call to setMessage from that same address with newMessage set to Updated passes the access condition and replaces the stored message.
Now consider a call from a different address. The equality check fails, so require reverts the call before the assignment. The intended result is that the unauthorized call does not change message. A test should verify both the rejection and the unchanged stored value; checking only for a failure does not confirm the state outcome you meant to protect.
It is useful to distinguish the contract’s logic from the surrounding transaction process. The code describes what execution should do when setMessage is called. A state-changing Ethereum contract interaction requires a signed transaction that is broadcast, selected for a block, executed, and later gains stronger confirmation or finality. A receipt can report failed execution even when the transaction was included in a block. Thus, “the function rejects the caller” describes the contract’s execution rule, not a promise about every step of transaction submission or confirmation.
Test the behavior before considering deployment
A focused test plan can begin with these cases:
- Initial state: after creation with a known string, check that
owneris the creating address andmessagematches the supplied text. - Authorized update: call
setMessageas the owner, then check that the stored message has changed to the requested value. - Unauthorized update: call as a different address, expect the
Only ownerrejection, and verify that the stored message remains unchanged. - Boundary inputs: test an empty string and a longer string if those values matter to the application. Decide what the intended behavior should be; this example imposes no rule against either input.
These tests check specified behavior, not every possible interaction or implementation flaw. Review compiler warnings and settings against the intended design, and make sure the compiler used matches the version range the project intends to support. Keep test results and build details available to reviewers so they can understand what was checked.
A structured verification framework can help organize design, build, and testing checks for EVM-based smart contracts and decentralized applications. OWASP describes its Smart Contract Security Verification Standard as a framework for this purpose, while noting that the currently published standard is an early version and must be supplemented with project-specific threat modeling and review. A framework is a starting structure, not evidence that this particular example has passed review. source
Passing tests establishes only that the tested cases produced the observed outcomes under the test conditions. It does not prove the absence of vulnerabilities or show that the code meets requirements that were never expressed in tests. Keep the claims narrow: report what was tested, rather than calling the contract secure on that basis.
Review risks and deployment prerequisites
Before adapting the example for a real use, write down the intended behavior and the consequences of incorrect or unauthorized changes. Then check that the code expresses those requirements, test both permitted and rejected actions, and seek independent review appropriate to the project’s purpose and risk. Any added external calls, permissions, or state variables would introduce behavior not covered by this minimal walkthrough and should be reviewed in context.
Do not infer recovery, security, or compliance properties from the example. The code contains no recovery function, and the evidence here does not establish a recovery method or guarantee that a deployed contract can be changed. Nor does this walkthrough establish any legal, tax, or regulatory obligation. Those subjects require current, jurisdiction-specific evidence and are outside the scope of this technical example.
This article also makes no claim about network availability or deployment fees. Those are time-sensitive operational details that require current authoritative evidence. The practical takeaway is narrower: trace the state, verify the access condition with tests, review the actual compiler and build settings, and treat deployment as a separate decision requiring project-specific evidence and review.
Sources and references
- OWASP Smart Contract Security Verification Standard — OWASP Foundation; retrieved 2026-10-19.
- Introduction to smart contracts — ethereum.org; retrieved 2026-10-19.
- Smart contract - Glossary — National Institute of Standards and Technology; retrieved 2026-10-19.
- Technical intro to Ethereum — ethereum.org; retrieved 2026-10-19.