---
# System prepended metadata

title: zkBNB - Bread and Butter
tags: [solidity, tutorials, BNB]

---

---
title: zkBNB - Bread and Butter
description: A complete overview of the Solidity programming language. There are many resources out there for Solc programmer, however, I feel like they are boring and they do not encapsulate the full inner workings of the language itself. I feel like it is best to have a working document that can be updated over time. 
lang: en
html: en
author: Dylan Kawalec
---
# zkBNB - Bread and Butter
###### tags: `tutorials`, `solidity`, `BNB`
> *zkBNB - Bread and Butter* is an easy to understand guide to help you write smart contracts on the zkBNB chain. It uses **metaphors**, **similies**, and **visualizations** that will help you enjoy learning Solidity programming and avoid feeling like you're bashing your head against a wall. Building layer 2 scaling solutions is exciting and will add a lot of value to new and existing projects living in the BNB ecosystem. 🎅

---
# Table of Contents

###### [Web 1.0](#web-1) : 
- This section provides a general overview of Solidity and Binance Smart Chain, including **installation** instructions and a review of **fundamental concepts** such as types, conditions, and functions.
    - Covering the basics of blockchain ✅
    - Setting up your Binance Work Station ✅
        - setting up a **zkBNB** project
    - Breaking down variables and functions for BNB ✅
    - Learning how we can be expressive in our code and control our contract's structure ✅
###### [Web 2.0](#web-2) : 
- Things to do on **zkBNB** vs **BSC** ?
    - Thoughrough breakdown of zkBNB
- **Writing**, **testing** and **debugging** smart contracts on zkBNB (6)
    - Smart contracts on zkBNB. 
        - **BEP20/721/1155**
        - Exploring REST API's for zkBNB
            - Bridging **BEP2**<>**BEP20**<>**zkBNB** pegged tokens

- *Functions, Modifiers* and *Fallbacks*(7)
- Exceptions, Events and Logging (8)
- Fundamentals Of Truffle (9)
- Debugging Contracts (10)
###### [Web 3.0](#web-3) : 
- Prioritizing **security** and **upgradability** when working with contracts handling large amounts of money in Solidity. In this section, we'll delve into the details of **Assembly code** and **token contracts** to learn various **design patterns** and become proficient in Solidity programming.

    - *Further reading for stress testing zkBNB to build games with added privacy.*  (**TBD**)

        - Exciting use cases that I believe are now avaiable to developers that would like to integrate zkBNB into a new or existing project


---
--- 
#  Web 1.0
- Instead of reading the all of ethereum's documentation, the [Bridge Builders DAO](https://bridge-builders.gitbook.io/bbd/welcome-builder-start/learning-the-blockchain/0.1-evm-ethereum) has already synthesized all of it into a single page document that you can read. This will give you a general overview of how most EVM blockchains work. 

## Spawing the chain

