Remix and Writing Your First Smart Contract

Gurnoor SinghGurnoor Singh
4 min read

Introduction to Solidity and Remix

  • .sol File Extension: Files with the .sol extension are Solidity contracts.

  • SPDX License Identifier (// SPDX-License-Identifier: MIT): Although not required by the compiler, including this identifier is recommended. If omitted, the compiler will show a warning, but it won’t prevent the code from running.

Compiling: Compiling transforms human-readable code into computer-readable code (bytecode).

Basic Data Types in Solidity

Here are some basic data types available in Solidity:

  • Boolean: true or false.

  • Integer (int, uint): Signed (int) and unsigned (uint) integers.

  • Address: Stores an Ethereum address.

  • Bytes: Low-level byte arrays, used to represent strings or binary data.

Bits vs. Bytes

  • Bit: The smallest form of data, representing either 0 or 1.

  • Byte: 1 byte equals 8 bits, and we often use bytes to represent data.

  • Difference:

  • Bits measure interface speed.

  • Bytes measure data storage.

For example, 100 Mb (Megabits) equals 12.5 MB (Megabytes), where:

  • b stands for bits.

  • B stands for Bytes.

Data Representation Example

bytes32 favoriteBytes32 = "cat";

Using bytes or bytes32 is sometimes more efficient for storing strings in Solidity.

Functions in Solidity

Functions, or methods, are subsections of code that execute specific tasks when called.

Deploying a Contract: Deploying a contract on Ethereum is similar to sending an ETH transaction, with the main difference being that deployment populates the data field with bytecode. Deploying modifies the blockchain and, therefore, requires a transaction and gas.

Immutability: Once deployed, a smart contract on the blockchain is immutable — it cannot be changed.

Writing Your First Solidity Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
contract SimpleStorage{//Basic Types : boolean, int, uint, address, bytes//  uint256 favoriteNumber = 88; // 256 bits == 32 bytes/// uint and uint256 are same/*   bool hasFavoriteNumber = true;uint256 favoriteNumber = 88; // 256 bits == 32 bytes/// uint and uint256 are samestring favoriteNumberinText = "88";int256 favoriteInt = -88;address myAddress = 0x5A9BD73AA4792607773942A60317e8D547eb20C5;bytes32 favoriteBytes32 = "cat"; // bytes and bytes32 are both different things*/uint256 public favoriteNumber; // 0 all these variables have a default value// default value in boolean is falsefunction store(uint256 _favoriteNumber) public{favoriteNumber = _favoriteNumber;// retrieve();}function retrieve() public view returns(uint 256){return favoriteNumber;}//0xd9145CCE52D386f254917e481eB44e9943F39138}

Function Visibility Specifiers

Each function in Solidity has a visibility specifier that determines where it can be accessed:

  • Public: Accessible both externally and internally. Automatically generates a getter function for state variables.

  • Private: Only accessible within the current contract.

  • External: Only accessible from outside the contract (not callable by this.function()).

  • Internal: Accessible only within the current contract and child contracts (inheritance).

Gas Costs and Optimizing Functions

The more computation a transaction requires, the higher the gas cost.

Solidity includes special keywords that indicate functions which don’t require transactions to be called. These are view and pure functions.

  • View Functions: These read state from the blockchain without modifying it. They don’t require gas when called directly.
function retrieve() public view returns (uint256) {
    return favoriteNumber;
}
  • In the retrieve() function, the code simply returns the value of favoriteNumber, without updating the blockchain.

  • Pure Functions: These do not read or modify the blockchain state, working solely with local or passed values.

  • Pure functions disallow updating the state and they disallow even reading from state or storage

  • Pure function would have been like we would have hard coded the value:

function retrieve() public pure returns (uint256) { return 7; }

Important Points:

  • No Gas for View and Pure: Calling view and pure functions directly does not require gas, as they don’t alter blockchain data.

  • Indirect Gas Cost: If a view or pure function is called from within another function that does require gas, then the call will incur a gas cost.

Example:

function store(uint256 _favoriteNumber) public {
    favoriteNumber = _favoriteNumber;
    retrieve(); // retrieve() incurs gas since store() changes blockchain state
}

In this case, retrieve() is indirectly included in the transaction, so it will add to the gas cost.

0
Subscribe to my newsletter

Read articles from Gurnoor Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Gurnoor Singh
Gurnoor Singh