Logika Blockchain - Rian010/Journal GitHub Wiki

blockchain juga ada beberapa mekanisme logika unik yang digunakan. Berikut adalah daftar lengkap dan rinci dari mereka:

Mapping:

Mapping merupakan struktur data yang menghubungkan antara key dan value. Dalam Solidity, mapping mirip dengan dictionary di Python atau object di JavaScript.

Contoh:

mapping (address => uint) public balances;
// The above code defines a mapping called `balances`, which maps addresses to unsigned integers

Struct:

Struct merupakan tipe data custom yang dapat digunakan untuk menyimpan beberapa variabel dalam satu entitas.

Contoh:

struct Student {
   address studentAddress;
   uint age;
   string name;
}
// The above code defines a struct type called `Student`, with three fields: an Ethereum address, an unsigned integer, and a string

Event:

Event adalah cara untuk memicu notifikasi terhadap client off-chain. Client bisa mendaftarkan event yang ingin dia follow dan setelah event terjadi, client akan menerima notifikasi. Event hampir selalu digunakan untuk logging transaksinya.

Contoh:

event Transfer(address indexed from, address indexed to, uint value);
// The above code defines an event called `Transfer`, with three parameters: two addresses and an unsigned integer

Fallback Function:

Fallback function adalah fungsi default yang dipanggil ketika tidak ada nama fungsi yang sesuai ditemui oleh compiler. Fallback function harus berepresentasi void dan tanpa parameter apapun.

Contoh:

function () external payable {}
// The above code defines a fallback function that accepts ether payments

Require Statement:

Require statement digunakan untuk memeriksa suatu kondisi dan jika kondisi tidak terpenuhi, maka transaksi akan ditolak dan ethers yang telah dibayar akan dikembalikan ke penyalur aslinya. Require statement biasanya digunakan untuk validasi input dan melindungi state contract.

Contoh:

require(beneficiary.send(value), "Failed to send Ether");
// The above code sends some ether to another account and checks whether the transaction was successful

Revert Statement:

Revert statement digunakan untuk mengembalikan state contract ke posisi sebelumnya dan mengembalikan ether yang diterima. Revert statement lebih aman daripada throw statement karena tidak akan memicu exception dan tidak akan membuat gas yang digunakan transaksi sebelumnya hilang.

Contoh:

revert();
// The above code reverts the state of the contract back to its previous state

Assert Statement:

Assert statement digunakan untuk memvalidasi suatu kondisi dan jika kondisi tidak terpenuhi, maka transaksi akan ditolak dan ethers yang telah dibayar akan dikembalikan ke penyalur aslinya. Assert statement lebih cocok digunakan untuk debugging purpose karena secara internal assert statement akan mencetak error message.

Contoh:

assert(balances[from] >= value);
// The above code ensures that there are enough funds in the `from` account

Modifiers:

Modifier adalah modifikasi untuk fungsi yang digunakan untuk memvalidasi masukan atau melakukan operasi tambahan sebelum atau sesudah eksekusi fungsi. Modifier didefinisikan sebagai fungsi tanpa return value dan dapat digunakan sebagai dekorator pada fungsi.

Contoh:

modifier onlyOwner {
   require(msg.sender == owner, "Only the owner can call this function");
   _;
}

function doSomething() public onlyOwner {
   // Do something here
}
// The above code defines a modifier called `onlyOwner` that restricts access to the `doSomething` function to the contract owner

Inherent State Variables:

Secara default, semua state variables di Solidity adalah inherent, artinya nilainya disimpan di blok Ethereum. Hal ini berarti bahwa setiap node network akan menyimpan salinan dari state variable tersebut.

Contoh:

uint public totalSupply;
// The above code defines a state variable called `totalSupply`

Immutable State Variables:

State variables immutable hanyalah dapat diinisialisasikan saat compile time dan nilainya tidak dapat diubah lagi setelah deploy contract. Immutable state variables disimpan di blok Ethereum, sam

aya seperti inherent state variables.

Contoh:

uint constant private INITIAL_SUPPLY = 10000;
// The above code defines an immutable state variable called `INITIAL_SUPPLY`

