πŸ±β€πŸ’» DEVELOPMENT LANGUAGES


Page Map


πŸ±β€πŸ’» A - INTRODUCTION

This section will contain all the development languages that I am learning. The guiding principle is to learn those languages and concepts that will enable fast and effective ROI. This list represents both active and passive learning.

πŸ±β€πŸ’» B - FOCUS

%%{init: {'theme':'dark', 'themeVariables':{'textColor':'#FBB454', 'nodeBorder':'#00D7FF', 'lineColor':'#00FFAB'}}}%%
graph LR
    A[Development<br>Languages]==>A1(fa:fa-check-square Solidity<br>Top Priority for <br> POCs, testing)
    A --> A2(Rust<br>Tool Development)

    %% A1 - Solidity 
    A1 --> A11(Yul/Yul+ <br> Intermedia Assembly <br> for solidity)
    A1 --> A21(HUFF <br> Assembly for <br> high optomization)
    
    %% A3 - Pythonic
    A --> A3[Pythonic]
    A3 --> A31(Apeworx<br>Recommended for <br>DS & Sec for web3)
    A3 --> A32(Vyper<br>Considered for<br>fast development)
    A3 --> A33(EthBrownie<br>Being used for <br>writing POC's)

    %% Website Click Links 
    %% Solidity 
    click A1 href "https://soliditylang.org/" "Click Solidity Language" _blank
    click A11 href "https://docs.soliditylang.org/en/v0.8.15/yul.html" "Click Yul Language" _blank
    click A21 href "https://docs.huff.sh/" "Click Huff Language" _blank
    
    %% Rust 
    click A2 href "https://doc.rust-lang.org/rust-by-example/" "Click Rust by example" _blank

    %% Pythonic 
    click A31 href "https://academy.apeworx.io/" "Click ApeWorkx Academy" _blank
    click A32 href "https://vyper-by-example.org/" "Click Vyper By Example by Smart Contract Programer" _blank
    click A33 href "https://eth-brownie.readthedocs.io/en/stable/" "Click Eth-Brownie" _blank

    
    

Warning

There is no perfect language, Solidity is Turing Complete , but has a learning curve, Rust is new comer closest to C Lang, pythonic variants make it faster to build dapps. Some of them are used specifically for executing MEV.

Other upcoming general languages of interest

  1. Carbon Lang - Developed by google, trying to be a successor to C++
  2. WebAssembly - Shipped to major browsers, Multiple known web frameworks now support compiling to web assembly for building webapps

πŸ±β€πŸ’» B1 - Solidity

  1. Maximum number of dapps are written in solidity on the ETHereum chain.
  2. TVL locked on chain stats - The maximum amount of TVL(total volume locked) in on Ethereum. This chain has some problems
    1. Excessive amount of time to confirm a trx , sometimes takes hours
    2. Problem of Frontrunning, Sandwich attacks & MEV
  3. Regardless of the above mentioned problems, as of writing this , his thing called the METAVERSE is taking shape, which is fundamentally a VR game with a social component and in game economics that run on smart contracts.
  4. Majority of the bug bounty programs on Immunefi

B1A - Yul / Yul+

  1. Yul is an intermediate language that gets compiled to bytecode.
    1. Playground - Online compiler to learn to use and understand yul lang
%%{init: {'theme':'dark', 'themeVariables':{'textColor':'#FBB454', 'nodeBorder':'#00D7FF', 'lineColor':'#00FFAB'}}}%%
graph LR
    A[Solidity]-->B(YUL)
    B-->C(bytecode)
  1. The point of using YUL/YUL+ is to write highly optomized and gas efficient code, it is a form of Solidity Assembly
    1. Assembly allows direct manipulation of the memory slots
    2. These assembly instructions use the EVM OpCodes
      1. You can identify an assembly block (YUL) with the code enclosed with assembly {
// Assembly solidity abstraction 
contract xyz {
    constructor {
        assembly {
            mstore(xx,xx)
            mload(xx,ss)
        }
    }
}
  • The instructions under assembly {...} ae used for direct manipulation of the variables in the EVM

Eg: YUL Based contract, which has been referenced from a recent code challenge - Source

πŸ”Ž CLICK/TAP TO REVEAL EXAMPLE CODE
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract UnhackableToken is ERC20 {
    mapping(address => uint256) nonce;
    constructor() ERC20("Unhackable Token", "UhT") {}
    function metaTransferFrom(
        address from,
        address to,
        uint256 amount,
        uint256 v,
        uint256 r,
        uint256 s
    ) public {
        uint256 _nonce = nonce[from];
        unchecked { ++ nonce[from]; }
        assembly {
            let ptr := mload(0x40)
            calldatacopy(ptr, 0x04, 0x60)
            mstore(add(ptr, 0x60), _nonce)
            let digest := keccak256(ptr, 0x80)
            mstore(ptr, digest)
            mstore(add(ptr, 0x20), v)
            mstore(add(ptr, 0x40), r)
            mstore(add(ptr, 0x60), s)
            let verified := staticcall(gas(), 0x01, ptr, 0x80, 0x00, 0x00)
            if iszero(verified) { revert(0x00, 0x00) }
        }
        _transfer(from, to, amount);
    }
}

This code can be tested in REMIX

Forge Yul Contract Compile Demo

The following is a terminal recording of the process of compilation of a yul(.yul) contract. forge will compile assembly blocks (inline assembly) via forge build

Commands explanation

#![allow(unused)]
fn main() {
forge init --no-commit --no-git <dir>
}
  • Here I am making a directory that doesnt have any preset commits (--no-commit) and it is not being initialized as a git repo(--no-commit), since I intended to only do some local testing
#![allow(unused)]
fn main() {
forge install --no-commit --no-git <library>
}
  • The above switches will also ensure that the library will be installed as as subdirectory, and not as as git submodule , so that you can push it your repository. This is also a good hack to download a git repository as a subdirectory without having to tinker with git sobmodules or subtrees

B1B - HUFF

  1. This language is used for writing highly optimized code for the EVM. Optomizing meaning-
    1. Fewer lines of code
    2. Cognizant of the gas cost per function call
    3. Enabling faster execution by using simpler logic
  2. Huff exposes the inner workings of the EVM and exposes it for manipulation
    1. Huff directly compiles to EVM op codes
  3. Language is primarily composed of Macros
πŸ”Ž CLICK TAP TO REVEAL EXAMPLE HUFF CODE

Source -

  1. Tweet - Mentioned first in this tweet, code was released as CTF
  2. Deployed on OPTIMISM - This was the vault contract which was compiled from huff
  3. Solution trx hash. It was hacked 42 mins later
  4. Github Gist with the code

Code

// Welcome.
// Your objective is to capture the Ether in this contract.
// Whatever you capture, you keep.
// The clock is ticking. Good hacking.

// -------------------------------------------------------------------------------------------------
// VAULT CONTRACT START

// -------------------------------------------------------------------------------------------------
// ABI DEFINITION

#define function owner() view returns (address)
#define function setOwner(address) nonpayable returns (bool)
#define function deposit() payable returns ()
#define function withdraw() nonpayable returns ()

#define event Deposit(address,uint256)
#define event Withdrawal(uint256)
#define event OwnerSet(address)

// -------------------------------------------------------------------------------------------------
// CONSTANTS

#define constant OWNER_SLOT = FREE_STORAGE_POINTER()
#define constant DEPOSIT_HASH = 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c
#define constant WITHDRAWAL_HASH = 0x4e70a604b23a8edee2b1d0a656e9b9c00b73ad8bb1afc2c59381ee9f69197de7
#define constant OWNERSET_HASH = 0x50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe2

// -------------------------------------------------------------------------------------------------
// MACROS

// Requires the msg.value to not be zero
#define macro PAY_UP() = takes (0) returns (0) {
    callvalue       // [msg.value]
    iszero          // [is_msg_value_zero]
    iszero          // [is_msg_value_non_zero]
    payed           // [payed_jumpdest, is_msg_value_non_zero]
    jumpi           // []
    0x00 0x00 revert
    payed:
}

// Returns owner address to caller
#define macro GET_OWNER() = takes (0) returns (0) {
    [OWNER_SLOT]    // [owner_slot]
    sload           // [owner]
    0x00            // [offset, owner]
    mstore          // []
    0x20            // [size]
    0x00            // [offset, size]
    return          // []
}

