Skip to content

Commit

Permalink
chore: update README.md and comment size tracking
Browse files Browse the repository at this point in the history
Signed-off-by: MASDXI <[email protected]>
MASDXI committed Dec 26, 2024

Verified

This commit was signed with the committer’s verified signature.
1 parent 6d6fdbf commit 53797e1
Showing 3 changed files with 50 additions and 78 deletions.
84 changes: 28 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
@@ -11,38 +11,30 @@ Purpose: "Dissertation"
<img src="./docs/assets/banner.png" width="450"/>
</h1>

# Forest: Unlocking Control & Traceability in Digital Currency System

## Abstract

> TODO
> TODO
**Keyword: Anti-Money Laundering (AML), Central Bank Digital Currencies (CBDC), Counter Financial Terrorism (CFT), Distributed Ledger Technology (DLT), Smart Contract**
## Motivation

## Introduction
The present-day Central Bank Digital Currency concept aims to utilize the advantages of blockchain or Distributed Ledger Technology (DLT) that provide immutability, transparency, and security, and adopts smart contracts, which plays a key feature in creating programmable money. However, technology itself gives an advantage and eliminates the problem ideally of compliance with the regulator and AML/CFT standard, but it does not seem practical to be done in the real world and is not efficiently responsible for the financial crime or incidents that occur in the open network of economic.

The present-day Central Bank Digital Currency concept aims to utilize the advantages of Blockchain Technology or Distributed Ledger Technology that provide immutability, transparency, and security, and adopts smart contracts, which plays a key feature in creating programmable money. However, technology itself gives an advantage and eliminates the problem ideally of compliance with the regulator and AML/CFT standard, but it does not seem practical to be done in the real world and is not efficiently responsible for the financial crime or incidents that occur in the open network of economic.
## Specification

## Related Works
> TODO
> Opinion: AI and Deep learning recognize and analyze the pattern, but it'd be nice if the data structure also provided a more efficient and fast response to the incident.
## Rationale

