# Credit-Debit

In this tutorial, we will show you how to create a credit-debit data tracking of an ERC-20 token using Blockflow CLI.&#x20;

Creating a credit-debit table on the blockchain offers enhanced security and transparency for financial transactions. This approach also facilitates seamless audits and reconciliations, as all transactions are permanently recorded and accessible as stored and managed at Blockflow.&#x20;

***

## Project Overview

The purpose of this tutorial is to teach you how to index ERC20 credit-debit data by creating databases for both. A short breakdown for the project is below -&#x20;

* Create a project directory and `cd` into it. Here' we will initialize the project and get the standard blockflow template according to the event to be indexed.
* Providing the appropriate schema.&#x20;
* Write the handler function to manage data from the tracked event.
* Test the project and verify the data stored over the databases.

***

## Setting up the project

* Download the Blockflow CLI using the command: `npm i -g @blockflow-labs/cli`. We can remove the -g tag if global installation is not required.&#x20;
* Create a project directory and `cd` into it to make it the present working directory.
* Use the `blockflow init` command to initiate the project.
* Below are the fields that need to be entered for the project. You can also let the default values for each field by pressing \[ENTER]. The last field requires you to select the instance trigger type with 4 choices. You can also add more than one trigger for a project.&#x20;

<figure><img src="https://3649849654-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWKI4iN0gfSv8mfprvkZT%2Fuploads%2F3WN634S9aKj7ymewOtvK%2Fimage.png?alt=media&#x26;token=cafc0269-31c0-4b5e-9315-03d0e482b3b7" alt=""><figcaption><p>The default values for the blockflow init command</p></figcaption></figure>

## Setting up the schema&#x20;

The below-mentioned schema is appropriate to track the credit-debit data for an ERC20 token transaction.&#x20;

```typescript
export interface ERC20Table {
  id: String;
  address: string;
  counterPartyAddress: string;
  tokenAddress: string;
  tokenName: string;
  tokenSymbol: string;
  rawAmount: number;
  rawAmountString: string;
  amount: string;
  amountString: string;
  usdValue: number;
  usdExchangeRate: number;
  transactionHash: string;
  logIndex: number;
  blockTimestamp: string;
  blockNumber: number;
  blockHash: string;
}
```

On placing the schema values at studio.schema.ts, use the command `blockflow typegen` to update the schema.ts file at `src/types`.&#x20;

***

## Writing the handler function&#x20;

Now we move onto writing the handler function to manage the data and populate the databases. We remove any unwanted handlers in the studio.yaml because it will generate unwanted handler files in the `src/handlers` directory.  We only require to track the data of the `Transfer` event so we remove all other handler. The final studio.yaml will look somewhat like this:&#x20;

```yaml
name: Project Apollo
description: A top-secret research project to the moon
startBlock: latest
userId: XXXXXXXX-XXXX-XXXX-XXXXXXXX-XXXXXXXX
projectId: XXXXXXXX-XXXX-XXXX-XXXXXXXX-XXXXXXXX
network: Ethereum
user: Jane-doe
schema:
  file: ./studio.schema.ts
execution: parallel
Resources:
  - Name: blockflow
    Abi: src/abis/blockflow.json
    Type: contract/event
    Address: "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3"
    Triggers:
      - Event: Transfer(address indexed,address indexed,uint256)
        Handler: src/handlers/blockflow/Transfer.TransferHandler
```

Use the command `blockflow codegen` to generate handler templates.

A `transfer.ts` file will appear in the handlers' directory with the template code as:&#x20;

```typescript
export const TransferHandler = async (
  context: IEventContext,
  bind: IBind,
  secrets: ISecrets,
) => {
  const { event, transaction, block, log } = context;
  const { from, to, value } = event;
```

We add import statements above this portion of code to import the schema, bignumber.js library which will be used later and lastly the tokenMetadata for the ERC20 token which is stored in `src/utils`.

