Skip to content

The-Sycorax/denaro

 
 

Repository files navigation

Denaro

Language Platform License: AGPLv3

Denaro, "money" in Italian, is a decentralized cryptocurrency built entirely in Python and utilizes PostgreSQL for blockchain data. It offers a blockchain implementation that developers can understand and extend without the complexity often found in traditional cryptocurrency codebases. Additionally, it can serve as a foundation for developers that are interested in creating their own cryptocurrency.

Features:
  • Proof-of-Work blockchain using SHA256 hashing with dynamic difficulty adjustment every 512 blocks. Blocks are limited to 2MB and can process approximately 3,800 transactions.

  • Peer-to-peer network with cryptographic node identity, ECDSA-based request signing, and automatic blockchain synchronization. Includes reputation management, rate limiting, and security measures for network protection.

  • Transaction system supporting up to 6 decimal places with ECDSA signature verification. Transactions can include up to 255 inputs and outputs, with optimized signature schemes and optional messages.

  • PostgreSQL database backend with indexed queries, connection pooling, and integrated transaction validation for efficient blockchain storage and retrieval.

  • Consensus versioning system enabling clean protocol upgrades with support for both soft and hard forks through activation height scheduling.

  • RESTful API interface built on FastAPI providing comprehensive blockchain interaction, transaction submission, and network queries with background task processing and CORS support.

Monetary Policy:

Denaro's monetary policy has been chosen for its optimal balance of a scarce total supply, frequent halving events, and long-term emission lifespan.

  • Initial Reward Per Block: 64 DNR
  • Halving Interval: 262,144 blocks.
    • Targets ~2.5 years per halving.
  • Maximum halvings: 64
  • Estimated Emission Lifespan: ~160 years.
  • Maximum Total Supply: 33,554,432 DNR

Denaro's Current Block Height

Denaro Projects:

Links:


Startup Guide

Node Setup:

Configuration and deployment of a Denaro node can be achieved using one of three methods: the setup.sh script, Docker, or a manual setup. The setup.sh script and Docker automate the installation of all prerequisites and configure the node according to user preference, while the manual setup allows full control over each step of the setup process.

It is highly recommended to review the Environment Configuration section before setting up a Denaro node.

Setup via setup.sh:

The setup.sh script automates the configuration and deployment of a single Denaro node. It handles system package installation, environment configuration, PostgreSQL database setup, Python virtual environment creation, dependency installation, and node startup.

Prerequisites: A Linux distribution (or WSL2), git, and user with sudo privileges.

Refer to the System Package Installation subsection below for the list of supported package managers and required system packages.

Commands:

# Clone the Denaro repository to your local machine.
git clone https://github.com/The-Sycorax/denaro.git

# Change directory to the cloned repository.
cd denaro

# Make the setup script executable.
chmod +x setup.sh

# Execute the setup script with optional arguments if needed.
./setup.sh [--skip-prompts] [--setup-db] [--skip-package-install] [--package-manager <name>]
CLI Arguments:
  • --skip-prompts: Runs the setup script non-interactively, bypasses all interactive prompts, and uses default values for all configuration variables.

  • --setup-db: Limits the setup script's actions to system package installation and PostgreSQL database configuration. Skips Python virtual environment setup, dependency installation, and node startup.

  • --skip-package-install: Skips the system package installation step. Should be used on distributions whose package manager is not natively supported by the script.

  • --package-manager <name>: Overrides the auto-detected package manager. Accepts apt, dnf, pacman, or zypper.

System Package Installation:

The setup script automatically detects the system's package manager and installs all required system packages. This can be overridden via the --package-manager argument.

The following package managers are supported:

  • apt (Debian, Ubuntu, and derivatives)
  • dnf (Fedora, RHEL 8+, Rocky Linux, AlmaLinux)
  • pacman (Arch Linux, Manjaro)
  • zypper (openSUSE, SUSE Linux Enterprise)

