tp

Crypto1010 Developer Guide

Acknowledgements

Design & Implementation

Crypto1010 is implemented as a modular command-line application with clear separation between authentication, input parsing, command execution, domain model, and persistence.

Architecture overview

High-level architecture diagram

Parser and command subsystem

Structural view (class diagram)

The class diagram below introduces parser-to-command construction and core command hierarchy before runtime interactions.

Parser and command subsystem class diagram

Command execution flow

The following sequence diagram shows the standard command path after a user is authenticated:

Generic command execution sequence

  1. User enters a command string.
  2. Crypto1010 passes the raw input to Parser.
  3. Parser constructs a concrete Command object.
  4. Crypto1010 executes the command with the current in-memory Blockchain and WalletManager.
  5. On success, Crypto1010 persists both blockchain and wallet states when save is enabled for that session.
  6. If a save operation fails, the app exits to avoid continuing with potentially inconsistent persistence state.

Authentication subsystem

Structural view (class diagram)

The class diagram below introduces account credential management and password hashing structure used during login/registration.

Authentication subsystem class diagram

Key authentication behavior:

CLI shell, prompt, and tab completion

Design rationale:

Adding a new command

  1. Add the new keyword and description to CommandWord so it appears in help.
  2. Implement a new Command subclass in the command package.
  3. Update Parser.parse(...) to construct the new command.
  4. Add focused JUnit tests under src/test/java/seedu/crypto1010/command.
  5. Add a manual test case in this guide.

Blockchain and Block subsystem

This section documents the enhancement: the blockchain core (Blockchain, Block) and integrity-first validation flow that powers validate, send, and persisted-chain loading.

Scope of enhancement

Architecture-level design

The blockchain subsystem is centered on two model classes:

ValidateCommand delegates all integrity checks to Blockchain.validate(); command layer does not duplicate blockchain logic. BlockchainStorage.load() also invokes validate() after deserialization. This means both interactive validation and startup data loading use the same invariant checks, avoiding drift between runtime and persistence behavior.

At system level, the flow is:

  1. Commands mutate/query blockchain through Blockchain APIs.
  2. Blockchain owns block construction and linkage rules.
  3. Storage serializes/deserializes raw state.
  4. Validation logic gates acceptance of loaded data.

This keeps blockchain rules in one place and reduces the risk of inconsistent behavior between command paths.

Structural view (class diagram)

The class diagram below introduces the static structure before runtime interactions.

Blockchain class diagram

Component-level design

Block design choices:

Why this design:

Blockchain design choices:

Validation stages in Blockchain.validate():

  1. Structural checks:
    • chain non-empty
    • block index continuity (block.index == iteration index)
  2. Cryptographic consistency:
    • block.computeCurrentHash() equals stored block.currentHash
  3. Data quality:
    • no blank/null transactions
  4. Genesis constraints:
    • previous hash equals fixed genesis predecessor
    • transaction data is exactly Genesis Block
  5. Linkage checks for non-genesis blocks:
    • block.previousHash == previousBlock.currentHash
  6. Economic/semantic checks:
    • transaction format must match sender -> receiver : amount
    • amount must be positive
    • sender must have sufficient running balance
    • exempt accounts (e.g., network, network-fee) bypass balance enforcement

Balance validation strategy

Validation uses a running Map<String, BigDecimal> keyed by normalized account names.

Rationale:

Block append behavior from transfer flow

SendCommand delegates to TransactionRecordingService, which composes one or two transaction strings (transfer + optional fee) and calls Blockchain.addTransactions(...).

Blockchain.addTransactions(...):

This ensures hash linkage is always created from canonical in-memory state, not externally supplied values.

Interaction views (sequence diagrams)

Validation flow:

Blockchain validation sequence

Append flow during send:

Block append sequence

Persistence interaction

BlockchainStorage serializes blocks to JSON and reconstructs them on load. After parsing JSON into Block objects, it calls validate(). Invalid chains are rejected with an IOException, and app startup falls back to a safe default chain. This prevents partially tampered or malformed persisted state from silently entering runtime.

Alternatives considered

  1. Recompute balance on demand for each transaction during validation without a running map:
    • Rejected because it is less efficient and harder to reason about for long chains.
  2. Put transaction-format validation in command/service only:
    • Rejected because persisted data could bypass command checks; blockchain-level validation must be authoritative.
  3. Allow direct block injection (addBlock(Block) API):
    • Rejected to reduce misuse risk. addTransactions(...) preserves index/hash derivation invariants.
  4. Skip validation during storage load for faster startup:
    • Rejected because startup should fail-safe against tampered files.

Trade-offs and known limitations

Planned next-step extension (post-v2.1)