```typescript
import { ERC20Table, IERC20Table } from "../../types/schema";
import BigNumber from "bignumber.js";
import { getTokenMetadata } from "../../utils/ERC20Metadata";
```

Now, before working onto populating the tables, we create two unique Id's, one for the credit table and the other for the debit one. We concatenate the prefix `credit` or `debit` based on the transaction type.&#x20;

```typescript
const uniqueIdcredit = `${transaction.transaction_hash}-${log.log_index}-"credit"`;
const uniqueIddebit = `${transaction.transaction_hash}-${log.log_index}-"debit"`;
```

We add the number of decimals to a variable declared by fetching it from the tokenMetadata because each token representation has a unique number of decimals. We place the amount of token value transferred in the variable valuebignumber. These variables are then used to create the amount fields for both the credit and debit tables. Bignumber.js is used over here as to prevent overflow of integers. We add a factor of multiplying by -1 in the debitAmount.

```typescript
const decimalsBigNumber = new BigNumber(tokenMetadata.decimals);
const divisionValue = new BigNumber(10).pow(decimalsBigNumber);
const valueBigNumber = new BigNumber(value.toString());
const amount = valueBigNumber.dividedBy(divisionValue).toString();
const debitAmount = valueBigNumber.dividedBy(divisionValue).times(-1).toString();
```

We now make the database connections and then query for a uniqueId, upon not getting an Id, we create a new document and populate it with the data for the respective table. Below is the code for DB binding and data popuation of the credit table. Similarly, we can populate the data for the debit table.

```typescript
const erc20CreditDebitDB: Instance = bind(ERC20Table);

  let erc20Table: IERC20Table = await erc20CreditDebitDB.findOne({
    id: uniqueIdcredit,
  });

  erc20Table ??= await erc20CreditDebitDB.create({
    id: uniqueIdcredit,
    address: address,
    counterPartyAddress: counterPartyAddress,
    tokenAddress: log.log_address,
    tokenName: tokenMetadata.tokenName,
    tokenSymbol: tokenMetadata.tokenSymbol,
    rawAmount: value,
    rawAmountString: value.toString(),
    amount: amount,
    amountString: amount.toString(),
    transactionHash: transaction.transaction_hash,
    logIndex: log.log_index,
    blockTimestamp: block.block_timestamp,
    blockNumber: block.block_number,
    blockHash: block.block_hash,
  });
```

Note that various fields in the table such as logIndex, blockNumber, etc. are populated by placing the respective values from blockflow's blockdata stored. Regarding the tokenMetdata, we create a tokenmetadata file in `src/utils` to store the data for a particular ERC20 token which is being tracked. The contents of the tokenMetadata file are below:

```typescript
interface TokenInfo {
  decimals: number;
  tokenName: string;
  tokenSymbol: string;
}

export const TOKENS: Record<string, TokenInfo> = {
  "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3": {
    decimals: 6,
    tokenName: "USD Ethena",
    tokenSymbol: "USDE",
  },
};

export const getTokenMetadata = (token: string) => {
  const findedToken = Object.keys(TOKENS).filter(
    (tokenAddr) => tokenAddr.toLowerCase() === token.toLowerCase(),
  );
  return TOKENS[findedToken[0]];
};
```

The token tracked over here for credit-debit tables is USDE(ethena).&#x20;

***

## Testing&#x20;

We use the below command to test if the handler logic is correct and the data gets stored on our specified collection in Mongo.

```bash
blockflow instance-test --startBlock <block number> --clean --range 10 --uri <connection string>
```

The \<block number> can be put of any range, but we can put it to `latest` if no opinion provided. The `— uri` holds the MongoDB connection URL which is tested locally shall be filled with `mongodb://localhost:27017/blockflow_studio`.&#x20;

Checkout the repo for credit-debit of USDE by Blockflow on [github](https://github.com/BlockFloww/cli-examples/tree/CreditDebit/CreditDebit).