Memory vs Storage:

Memory dan storage adalah dua jenis tempat penyimpanan yang berbeda di Solidity. Memory digunakan untuk menyimpan variabel lokal dan argumen fungsi, sedangkan storage digunakan untuk menyimpan state variables. Secara default, semua variabel lokal dan argumen fungsi dimasukkan ke memory, sedangkan state variables dimasukkan ke storage.

Contoh:

function add(uint a, uint b) public pure returns (uint c) {
   c = a + b;
}
// The above code uses memory to store arguments `a` and `b` and local variable `c`

function updateBalances(address beneficiary, uint value) public {
   balances[beneficiary] += value;
}
// The above code stores the updated balance in storage

Delegatecall:

Delegatecall adalah operator yang digunakan untuk memanggil fungsi pada contract lain dengan menggunakan context contract saat ini. Fungsionalitas delegatecall sangat mirip dengan call, namun bedanya delegatecall akan menggunakan storage dari contract yang dipanggil.

Contoh:

library MathLibrary {
   function multiply(uint a, uint b) public pure returns (uint c) {
      c = a * b;
   }
}

contract Calculator {
   using MathLibrary for uint;
   function calculate(uint a, uint b) public view returns (uint c) {
      c = a.multiply(b);
   }
}
// The above code defines a library called `MathLibrary` and uses it within the `Calculator` contract via `delegatecall`.

Interface:

Interface adalah abstraksi dari kontrak yang hanya memuat signature fungsi tanpa implementasi. Interface digunakan untuk membuat kontrak yang saling berkomunikasi. Kontrak yang mengimplementasikan interface harus mengimplementasikan semua fungsi yang terdapat pada interface.

Contoh:

interface Token {
   function approve(address spender, uint value) public returns (bool success);
   function allowance(address owner, address spender) public view returns (uint remaining);
}

contract Exchange {
   function buyTokens(Token token, uint tokensToBuy, uint price) public {
      require(token.approve(address(this), tokensToBuy), "Approval failed");
      // Other logic goes here
   }
}
// The above code defines an interface called `Token` and implements it in the `Exchange` contract.

Upgradeability:

Upgradeability adalah fitur penting dalam desain smart contract. Upgradeability memungkinkan developer untuk mengupdate kontrak tanpa harus membuat kontrak baru. Untuk mencapai upgradeability, developer dapat menggunakan protokol seperti Proxy Contract Design Pattern.

Contoh:

contract MyContractV1 {
   // Implementation details go here
}

contract MyContractProxy is Initializable {
   address public implementation;
   constructor() initializer() public {}
   function initialize(address impl) public initializer {
      implementation = impl;
   }
   function __default() public payable {
      assembly {
         calldataload(0)
         let ptr := mload(0x40)
         calldatacopy(ptr, 0, calldatasize())
         let result := delegatecall(gas(), implementation, ptr, calldatasize(), 0, 0)
         returndatacopyptr(0, ptr, returndatasize())
         switch result
            case 0 { revert(ptr, returndatasize()) }
            default { return(ptr, returndatasize()) }
      }
   }
}
// The above code shows how to use proxy pattern to achieve upgradability.

EternalStorage:

EternalStorage adalah pola desain yang memisahkan data permanen dari logika bisnis dalam smart contract. Pola ini memungkinkan data permanen tetap ada meski kontrak bisnis gagal atau dihapus. Data permanen disimpan dalam kontrak separuh independen yang disebut EternalStorage.

Contoh:

contract MyContract is EternalStorage {
   function getData() public view returns (uint) {
      return getUint("dataKey");
   }
   function setData(uint data) public {
      setUint("dataKey", data);
   }
}

contract EternalStorage {
   mapping (string => uint) public uInts;
   function setUint(string key, uint value) public {
      uInts[key] = value;
   }
   function getUint(string key) public view returns (uint) {
      return uInts[key];
   }
}
// The above code shows how to separate permanent data from business logic using EternalStorage pattern.

Factory Contract:

