# Catatan Seekor Solidity

Solidity adalah bahasa pemrograman berorientasi objek yang dirancang untuk mengimplementasikan smart contract pada blockchain Ethereum.

## Fundamental

### Contract Structure

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyContract {
    // State variables
    uint public myNumber;
    string public myString;
    
    // Constructor
    constructor(uint _number, string memory _string) {
        myNumber = _number;
        myString = _string;
    }
    
    // Functions
    function setNumber(uint _number) public {
        myNumber = _number;
    }
    
    function getNumber() public view returns (uint) {
        return myNumber;
    }
}
```

### Data Types

```solidity
// Value Types
uint256 public unsignedInteger = 42;
int public signedInteger = -42;
bool public boolean = true;
address public contractAddress = address(this);

// Reference Types
string public text = "Hello World";
bytes public data = "0x1234";
uint[] public numberArray = [1, 2, 3, 4, 5];
mapping(address => uint) public balances;
```

### Function Modifiers

```solidity
contract ModifierExample {
    address public owner;
    
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }
    
    function restrictedFunction() public onlyOwner {
        // Only owner can call this
    }
}
```

### Events

```solidity
contract EventExample {
    event Transfer(address indexed from, address indexed to, uint amount);
    
    function transfer(address to, uint amount) public {
        // Transfer logic here
        emit Transfer(msg.sender, to, amount);
    }
}
```

## Smart Contract Examples

### Simple Token Contract

```solidity
contract SimpleToken {
    string public name = "Simple Token";
    string public symbol = "ST";
    uint8 public decimals = 18;
    uint256 public totalSupply = 1000000 * 10**18;
    
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;
    
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    
    constructor() {
        balanceOf[msg.sender] = totalSupply;
    }
    
    function transfer(address to, uint256 amount) public returns (bool) {
        require(balanceOf[msg.sender] >= amount, "Insufficient balance");
        balanceOf[msg.sender] -= amount;
        balanceOf[to] += amount;
        emit Transfer(msg.sender, to, amount);
        return true;
    }
}
```

## Best Practices

### Security Considerations

* Always validate inputs
* Use SafeMath library (though not needed in Solidity 0.8+)
* Implement access control
* Be careful with external calls
* Use reentrancy guards

### Gas Optimization

* Use appropriate data types
* Pack structs efficiently
* Minimize storage operations
* Use events instead of storage for logs

### Function Visibility

* Use `external` for functions that are only called externally
* Use `public` for functions that need to be called both externally and internally
* Use `internal` for functions that are only called within the contract
* Use `private` for functions that are only called within the current contract

## References

### Stack Exchange

* [`external` vs `public` best practices](https://ethereum.stackexchange.com/questions/19380/external-vs-public-best-practices)

### Articles

* [Solidity Tutorial : all about Assembly](https://jeancvllr.medium.com/solidity-tutorial-all-about-assembly-5acdfefde05c)

## Tools

### Development Environment

* Remix IDE (browser-based)
* Hardhat (development framework)
* Truffle (development framework)
* Foundry (testing framework)

### Testing

* Hardhat Test
* Truffle Test
* Foundry Test
* OpenZeppelin Test Helpers

### Deployment

* Hardhat Deploy
* OpenZeppelin Defender
* Etherscan API
* Infura/Alchemy for RPC
