VOOZH about

URL: https://blog.logrocket.com/writing-smart-contracts-solidity/

⇱ Writing smart contracts with Solidity - LogRocket Blog


2021-11-19
1173
#blockchain
Simohamed Marhraoui
77721
πŸ‘ Image

See how LogRocket's Galileo AI surfaces the most severe issues for you

No signup required

Check it out

πŸš€ Sign up for The Replay newsletter

The Replay is a weekly newsletter for dev and engineering leaders.

Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.

What is a smart contract?

Popularized by Ethereum, smart contracts are programs that are stored and executed on a blockchain. The term was coined in the late ’90s in an attempt to β€œprovide the blueprint for ideal security.”

πŸ‘ Solidity Logo Over a Tiled Background

This blueprint governs the relationship between parties when an event occurs using code, making it vastly secure and as predictable as the code itself.

Smart contracts vs. external accounts

Much like an external (Ethereum) account, smart contracts have addresses and can hold and transfer funds. External accounts, however, are not bound to a single network. You can use the same account to connect to any number of blockchain networks.

Smart contracts, on the other hand, can only be connected to one specific network. They can augment or replace real-life contracts because of their transparent nature and the immutability of the system (blockchain) they run on. The most popular way to write such a contract is through the Solidity programming language.

Introducing Solidity

Solidity is a compiled object-oriented programming language created by the Ethereum team that has JavaScript-like syntax. Unlike JavaScript, Solidity is strongly-typed and makes great use of inheritance.

Solidity compiles our source code into deployable byte code and an Application Binary Interface (ABI) to interact with the byte code using other smart contracts or programming languages.

Writing a smart contract with Solidity

// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.4.17 <0.9.0;

contract Storage {
 uint data;

 function set(uint newData) public {
 data = newData;
 }

 function get() public view returns (uint) {
 return data;
 }
}

Because smart contracts’ source code is often readily available to read, it’s a good idea to specify the license of your code in the first line after SPDX-License-Identifier:.

Following that, the pragma directive tells the compiler which version of Solidity to use. The versions start with 0. to indicate that breaking changes are to be expected in minor, regular updates. Our smart contract can be compiled against version 0.4 or higher, but not version 0.9.

Contracts

Contracts in Solidity are pretty similar to JavaScript classes in that they hold variables and methods that interact with one another. But unlike classes, you do not need a this keyword to access a variable in Solidity. It’s also mandatory to have semicolons after declarations (function definitions do not count.)

Our Storage contract holds integer data (annotated by the uint type keyword) and exposes two functions that can change and display it. The data variable is a storage variable that will exist for the lifetime of our contract. If we deploy this contract, anyone can call set and get to modify and retrieve the value of data.

Initializing our variables in Solidity contracts

To initialize our data variable with a value, contracts can provide a constructor function that takes zero or more arguments:

contract Storage {
 uint data;

 constructor (uint defaultData) {
 data = defaultData;
 }

 function set(uint newData) public {
 data = newData;
 }

 function get() public view returns (uint) {
 return data;
 }
}

Inheritance

A contract can inherit from another contract through the is keyword:

// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.4.17 <0.9.0;

contract C {
 string public greeting = 'hello';
}

contract D {
 string public farewell = 'goodbye';
}

contract E is C, D {}

Contract D will have access to both greeting and farewell variables.

Solidity functions

Solidity functions have the following pattern:

function <function name>(<parameters type>) \[function type\] [returns (<return type>)] {}

The commonly used function types are public, external, private, internal, view, pure, and payable.

Here’s how the types that govern the visibility of the function work:

  • public: anyone can call the function
  • external: anyone but the contract can call the function. Using the external type instead of public can have a performance boost and potentially save a lot of gas
  • private: only the contract holding the function can call it
  • internal the contract and its derivatives can call the function

These types govern access to the state:

  • view: the function only reads the state
  • pure: the function neither reads nor writes to the state

Note that payable is used when the function can accept payment when it’s called.

A more detailed pattern for the function type would look like this:

{public|external|private|internal} [pure|view|payable]

Thus, in our contract, the get function that has the types public view returns (uint) is universally accessible, reads data, and returns an integer.


Over 200k developers use LogRocket to create better digital experiences

πŸ‘ Image
Learn more β†’