Factory contract adalah pola desain yang digunakan untuk membuat instance baru dari smart contract. Factory contract biasanya digunakan ketika kita ingin membuat banyak instance dari smart contract yang sama dengan konfigurasi yang berbeda.

Contoh:

contract TokenFactory {
   mapping (address => Token) public tokens;
   function createToken(string memory name, string memory symbol, uint decimals, uint supply) public {
      Token token = new Token(name, symbol, decimals, supply);
      tokens[address(token)] = token;
   }
}

contract Token is ERC20 {
   constructor(string memory name_, string memory symbol_, uint decimals_, uint supply_) ERC20(supply_) public {
      name = name_;
      symbol = symbol_;
   }
   // Rest of the ERC20 implementation goes here
}
// The above code creates factory contract named TokenFactory that allows creating multiple instances of Token contract with different configurations.

Access Control:

Access control adalah mekanisme yang digunakan untuk membatasi akses ke fungsi atau data di smart contract. Ada beberapa metode yang dapat digunakan untuk mengatur access control, termasuk modifier, inheritance, dan role-based access control.

Contoh:

contract AccessControlled {
   address public admin;
   constructor() public {
      admin = msg.sender;
   }
   modifier onlyAdmin() {
      require(msg.sender == admin, "Caller is not admin");
      _;
   }
   function setFee(uint fee) public onlyAdmin {
      // Set fee
   }
   function collectFee() public {
      // Collect fee
   }
}
// The above code sets up simple access control by defining admin address and using onlyAdmin modifier to limit who can call certain functions.

Safe Math Library:

Safe Math Library adalah perpustakaan matematika yang menjamin bahwa operasi matematika tidak akan overflow atau underflow. Overflow dan underflow dapat menyebabkan bug fatal dan exploit di smart contract. Safe Math Library memastikan bahwa hal tersebut tidak terjadi.

Contoh:

library SafeMath {
   function add(uint a, uint b) internal pure returns (uint c) {
      c = a + b;
      require(c >= a, "Overflow");
   }
   function sub(uint a, uint b) internal pure returns (uint c) {
      c = a - b;
      require(a >= b, "Underflow");
   }
   // More safe math operations go here
}
contract MyContract {
   using SafeMath for uint;
   uint public myNumber;
   function increaseNumber(uint num) public {
      myNumber = myNumber.add(num);
   }
   function decreaseNumber(uint num) public {
      myNumber = myNumber.sub(num);
   }
}
// The above code uses SafeMath library to ensure mathematical operations don't cause overflow or underflow errors.

ERC Standards:

ERC standards adalah standar yang ditetapkan oleh Ethereum Request for Comments (ERC). ERC standar mempermudah interoperabilitas antar smart contract dan dapat digunakan sebagai template untuk membuat smart contract yang mudah dipahami dan digunakan oleh pengembang dan pengguna. Beberapa contoh ERC standard termasuk ERC20, ERC721, ERC1155, ERC998, dan lain-lain.

Contoh:

pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract MyToken is IERC20 {
   string public name;
   string public symbol;
   uint8 public decimals;
   uint256 public totalSupply;
   mapping(address => uint256) public balanceOf;
   constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _totalSupply) ERC20(_name, _symbol) {
      name = _name;
      symbol = _symbol;
      decimals = _decimals;
      totalSupply = _totalSupply;
      balanceOf[msg.sender] = _totalSupply;
   }
   function transfer(address recipient, uint256 amount) public override returns (bool) {
      require(balanceOf[msg.sender] >= amount, "Insufficient funds");
      require(recipient != address(0), "Invalid recipient");
      balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount);
      balanceOf[recipient] = balanceOf[recipient].add(amount);
      emit Transfer(msg.sender, recipient, amount);
      return true;
   }
   // More ERC20 functions go here
}
// The above code implements basic functionality of ERC20 token.

Demikianlah beberapa logika yang umum digunakan di smart contract dalam dunia blockchain. Selain itu, ada juga beberapa pola desain lain yang dapat digunakan, seperti Singleton, Registry, Crowdsale, auctions, dan lain-lain. Semua pola desain ini dapat digabungkan dan diadaptasi sesuai kebutuhan aplikasi.