For distributions that use a different package manager, the required system packages must be installed manually before running the script with the --skip-package-install argument.

Additionally, it is nessessary to ensure that the package names specified are adjusted to correspond with those recognized by your package manager, and that Python version 3.8 or higher is installed.

Required Packages:

  • Debian / Ubuntu (apt): gcc, libgmp-dev, libpq-dev, postgresql, python3, python3-dev, python3-venv
  • Fedora / RHEL (dnf): gcc, gmp-devel, libpq-devel, postgresql-server, python3, python3-devel
  • Arch Linux (pacman): gcc, gmp, postgresql-libs, postgresql, python
  • openSUSE (zypper): gcc, gmp-devel, postgresql-devel, postgresql-server, python3, python3-devel
Setup via Docker:

The Docker setup provides a containerized deployment option for Denaro nodes. Unlike the setup.sh script, it encapsulates everything needed to run a Denaro node in isolated Docker containers. This avoids installing dependencies on the host system and prevents conflicts with system packages. Additionally, the Docker setup allows for multi-node deployments, while the setup.sh script does not.

At the core of the Docker setup is the docker-entrypoint.sh script, which automates the configuration and deployment of each node. When a node's container starts, this script automatically provisions the PostgreSQL database, generates the necessary environment configuration, handles bootstrap node selection, and starts the Denaro node. Docker coordinates the supporting services, shared resources, and startup order of each container.

To test public node behavior over the Internet, the Docker setup includes optional support for exposing a node on the Internet by establishing an SSH reverse tunnel via Pinggy.io's free tunnleing service. For more information please refer to: 2025-09-18-refactor(docker).md: Optional Public Node Tunnleing.

Prerequisites: A Linux distribution (or WSL2), git, Docker and the Docker Compose plugin installed, and a user with permissions to run docker commands.

Commands:

# Clone the Denaro repository to your local machine.
git clone https://github.com/The-Sycorax/denaro.git

# Change directory to the cloned repository.
cd denaro

# Create the PostgreSQL volume
docker volume create denaro_postgres_volume

# Run the Docker containers
docker compose -f ./docker/docker-compose.yml up --build --force-recreate -d

# Optionally show node logs
docker logs -f <container-name>
Custom Node Configuration:

For documentation related to Denaro's Docker setup, please refer to: 2025-09-18-refactor(docker).md and 2025-10-14-refactor(docker).md. Please note that some information may be outdated.

To add or modify nodes in docker-compose.yml, use the structure outlined in the examples below.

Basic Node Example (Default):
  denaro-node-3006:
    <<: *denaro-node-base
    image: denaro-node-3006
    container_name: denaro-node-3006
    hostname: denaro-node-3006
    volumes:
      - denaro_node_3006_volume:/app
      - denaro_node_registry_volume:/shared/denaro-node-registry
      - denaro_node_topology_volume:/shared/denaro-node-topology:ro
    depends_on:
      denaro-node-topology: { condition: service_completed_successfully }
      postgres: { condition: service_started }
    ports: [ "3006:3006" ]
    environment:
      NODE_NAME: 'denaro-node-3006'
      DENARO_NODE_PORT: '3006'
      DENARO_BOOTSTRAP_NODE: 'https://node.denaro.network'
      #ENABLE_PINGGY_TUNNEL: 'true'
      #DENARO_SELF_URL: ''

# Ensure the node's volume is added
volumes:
  denaro_node_3006_volume:
    name: denaro_node_3006_volume
