Blockchain Smart Contract | Chapter 1: Solidity Remix Basic

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
- Chapter 1: Solidity Remix Basic Syntax
- Chapter 2: Simulation VM with Ganache and MetaMask for Solidity Smart Contract (you in here)
- Chapter 3: Building Simple Decentralized Application with React and Truffle Box
Table of Contents
- Basic Syntax
- Basic Usage
- Remix IDE
- Workspace
- Remixd
- Variable and Types
- Function
- Address
- Location
- Array
- Struct
- Mapping
- Contract
- Constructor
- Inheritence
- Abstract
- Next
- Source
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:
- Version Line
- Contract Line
- Variable Line
- 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:
- local browser (default)
- 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:
- Install remixd
- 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)
offile-name.sol
.For Example:
(BasicSyntaxContract) BasicSyntaxContract.sol
Here is the illustration to compile the contract:

So the steps to compile are:
- Choose the contract and file
- Submit
Compile contract
. - 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
oreth
- Contract -> contract that we want to deploy
Steps:
- We input all the form deployment
- Submit deploy
- 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:
function set
-> to set the datafunction 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
- Fallback: https://docs.soliditylang.org/en/v0.8.17/contracts.html#fallback-function
- Receive: https://docs.soliditylang.org/en/v0.8.17/contracts.html#receive-ether-function
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:
- storage: lokasi penyimpanan sifatnya permanen (disemua fungsi). seperti hardisk. state variable. gas lebih besar.
- memory: gas lebih kecil. hanya bisa di akses di fungsi saja. seperti ram.
- calldata: lokasi tidak dapat di modification, lalu sifatnya tidak persistent / tetap, lokasi default parameternya.
- 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:
- public — all can access
- external — cannot be accessed internally, only externally
- internal — only this contract and contract deriving / inheritence from it can access
- 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