The current implementation validates a complete chain each time. A planned extension is an incremental validation cache:

Reason for planning this enhancement:

Wallet, WalletManager, and KeyPair subsystem

This section documents wallet identity and lifecycle management through Wallet, WalletManager, and KeyPair.

Structural view (class diagram)

The class diagram below introduces core wallet classes before command-level interactions.

Wallet subsystem class diagram

Scope of enhancement

Architectural-level design

The subsystem spans three model classes:

Wallet does not generate keys internally. KeygenCommand calls KeyPair.generate(...) and injects the result via wallet.setKeys(...).

Component-level design

KeyPair design choices:

Wallet design choices:

WalletManager design choices:

Trade-offs and known limitations

Tutorial

This section documents the tutorial enhancement.

Component-level design

TutorialCommand design choices:

Why this design:


Structural view (class diagram)

Tutorial Class Diagram


Input handling and execution loop

The tutorial uses a blocking input loop based on Scanner.nextLine():

Control flow behaviour:

  1. If input matches "exit":
    • Immediately triggers ExitCommand
    • Terminates the entire application
  2. If input matches "tutorial exit":
    • Breaks tutorial loop and exits tutorial mode only
  3. If input matches expected instruction:
    • Parsed via Parser.parse(input)
    • Executed on tutorialBlockchain
    • Advances step index
  4. Otherwise:
    • Displays error message via CliVisuals.printWarning(ERROR_MESSAGE)
    • Repeats current step

Tutorial Execution Flow

Tutorial Sequence Diagram


Tutorial data model

The tutorial content is defined as static arrays:

Rationale:


Error handling strategy

Two layers of error handling are used:

  1. Input-level validation
    • Invalid commands trigger CliVisuals.printWarning(ERROR_MESSAGE)
    • Does not advance tutorial state
  2. Execution-level validation
    • Crypto1010Exception is caught during command execution
    • Prevents tutorial crash and preserves current step

Design considerations

Isolation of state

Strict step control

Reuse of command system

UI abstraction


Limitations

help command implementation

HelpCommand uses prefix-based argument parsing:

Validation sequence:

  1. parse prefixes
  2. if no arguments provided, display general help message listing all commands
  3. if c/COMMAND is provided, extract the command keyword
  4. verify the command exists
  5. retrieve the corresponding command’s help description
  6. display the format and usage details of the specified command

tutorial command implementation

TutorialCommand uses argument-based parsing:

Validation sequence:

  1. verify argument equals start, otherwise throw invalid format error
  2. initialize a default Blockchain and WalletManager for tutorial isolation
  3. create a Parser instance for handling tutorial inputs
  4. print tutorial welcome message
  5. iterate through predefined tutorial steps:
    • display instructional message
    • prompt user to enter the expected command
  6. read user input from Scanner
  7. if input equals tutorial exit, terminate tutorial and print tutorial exit message
  8. if input equals exit, trigger global application exit
  9. if input matches expected instruction (with special handling for dynamic inputs like send), execute command using parser
  10. if execution fails or input is incorrect, display error message and repeat step
  11. continue until all tutorial steps are completed or user exits

create command implementation

CreateCommand uses prefix-based argument parsing:

Validation sequence:

  1. parse prefixes
  2. verify no wallet with the same name exists
  3. verify no wallet with the same non-generic currency exists
  4. delegate wallet construction to WalletManager via createWallet()

logout command implementation

keygen command implementation

KeygenCommand uses prefix-based argument parsing:

Validation sequence:

  1. parse prefixes
  2. verify wallet exists
  3. verify wallet does not already have keys (regeneration blocked)
  4. delegate keypair generation to KeyPair.generate(currencyCode)
  5. set generated keys/address into wallet

Transaction and balance logic

Transactions are represented in this format: sender -> receiver : amount

Balance for a wallet is computed by scanning all transactions:

send command implementation

SendCommand uses prefix-based argument parsing:

This flow was significantly enhanced by jainamashah to improve reliability, validation, and user feedback. The command now robustly handles edge cases, provides clearer error messages, and supports both speed-based and manual fee overrides.

Validation sequence:

  1. parse prefixes
  2. verify wallet exists
  3. verify amount > 0
  4. validate recipient address format
  5. resolve fee (manual or speed-based)
  6. pass the transfer to TransactionRecordingService
  7. output a detailed transaction summary including all relevant fields (wallet, recipient, amount, speed, fee, note)

SendCommand diagrams

The following diagrams document the static structure, validation, and activity flow of the send command:

Key design points shown in the diagrams:

SendCommand class diagram

SendCommand validation sequence diagram

SendCommand activity diagram

Centralized transfer recording

crossSend command implementation