Multi-Node Example:
  # First Node
  denaro-node-3006:
    <<: *denaro-node-base
    image: denaro-node-3006
    container_name: denaro-node-3006
    hostname: denaro-node-3006
    volumes:
      - denaro_node_3006_volume:/app
      - denaro_node_registry_volume:/shared/denaro-node-registry
      - denaro_node_topology_volume:/shared/denaro-node-topology:ro
    depends_on:
      denaro-node-topology: { condition: service_completed_successfully }
      postgres: { condition: service_started }
    ports: [ "3006:3006" ]
    environment:
      NODE_NAME: 'denaro-node-3006'
      DENARO_NODE_PORT: '3006'
      DENARO_BOOTSTRAP_NODE: 'https://node.denaro.network'
      #ENABLE_PINGGY_TUNNEL: 'true'
      #DENARO_SELF_URL: ''

  # Second Node
  denaro-node-3007:
    <<: *denaro-node-base
    image: denaro-node-3007
    container_name: denaro-node-3007
    hostname: denaro-node-3007
    volumes:
      - denaro_node_3007_volume:/app
      - denaro_node_registry_volume:/shared/denaro-node-registry
      - denaro_node_topology_volume:/shared/denaro-node-topology:ro
    depends_on:
      denaro-node-topology: { condition: service_completed_successfully }
      postgres: { condition: service_started }

      # This condition is meant for proper startup ordering, but is really only
      # nessessary if the DENARO_BOOTSTRAP_NODE variable is set to a node that
      # is already present in the compose file.
      denaro-node-3006: { condition: service_healthy }

    ports: [ "3007:3007" ]
    environment:
      NODE_NAME: 'denaro-node-3007'
      DENARO_NODE_PORT: '3007'
      DENARO_BOOTSTRAP_NODE: 'http://denaro-node-3006:3006'  # Connects to first node

  # Third Node
  denaro-node-3008:
    <<: *denaro-node-base
    image: denaro-node-3008
    container_name: denaro-node-3008
    hostname: denaro-node-3008
    volumes:
      - denaro_node_3008_volume:/app
      - denaro_node_registry_volume:/shared/denaro-node-registry
      - denaro_node_topology_volume:/shared/denaro-node-topology:ro
    depends_on:
      denaro-node-topology: { condition: service_completed_successfully }
      postgres: { condition: service_started }

      # This condition is meant for proper startup ordering, but is really only
      # nessessary if the DENARO_BOOTSTRAP_NODE variable is set to a node that
      # is already present in the compose file.
      denaro-node-3007: { condition: service_healthy }

    ports: [ "3008:3008" ]
    environment:
      NODE_NAME: 'denaro-node-3008'
      DENARO_NODE_PORT: '3008'
      DENARO_BOOTSTRAP_NODE: 'http://denaro-node-3007:3007' # Connects to second node

# Ensure that the volumes of additional nodes are added
volumes:
  denaro_node_3006_volume:
    name: denaro_node_3006_volume
  denaro_node_3007_volume:
    name: denaro_node_3007_volume
  denaro_node_3008_volume:
    name: denaro_node_3007_volume
Important Notes:

This information is meant to document the correct requirements for the Docker setup. This applies primarily to advanced setups and custom configurations. The default docker-compose.yml and examples above already satisfy these requirements.

  • Each node service must include the <<: *denaro-node-base merge. This ensures that Docker Compose applies the required denaro.node=true label, mounts the shared volumes, and establishes the baseline dependencies on services that are required by the entrypoint script.

  • Each node service requires its own dedicated volume (for example, denaro_node_3006_volume) mounted to /app. This volume preserves the node's configuration files, and application state across container restarts. Additionally, this volume should not be shared with other nodes, doing so may result in unexpected behavior.

  • Each node service must be assigned a unique NODE_NAME and DENARO_NODE_PORT value. The entrypoint script uses these values to derive per-node database names and healthcheck targets. Duplicate values will cause database conflicts and prevent proper node identification.

  • The shared node-registry and node-topology volumes must remain mounted on all node services. These volumes enable the entrypoint script to coordinate peer discovery through the shared registry and provide the dependency information required by the topology-aware healthcheck system.

  • When configuring multi-node deployments, use depends_on with the service_healthy condition to establish startup ordering. This ensures that Docker Compose waits for upstream peer nodes to become healthy before launching dependent nodes, preventing bootstrap connection failures during startup.

