# 1 - Contemporary Contracts

## **Dev Toolchain and Workspace Setup**

**Creating Your Smart Contract Workspace:**

* Use the `l1x-forge` command to create a new project workspace:

```bash
l1x-forge new --name "your repository name" --template l1x-ft
```

**Understanding Configuration Files and Default Settings:**

* Explore `devbox.json` and `l1x-conf/l1x_chain_config.yaml` for workspace and chain configuration.

**Getting Started with the Devbox Shell**

#### **Activating the Devbox Shell:**

* &#x20;cd into your repository and activate the Devbox shell to install necessary packages:

```
devbox shell
```

**Using Workspace Workflow Script Commands**

**List Available Script Commands:**

* View available script commands in your devbox shell:

```
devbox run -l
```

**Specifying the Chain Type:**

In the configuration file `l1x-conf/l1x_chain_config.yaml`, specify the chain type for deploying and working with the workspace contract. Choose between `beta_mainnet` or `local_devnet` based on your development and deployment needs.

**Initializing Setup**

```bash
devbox run 01_init_setup
```

**Starting the Devnode Services:**

To start the devnode services, use this command:

```plaintext
devbox run 02_start_devnode
```

**Checking DevNet Service Status:**

To ensure everything is functioning smoothly, use the following commands to check the service status:

```plaintext
devbox run 02_check_chain_state
devbox run 02_check_devnet_db_state
```

These commands provide insights into the DevNet service status, confirming that the services are initialized and operational.

**Using Workspace Workflow Script Commands**

This section introduces the workspace's workflow script commands that you can use. Here is a list of supported commands:

**List Available Script Commands:** To see a list of available script commands, use the following command in your devbox shell:

```
devbox run -l | sort
```

This will list all the available script commands, such as:

```
* 01_init_setup
* 01_teardown_setup
* 02_check_chain_state
* 02_check_devnet_db_state
* 02_prune_devnode
* 02_start_devnode
* 02_stop_devnode
* 10_compile
* 10_compile_ebpf_cmd
* 11_clean
* 11_clean_logs
* 12_deploy_contract
* 13_init_contract
* 15_ft_token_balance_ava
* 16_ft_token_balance_bobby
* 17_ft_token_balance_emma
* 18_mint_to_emma
* 30_chk_balance_super
* 31_chk_balance_ava
```

####

## **Building and Deploying the Smart Contract**

**Compile the Contract:**

* Compile your contract with the following command:

```
devbox run 10_compile
```

**Deploying the Contract:**

* Deploy the compiled contract and note the displayed contract address:

```
devbox run 12_deploy_contract
```

**Initializing the contract**

```
devbox run 13_init_contract
```

**Function Invocation**

1. **Invoke the ft\_mint() Function:**
   * Invoke `ft_mint()` to mint tokens from Ava's account to Emma's account, updating the contract address in the file `l1x-conf/scripts/010-20-uc-mint-ava-to-emma.json`:

```bash
devbox run 18_mint_to_emma
```

* **Invoke the ft\_balance\_of() Function:**
  * Check the token balance status of Emma's account by invoking `ft_balance_of()`, ensuring the contract address from step 9.2 is updated in the file `l1x-conf/scripts/010-05-uc-check-emma-balance.json`:

```bash
devbox run 17_ft_token_balance_emma
```

**Cleanup and Troubleshooting**

1. **Stopping Devnode Services:**
   * Stop the devnode services with this command:

```bash
devbox run 02_stop_devnode
```

* **Cleaning Up Service Resources and Storage:**
  * Release resources and storage space with this command:

```bash
devbox run 02_prune_devnode
```

## **Contract | Code Explainer**

1. **Overview of FT Contract:**
   * The FT (Fungible Token) Contract in the L1X platform is a standard implementation for handling fungible tokens within the ecosystem. It allows for the creation, transfer, and management of tokens that have identical value to each other, facilitating a wide range of decentralized applications and financial solutions.
2. **Contract Structure and Code Explanation:**\
   The `L1xFtErc20` struct in the code defines the main structure of the token contract. It holds metadata about the token, a map of account addresses to their balances, a map for allowances, and a variable for total supply.

**`L1xFtErc20` Structure**

```rust
pub struct L1xFtErc20 {
    metadata: FTMetadata,
    balances: LookupMap<Address, u128>,
    allowances: LookupMap<Address, FTAllowance>,
    total_supply: u128,
}
```

\
**Initialization of the Contract: `new` Method**

The `new` method is used to initialize the contract with metadata, account IDs, and amounts. It ensures that the function caller is the contract owner and then sets up the initial balances for the provided account IDs.

```rust
pub fn new(
    metadata: FTMetadata,
    account_ids: Vec<Address>,
    amounts: Vec<U128>,
) {
    assert_eq!(
        caller_address(),
        contract_owner_address(),
        "Only the owner can call this function"
    );

    let mut contract = Self {
        metadata,
        balances: LookupMap::new(STORAGE_BALANCES_KEY.to_vec()),
        allowances: LookupMap::new(STORAGE_ALLOWANCES_KEY.to_vec()),
        total_supply: Default::default(),
    };
    contract.initialize_balance_holders(account_ids, amounts);
    contract.save();
}
```

**Minting Tokens: `ft_mint` Method**

The `ft_mint` method allows the contract owner to mint new tokens for a specified recipient. It updates the total supply and the balance of the recipient.

```rust
pub fn ft_mint(recipient_id: Address, amount: U128) {
    assert_eq!(
        caller_address(),
        contract_owner_address(),
        "Only the owner can call this function"
    );

    let mut contract = Self::load();
    contract.mint(&recipient_id, amount.0);
    contract.save();
}
```

#### Transferring Token&#x73;**: `ft_transfer` Method**

The `ft_transfer` method allows a user to transfer a specified amount of tokens to a recipient account. The function ensures that the sender has enough balance to make the transfer.

```rust
pub fn ft_transfer(recipient_id: Address, amount: U128) {
    let mut contract = Self::load();
    let sender_id = l1x_sdk::caller_address();
    contract.transfer(&sender_id, &recipient_id, amount.into());
    contract.save()
}
```

#### Querying Balanc&#x65;**: `ft_balance_of` Method**

The `ft_balance_of` method allows one to query the balance of a specific account in the contract. It returns the balance as a `U128` type.

```rust
pub fn ft_balance_of(account_id: Address) -> U128 {
    let contract = Self::load();
    contract.balance_of(&account_id).unwrap_or_default().into()
}
```

##