history command implementation

viewchain command implementation

Persistence implementation

Structural view (class diagram)

The class diagram below introduces storage-layer classes before persistence behavior details.

Storage subsystem class diagram

Product scope

Target user profile

Value proposition

Crypto1010 provides a compact, practical environment to understand wallet transfers, block structure, hash linkage, and blockchain validation without requiring external infrastructure or a real network.

User Stories

Version As a … I want to … So that I can …
v1.0 new user view usage instructions quickly learn available commands
v1.0 user create wallets simulate distinct senders and receivers
v1.0 user list wallets confirm available wallets in the current session
v1.0 user check wallet balance verify transaction effects numerically
v1.0 user send funds with fee controls model transfer and fee trade-offs
v2.1 user send funds to another account with the same currency move balances between login accounts without exchanges
v1.0 user view my wallet send history review past outgoing transfers
v1.0 user validate the blockchain confirm chain integrity after modifications
v2.2 expert user view a blockchain overview quickly inspect chain size and per-block summaries
v1.0 user inspect a specific block view exact block-level transaction data

Planned enhancement: cross-account address resolution

Non-Functional Requirements

Glossary

Instructions for manual testing

Prerequisites

Running the app

  1. Run ./gradlew run (or .\gradlew run on Windows PowerShell).

Manual test cases

The following test cases were contributed and maintained by jainamashah to ensure robust coverage of all major flows and edge cases:

  1. Authentication:
    • Launch the app.
    • At Choice:, enter 2 (or register).
    • Enter a username and password.
    • Expected: account is created and the app logs in to that account.
    • Relaunch the app and at Choice:, enter 1 (or login) with the same credentials.
    • Expected: login succeeds and the same account data is loaded.
    • Press Tab at Choice:.
    • Expected: only auth-scope suggestions (1, 2, 3, login, register, exit) are offered.
    • After successful login, press Tab in command prompt.
    • Expected: command-scope suggestions are offered, and auth menu suggestions are no longer offered.
    • Enter a valid username with wrong password 5 times.
    • Expected: subsequent login attempts for that username are temporarily rejected for 30 seconds.
  2. Help
    • help
    • Expected: prints out the list of commands
    • help c/list
    • Expected: prints out details about the list command
  3. Tutorial
    • tutorial start
    • Expected: begins interactive tutorial guiding through steps needed to make a simple transaction
    • tutorial exit
    • Expected: exits the interactive tutorial
  4. Create wallets:
    • create w/alice
    • create w/bob
    • Expected: confirmation messages for each wallet.
    • create w/main curr/btc
    • Expected: wallet created message showing currency btc.
  5. List wallets:
    • list
    • Expected: numbered wallet list including alice, bob, and any currency-tagged wallet with its currency shown.
  6. Generate wallet keys:
    • keygen w/alice
    • Expected: wallet address is generated and shown.
    • Run keygen w/alice again.
    • Expected: error that wallet already has a key pair.
  7. Check balance:
    • balance w/bob
    • Expected: balance displayed with 8 decimal places.
  8. Successful transfer:
    • send w/bob to/0x1111111111111111111111111111111111111111 amt/1
    • Expected: success output including wallet, recipient, amount, speed, and fee.
  9. Invalid transfer format:
    • send invalid
    • Expected: invalid send format error.
  10. Invalid recipient address:
    • send w/bob to/not-an-address amt/1
    • Expected: invalid recipient address error.
  11. View wallet send history:
    • history w/bob
    • Expected: either numbered outgoing send history entries or a no-history message.
  12. Successful cross-account transfer:
    • Register/login as account sender.
    • create w/main curr/btc
    • Ensure main has some balance in your test data.
    • Register a second account receiver.
    • crossSend acc/receiver amt/1 curr/btc
    • Expected: success output showing sender wallet, recipient account, recipient wallet, and currency.
    • Login as receiver.
    • list
    • Expected: a btc wallet exists if one was not already present.
  13. Logout and switch account:
    • Log in as any existing account.
    • logout
    • Enter n.
    • Expected: logout is cancelled and the session continues.
    • logout
    • Enter y.
    • Expected: account access menu is shown again and you can login or register as a different user.
  14. Validate chain:
    • validate
    • Expected: valid-chain success message unless data is corrupted.
  15. View blockchain overview:
    • viewchain
    • Expected: total block count, total transaction count, and compact block rows are printed.
  16. View block details:
    • viewblock 1
    • Expected: full block metadata and transaction list.
  17. Out-of-range block:
    • viewblock 999
    • Expected: block index out of range error.
  18. Exit:
    • exit
    • Expected: program terminates and blockchain state is saved.

Data reset / test isolation