Solidity, however, provides us with a shortcut to automatically create get functions that display our state. By simply adding the keyword public before our variable data, a data function will be created to replace our get function:

contract Storage {
 uint public data; // a data function will be created to access the `data` variable

 constructor (uint defaultData) {
 data = defaultData;
 }

 function set(uint newData) public {
 data = newData;
 }
}

Deploying using Remix

To test and deploy our contract to a blockchain network, we can either rely on an IDE like Remix to simplify our job or use a real coding environment. For this article, we’ll use Remix.

Remix is a Solidity IDE used to compile, deploy, and manually test Solidity code. It can interface with an array of Ethereum test networks, as well as the main network.

First, create a new contract under the contracts directory and copy over our contract code.

πŸ‘ Contracts Directory

πŸ‘ Contract Code

When our Solidity code is saved, Remix will automatically compile our code, creating a bytecode that gets sent to the network, as well as an ABI to interact with the deployed contract.

We can inspect both the bytecode and the ABI in the Solidity compiler tab:

πŸ‘ ABI

If our code compiles successfully, we can start deploying and interfacing with it under the deploy and run transactions tab.

In this tab, we can pick our environment, the contract to deploy, and which account to deploy it with. JavaScript VM means that Remix will maintain a blockchain network inside our browser to make testing run as fast as possible.

The value input is associated with payable function calls and is unnecessary for our contract.

πŸ‘ Deployed Contracts

At the bottom of the tab, we see Deployed Contracts, which indicates that we can deploy multiple instances of one or many contracts.

Under Contracts, Remix picks up on our defaultData inside the constructor function. Enter an integer and hit Deploy to deploy a new contract:

πŸ‘ Deploy Dropdown

πŸ‘ Storage Dropdown

The data button represents the automatically generated getter for our public data variable, while the set button represents our set method.

The color difference can be attributed to the fact that our getter data function does not modify the state in our app, and therefore, does not cost anything to run on the blockchain. However, our set function is a transaction type of function that consumes gas and resources to run, much like the initial Deploy button.

Running the data function would return our initial input 2021 and set modifies it accordingly.

πŸ‘ Data 2021

πŸ‘ Set 2022

πŸ‘ Data 2022

Conclusion

In this article, we looked at the basic building blocks of a Solidity contract, as well as how to write, compile, deploy, and test our Solidity code using the Remix IDE. From this point on, we should take it a step further and use a real environment using Ganache and Truffle. Happy hacking.

Join organizations like Bitso and Coinsquare that use LogRocket to proactively monitor their Web3 apps

Client-side issues that impact users’ ability to activate and transact in your apps can drastically affect your bottom line. If you’re interested in monitoring UX issues, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

πŸ‘ LogRocket Dashboard Free Trial Banner

LogRocket lets you replay user sessions, eliminating guesswork around why bugs happen by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings β€” compatible with all frameworks.

LogRocket's Galileo AI watches sessions for you, instantly identifying and explaining user struggles with automated monitoring of your entire product experience.

Modernize how you debug web and mobile apps β€” start monitoring for free.

πŸ‘ Image
πŸ‘ Image
πŸ‘ Image

Stop guessing about your digital experience with LogRocket

Get started for free

Recent posts:

How to build a virtual engineering team with Gemini CLI subagents

Learn how to use Gemini CLI subagents to delegate frontend, backend, testing, and docs tasks to specialized agents with guardrails and clear ownership.

πŸ‘ Image
Emmanuel John
Jun 18, 2026 β‹… 10 min read

Debug Next.js apps with AI agents and next-browser

Learn how next-browser gives AI agents runtime context for debugging Next.js apps, including React props, hydration, PPR, forms, and performance.

πŸ‘ Image
Emmanuel John
Jun 17, 2026 β‹… 9 min read

Stop hardcoding LLM SDKs: Dynamic LLM routing with OpenRouter and Next.js

Build dynamic LLM routing in Next.js with OpenRouter, TanStack AI, task classification, model fallbacks, and cost-aware routing.

πŸ‘ Image
Chizaram Ken
Jun 16, 2026 β‹… 13 min read

What is TSRX?: What JSX would look like if it were designed today

TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension β€” no new framework required.

πŸ‘ Image
Ikeh Akinyemi
Jun 12, 2026 β‹… 6 min read
View all posts

Hey there, want to help make our blog better?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now