// Definitely does not... como se dice... pull the rug
#define macro NOT_A_RUG_PULL() = takes (0) returns (0) {
    PAY_UP()
    0x04            // [arg0_offset]
    calldataload    // [arg0]
    dup1            // [arg0, arg0]
    0x45            // [magic_number, arg0, arg0]
    lt              // [lt_magic_number, arg0]
    loop            // [loop_jumpdest, lt_magic_number, arg0]
    jumpi           // [arg0]
    0x00 0x00 revert
    loop:           // [arg0]
        0x01        // [one, arg0]
        swap1       // [arg0, one]
        sub         // [result]
        dup1        // [result, result]
        0x45        // [magic_number, result, result]
        eq          // [is_magic_number, result]
        iszero      // [not_magic_number, result]
        loop        // [loop_jumpdest, not_magic_number, result]
        jumpi       // [result]

    // come and take it.
    WITHDRAW()

    not_valid:
        0x00 0x00 revert
}

// Sets a new owner.
// Authentication is checked in the function selector switch.
#define macro SET_OWNER() = takes (0) returns (0) {
    0x04            // [arg0_offset]
    calldataload    // [arg0]
    [OWNER_SLOT]    // [owner_slot, arg0]
    sstore          // []

    caller          // [topic1]
    [OWNERSET_HASH] // [topic0, topic1]
    0x00            // [size, topic0, topic1]
    dup1            // [offset, size, topic0, topic1]
    log2            // []

    0x01            // [success]
    0x00            // [offset, success]
    mstore          // []
    0x20            // [size]
    0x00            // [offset, size]
    return          // []
}

