Coinmonks

Coinmonks is a non-profit Crypto Educational Publication. Other Project — https://coincodecap.com/ & Email — gaurav@coincodecap.com

Follow publication

Blockchain Smart Contract | Chapter 1: Solidity Remix Basic

Kecci
Coinmonks
Published in
11 min readMar 1, 2023
Chapter 1 — Solidity Basic for Learning Smart Contract Blockchain with Remix IDE.

Smart contracts are self-executing contracts that enable the automation of complex financial transactions on blockchain networks. Solidity is a high-level programming language used to write smart contracts on the Ethereum blockchain. It is a contract-oriented, statically-typed language that supports inheritance, libraries, and user-defined types. Understanding the Solidity syntax is crucial for developers who want to write smart contracts on the Ethereum blockchain.

In this chapter, we will introduce the concept of blockchain smart contracts and discuss the importance of Solidity syntax in developing smart contracts. We will explore the fundamental building blocks of Solidity, such as data types, variables, functions, and control structures. Understanding these building blocks is critical for writing efficient and secure smart contracts.

The chapters

Table of Contents

Basic Syntax

First we want to look at the basic syntax in solidity code. For example code on here: /contracts/BasicSyntaxContract.sol

or it look like this:

pragma solidity >=0.7.0 <0.9.0;