- [ERC20](https://eips.ethereum.org/EIPS/eip-20) fungible token intended to be currency-like, but the data structure is account-based, making it hard to separate money when it's mixed with the total balance.
- [ERC721](https://eips.ethereum.org/EIPS/eip-721) not suitable due to metadata not being stored on-chain, it can be modified to support, but it's not intended to be exchangeable.
- [ERC1155](https://eips.ethereum.org/EIPS/eip-1155) metadata problem is the same as `ERC721`, however, `ERC1155` can utilize tokenId as root, it can freeze the balance for each account, but it ends up with you can't to separate the money when it's stored in the total balance.
- [ERC1400](https://eips.ethereum.org/EIPS/eip-1400) have characteristic base from `ERC20` but extended functionality for freeze account or freeze balance.
- [ERC3643](https://eips.ethereum.org/EIPS/eip-3643) have characteristic same as `ERC1400` but extended functionality for store the document and other feature.
- [ERC-20](https://eips.ethereum.org/EIPS/eip-20) fungible token intended to be currency-like, but the data structure is account-based, making it hard to separate money when it's mixed with the total balance.
- [ERC-721](https://eips.ethereum.org/EIPS/eip-721) not suitable due to metadata not being stored on-chain, it can be modified to support, but it's not intended to be exchangeable.
- [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) metadata problem is the same as `ERC-721`, however, `ERC-1155` can utilize tokenId as root, it can freeze the balance for each account, but it ends up with you can't to separate the money when it's stored in the total balance.
- [ERC-1400](https://eips.ethereum.org/EIPS/eip-1400) have characteristic base from `ERC-20` but extended functionality for freeze account or freeze balance.
- [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) have characteristic same as `ERC-1400` but extended functionality for store the document and other feature.
- [MerkleTree](https://www.geeksforgeeks.org/blockchain-merkle-trees/) not suitable for the payment due to its need to maintain the root hash and generate proof every time.
- [UTXO](https://www.geeksforgeeks.org/what-is-unspent-transaction-output-utxo/) maintain the amount of money or group of money in each individual `transaction`. To spend the `transaction`, the caller needs to be the `owner` of the `transaction` that needs to be spent.
- [eUTXO](https://docs.cardano.org/about-cardano/learn/eutxo-explainer/) extended version of `UTXO`, purpose of `eUTXO` is adding/carrying additional data as `extraData` or `payload` in the transaction.

## Methodology

Introduce implementation call `Forest` used the way to modified the state to keep tracking subtree avoid to creating transaction output for change back the to spender like in `UTXO`.

## Conclusion and Evaluation

| Features | ERC20 | UTXO | eUTXO | Forest |
| Features | ERC-20 | UTXO | eUTXO | Forest |
| ------------------------------------------------------------------- | ----- | ---- | ----- | ------ |
| freeze the `sender` account. |||||
| freeze the `recipient` account. |||||
@@ -51,16 +43,16 @@ Introduce implementation call `Forest` used the way to modified the state to kee
| freeze the specifics `tokenId` or `TxId` that relevant to the root. |||||
| keep tracking child/subtree. |||||

- For `ERC20` provide events and keep tracking each `Transfer`,
but the problem is the `ERC20` model can't separate `clean money` from `dirty money`,
due to the `ERC20` not have `tokenId` to keep tracking each token when it's move.
- For `ERC721` its use non-fungible, each token is unique and not intend to keep tracking amount or value.
- For `ERC1400`, includes features like partitioned balances,
- For `ERC-20` provide events and keep tracking each `Transfer`,
but the problem is the `ERC-20` model can't separate `clean money` from `dirty money`,
due to the `ERC-20` not have `tokenId` to keep tracking each token when it's move.
- For `ERC-721` its use non-fungible, each token is unique and not intend to keep tracking amount or value.
- For `ERC-1400`, includes features like partitioned balances,
allowing tokens to be split into subsets based on conditions or rules (e.g., restrictions, investor categories).
It also supports document management, enabling the attachment of legal documents to tokens, and integrates with compliance mechanisms,
ensuring that transfers comply with rules like KYC/AML checks. However,
`ERC1400` tokens still face challenges in tracking the history or provenance of individual tokens beyond their partitioned states.
- For `ERC1155` improves upon ERC20 and ERC721 by offering more flexibility and reducing operational overhead,
`ERC-1400` tokens still face challenges in tracking the history or provenance of individual tokens beyond their partitioned states.
- For `ERC-1155` improves upon ERC-20 and ERC-721 by offering more flexibility and reducing operational overhead,
it does not inherently provide a way to distinguish between `clean` and `dirty` tokens,
as it lacks the ability to track individual token histories like `UTXO` models do.
- For `UTXO` and `eUTXO` facing challenge to combine multiple `UnspentTransaction` and spent as one,
@@ -72,15 +64,15 @@ Introduce implementation call `Forest` used the way to modified the state to kee
- For `Forest` use to modify an existing state rather than create a new output transaction, like in `UTXO` or `eUTXO` do,
it allows spending the transaction multiple times till it's met `0`, The `Forest` model enables tracking of child/subtree structures,
providing a hierarchical view of token flows and relationships,
which is not possible in traditional token standards like `ERC20`, `ERC721`, `ERC1155`, `ERC1400`, and `ERC3643`.
which is not possible in traditional token standards like `ERC-20`, `ERC-721`, `ERC-1155`, `ERC-1400`, and `ERC-3643`.

## For Further Work
## Security Considerations

Currently, `Forest` not 100% compatible with existing `ERC20` standard.
To complete and fully supported `ERC20` interface `Forest` require to have automatically select and spent the transaction.
However it's doesn't need to be store each transaction in sorted list.
Currently, `Forest` not 100% compatible with existing `ERC-20` standard.
To complete and fully supported `ERC-20` interface `Forest` require to have automatically select and spent the transaction.
However, it doesn't need to be store each transaction in sorted list.

- Rewrite the contract not inherit ERC20 from `@openzeppelin/contracts` can reduce unnecessary `gasUsed`.
- Rewrite the contract not inherit ERC-20 from `@openzeppelin/contracts` can reduce unnecessary `gasUsed`.
- Adopting `FIFO` or First-In-First-Out style which is can be done in smart contract but should be considering the `gasUsed`.
- Second off-load heavy computation from the smart contract to a custom pre-compiled contract.
- Third create a stateful pre-compiled contract that fully functional same as the smart contract specification.
@@ -94,26 +86,6 @@ Additionally, once a transaction's output has been spent, it can be marked as sp
which further complicates the ability to trace the flow of funds. While these strategies are effective in managing state size,
they can hinder users' ability to follow transaction trails, making it difficult to verify the origins of funds.

## Glossary of Terms

**AML** Anti-Money Laundering
**B2G** Back to Genesis
**CBDC** Central Bank Digital Currency
**CFT** Counter Financial Terrorism
**C2C** Customer to Customer
**DLT** Distributed Ledger Technology
**eUTXO** Extended Transaction Output
**KYC** Know Your Customer
**UTXO** Unspent Transaction Output

## Reference

<div align="center">
<img src="./docs/assets/reports/BOT-rCBDC-Fraud-Handling01.png" width="450"/>
<p style="text-align: center;"><em>Conceptual Feasibility Fraud Handling from rCBDC BOT report page 33.</em></p>
</div>

<div align="center">
<img src="./docs/assets/reports/BOT-rCBDC-Fraud-Handling02.png" width="450"/>
<p style="text-align: center;"><em>Comparison of As is and To be (Conceptual) from rCBDC BOT report page 33.</em></p>
</div>
## Copyright

Copyright 2024 Sirawit Techavanitch. Licensed under the [Apache-2.0](./LICENSE)
24 changes: 12 additions & 12 deletions contracts/abstracts/ForestToken.sol
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
abstract contract ForestToken is ERC20, IForestERC20 {
using Forest for Forest.Forest;

Forest.Forest private _trees;
Forest.Forest private _ledger;

/**
* @dev Constructor to initialize the ERC20 token with a name and symbol.
@@ -30,7 +30,7 @@ abstract contract ForestToken is ERC20, IForestERC20 {
* @return The transaction details.
*/
function _transaction(address account, bytes32 tokenId) internal view returns (Forest.Transaction memory) {
return _trees.transaction(account, tokenId);
return _ledger.transaction(account, tokenId);
}

/**
@@ -41,17 +41,17 @@ abstract contract ForestToken is ERC20, IForestERC20 {
* @param value The amount of tokens to transfer.
*/
function _transfer(address from, address to, bytes32 tokenId, uint256 value) internal virtual {
Forest.Transaction memory txn = _trees.transaction(from, tokenId);
_trees.spendTransaction(Forest.TransactionInput(tokenId, value), from);
_trees.createTransaction(
Forest.Transaction memory txn = _ledger.transaction(from, tokenId);
_ledger.spendTransaction(Forest.TransactionInput(tokenId, value), from);
_ledger.createTransaction(
Forest.TransactionOutput(value, to),
txn.root,
tokenId,
Forest.calculateTransactionHash(from, _trees.transactionCount(from)),
Forest.calculateTransactionHash(from, _ledger.transactionCount(from)),
from
);
if ((txn.value - value) == 0) {
_trees.consumeTransaction(tokenId, from);
_ledger.consumeTransaction(tokenId, from);
}
_update(from, to, value);
}
@@ -62,11 +62,11 @@ abstract contract ForestToken is ERC20, IForestERC20 {
* @param value The amount of tokens to mint.
*/
function _mintTransaction(address account, uint256 value) internal {
_trees.createTransaction(
_ledger.createTransaction(
Forest.TransactionOutput(value, account),
Forest.calculateTransactionRootHash(),
bytes32(0),
Forest.calculateTransactionHash(address(0), _trees.transactionCount(address(0))),
Forest.calculateTransactionHash(address(0), _ledger.transactionCount(address(0))),
address(0)
);
_mint(account, value);
@@ -79,10 +79,10 @@ abstract contract ForestToken is ERC20, IForestERC20 {
* @param value The amount of tokens to burn.
*/
function _burnTransaction(address account, bytes32 tokenId, uint256 value) internal {
if (value == _trees.transactionValue(account, tokenId)) {
_trees.consumeTransaction(tokenId, account);
if (value == _ledger.transactionValue(account, tokenId)) {
_ledger.consumeTransaction(tokenId, account);
} else {
_trees.spendTransaction(Forest.TransactionInput(tokenId, value), account);
_ledger.spendTransaction(Forest.TransactionInput(tokenId, value), account);
}
_burn(account, value);
}
20 changes: 10 additions & 10 deletions contracts/libraries/Forest.sol
Original file line number Diff line number Diff line change
@@ -12,7 +12,8 @@ library Forest {
*/
struct Transaction {
bytes32 root; // Root hash of the transaction
bytes32 parent; // Parent transaction hash
bytes32 parent; // Parent transaction hash (previous tx)
// @TODO adding ownership address parent (previous tx ownership)
uint256 value; // Value associated with the transaction
}

@@ -68,7 +69,6 @@ library Forest {
* @dev Structure representing a forest contains multiple unbalance-tree of transactions for a specific account.
*/
struct Forest {
mapping(address => uint256) size; // Number of transactions for each account
mapping(address => uint256) nonces; // Nonce (transaction count) for each account
mapping(address => mapping(bytes32 => Transaction)) trees; // Mapping of account to transaction trees
mapping(bytes32 => uint256) hierarchy;
@@ -230,7 +230,7 @@ library Forest {
txOutput.value
);
self.nonces[creator]++;
self.size[txOutput.account]++;
// self.size[txOutput.account]++;

emit TransactionCreated(id, root, creator, txOutput.account);
}
@@ -274,7 +274,7 @@ library Forest {
revert TransactionNotExist();
}
self.trees[account][id].value = 0;
self.size[account]--;
// self.size[account]--;

emit TransactionConsumed(id);
}
@@ -298,10 +298,10 @@ library Forest {
* @param account The address of the account.
* @return The size (number of transactions) for the account.
*/
function size(
Forest storage self,
address account
) internal view returns (uint256) {
return self.size[account];
}
// function size(
// Forest storage self,
// address account
// ) internal view returns (uint256) {
// return self.size[account];
// }
}

0 comments on commit 53797e1

Please sign in to comment.