Manual Setup:

A Denaro node can also be configured and deployed manually without the use of the setup.sh script or Docker. This is useful for users that require full control over the configuration process, or for systems where the automated setup script is not viable.

The steps below replicate the operations performed by the setup.sh script, including system package installation, environment configuration, PostgreSQL database setup, Python virtual environment creation, and node startup.

Prerequisites: A Linux distribution (or WSL2), git, and user with sudo privileges.

1. Install Required System Packages:

Refer to the System Package Installation subsection of Setup via setup.sh for the list of supported package managers and required system packages.

2. Clone the Repository:
# Clone the Denaro repository to your local machine.
git clone https://github.com/The-Sycorax/denaro.git

# Change directory to the cloned repository.
cd denaro
3. Configure the .env File:

Create a .env file in the root of the Denaro directory and define the required environment variables. For details on each variable please refer to the Environment Configuration section.

Example .env file (.env.example):

POSTGRES_USER='denaro'
POSTGRES_PASSWORD='denaro'
DENARO_DATABASE_NAME='denaro'
DENARO_DATABASE_HOST='127.0.0.1'

DENARO_NODE_HOST='127.0.0.1'
DENARO_NODE_PORT='3006'
DENARO_SELF_URL=''
DENARO_BOOTSTRAP_NODE='http://node.denaro.network'

LOG_LEVEL='INFO'
LOG_FORMAT='%(asctime)s - %(levelname)s - %(name)s - %(message)s'
LOG_DATE_FORMAT='%Y-%m-%dT%H:%M:%S'
LOG_CONSOLE_HIGHLIGHTING='True'
LOG_INCLUDE_REQUEST_CONTENT='False'
LOG_INCLUDE_RESPONSE_CONTENT='False'
LOG_INCLUDE_BLOCK_SYNC_MESSAGES='False'

The default values shown above are sufficient for a local node. The values defined for POSTGRES_USER, POSTGRES_PASSWORD, and DENARO_DATABASE_NAME must match those used during the PostgreSQL database setup in the next step.

4. Configure the PostgreSQL Database:

This step creates the database, creates the database user, sets the password, grants privileges, and assigns ownership. The values used in the commands below should match those defined in the .env file.

Create the database, user, and grant privileges:

# Create the Denaro database.
sudo -u postgres psql -c "CREATE DATABASE denaro;"

# Create the database user.
sudo -u postgres psql -c "CREATE USER denaro;"

# Set the password for the database user.
sudo -u postgres psql -c "ALTER USER denaro WITH PASSWORD 'denaro';"

# Grant privileges on the database to the user.
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE denaro TO denaro;"
sudo -u postgres psql -d denaro -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO denaro;"
sudo -u postgres psql -d denaro -c "GRANT ALL ON SCHEMA public TO denaro;"

# Assign ownership of the database to the user.
sudo -u postgres psql -c "ALTER DATABASE denaro OWNER TO denaro;"

Enable password authentication:

PostgreSQL must be configured to allow password (md5) authentication for local Unix domain socket connections. To do so the pg_hba.conf must be modified. This file is typically located at /etc/postgresql/<PG_VERSION>/main/pg_hba.conf, where <PG_VERSION> is the major version of the installed PostgreSQL package.

Change the following line:

local   all             all                                     peer

To:

local   all             all                                     md5

Then restart PostgreSQL for the changes to take effect:

sudo service postgresql restart

Import the database schema:

# Import the Denaro database schema.
PGPASSWORD='denaro' psql -U denaro -d denaro -f denaro/schema.sql

Replace the PGPASSWORD value, -U argument, and -d argument with those defined in the .env file.

5. Create a Python Virtual Environment and Install Dependencies:

A Python virtual environment is highly recommended to avoid conflicts with system-wide Python packages.

# Create the virtual environment in ./venv.
python3 -m venv venv

# Activate the virtual environment.
source venv/bin/activate

