DEV Community

Cover image for Introduction to Smart Contracts (Solidity) Part 1
Majid Kareem
Majid Kareem

Posted on

Introduction to Smart Contracts (Solidity) Part 1


This is the first in a possibly long list of web3 tutorials to come. It was written to serve as an entry point for beginners to Solidity programming.


It assumes no previous knowledge of solidity although some knowledge of other programming languages like python or JavaScript will make the journey a lot easier.

What are smart contracts

A smart contract is a program that runs at an address on Ethereum. They're made up of data and functions that can execute upon receiving a transaction.

What makes up a smart contract

Smart contracts comprise different parts:

  • Data

  • Environment variables

  • Functions

  • Events and Logs

we will be having a brief explanation of each part below.


Any contract data must be assigned to a location: either to storage or memory. It's costly to modify storage in a smart contract so you need to consider where your data should live.

Persistent data is referred to as storage and is represented by state variables. These values get stored permanently on the blockchain. You need to declare the type of a variable so that the contract can keep track of how much storage it needs when it compiles.

It is comparatively costly to read, and even more to initialize and modify storage. Because of this cost, you should minimize what you store in persistent storage to what the contract needs to run. Store data like derived calculations, caching, and aggregates outside of the contract. A contract can neither read nor write to any storage apart from its own.

// Solidity example
contract Storage {
    uint savedData; // State variable
Enter fullscreen mode Exit fullscreen mode

You'll likely be familiar with most types if you've already programmed in object-oriented languages. However, the address type should be new to you if you're new to Ethereum development.

An address type can hold an Ethereum address which equates to 20 bytes or 160 bits. It returns a hexadecimal notation with a leading 0x.

Other types include:

  • boolean
  • integer
  • fixed point numbers
  • fixed-size byte arrays
  • dynamically-sized byte arrays
  • Rational and integer literals
  • String literals
  • Hexadecimal literals
  • Enums

For detailed explanations on each type, visit the official documentation for Solidity types

Values that are only stored for the lifetime of a contract function's execution are called memory variables. Since these are not stored permanently on the blockchain, they are much cheaper to use.

To learn more about the EVM stores data, check out the docs on Solidity

Environment variables

In addition to the variables you define in your contract, there are some special global variables. They are primarily used to provide information about the blockchain, the current transaction, or are general-use utility functions.

Examples include:

  • block.chainid (uint): the current chain id
  • block.timestamp (uint): the current block timestamp as seconds since unix epoch
  • msg.value (uint): number of wei/Ether sent with the message
  • msg.sender (address): sender of the message (current call)
  • blockhash(uint blockNumber) returns (bytes32): hash of the given block when blocknumber is one of the 256 most recent blocks; otherwise returns zero


Functions are the executable units of code. In the most simplistic terms, functions can get or set information in response to incoming transactions on the blockchain.

Function Calls can happen internally or externally and have different levels of visibility towards other contracts. Functions accept parameters and return variables to pass parameters and values between them.

Function visibility
Solidity knows two kinds of function calls: external ones that do create an actual EVM message call and internal ones that do not. Furthermore, internal functions can be made inaccessible to derived contracts. This gives rise to four types of visibility for functions.

  • external
  • public
  • internal
  • private

For detailed explanations on each visibility type, visit the solidity docs on function visibility

// Solidity example to show different parts of a function
function setUsername(string memory value) public {
    userName = value;

Enter fullscreen mode Exit fullscreen mode
  • The parameter value of type string is passed into the function: setUsername.
  • It's declared public, meaning anyone can access it.

Events and Logs

Events let you communicate with your smart contract from other subscribing applications. When a transaction is mined, smart contracts can emit events and write logs to the blockchain that other applications can then process.

Solidity events give an abstraction on top of the EVM’s logging functionality. Applications can subscribe and listen to these events through the RPC interface of an Ethereum client.

For more explanations check out Solidity Events

So far we've learned the basic parts of a smart contract written in Solidity. These various parts are what when put together form a group of code that executes certain commands on the blockchain.

I know this is a pretty long (and possibly boring) tutorial, but since it's a tutorial on smart contracts, it won't be complete if we don't write any smart contracts.
Below is an example of a very simple smart contract written in solidity. It was lifted directly (with a little update to use the latest version of solidity) from the Ethereum documentation

//SPDX-License-Identifier: Unlicense
// Specifies the version of Solidity, using semantic versioning.
// Learn more:
pragma solidity ^0.8.4;

// Defines a contract named `HelloWorld`.
// A contract is a collection of functions and data (its state).
// Once deployed, a contract resides at a specific address on the Ethereum blockchain.
// Learn more:
contract HelloWorld {

    // Declares a state variable `message` of type `string`.
    // State variables are variables whose values are permanently stored in contract storage.
    // The keyword `public` makes variables accessible from outside a contract
    // and creates a function that other contracts or clients can call to access the value.
    string public message;

    // Similar to many class-based object-oriented languages, a constructor is
    // a special function that is only executed upon contract creation.
    // Constructors are used to initialize the contract's data.
    // Learn more:
    constructor(string memory initMessage) {
        // Accepts a string argument `initMessage` and sets the value
        // into the contract's `message` storage variable).
        message = initMessage;

    // A public function that accepts a string argument
    // and updates the `message` storage variable.
    function update(string memory newMessage) public {
        message = newMessage;

Enter fullscreen mode Exit fullscreen mode

Here is a list of references and useful links for further reading

Ethereum official doc on smart contracts
Official Solidity docs
Remix an IDE for writing smart contracts

Here is a link to My Public profile if you feel the tutorial is not enough and you need a 1 on 1 session 😉.

Discussion (0)