contract BasicSyntaxContract {
// init variables
uint storedData;

// set storedData
function set(uint x) public {
storedData = x;
}

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

There is always 4 components for the syntax line:

  1. Version Line
  2. Contract Line
  3. Variable Line
  4. Function Line

1. Version Line

pragma solidity >=0.7.0 <0.9.0;

2. Contract Line

contract BasicSyntaxContract {
....
// Here we define variables and functions
}

3. Variable Line

    // init variables
uint storedData;

4. Function Line

    // set storedData   
function set(uint x) public {
storedData = x;
}

Basic Usage

Remix IDE

To running the contract we use Remix IDE on https://remix.ethereum.org/

Workspace

There is 2 types of workspaces:

  1. local browser (default)
  2. local filesystem (localhost, we need to use remixd)

Remixd

To install remixd and usage, you can follow: https://remix-ide.readthedocs.io/en/latest/remixd.html

Here simple steps:

  1. Install remixd
  2. Run remixd on the directory/folder where it is the workspace, command: remixd

3. Choose workspace on remix-ide on localhost.

4. Done, connected to localhost.

I. Compile Contract

After we choose our workspace, we can compile the contract that we code before.

To compile the contract, we need to choose the (contract-name) of file-name.sol.

For Example:

(BasicSyntaxContract) BasicSyntaxContract.sol

Here is the illustration to compile the contract:

So the steps to compile are:

  1. Choose the contract and file
  2. Submit Compile contract.
  3. It generated an artifacts file on your contracts folder.

II. Deploy Contract

In deploy sections, we can see some input:

  • Environments -> The Virtual Machine that we use
  • Accounts -> Address account that want to use
  • Gas limit -> Limit gas
  • Value -> value of cost, we can use wei or eth
  • Contract -> contract that we want to deploy

Steps:

  1. We input all the form deployment
  2. Submit deploy
  3. Deployed to transaction section and our eth address will cutted for the creation of contract.

III. Transaction Contract

After we deploy, we can see in the deployed contracts section. Some form of interface our transaction of the contract.

In the code before, we have 2 functions:

  1. function set -> to set the data
  2. function get -> to get the data

We also can see the result if the interface are generated on the deployed contracts.

Here example the transactions the submit button & logs:

  • set with the input with 10 value.
  • get the data for 10 value.

Variable and Types

After we know basic syntax and basic usage, we want to know deep about variables and types of sol, we can see the example code on here: /contracts/VariableTypes.sol

Function

After we know basic syntax, usage, variables, and types, we want to know more usage of functions.

Basic function

contract HelloWorld {
uint result;

function printHello() public pure returns(string memory) {
return 'Hello World';
}
function add(uint a, uint b) public {
// local
uint temp = a + b;
// need to save to local variable first, then we set to global variable
result = temp;
}
function getResult() public view returns(uint) {
return result;
}
}

Payable function

contract PayableContract {
uint receivedAmount;

// we need to define the function with `payable`
function savedEther() payable public {
// we can use `msg.value` from the form input of the deployed contract
receivedAmount = msg.value;
}
function getTotalAmount() public view returns(uint) {
return receivedAmount;
}
}

Overload function

contract OverloadContract {
// Overload -> name could be same, but different parameter
function tambah(uint a, uint b) public pure returns(uint hasil) {
hasil = a + b;
// overload function should not write return
}
function tambah(uint a, uint b, uint c) public pure returns(uint hasil) {
hasil = a + b + c;
// overload function should not write return
}
}

Fallback and receive functions

contract FallbackReceiveContract {
uint x;
uint y;
// This function is called for all messages sent to
// this contract, except plain Ether transfers
// (there is no other function except the receive function).
// Any call with non-empty calldata to this contract will execute
// the fallback function (even if Ether is sent along with the call).
fallback() external payable { x = 1; y = msg.value; }
// This function is called for plain Ether transfers, i.e.
// for every call with empty calldata.
receive() external payable { x = 2; y = msg.value; }
}

Address

You can see the code on here: /contracts/AddressContract.sol

Address of Sender

    address public caller;

// Address of sender: 2 action, first in set, then in get caller
function getCallerAddress() public returns(address) {
caller = msg.sender;
return caller;
}
// Address of sender: More Lebih concise than function before, direct set & get.
function getCallerAddressWithView() public view returns(address caller) {
caller = msg.sender;
}

Address of Smart Contract

    function getAddressThis() public view returns(address) {
address myAddress = address(this);
return myAddress;
}

Transfer & Send Address

    // Set Saldo
uint receivedAmount;

// Constant for 1 ether to wei
uint ether1 = 1000000000000000000;
// Add ether balance to smart contract
function receiveEther() payable public {
receivedAmount = msg.value;
}
// Address payable, there is 2 type: send and transfer
function transferEther(address payable _address, uint amount) public {
// _address -> address of receiver
_address.transfer(amount * ether1);
}
// Send
function sendFund(address payable _address, uint amount) public returns(bool) {
// _address -> address of receiver
_address.send(amount * ether1);
}

Location

You can see the code on here: /contracts/LocationContract.sol

Ada 4 tipe penyimpanan smart contract:

  1. storage: lokasi penyimpanan sifatnya permanen (disemua fungsi). seperti hardisk. state variable. gas lebih besar.
  2. memory: gas lebih kecil. hanya bisa di akses di fungsi saja. seperti ram.
  3. calldata: lokasi tidak dapat di modification, lalu sifatnya tidak persistent / tetap, lokasi default parameternya.
  4. stack: data sifat nya non-persistent, mirip calldata. dikelola langsung oleh vm ethereum. menggunakan lokasi data stack tersebut untuk variable selama ada eksekusi. sampai 1024 level.

Storage vs Memory

    // storage
bool isReady; // storage
string name; // storage

function iniFungsi() public {
// values
bool isOk; // memory
uint number; // memory
address account; // memory
}

Reference & Copy Location

Copy Location:

    function iniValue() public pure returns (uint) {
uint localVar1 = 10;
uint localVar2 = 20;

localVar1 = localVar2; // copy, not reference, not reflection
localVar1 = 40;
return localVar1; // 40
}

Reference Location:

    function thisFunction() public pure returns (uint[] memory, uint[] memory) {
uint[] memory localMemoryArray1 = new uint[](3);

localMemoryArray1[0] = 1;
localMemoryArray1[1] = 2;
localMemoryArray1[2] = 3;
uint[] memory localMemoryArray2 = localMemoryArray1; // reference, could be reflection
localMemoryArray1[0] = 10; // take effect on memory1 & memory2 (because referenced)
return (localMemoryArray1, localMemoryArray2); // same result (10, 2, 3) & (10, 2, 3)
}

Array

You can see the code on here: /contracts/ArrayContract.sol

Fixed Array

// Fixed
contract ArrayContract {

function getData() public pure returns (uint[5] memory) {
uint[5] memory data = [uint(50), 60, 70, 80, 100];
return data;
}
function getSingleData() public pure returns (uint) {
uint[5] memory data = [uint(50), 60, 70, 80, 100];
return data[1]; // 60, karena index start dari 0.
}
uint[5] datas; // state variable, public dan permanent
function getDataPublic() public returns (uint){
datas = [uint(50), 60, 70, 80, 100]; // fixed array
return datas[1];
}
}

Dynamic Array

// Dynamic
contract DynaimcArrayContract {
/* Cara 1: Using inline */
uint[] data;

function getData() public returns (uint[] memory) {
data = [60, 70, 30, 40];
return data;
}
/* Cara 2: Using new empty */
uint[] dataNew;
function getDataNew() public returns (uint[] memory) {
dataNew = new uint[](3);

dataNew[0] = 10;
dataNew[1] = 20;
dataNew[2] = 30;
return dataNew;
}
}

Length Array

contract ArrayLenghtContract {
uint[7] data;

function arrayExample() public payable returns (uint[7] memory) {
data = [uint(10), 20, 30, 40, 50, 60];
return data;
}
function arrayLength() public returns (uint) {
uint x = data.length;
return x;
}
}

Push array (insert, last insert)

contract PushArrayContract {
uint[] arr;

function insert() public returns (uint[] memory) {
arr = [1, 2, 3];
//Push array
arr.push(4);
arr.push(5);
return arr; // 1, 2, 3, 4, 5
}
}

Pop (last out)

contract PopArrayContract {
uint[] arr;

function pop() public returns (uint[] memory) {
arr = [1, 2, 3];
//Push array
arr.pop();
arr.pop();
return arr; // 1
}
}

Struct

struct Book {
string title;
string author;
uint id;
bool isReady;
}

Struct data function insert

    Book book1;

function addBook() public {
book1 = Book("solidity program", "john", 1, true);
}
function getBook() public view returns (string memory, string memory, uint, bool) {
return (book1.title, book1.author, book1.id, book1.isReady);
}

Struct data inline insert

    Book book2 = Book("create dapps", "kennedy", 12, false);

function getBook2() public view returns (string memory, string memory, uint, bool) {
return (book2.title, book2.author, book2.id, book2.isReady);
}

Struct data array

    Book[] public books;

function newBook(string memory title, string memory author, uint id, bool isReady) public {
books.push(Book(title, author, id, isReady));
}
function infoBook(uint _index) public view returns (string memory, string memory, uint, bool) {
Book storage book = books[_index];
return (book.title, book.author, book.id, book.isReady);
}

Mapping

You can see the code on here: /contracts/MappingContract.sol

Mapping

contract MappingContract {
mapping(address => uint) public myMap;

function set(address _addr, uint _i) public {
myMap[_addr] = _i;
}

function get(address _addr) public returns (uint){
return myMap[_addr];
}
}

Nested Mapping

contract NestedMappingContract {
mapping(address => mapping(uint => bool)) public nested;
function set(address _addr, uint _i, bool _boo) public {
nested[_addr][_i] = _boo;
}
function get(address _addr, uint _i) public returns (bool){
return nested[_addr][_i];
}
}

Contract

There is several types of contract:

  1. public — all can access
  2. external — cannot be accessed internally, only externally
  3. internal — only this contract and contract deriving / inheritence from it can access
  4. private — can be accessed only from this contract

You can see the code on here: /contracts/Contract.sol

Parent Contract

contract Parent {
uint private data;

uint public info;
// initialization (dijalankan pertamakali)
constructor() {
info = 10;
}
function increment(uint a) private pure returns (uint) {
return a + 1;
}
function setIncrement() public pure returns (uint) {
// bisa menggunakan private function, karena dalam 1 contract.
return increment(2);
}
// public
function updateData(uint a) public {data = a;}
function getData() public view returns (uint) { return data; }
function compute(uint a, uint b) internal pure returns (uint) {return a + b;}
}

External Contract

contract ExternalContract {
function readData() public returns (uint) {
Parent c = new Parent();
c.updateData(7);
return c.getData();
}
}

Inheritence Contract from Parent

contract NewContract is Parent {
uint private result;
Parent private c;
constructor() {
c = new Parent();
}
function getComputeResult() public {
result = compute(3, 5);
}
function getResult() public view returns(uint) {
return result;
}
function getInfo() public view returns(uint) {
return c.info();
}
}

Constructor

You can see the code on here: /contracts/ConstructorContract.sol

contract ConstructorContract {
int totalSupply;
address private owner = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
constructor(int _totalSupply) public {
if (owner == msg.sender) {
totalSupply = _totalSupply;
}
}
function getTotalSupply() public view returns (int) {
return totalSupply;
}
}

Inheritence

Single Inheritence

You can see the code on here: /contracts/InheritenceContract.sol

Multi Level Inheritence

You can see the code on here: /contracts/MultiLevelInheritenceContract.sol

Hierarchy Inheritence

You can see the code on here: /contracts/HierarchyContract.sol

Multiple Inheritence

You can see the code on here: /contracts/MultipleInheritenceContract.sol

Payable

You can see the code on here: /contracts/PayableContract.sol

pragma solidity >=0.7.0 <0.9.0;

contract PayableContract {
address payable public owner;

constructor() payable {
owner = payable(msg.sender);
}
// payable: artinya bisa kirim ether dan menerima ether
function deposit() public payable {
}
function getAmount() public view returns (uint) {
uint amount = address(this).balance;
return amount;
}
function withdraw() public {
uint amount = address(this).balance;
(bool success,) = owner.call{value : amount}("");
require(success, "Failed to withdraw ");
}
function transfer(address payable _to, uint _amount) public {
(bool success,) = _to.call{value : _amount}("");
require(success, "Failed kirim ether to owner");
}
}

Abstract

You can see the code on here: /contracts/AbstractContract.sol

pragma solidity >=0.7.0 <0.9.0;

abstract contract AbstractContract {
function getNumber(uint a, uint b) public virtual;
function calculate() public virtual view returns (uint);
}

contract Calculator is AbstractContract {
uint lenght;
uint width;
function getNumber(uint a, uint b) public override {
lenght = a;
width = b;
}
function calculate() public override view returns (uint) {
return lenght * width;
}
}

Conclusion

You can see the full code in here: https://github.com/kecci/solidity-remix-basic

Next

After we know about the solidity syntax and usage. Next we want to simulate the blockchain test VM with Ganache and MetaMask, so the next chapter will be in here: https://github.com/kecci/solidity-truffle-ganache-remix

Source

New to trading? Try crypto trading bots or copy trading on best crypto exchanges

Join Coinmonks Telegram Channel and Youtube Channel get daily Crypto News

Also, Read

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Coinmonks
Coinmonks

Published in Coinmonks

Coinmonks is a non-profit Crypto Educational Publication. Other Project — https://coincodecap.com/ & Email — gaurav@coincodecap.com

Kecci
Kecci

Written by Kecci

Coders + Librarian @Github

No responses yet

Write a response