# Install the required Python packages.
pip install -r requirements.txt

To deactivate the virtual environment at any time, run deactivate.

6. Start the Node:

With all prerequisites configured, the Denaro node can be started:

# Start the Denaro node.
python3 run_node.py

# Manualy start the Denaro node via uvicorn (Optional).
uvicorn denaro.node.main:app --host 127.0.0.1 --port 3006 

The node binds to the host and port defined by DENARO_NODE_HOST and DENARO_NODE_PORT in the .env file. To stop the node, press Ctrl+C in the terminal.

When running a publically facing node, the node's own port (e.g. 3006) should be exposed to the Internet in order to allow connections to it.


Environment Configuration

Denaro uses environment variables for node and database configuration. In the standard setup without Docker, all environment vairables are managed through a .env file in Denaro's root directory. For the Docker Setup please refer to the Docker Setup Configuration section.

All variable values should be enclosed in quotes.

Environment Variables:
Node Configuration:
DENARO_NODE_HOST:
  • <str>: The hostname or IP address the node binds to.

  • Required.

  • Default: 127.0.0.1

DENARO_NODE_PORT:
  • <str>: The port the node listens on for incoming connections.

  • Required.

  • Default: 3006

NODE_NAME:
  • <str>: A unique identifier for the node within the Docker Compose file. This variable is required since the entrypoint script uses its value to derive DENARO_DATABASE_NAME, as well as DENARO_SELF_URL when it is not explicitly set.

  • Should match the container name of the node service.

  • Required; Docker only.

DENARO_BOOTSTRAP_NODE:
  • <str>: Specifies the bootstrap-node to connect to. This can be any Denaro node that is reachable via the Internet or internal network. It is used for joining Denaro's P2P network (mainnet or isolated), and discovering additional peers.

  • The accepted values are different based on the setup type:

    Standard Setup:
    • <url>: Fixed HTTP(S) address of a Denaro Node.
    Docker Setup:

    In the Docker setup, this variable specifies either the selection criteria, a node name, or a fixed HTTP(S) address of the bootstrap-node.

    • 'self': Bootstraps against the node's own address (DENARO_SELF_URL). The node starts with no peers and remains isolated unless others connect to it.

    • <url>: Fixed HTTP(S) address of a Denaro Node.

    • <node-name>: The NODE_NAME of another node in the compose file. The target node must be public (with ENABLE_PINGGY_TUNNEL=true). The entrypoint script waits up to 120s for the target to publish its URL to the registry. Falls back to 'self' if unavailable.

    • 'random': Randomly selects a bootstrap-node from all other public nodes (with ENABLE_PINGGY_TUNNEL=true) in the compose file. The entrypoint script waits up to 120s for all public nodes to register before choosing. Falls back to 'self' if no public nodes are available.

  • Optional.

  • Default: https://node.denaro.network

DENARO_SELF_URL:
  • <str>: Specifies the HTTP(S) address of the node itself, reachable via the Internet or internal network. Other peers use this address to connect back to the node, and is required for publicly facing nodes.

  • When left unset or is set to a local address, the node will operate as a private node.

Docker Setup:
  • DENARO_SELF_URL should only be directly specified if the node is publicly facing. Otherwise, the entrypoint script will set it automatically in one of two ways:

    • If left unset, its value is derived from NODE_NAME and DENARO_NODE_PORT as http://{NODE_NAME}:{DENARO_NODE_PORT}.

    • If ENABLE_PINGGY_TUNNEL='true', its value is overridden with the public URL assigned to the node by Pinggy.io.

  • Optional.

  • Default: unset

ENABLE_PINGGY_TUNNEL:
  • <str-bool>: Enables public tunneling via Pinggy.io for up to 60 minutes. This overrides DENARO_SELF_URL with the public URL assigned to the node by Pinggy. Useful for testing public node behavior over the Internet.

  • Optional; Docker only.

  • Default: 'false'