Ethereum compatible blockchains such as the **[Binance Smart Chain](https://academy.binance.com/en)**, are decentralized distributed databases (DDD) that have no single point of failure. Servers maintain the state of the DDD using with what's known as a ledger, which records every entry made by anyone in the world. When a person stakes, or invests, in a blockchain, they have shared ownership of it. This shared ownership cannot be changed, making the ledger immutable. In other words, it cannot be altered or tampered with. Additionally, these blockchains are transparent, meaning that all transactions and entries are visible to everyone. They are also resistant to corruption, making them secure and reliable for recording and storing data.

In a blockchain system, accounts update the current state of the ledger, or database, through a process called a transaction. **Smart contracts** are self-executing contracts with the terms of the agreement between buyer and seller being directly written into lines of code. These contracts act as intermediaries for users to interact with the blockchain ledger and facilitate the execution of transactions. Transactions are processed and temporarily separated from the main ledger, and then eventually added back onto the chain, updating the state of the ledger for all users to see. In this way, smart contracts and transactions work together to update and maintain the current state of the blockchain ledger.

Blockchains are designed to be **trustworthy**, **autonomous**, and resistant to the need for intermediaries or middlemen. This means that no one person or group owns the entire chain, and no one person is responsible for managing accounts or processing transactions. Instead, the network of users collectively maintains the integrity and security of the blockchain. Smart contracts are self-executing contracts with the terms of the agreement written into lines of code, and they play a key role in facilitating transactions and interactions on the blockchain. Because they operate independently and do not require a central authority to enforce their terms, smart contracts are often referred to as decentralized autonomous organizations **(DAOs)**.

users sign transactions using a combination of public and private keys, which are used for highly sophisticated cryptographic purposes. This process is commonly referred to as **symmetric** and **asymmetric** key encryption. The private key is a unique code that is used to sign and authorize a transaction, while the public key is a unique code that is used to identify the user and verify the authenticity of the transaction. Together, these keys enable secure and reliable communication and transactions on the blockchain. 

**By the way, never share your private key with anyone, only your public key.** 

Blocks have a *fingerprint* known as a **hash**, which has a fixed length that is formed using the input data being collected in each block in the block chain. This is stored on the blockchain 

- If you want to play with SHA-256, [click here](https://passwords-generator.org/sha256-hash-generator). Try typing in your name and gernating a hash. Change it, and watch the hash change. Then try changing it back to the original input value you started with. 

Every account has a unique finger print. Know one will ever be able to decrypt your hash to discover the original input value, unless you gave it away. This is commonly reffered to as your **key phrase**.

When we make transactions on the blockchain, we use **digital signatures** to prove that the transaction is legitimate and can be trusted. A digital signature is created using a private key, which is a unique code that only the owner of the key knows. To sign a transaction or contract, we use our private key to create a digital signature.

The network of servers validating the blockchain, known as nodes, can then verify the authenticity of the transaction by checking the digital signature against the corresponding public key. The public key is a unique code that is associated with the private key, and it is used to identify the user and verify the authenticity of the transaction. By validating the public key, the nodes can confirm that the transaction was indeed signed by the owner of the private key, and they can trust that the transaction is valid. 

> A digital signature is like a special writing that only you can make.
It's used to prove that you did something online or sent a message.
Your computer uses a special "key" to make the digital signature.
When someone else gets the message or sees what you did, their computer checks the signature.
If the signature is correct, they know it was really you. If not, they might not trust it.

## Binance Governance 
- [Read the BSC white Paper](https://github.com/bnb-chain/whitepaper/blob/master/WHITEPAPER.md)
### [Beacon Chain Governance](https://docs.bnbchain.org/docs/beaconchain/governance)
![](https://i.imgur.com/VN4DHHc.png)
### [Binance Smart Chain Governance](https://docs.bnbchain.org/docs/learn/bsc-gov)
![](https://i.imgur.com/E1VJ2UX.png)



Blockchain technology is designed to be a trustless and fair system for managing assets. Trustless refers to the fact that the system does not rely on any central authority or intermediary to enforce rules or facilitate transactions. Instead, it relies on the collective power of the network of users to maintain the integrity and security of the system. This means that individuals do not have to trust any one person or entity to ensure that their assets are being handled fairly and securely.

"*Radically fair*" refers to the fact that the system is designed to be transparent and unbiased. All transactions and interactions on the blockchain are recorded and visible to all users, and the rules for the system are predetermined and cannot be altered by any single person or group. This ensures that all users are treated equally and that the system operates in a fair and transparent manner.

However, the concept of radical fairness is closely tied to the idea of [**consensus**](https://docs.bnbchain.org/docs/learn/consensus). In BNB blockchain network, consensus refers to the process of **agreeing on the state** of the ledger, including both blocks that have already been stored and blocks that will be stored in the future. There have been many different consensus models proposed by various blockchain networks, each with varying levels of complexity. 


[![Binance Smart Chain Picture](https://i.imgur.com/NtF0s7S.png)](https://docs.bnbchain.org/docs/zkbnb/zkbnb-overview/)

In the case for the Binance Smart Chain, it uses a [**Proof of Authority Stake**](https://docs.bnbchain.org/docs/beaconchain/learn/architecture) consensus, which simply means that validators must verify they are trusted before being issues keys to stake and validate the BNB chain. 

> **Please read the [Bridge Builder DAO](https://bridge-builders.gitbook.io/bbd/welcome-builder-start/learning-the-blockchain/0.1-evm-ethereum) to get more information about how all of this works under the hood for Ethereum's POS network.** 



## Accountability
### Accounts

> **We'll see this keyword `External` in Solidity later.** 

**External account**: This refers to a user who has a public and private key. The first 160 out of the 256 characters of the public key are used for people to share with others, while the private key is kept secret and never shared with others.

- BSC Account:   `0xa19dEf1C91fD63615E03caAF0d5EAF2Eba81fFFc`

This `account` holds a `balance`, and can execute **functions** in **smart contracts**. 

**Contract accounts**:  These do not have a private key, but they do contain code that can be executed if an **external signer** uses the appropriate amount of `gas` to execute the contract on the blockchain. In the case for BSC, you have a 140M gas ceiling per block. 
When people buy things, they perform a **transaction**, which costs a fee that is consumed by miners; that fee is the gas users or contracts spend. 

*Where* or *who* is responsible for paying the fee, is denoted using the `from` keyword. 
Where the transaction's ether is going to, is denoted using the `to` keyword-- and the `value` keyword is the amount of ether being passed between acounts.


---
--- 
--- 
## Testing Smart Contracts
Go to [remix](https://remix-project.org/) and watch [Youtube](https://www.youtube.com/watch?v=WmeWbo7wzGI) to figure out how to use it with other blockchains you want to program for. Or you can make really fast progress and read this [Harmony tutorial](https://bridge-builders.gitbook.io/bbd/welcome-builder-start/building-a-currency/1.2-hrc-20-harmony-token) and launch your first token (STEP-BY-STEP). This process of launching a token on Harmony would be the same as ethereum, or binance; just make sure you are using a BNB wallet when interacting with the code on remix. You can use this faucet to get test BNB tokens 

## First, Hello Solidity.
```solidity!
pragma solidity 0.8.1;

// This is the contract definition
contract HelloSolidity {
  // This is a private state variable
  string private message;

  // This is the constructor function
  constructor() public {
    // Initialize the message variable
    message = "Hello, Solidity, that was super easy...";
  }

  // This is a public function that returns the value of the message variable
  function getMessage() public view returns (string memory) {
    return message;
  }
}

//if you read this line by line, don't try to memorize anything, just read it slowly. You will see how simple it is, even if this new to you. 
```

> Solidity compiles this code into **[byte code](https://medium.com/@eiki1212/explaining-ethereum-contract-abi-evm-bytecode-6afa6e917c3b)**, which is then converted into **[Opcode](https://ethereum.org/en/developers/docs/evm/opcodes/)** instructions that are stored in the stack and processed using memory. After compilation, the memory is discarded and any data in the machine state is transferred to the **World state**, which is the storage associated with the blockchain. 
> To much storage can be expensive, so it is generally best practice to write shorter and simpler contracts to minimize costs! 
> Defining the `pragma` version is also a good practice for ensuring the security of your contract 😉

#### ABI := `external` & `public` functions + (parameters) & `return` types.
- **ABI** is important because it **defines** contracts for what they are, and allows anyone, the callers, to **invoke** the contract **externally**. It's also what makes the contract ***unique***.  


#### Bytecode := Low level instructions for the compiler, which uses Opcode to interpret the meaning of these instructions. 
- later on I'll describe how the compiler works under the hood once we start talking about assembly code, but that's not important right now. 
- Remember **Bytecode** and **ABI**

###### Further reading
>If you want to get a super head start, synthesize any developer portal of your choice, such as [Binance's](https://bnbdev.community) to see how they would summarize their fundamental blockchain concepts. All chains are different, and not all blockchains use Solidity -- check that first to see if this is even worth your time. 

---
## EVM compiler "cliff note"
![](https://i.imgur.com/LzWi2hF.png)
![](https://i.imgur.com/IjxvtSB.png)
![](https://i.imgur.com/sI9Xyo1.png)

--- 


# Building on Binance Smart Chain

BNB has several chains to choose from to build your contracts. 

1. BNB (Binance Beacon Chain)
- This is where the [Binance DEX](https://www.binance.com/en) lives, and where all **staking** and **voting** occurs.

2. [**BSC**](https://www.bnbchain.org/en/developers) (Layer One [Binance Smart Chain](https://docs.bnbchain.org/docs/bnbIntro))
- Any smart contract can be deployed here.


3. [**zkBNB**](https://docs.bnbchain.org/docs/zkbnb/zkbnb-overview/) (Layer Two Zero-Knowledge Rollup Chian)
- Gaming, NFT, AMM & Metaverse chain. This is a performance chain meant to make transactions cheaper and faster, but will only be compatable with *some* contract logic. Read the [zkBNB Docs](https://github.com/bnb-chain/zkbnb/) to learn more. 


4. [**BAS**](https://www.bnbchainlist.org) (Binance Side-Chain)
- "Customizable Layer Two Blockchain". These side-chains can also leverage zkBNB chain as their own rollup system as well, and are essentially copy's of the Binance Smart Chain with limited validator's running the nodes. Side-Chains have the same security features as the Binance Smart Chain. 

5. [TBD] - [The Future](https://docs.bnbchain.org/docs/dev-outlook/scaling)
6. [TBD] - [is Near](https://docs.bnbchain.org/docs/dev-outlook/scaling)
---
### *BNB Architecture Graphics*
![](https://i.imgur.com/Fagvtt2.png)
### [Binance Side-Chain](https://docs.bnbchain.org/docs/BNBSidechain/overview/bs-overview)
![](https://i.imgur.com/ave0esl.png)

### [zkBNB](https://docs.bnbchain.org/docs/zkbnb/zkbnb-overview)
![](https://i.imgur.com/JYZjtY0.jpg)

--- 
---
# Setting up your [Binance Workstation](https://bnbdev.community/community)

In this overview, we will be discussing how to build smart contracts in Solidity for the zkBNB chain. The zkBNB chain is a fast and efficient Layer 2 blockchain that is suitable for use with **non-fungible tokens** (NFTs), **games**, **automated market makers** (AMMs), and **tokens**. The focus of this tutorial will be on creating contracts for these types of assets, as most of the custom Solidity logic is typically used in these types of applications. **zkBNB** has built in liquidity pools, Native Name Services, an NFT marketplace 'out-of-the-box', 10,000 TPS and 100x lower fee's while still using  native BEP20 tokens.

The process of writing a smart contract on the Binance Smart Chain is the same as the process for writing a smart contract on the zkBNB chain. The steps and considerations involved in writing a smart contract are the same for both chains. 

## Important links! 👩🏼‍💻
**Main network**: [zkBNB Main Repository](https://github.com/bnb-chain/zkbnb)
- ["zkBNB SDK"](https://github.com/bnb-chain/zkbnb-go-sdk) : The `ZkBNB Go SDK` provides a thin wrapper around thin all the apis provided by ZkBNB, including a simple key manager for signing txs and sending signed txs to ZkBNB.
- ["Layer 2 ZkBNB Rollup Library"](https://github.com/bnb-chain/zkbnb-crypto): `zkbnb-crypto` is the crypto library for ZkBNB Protocol. It implements rollup block circuit and supports exporting groth16/plonk proving key, verifying key and solidity verifier contract
- [Layer One & Two Communitcation Contract](https://github.com/bnb-chain/zkbnb-contract): The above framework shows that the `zkbnb-contract` is one of the core components, it is the entrance and exit of L2 ecosystem. `zkbnb-contract` achieves full security of the BSC layer 1, and acts as the communication relayer between the zkBNB chain and the BSC chain. It also gives us a "full exit" request in case the user can request through L1 smart contract to withdraw funds if he thinks that his transactions are censored by ZkBNB.

**Test network**: [BSC Testnet](https://testnet.bscscan.com/)

### Scaffold
- [BSC Truffle Starterbox ](https://bnbdev.community/library/scaffolds/seSdZOOFjg) (Good to have)


### Tools
- [Nodereal BNB](https://nodereal.io/bnb-dev-tools) (Custom)
- [zkBNB Wallet](https://test.zkbnbchain.org/wallet)


### Final Project: Full stack zkBNB
- [BSC Full stack guide](https://github.com/bnb-chain/bnb-chain-tutorial/tree/main/01-%20Hello%20World%20Full%20Stack%20dApp%20on%20BSC) (without zkBNB integration)

> It is important to keep the following links open and accessible as you progress through this tutorial. You should have these links open in separate tabs so that you can easily refer to them as needed.

---
### Prepare your zkBNB Workstation
You will need to make sure you have your developer workstation ready to go: Refer to the following packages: 

- instead of using `geth`, we will be using the Binance cli instead.
```
npm install -g @binance-chain/cli
```
- **Node.JS**: 
    - Download the latest stable version of Node.js from the official website (https://nodejs.org/) or using a package manager such as Homebrew (for macOS) or APT (for Linux).
    - Follow the installation instructions provided by the Node.js website or package manager to install Node.js and npm on your system.
    - Once Node.js and npm are installed, you can verify that they are correctly installed by running the following commands:
        ```
        node -v
        ```
        ```
        npm -v
        ```
    - In case you need to change the version of node to a specific version in case this tutorial becomes to outdated, then run the `brew install nvm` and run `nvm use ##.##.##` to change the version of node. You can easily switch between version of node/npm by running `brew switch node 12.22.0`.




- [**Ganache-cli**](https://trufflesuite.com/ganache/) 
    - This is a local blockchain environment tool which we'll use to interact with the binance client's private key to test our application locally. 
    - You're welcome to download the cli version instead of the complete application. However, it is easier to configure tests using the application. It's totally your preference. 
        ```
        npm install -g ganache-cli
        ```
        
- [**Solidity**](https://docs.soliditylang.org/en/latest/solidity-by-example.html)
    - We'll install solidity globally to our system.
        ```
        npm install -g solc
        ```
    - Check to see that it was installed correctly. 
        ```
        solc --version
        ```
    - Keep in mind that these instructions are for installing Solidity globally on your system. If you only want to install Solidity for a specific project, you can use the `npm init` command to create a new `package.json` file for your project and then use npm install to install Solidity as a dependency for your project.
    - if npm is not working, then install it using **homebrew**
        ```
        brew install solidity
        ```
        `solc --version`

- **Wallet**
    * You're welcome to use either **Metamask**, or **trust wallet**. 

    - [Metamask testnet configuration](https://www.coincarp.com/chainlist/binance-smart-chain-testnet/) 

- [**Web3**](https://github.com/web3/web3.js) : the version you will be using will already be configured using `truffle` but you're welcome to install it globally; however, it's not nessesary. 

- **Truffle**: `npm install -g truffle` & `truffle version`

    - If you only want to install Truffle for a specific project, you can use the `npm init` command to create a new `package.json` file for your project and then use npm install to install Truffle as a dependency for your project.



---
# Setting up zkBNB Workstation
1. zkBNB SDK + Truffle + .env, .secret, 
---
--- 
# Smart Contracts on zkBNB


 
---
---
---
---

# Breaking down variables and functions


### State Variables 🌐
- **bool**(`bool`): A boolean type that can store either "true" or "false". (1 or 0)

- **uint8/256**(`uint`): An unsigned integer type that can store only positive numbers. The size of the type (8 or 256 bits) determines the range of values it can hold.

- **int8/256**(`int`): A signed integer type that can store positive or negative numbers. The size of the type (8 or 256 bits) determines the range of values it can hold.

- **bytes**(`bytes1`, `bytes4`...): A fixed-size byte array that can hold up to 32 bytes of data.

- **address**(`address`): A special type that represents an Ethereum account address. It is a 20-byte value.

- **Payable address**(`payable`): A special type of address that can receive ether through the .send and .transfer methods.

- **enumerations** (`enum`) are custom data types that represent predefined constants. They must have at least one member and cannot have a semicolon at the end. Enums cannot be declared within functions and can be updated using modifiers.

- **reference types** in Solidity include arrays, structs, and strings. These types are stored in memory and are passed "by reference" when assigned to variables or passed as function arguments.

- **mapping**: A key-value data structure that cannot be declared within functions or used as state variables. Mappings can be "*passed by reference*" in a function if there is a state variable, but they cannot be iterated through using the "=>" operator.

- **array**: A type that can hold a fixed or dynamic number of elements of the same type. Arrays of strings or bytes are considered "***special***" arrays.

- **struct**: A reference type data structure that can hold a combination of different types.
``` solidity 
function exampleFunction(bool inputBool, uint8 inputUint8, int8 inputInt8, bytes inputBytes, address inputAddress, payable inputPayableAddress, enum MyEnum inputEnum, mapping(uint => uint) inputMapping, array inputArray, struct MyStruct inputStruct) public returns (bool outputBool, uint8 outputUint8, int8 outputInt8, bytes outputBytes, address outputAddress, payable outputPayableAddress, enum MyEnum outputEnum, mapping(uint => uint) outputMapping, array outputArray, struct MyStruct outputStruct) {
    outputBool = inputBool;
    outputUint8 = inputUint8;
    outputInt8 = inputInt8;
    outputBytes = inputBytes;
    outputAddress = inputAddress;
    outputPayableAddress = inputPayableAddress;
    outputEnum = inputEnum;
    outputMapping = inputMapping;
    outputArray = inputArray;
    outputStruct = inputStruct;
}
```
```solidity 
enum MyEnum {
    Option1,
    Option2,
    Option3
}

struct MyStruct {
    uint a;
    string b;
    bool c;
}

```
> In Solidity, when values are "**passed by value**," the values in the memory location are copied to the target location. When values are "**passed by reference**," a pointer to the memory location is copied, creating a new variable instance that refers to the original data.

### State Variables and their Qualifiers 🌎

- **Internal**: Cannot be modified by external functions or contracts.
- **External**: Can be modified by external functions or contracts through an interface.
- **Private**: Owned by the contract and not accessible to derived contracts.
- **Public**: Accessible through a "getter" function.

    **Modifiers:**
    > Constant: Immutable and cannot be modified.
    New: Only applies to contracts or arrays, and allows them to be created dynamically.

    **Functions**:
    >View: Alias for constant functions, which do not modify the contract's state.
    Pure: Does not read or write to the contract's state.
    Payable: Can accept ether, and will fail if the sender does not provide enough ether.

    **Literals**:
    >String literals: Surrounded by single or double quotes.
    Numeric literals: Integers or floats.
    Hexadecimal literals: Prefixed with "0x".

    **Arrays**:
    >Dynamic arrays: Can be modified using methods such as .pop, .push, and .length (except for strings).
    Fixed arrays: Cannot be modified.

    **Methods**:
    >.balance: Returns the balance of an address type.
    .call, .delegateCall, .callcode: Used to call functions on other contracts.
    .send, .transfer: Used to send ether to another address.
    
    ```solidity 
    pragma solidity ^0.8.0;
    import "https://github.com/binance-chain/smart-contract-standards/blob/master/smart-contract-standards/contracts/BEP20.sol";
    //This Contract uses every Qualifier mentioned above.

    contract zkBNBContract is BEP20{
        // Variables with different visibility and mutability
        internal uint internalVariable;
        external uint externalVariable;
        private uint privateVariable;
        public uint publicVariable;

        // Constant variable
        uint constant variable = 0;

        // New variable
        uint[] public newVariable;

        function setInternalVariable(uint newValue) internal {
            internalVariable = newValue;
        }

        // View function
        function getInternalVariable() view public returns (uint) {
            return internalVariable;
        }

        // Pure function
        function add(uint a, uint b) pure public returns (uint) {
            return a + b;
        }

        // Payable function
        function sendEther(address recipient, uint amount) payable public {
            require(msg.value >= amount, "Insufficient BNB sent.");
            recipient.transfer(amount);
        }

        // String literal
        string public stringLiteral = "This is a string literal.";

        // Numeric literal
        uint public numericLiteral = 42;

        // Hexadecimal literal
        bytes32 public hexLiteral = 0x1234abcd5678ef01;

        // Dynamic array
        uint[] public dynamicArray;

        // Fixed array
        uint[3] public fixedArray;

        function modifyDynamicArray() public {
            // Modify dynamic array
            dynamicArray.push(1);
            dynamicArray.pop();
        }

        function getArrayLength() public view returns (uint) {
            // Get length of dynamic array
            return dynamicArray.length;
        }

        function getBalance() public view returns (uint) {
            // Get balance of contract
            return address(this).balance;
        }

        function callOtherContract() public {
            // Call function on another contract
            address(otherContract).call(bytes4(keccak256("functionName()")));
        }

        function sendEtherToAddress() public {
            // Send ether to another address
            address(recipient).send(1 ether);
        }
    }
    ```

### Storage and Memory 💽
In Solidity, a **modifier** is a special type of function that is executed before a target function. The underscore character ('_') is used as a placeholder to indicate the target function, and the rest of the code in the modifier is executed before the target function.

The "**payable**" modifier is used to indicate that a function can accept ether as an argument. It is often used in conjunction with the "**require**" keyword in a modifier to check the balance of the sender before executing the function. *The "payable" modifier is usually placed in the return statement for functions*.

The "**msg.sender**" variable represents the address of the sender of the current message or transaction.

In Solidity, there are three types of memory: **storage, memory, and calldata.**

>**Storage**: Global and permanent, with assignments creating a new copy in storage.
**Memory**: Temporary and only exists during the execution of a function. Assignments to memory variables from state variables create a new copy in memory. Assignments of memory variables to other memory variables do not copy the data into storage.
**Calldata:** Contains the arguments of a function and is not modifiable.
The stack is a data structure in Solidity that is used to store state variables and function arguments. It has a depth of 1024 levels, and attempting to go beyond this depth will cause an exception to be thrown.
```solidity!
pragma solidity ^0.8.0;
import "https://github.com/binance-chain/bep1155-sol/bep1155.sol";
/*This contract examplifies  the use of storage, memory, and calldata in Solidity. It also includes the use of stack, modifiers, and payable functions, as well as state and memory variables.
*/
contract MySuperCoolZKBNBContract is BEP1155{
    // Payable function with require modifier
    function doSomething(uint value) payable public {
        // Check balance of sender before executing function
        require(msg.value >= value, "Insufficient BNB sent.");

        // Do something
    }

    // Modifier function
    modifier onlyOwner {
        // Check if sender is owner
        require(msg.sender == owner, "Only the owner can execute this function.");

        // Execute target function
        _;
    }

    // Target function with modifier
    function doSomethingElse(uint value) onlyOwner public {
        // Do something else
    }

    // State variable
    address public owner;

    // Memory variable
    uint[] memory array;

    // Function that uses storage, memory, and calldata
    function modifyArray(uint[] calldata newArray) public {
        // Assign value of calldata variable to memory variable
        array = newArray;

        // Modify storage variable
        owner = msg.sender;

        // Push value to memory array
        array.push(1);
    }

    // Function that uses stack
    function testStack() public {
        // Create variables on stack
        uint value1 = 1;
        uint value2 = 2;
        uint value3 = 3;
        uint value4 = 4;
        uint value5 = 5;
    }
}
```

### Variable composition with Functions | ⼬
In Solidity, a struct is a *custom data* type that consists only of variables and mappings. It is used to group related data together and can be used in place of multiple separate variables.

An **event** is a mechanism in Solidity that allows external calls to be notified about the state of the contract. Events are stored on the blockchain in the "LogsBloom" data structure and can be used to track the history of a contract. The "emit" keyword is used to raise an event and notify external calls.

A **function** in Solidity is a block of code that can be executed by calling it with the "**this**" keyword. There can be only one unnamed function per contract, known as the "**fallback function**," which is executed when no function name is specified. Functions can use the "**return**" keyword to specify a value to be returned to the caller.

Variables declared in function arguments are stored in "*calldata*" or "*memory*" depending on the type of the variable. If a variable is declared within a function, it is stored in "*memory*." If it is a reference type, it must be declared as such. References in functions with "*storage*" should point to state variables in the contract. Arguments supplied by modifiers (callers) are stored in "calldata" or "*memory.*"

The "**keccak256**" function is a cryptographic hash function that generates a hash of the argument passed to it. It is commonly used in Solidity to create unique identifiers or to verify the integrity of data.

## **Solidity Variables & Functions**

All variables in Solidity have a scope and can be marked as `public`, `private`, or `internal`. 

For example: 
`uint64 <scope> nameVariable = 0;`

### Type Conversion

It is possible to change the type of a variable in Solidity. There are two types of conversion:

1. **Implicit conversion**: this occurs when you convert one data type to another in a way that is legal in Solidity and requires no special handling. For example, converting a uint8 to a uint16 is an implicit conversion.

2. **Explicit conversion**: this occurs when you need to convert one data type to another and implicit conversion is not possible. In this case, you can use a function like `ConversionExplicit<type>to<type>() pure public {...} ` to perform the conversion. You can also use `Conversion<type>to<type>() pure public {...}`.

It is generally not a good idea to try to convert basic primitive types to other types that are not compatible, such as integers to strings. However, you can use the byte type to convert any data type to a byte type, which can then be converted into other types using conversion functions.

### **Transaction and Message Variables**
Block and transaction global variables can be used to access information about the current state of transactions or blocks in the Ethereum network. This is known as logging.
#### **Transaction and Message Variables**
- Event types: these are used to define the types of events that can be emitted by a contract. Examples include `event logstring(string)`, `event loguint(uint)`, `event logbytes(bytes)`, `event logaddress(address)`, `event logbyte4(bytes4)`, and `event logblock(bytes32)`.
- `block.difficulty`, `block.gasLimit`, and `block.timestamp` can be used to access information about the current block.
- `blockhash(block.number)` can be used to retrieve the hash of the current block.

- `gasLeft()`, `tx.gasprice`, `msg.data`, `msg.sig`, `msg.value`, `msg.sender`, and `tx.origin` can be used to access information about the current transaction or message.

- The **emit** keyword can be used to log events or access global variables. For example, `emit logaddress(block.coinbase)` will log the miner's address as an event, and `emit logblock(blockhash(block.number))` will log the hash of the current block as an event.

#### **Cryptographic Variables**

1. **sha256**: A cryptographic hash function that is used to generate a fixed-size string (the hash) from an input. It is also known as "SHA2".
2. **keccak256**: Another cryptographic hash function that is used to generate a hash from an input. It is also known as "SHA3" and is more widely used than sha256.


#### **Address Variables**
> **Remember this, “6 for 3”. This means, 6 global functions and 3 global properties**
> 
> `< address >.func(argument) … return(parameter)`
- **transfer**: a global function that sends tokens (or ether) to a specified address.
- **send**: another global function that sends tokens (or ether) to a specified address, but it returns a boolean value indicating whether the transfer was successful.
- **call**: a global function that is used to execute a function in another contract and can modify the state of that contract.
    - **staticcall**: a global function that is used to execute a function in another contract, but it *does not allow the called contract to modify* the state of the calling contract.
    - **delegatecall**: a global function that is used to execute a function in another contract, but it executes the function in the context of the calling contract, giving the function access to the storage and balance of the calling contract rather than its own contract.
- **ecrecover**: a global function that is used to verify the sender of a message using their digital signature. It takes four arguments: messageHash, v, r, and s. It is only available in assembly and is typically used to verify off-chain computations, DIDs (Decentralized Identifiers), or addresses on DEXs (Decentralized Exchanges).
    > `ECDSA` is Elliptic Curve Digital Signature Algorithm
    > `s` takes the first 32 bytes of a Digital Signature
    > `r` is the Digital Signature from position 66-130 == 32 bytes
    > `v` is the last 1 byte of the Digital signature

    ##### **Address Properties**
    - **balance**: A "getter" property that retrieves the balance held by any address.
        - **code**: a property that returns the bytecode associated with a contract's creation in another format.
        - **codehash**: same thing but returns the contracts creation*in the form of a hash*.

#### Contract Universal Variables 
- **this**: a personal reference to the contract for any public methods.
- **super**: a reference to the contract that is being inherited by the current contract.
- **now**: a built-in global variable that returns the current block timestamp.
- **tx**: a built-in global variable that contains information about the current transaction, such as tx.gasprice, tx.origin, and tx.value.
- **block**: a built-in global variable that contains information about the current block, such as block.difficulty, block.gasLimit, block.number, and block.timestamp.

    ###### Special Variables 
    - `_`: a placeholder variable that can be used as a placeholder for an unused function argument or as a loop index.
    - `__LINE__`: a built-in global variable that returns the current line number in the contract source code.
    - `__FILE__`: a built-in global variable that returns the current file name of the contract source code.
    - `__FUNCTION__`: a built-in global variable that returns the current function name.

# Being expressive in our code and control our contract's structure

We have `if else`, `while`, `do while`, `for`, `break`, `continue` and `return`.

> A **`break`** statement is used to exit a loop early, before the loop's condition becomes false. When a break statement is encountered inside a loop, control is immediately transferred to the statement following the loop.
> A **`continue`** statement is used to skip the rest of the current iteration of a loop and move on to the next iteration. When a continue statement is encountered inside a loop, control is immediately transferred to the loop's increment statement, skipping any remaining code in the current iteration.
> A **`return`** statement is used to exit a function early and return a value to the caller. When a return statement is encountered inside a function, control is immediately transferred out of the function, and the specified value (if any) is returned to the caller. The function execution ends, and any remaining code in the function is not executed.



### **All loops** (by example)
``` solidity
pragma solidity 0.8.0;

enum zkBNB {
  BSC,  // Binance Smart Chain
  ETH,  // Ethereum
  KNC,  // Kyber Network
  ZEN,  // Horizen
}

contract ZkBNBExample {
  function exampleControlStructures(zkBNB chain) public returns (bool) {
    if (chain == zkBNB.BSC) {
      // code for Binance Smart Chain
      return true;
    } else if (chain == zkBNB.ETH) {
      // code for Ethereum
      return true;
    }

    uint count = 0;
    while (count < 10) {
      if (chain == zkBNB.KNC) {
        break;  // exit the while loop early
      }
      count++;
    }

    do {
      if (chain == zkBNB.ZEN) {
        continue;  // skip the rest of the do-while loop and move to the next iteration
      }
      // code to be executed in the do-while loop
    } while (count > 0);

    for (uint i = 0; i < 5; i++) {
      if (chain == zkBNB.ETH) {
        return false;  // exit the function early
      }
      // code to be executed in the for loop
    }

    return true;
  }
}

```
---
- **if-else** loop
``` solidity
if (condition1) {
  // code to be executed if condition1 is true
} else if (condition2) {
  // code to be executed if condition1 is false and condition2 is true
} else {
  // code to be executed if neither condition1 nor condition2 is true
}
```
- **While** loop
```solidity!
uint count = 10;
// code to be executed as long as the condition is true. Our condition is 'count'
while (count > 0) {
  // code to be executed as long as count is greater than 0
  count--;  // decrement count by 1
}

```
- **do...while** loop
```solidity!
pragma solidity 0.8.0;

contract Example {
  event ActionCompleted(uint id);

  function doAction(uint id) public {
    do {
      // code to execute the action
      emit ActionCompleted(id);  // emit an event when the action is completed
    } while (!hasActionCompleted(id));  // continue looping until the action is completed
  }

  function hasActionCompleted(uint id) public view returns (bool) {
    // code to check if the action with the given id has completed
  }
}
```
- **for loop**
```Solidity!
pragma solidity ^0.6.0;

contract Example {
  mapping(uint => string) public names;

  function printNames() public {
    for (uint i = 0; i < names.length; i++) {
      // code to print the key-value pair to the console
      console.log(i, ":", names[i]);  // prints "0: Alice", "1: Bob", etc.
    }
  }
}
```
---
- **Return** Statements (two ways of using it)
```solidity!
function foo(uint a) public returns (bool, uint) {
  // code to calculate the return values
  return (true, a * 2);
}
```
--- 
---
---

# [Web 2.0](#web-2)


## Things to do on **zkBNB** vs **BSC** ?
> - zkBNB: Architectural Overview, “How dApp’s on BSC will become faster and cheaper”.
>
> - zkBNB Developer workstation guide, “zkBNB workstation set-up.”
> 
> - zkBNB token API guide: How to work with zkBNB list of REST-API’s 
>
> - zkBNB Smart Contract guide: Testing BEP20/721/1155’s on Layer 2
> 
> - zkBNB NFT marketplace tutorial: How to Create, Mint, Transfer, BUY/SELL, Match and cancel orders 
> 
> - zkBNB Wallet tutorial: Bridging between BSC<>zkBNB, and using the Full method.
## zkBNB Arcitectural Overview
**ZkBNB** is a decentralized, zero-knowledge rollup platform that operates on the Binance Smart Chain, offering unlimited scalability with low fees, security, speed, and self-custody. 

It can handle up to **5,000 transactions per second** and support up to **100 million addresses**, making it well-suited for a wide range of use cases including *NFT minting and trading, gaming, DeFi pooling, AMM, and derivatives*. With easy-to-use SDKs and no need to deploy smart contracts within the ecosystem, zkBNB is an attractive choice for developers looking to build and deploy dApps. 

ZkBNB allows [for the issuance, use, payment, and exchange of digital assets in a secure and transparent manner](https://test.zkbnbchain.org/market). It works in conjunction with the Binance Smart Chain, sharing the same universe of tokens, including **BNB**, **BEP2**, and **NFT**. This means that the same token can be used on both networks and can easily be transferred between them, and the total supply of a token should be managed across both networks. 

To use ZkBNB, users can deposit tokens in a contract on the BSC and track their deposits through the **ZkBNB monitor**. From there, they can send transactions to the **committer** for processing and transfer any amount of funds to any existing account on ZkBNB. To withdraw from the platform back to the BSC, users simply need to initiate a withdrawal transaction, which will burn their funds on ZkBNB and unlock a corresponding amount of tokens on the BSC. [ZkBNB provides a convenient and efficient way for users to manage and use digital assets](https://test.zkbnbchain.org/wallet) on the Binance Smart Chain.

[![](https://hackmd.io/_uploads/rJL5Oybqo.png)](https://github.com/bnb-chain/zkbnb/#framework)

As you can see, there are several key components that make zkBNB operate smoothly and efficiently. 
It's very reminiscent of a well oiled car. 

The **committer** acts as the engine of the platform, executing transactions and producing consecutive blocks. The **monitor** is like a dashboard, providing important information and tracking events on the Binance Smart Chain. The **witness** acts like a transmission, re-executing transactions and shifting them into the correct position. The **prover** is like a GPS system, generating proof's based on the witness materials to guide the platform. The **sender** behaves like the gears of the car, rolling up compressed L2 blocks and *shifting* them into place on the L1 layer. 

The computational process for the ZkBNB platform occurs off-chain, while users' funds are held on the Layer 1 Binance Smart Chain. The proof is generated by the prover and returned to the platform through the **recovery tool**, which uses the **API server** to maintain communication. This allows for efficient, secure, and transparent management of digital assets on the ZkBNB platform. 

###### ZkBNB **Solves for the Side-Chain security & scalability problem.**
The [Binance Side-Chains](https://www.bnbchainlist.org) are designed to be compatible with a variety of technologies and do not use the same consensus mechanism or execution environment as the Binance Smart Chain. However, the **[BEP100](https://github.com/bnb-chain/BEPs/pull/132/files)** proposal suggests a way to create side chains that are compatible with the BSC and connect them through a native relayer hub. The security of the native relayer hub is ensured by the side chain itself. ZkBNB can effectively **address potential security issues** by using zkSNARK proofs, which offer the same level of security as the BSC. 

 ⭐️ With this in mind, we can see how dApps that function with BSC-compatible side chains, such as *games and marketplaces*, can have their own **copy of the BSC chain** while also taking advantage of the utilities offered by ZkBNB. 

###### Technology Specifics

ZkBNB publishes state data for every transaction that is processed off-chain on the BSC, which allows for independent validation of the state of the L2 chain and prevents malicious committers from censoring or freezing the chain. This **data is made available** to all network participants as **calldata**, and a default client is provided to replay all state on the Layer 2 based on this calldata. Transactions are finalized on the BSC's Layer 1 and generally settle within 10 minutes. However, the confirmation time for **state transitions is instant** and user's can continue to issue more transactions even if a committer halts transactions. In the event that transactions are halted, users can interact directly with the main-net's roll-up contract, making the system **censorship resistant**. 

###### Transaction lifecycle

A user initiates a transaction or priority operation which is processed by the committer and added to a block as a Rollup operation. Once the block is complete, the sender submits it to the ZkBNB smart contract as a block commitment and the proof for the block as a block verification. If the verification is successful, the new state is considered finalized and the logic of some Rollup transactions is checked by the smart contract.

###### Token Specifics 
zkBNB will only support **BEP20**, **BEP721**, and **BEP1155** tokens at a maximum of 65535 BEP20 tokens and 1099511627775 BEP721 tokens. Users will be able to deposit and transfer coins, while NFT's will be able to do the same as well as mint. 


These tokens will be interoperable with the BSC layer 1 address's using layer 2 `RegisterZNS` addresses, which act like a BSC account's layer One & Two addresses. This allows users to use the same address for both the BSC and zkBNB platforms. 
###### Token Functions 
###### [tokenomics](https://github.com/bnb-chain/zkbnb/blob/master/docs/tokenomics.md#list-token)
- The `AssetGovernance` contract manages all tokens on ZkBNB, and we add tokens using the `addAsset` which checks for `listingFee` and `listingFeeToken`

we have the typical `Transfer `, `Withdraw` functions avialable to us as well as other special functions...

![](https://hackmd.io/_uploads/rk1U5g-5j.png)


`EmptyTx`: This function is used to create a placeholder transaction on the blockchain, typically with no associated value or data. It may be used as a placeholder for future transactions or as a way to mark the completion of a previous transaction.

`CreateCollection`: This function allows for the creation of a new collection or group of non-fungible tokens (NFTs) on the platform.

`MintNft`: This function allows for the creation of a new NFT and its addition to an existing collection.

`TransferNft`: This function allows for the transfer of a particular NFT from one account to another.

`AtomicMatch`: This function allows for the atomic exchange of two specified NFTs between two accounts, ensuring that both parties agree to the exchange before it is completed.

`CancelOffer`: This function allows for the cancellation of a previous offer to exchange an NFT with another party.

`WithdrawNft`: This function allows for the withdrawal of a particular NFT from the platform or contract to an external account.

`Deposit`: This function allows for the deposit of a specified amount of a particular asset or token onto the platform.

`DepositNft`: This function allows for the deposit of a particular NFT onto the platform.

`FullExit`: This function allows for the full withdrawal of a specified amount of a particular asset or token from the platform to an external account.

`FullExitNft`: This function allows for the full withdrawal of a particular NFT from the platform to an external account.

`RegisterZNS`: This is a layer-1 transaction and a user needs to call this method first to register a layer-2 account

###### [Merkle Tree's ](https://github.com/bnb-chain/zkbnb/blob/master/docs/protocol.md#state-merkle-treeheight)
We have three unique trees on the platform: the `AccountTree`, [NftTree](https://github.com/bnb-chain/zkbnb/blob/master/docs/protocol.md#nfttree), and `AssetTree`. The` AccountTree` and `NftTree` each have a depth of 32, while the AssetTree has a depth of 16 and is a sub-tree of the AccountTree. The empty leaf for all of these trees is set to 0 for every attribute of every node.












## zkBNB Workstation Guide
"“zkBNB workstation set-up.”"

---
### Exploring all REST API's available on zkBNB
"How to work with zkBNB list of REST-API’s" 
###### Sharing an example:  `Bridging **BEP2**<>**BEP20**<>**zkBNB** pegged tokens`
--- 
### **Writing**, ~~**testing** and **debugging**~~ smart contracts on zkBNB (6)
"~~Testing~~ writting BEP20/721/1155’s that can be used on zkBNB's Layer 2 roll-up" 

#### **BEP20/721/1155**
- zkBNB NFT marketplace tutorial: How to Create, Mint, Transfer, BUY/SELL, Match and cancel orders 
- zkBNB Wallet tutorial: Bridging between BSC<>zkBNB, and using the Full method.

## Smart contracts on zkBNB. 
### *Functions, Modifiers* and *Fallbacks*(7)
### Exceptions, Events and Logging (8)
### Fundamentals Of Truffle (9)
### Debugging Contracts (10)