// Deposits tokens into the contract.
// Since withdrawal is permissioned to the owner, there is no need to have accounting.
// We log here for indexers.
#define macro DEPOSIT() = takes (0) returns (0) {
    callvalue       // [msg.value]
    iszero          // [is_msg_value_zero]
    iszero          // [is_msg_value_non_zero]
    deposited       // [deposited_jumpdest, is_msg_value_non_zero]
    jumpi           // []
    0x00 0x00 revert

    deposited:
        callvalue       // [msg.value]
        0x00            // [offset, msg.value]
        mstore          // []

        caller          // [topic1]
        [DEPOSIT_HASH]  // [topic0, topic1]
        0x20            // [size, topic0, topic1]
        0x00            // [offset, size, topic0, topic1]
        log2            // []
}

// Withdraws tokens from contract.
// Authentication is checked in the function selector switch.
#define macro WITHDRAW() = takes (0) returns (0) {
    selfbalance     // [balance]
    0x00            // [retSize, balance]
    dup1            // [retOffset, retSize, balance]
    dup1            // [argSize, retOffset, retSize, balance]
    dup1            // [argOffset, argSize, retOffset, retSize, balance]
    dup5            // [value, argOffset, argSize, retOffset, retSize, balance]
    caller          // [msg.sender, value, argOffset, argSize, retOffset, retSize, balance]
    gas             // [gasleft, msg.sender, value, argOffset, argSize, retOffset, retSize, balance]
    call            // [success, balance]
    success         // [success_jumpdest, success, balance]
    jumpi           // [balance]

    pop             // []
    0x00            // [size]
    dup1            // [offset, size]
    revert          // []

    success:
        0x00                // [offet, balance]
        mstore              // []

        [WITHDRAWAL_HASH]   // [topic0]
        0x20                // [size, topic0]
        0x00                // [offset, size, topic0]
        log1                // []
}

// Authenticates the msg.sender
// If is the owner, jump to the `jumpdest`, else revert
#define macro AUTHENTICATE() = takes (0) returns (0) {
    // takes:       // [jumpdest]
    caller          // [msg.sender, jumpdest]
    [OWNER_SLOT]    // [owner_slot, msg.sender, jumpdest]
    sload           // [owner, msg.sender, jumpdest]
    eq              // [is_owner, jumpdest]
    authenticated           // [jumpdest, is_owner]
    jumpi           // []
    0x00            // [size]
    dup1            // [offset, size]
    revert          // []
    authenticated:  // []
}

// -------------------------------------------------------------------------------------------------
// CONSTRUCTOR

#define macro CONSTRUCTOR() = takes (0) returns (0) {
    caller          // [msg.sender]
    [OWNER_SLOT]    // [owner_slot, msg.sender]
    sstore          // []
    DEPOSIT()
}

// -------------------------------------------------------------------------------------------------
// ENTRY POINT

#define macro MAIN() = takes (0) returns (0) {
    0x00 calldataload 0xe0 shr

    // Permissionless function selectors
    dup1 0x8da5cb5b eq get_owner jumpi
    dup1 0x69696969 eq i_wonder_wat_this_does jumpi
    dup1 0xd0e30db0 eq deposit jumpi

    // Every function from here on is authenticated.
    // We do one check for gas and size efficiency.
    AUTHENTICATE()

    // Authenticated functions selectors
    dup1 0x13af4035 eq set_owner jumpi
    dup1 0x3ccfd60b eq withdraw jumpi

    // No selector matched. As a fallback (because we love money),
    // we'll return to ensure any accidental Ether sent is locked :)
    // Get rugged, turds.
    0x00 0x00 return

    // Permissionless macros
    get_owner:
        GET_OWNER()
    i_wonder_wat_this_does:
        NOT_A_RUG_PULL()
    deposit:
        DEPOSIT()

    // Authenticated macros
    set_owner:
        SET_OWNER()
    withdraw:
        WITHDRAW()

    // If we haven't returned by this point, we'll just return.
    0x00 0x00 return
}

// -------------------------------------------------------------------------------------------------
// VAULT CONTRACT END