Database Configuration:
POSTGRES_USER:
  • <str>: The PostgreSQL username used to authenticate with the database.

  • Required.

  • Default: 'denaro'

POSTGRES_PASSWORD:
  • <str>: The password for the PostgreSQL user.

  • Required.

  • Default: 'denaro'

DENARO_DATABASE_NAME:
  • <str>: The name of the node's PostgreSQL database.
Docker Setup:
  • In the Docker setup, DENARO_DATABASE_NAME should not be directly specified. It is automatically set from NODE_NAME by the entrypoint script, with hyphens replaced by underscores.
  • Required for the standard setup, but not required for the Docker setup.

  • Default: 'denaro'

DENARO_DATABASE_HOST:
  • <str>: The hostname or IP address of the PostgreSQL server.

  • Required.

  • Default: '127.0.0.1'

DOCKER_ENABLE_PGADMIN:
  • <str-bool>: Toggles the pgAdmin container for browser-based database management.

  • Optional; Docker only.

  • Default: 'false'

Logging Configuration:
LOG_LEVEL:
  • <str>: Specifies the logging verbosity level (e.g., DEBUG, INFO, WARNING, ERROR, CRITICAL).

  • Optional.

  • Default: 'INFO'

LOG_FORMAT:
  • <str>: Specifies the log message string using standard Python logging format specifiers.

  • Optional.

  • Default: '%(asctime)s - %(levelname)s - %(name)s - %(message)s'

LOG_DATE_FORMAT:
  • <str>: Specifies the date format for log timestamps using standard strftime directives.

  • Optional.

  • Default: '%Y-%m-%dT%H:%M:%S'

LOG_CONSOLE_HIGHLIGHTING:
  • <str-bool>: Toggles Rich console syntax highlighting for log outputs.

  • Optional.

  • Default: 'true'

LOG_INCLUDE_REQUEST_CONTENT:
  • <str-bool>: Toggles HTTP request body content in the log.

  • Optional.

  • Default: 'false'

LOG_INCLUDE_RESPONSE_CONTENT:
  • <str-bool>: Toggles HTTP response body content in the log.

  • Optional.

  • Default: 'false'

LOG_INCLUDE_BLOCK_SYNC_MESSAGES:
  • <str-bool>: Toggles verbose blockchain synchronization messages in the log.

  • Optional.

  • Default: 'false'

Docker Setup Configuration:

When deploying a Denaro node with Docker, configuration is split between a globally shared .env file in Denaro's root directory, and per-container in the docker-compose.yml file. This is to prevent variable overriding conflicts, especially for multi-node setups.

Global .env Variables:

These variables should only be included in the .env file, are shared across all containers, and are required for the Docker setup.

  • POSTGRES_USER
  • POSTGRES_PASSWORD
  • DENARO_DATABASE_HOST
  • DENARO_NODE_HOST
  • DOCKER_ENABLE_PGADMIN
Per-Node Variables (docker-compose.yml):

These variables should be configured per-node within the docker-compose.yml environment block. They should not be included in the .env file.

  • NODE_NAME
  • DENARO_NODE_PORT
  • DENARO_BOOTSTRAP_NODE
  • DENARO_SELF_URL
  • ENABLE_PINGGY_TUNNEL
Important Notes:
  • DENARO_DATABASE_NAME should not be directly specified. It is automatically set from NODE_NAME by the entrypoint script, with hyphens replaced by underscores.

  • DENARO_SELF_URL should only be directly specified if the node is publicly facing. Otherwise, the entrypoint script will set it automatically in one of two ways:

    • If left unset, its value is derived from NODE_NAME and DENARO_NODE_PORT as http://{NODE_NAME}:{DENARO_NODE_PORT}.

    • If ENABLE_PINGGY_TUNNEL='true', its value is overridden with the public URL assigned to the node by Pinggy.io.

  • Logging configuration variables can be set in either the .env file to apply globally, or per-node in the docker-compose.yml file.


Database Management

The PostgreSQL database used by Denaro can be managed through several methods.

Warning

Database management is intended for development and testing purposes only and should not be used in mainnet node environments.

Additionally, it is highly recommended that the PostgreSQL port (5432) and pgAdmin port (5050) are not publicly exposed on the Internet, especially if default credentials are in use, since that would go against the most basic of security standards.

Management Options:
psql (CLI):

psql is the official PostgreSQL command-line client and provides direct access to the database. It can be used to run queries, inspect schemas, and perform administrative tasks.

# Connect to the Denaro database directly
PGPASSWORD='<POSTGRES_PASSWORD>' psql -h 127.0.0.1 -p 5432 -U <POSTGRES_USER> -d <DENARO_DATABASE_NAME>

Replace <POSTGRES_PASSWORD>, and <POSTGRES_USER> with the credentials defined in the .env file.

Also replace <DENARO_DATABASE_NAME> with the value defined for it. This will be different based on the setup type:

  • In the standard setup it's value is defined in the .env file.
  • In the Docker setup, it's value is automatically set from NODE_NAME by the entrypoint script, with hyphens replaced by underscores.
pgAdmin (Included in Docker Setup):

A pgAdmin container is included in the Docker setup and provides a browser-based GUI for managing the PostgreSQL database.

The pgAdmin container can be enabled by setting the DOCKER_ENABLE_PGADMIN variable to true in the .env file, and is accessible from the host machine once the Docker containers are running.

Access:

Property Value
URL http://localhost:5050
Default Email [email protected]
Default Password admin

Note: If the default login credentials are in use, it is highly recommended that the pgAdmin port (5050) is not publicly exposed. The default login credentials for pgAdmin can be changed in it's envoronment block within the docker-compose.yml file.

Third-Party GUI Clients:

Any PostgreSQL-compatible GUI client can be used to connect to the database. Popular options include:

  • DBeaver — A free, cross-platform database tool that supports PostgreSQL and many other databases.

  • TablePlus — A modern, native GUI client for macOS, Windows, and Linux.

  • DataGrip — A JetBrains IDE with advanced SQL editing and database management features.

To connect, use the nessessary values and credentials defined in the node's .env file. The database should generally be accessible at 127.0.0.1:5432 from the host machine. However, this address may be different if deployed using Docker.


Running a Denaro Node

Note: The information in this section is already documented in the Manual Setup section, but is included here for easy reference. This section dose not apply to nodes deployed using Docker.

A Denaro node can be started manually if you have already executed the setup.sh script and chose not to start the node immediately, or if you need to start the node in a new terminal session.

It is recommended that a Python virtual environment is activated and that the required Python packages are installed prior to starting a node, particularly if the setup script was run with the --setup-db argument or if the installation was performed manually.

Commands to manually start a node:

# Navigate to the Denaro directory.
cd path/to/denaro

# Create a Python virtual environment (Optional).
sudo apt install python3-venv
python3 -m venv venv
source venv/bin/activate

# Install the required packages if needed.
pip install -r requirements.txt

# Start the Denaro Node
python3 run_node.py

# Manualy start the Denaro node via uvicorn (Optional).
uvicorn denaro.node.main:app --host 127.0.0.1 --port 3006 

# To stop the node, press Ctrl+C in the terminal.

To exit a Python virtual environment:

deactivate

Nodeless Wallet Setup

To setup a nodeless wallet, use Denaro Wallet Client GUI.


Mining

Denaro adopts a Proof of Work (PoW) system for mining using SHA256 hashing, with dynamic difficulty adjustment every 512 blocks to maintain a target block time of 180 seconds (3 minutes).

Mining Details:
  • Block Hashing Algorithm:

    • Utilizes the SHA256 algorithm for block hashing.

    • The hash of a block must begin with the last difficulty hexadecimal characters of the hash from the previously mined block.

    • difficulty can have decimal digits, which restricts the difficulty + 1st character of the derived hash to have a limited set of values.

      from math import ceil
      
      difficulty = 6.0
      decimal = difficulty % 1
      
      charset = '0123456789abcdef'
      count = ceil(16 * (1 - decimal))
      allowed_characters = charset[:count]
  • Difficulty Adjustment:

    • Difficulty adjusts every 512 blocks based on the actual block time versus the target block time of 180 seconds (3 minutes).
    • Starting difficulty is 6.0.
  • Block Size and Capacity:

    • Maximum block size is 2MB (raw bytes), equivalent to 4MB in hexadecimal format.
    • Transaction data is limited to approximately 1.9MB hex characters per block.
  • Rewards:

    • Block rewards start at 64 DNR and decrease by half every 262,144 blocks until they reach zero.
Mining Software:
  • CPU Mining:

    The CPU miner script (cpu_miner.py) can be used to mine Denaro on any machine with Python version 3.8 or higher installed.

    Usage:
    • Syntax:

      python3 miner/cpu_miner.py [-h] [-a ADDRESS] [-n NODE] [-w WORKERS] [-m MAX_BLOCKS]
    • Arguments:

      • --address, -a (Required): Your public Denaro wallet address where mining rewards will be sent.

      • --node, -n (Optional): The URL or IP address of the Denaro node to connect to. Defaults to http://127.0.0.1:3006/.

      • --workers, -w (Optional): The number of parallel processes to run. It's recommended to set this to the number of CPU cores you want to use for mining. Defaults to 1.

      • --max-blocks, -m (Optional): Maximum number of blocks to mine before exiting. If not specified, the miner will continue indefinitely.

      • --help, -h: Shows the help message.

    Examples:
    • Basic Mining (Single Core)

      python3 miner/cpu_miner.py --address WALLET_ADDRESS
    • Mining while connected to a Remote Node

      python3 miner/cpu_miner.py --address WALLET_ADDRESS --node https://denaro.network
    • Mining with Multiple Cores

      python3 miner/cpu_miner.py --address WALLET_ADDRESS --workers 8

    (Replace WALLET_ADDRESS with your actual Denaro address)

  • GPU Mining:

    The GPU mining script (cuda_miner.py) can be used to mine Denaro with a modern Nvidia GPU that supports CUDA.

    For more information on GPU mining please refer to Denaro CUDA Miner Setup and Usage.


Blockchain Synchronization

Denaro nodes maintain synchronization with the network through automatic peer discovery and chain validation mechanisms that ensure all nodes converge on the longest valid chain. Additionally nodes can also be manually synchronized.

Automatic Synchronization:

Nodes automatically detect and synchronize with longer chains through two mechanisms:

  • Handshake Synchronization: When connecting to a peer, nodes exchange chain state information. If the peer has a longer valid chain, synchronization is triggered immediately.

  • Periodic Chain Discovery: A background task polls 2 random peers every 60 seconds to check for longer chains, ensuring the node remains synchronized even without new connections.

Manual Synchronization:

To manually initiate blockchain synchronization, a request can be sent to a node's /sync_blockchain endpoint:

curl http://127.0.0.1:3006/sync_blockchain

The endpoint accepts an optional node_id parameter to sync from a specific peer. The node ID of a peer can be found in the ./data/active_peers.json file, or via a node's /get_peers endpoint:

curl "http://127.0.0.1:3006/sync_blockchain?node_id=NODE_ID"
The endpoint returns an error if a sync operation is already in progress.

License

Denaro is released under the terms of the GNU Affero General Public License v3.0. See LICENSE for more information or goto https://www.gnu.org/licenses/agpl-3.0.en.html

About

Denaro is a decentralized cryptocurrency built entirely in Python and utilizes PostgreSQL for blockchain data. It offers a blockchain implementation that developers can understand and extend without the complexity often found in traditional cryptocurrency codebases.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 74.7%
  • Shell 23.6%
  • Cuda 1.3%
  • Dockerfile 0.4%