monero Documentation

Monero: the secure, private, untraceable cryptocurrency

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy monero on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name monero -p 18080:18080 --restart always monero-project/monero:latest

1. Project Overview & Quickstart (monero-project/monero)

File: README.md

Monero

Copyright (c) 2014-2026, The Monero Project
Portions Copyright (c) 2012-2013 The Cryptonote developers.

Table of Contents

Development resources

  • Web: getmonero.org
  • Mail: [email protected]
  • GitHub: https://github.com/monero-project/monero
  • IRC: #monero-dev on Libera
  • It is HIGHLY recommended that you join the #monero-dev IRC channel if you are developing software that uses Monero. Due to the nature of this open source software project, joining this channel and idling is the best way to stay updated on best practices and new developments in the Monero ecosystem. All you need to do is join the IRC channel and idle to stay updated with the latest in Monero development. If you do not, you risk wasting resources on developing integrations that are not compatible with the Monero network. The Monero core team and community continuously make efforts to communicate updates, developments, and documentation via other platforms โ€“ but for the best information, you need to talk to other Monero developers, and they are on IRC. #monero-dev is about Monero development, not getting help about using Monero, or help about development of other software, including yours, unless it also pertains to Monero code itself. For these cases, checkout #monero.

Vulnerability response

Research

The Monero Research Lab is an open forum where the community coordinates research into Monero cryptography, protocols, fungibility, analysis, and more. We welcome collaboration and contributions from outside researchers! Because not all Lab work and publications are distributed as traditional preprints or articles, they may be easy to miss if you are conducting literature reviews for your own Monero research. You are encouraged to get in touch with the Monero research community if you have questions, wish to collaborate, or would like guidance to help avoid unnecessarily duplicating earlier or known work.

The Monero research community is available on IRC in #monero-research-lab on Libera, which is also accessible via Matrix.

Announcements

  • You can subscribe to an announcement listserv to get critical announcements from the Monero core team. The announcement list can be very helpful for knowing when software updates are needed.

Introduction

Monero is a private, secure, untraceable, decentralised digital currency. You are your bank, you control your funds, and nobody can trace your transfers unless you allow them to do so.

Privacy: Monero uses a cryptographically sound system to allow you to send and receive funds without your transactions being easily revealed on the blockchain (the ledger of transactions that everyone has). This ensures that your purchases, receipts, and all transfers remain private by default.

Security: Using the power of a distributed peer-to-peer consensus network, every transaction on the network is cryptographically secured. Individual wallets have a 25-word mnemonic seed that is only displayed once and can be written down to backup the wallet. Wallet files should be encrypted with a strong passphrase to ensure they are useless if ever stolen.

Untraceability: By taking advantage of ring signatures, a special property of a certain type of cryptography, Monero is able to ensure that transactions are not only untraceable but have an optional measure of ambiguity that ensures that transactions cannot easily be tied back to an individual user or computer.

Decentralization: The utility of Monero depends on its decentralised peer-to-peer consensus network - anyone should be able to run the monero software, validate the integrity of the blockchain, and participate in all aspects of the monero network using consumer-grade commodity hardware. Decentralization of the monero network is maintained by software development that minimizes the costs of running the monero software and inhibits the proliferation of specialized, non-commodity hardware.

About this project

This is the core implementation of Monero. It is open source and completely free to use without restrictions, except for those specified in the license agreement below. There are no restrictions on anyone creating an alternative implementation of Monero that uses the protocol and network in a compatible manner.

As with many development projects, the repository on GitHub is considered to be the "staging" area for the latest changes. Before changes are merged into that branch on the main repository, they are tested by individual developers in their own branches, submitted as a pull request, and then subsequently tested by contributors who focus on testing and code reviews. That having been said, the repository should be carefully considered before using it in a production environment, unless there is a patch in the repository for a particular show-stopping issue you are experiencing. It is generally a better idea to use a tagged release for stability.

Anyone is welcome to contribute to Monero's codebase! If you have a fix or code change, feel free to submit it as a pull request directly to the "master" branch. In cases where the change is relatively small or does not affect other parts of the codebase, it may be merged in immediately by any one of the collaborators. On the other hand, if the change is particularly large or complex, it is expected that it will be discussed at length either well in advance of the pull request being submitted, or even directly on the pull request.

Supporting the project

Monero is a 100% community-sponsored endeavor. If you want to join our efforts, the easiest thing you can do is support the project financially. Both Monero and Bitcoin donations can be made to donate.getmonero.org if using a client that supports the OpenAlias standard. Alternatively, you can send XMR to the Monero donation address via the donate command (type help in the command-line wallet for details).

The Monero donation address is:
888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H
Viewkey:
f359631075708155cc3d92a32b75a7d02a5dcf27756707b47a2b31b21c389501
Base address for restoring with address and viewkey:
44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A

The Bitcoin donation address is:
1KTexdemPdxSBcG55heUuTjDRYqbC5ZL8H

Core development funding and/or some supporting services are also graciously provided by sponsors:





License

See LICENSE.

Contributing

If you want to help out, see CONTRIBUTING for a set of guidelines.

Scheduled software/network upgrades

Monero uses a scheduled software/network upgrade (hard fork) mechanism to implement new features into the Monero software and network. This means that users of Monero (end users and service providers) should run current versions and upgrade their software when new releases are available. Software upgrades occur when new features are developed and implemented in the codebase. Network upgrades occur in tandem with software upgrades that modify the consensus rules of the Monero network. The required software for network upgrades will be available prior to the scheduled network upgrade date. Please check the repository prior to this date for the proper Monero software version. Below is the historical schedule and the projected schedule for the next upgrade.

Dates are provided in the format YYYY-MM-DD. The "Minimum" is the software version that follows the new consensus rules. The "Recommended" version may include bug fixes and other new features that do not affect the consensus rules.

Software upgrade block height Date Fork version Minimum Monero version Recommended Monero version Details
1009827 2016-03-22 v2 v0.9.4 v0.9.4 Allow only >= ringsize 3, blocktime = 120 seconds, fee-free blocksize 60 kb
1141317 2016-09-21 v3 v0.9.4 v0.10.0 Splits coinbase into denominations
1220516 2017-01-05 v4 v0.10.1 v0.10.2.1 Allow normal and RingCT transactions
1288616 2017-04-15 v5 v0.10.3.0 v0.10.3.1 Adjusted minimum blocksize and fee algorithm
1400000 2017-09-16 v6 v0.11.0.0 v0.11.0.0 Allow only RingCT transactions, allow only >= ringsize 5
1546000 2018-04-06 v7 v0.12.0.0 v0.12.3.0 Cryptonight variant 1, ringsize >= 7, sorted inputs
1685555 2018-10-18 v8 v0.13.0.0 v0.13.0.4 max transaction size at half the penalty free block size, bulletproofs enabled, cryptonight variant 2, fixed ringsize 11
1686275 2018-10-19 v9 v0.13.0.0 v0.13.0.4 bulletproofs required
1788000 2019-03-09 v10 v0.14.0.0 v0.14.1.2 New PoW based on Cryptonight-R, new block weight algorithm, slightly more efficient RingCT format
1788720 2019-03-10 v11 v0.14.0.0 v0.14.1.2 forbid old RingCT transaction format
1978433 2019-11-30 v12 v0.15.0.0 v0.16.0.0 New PoW based on RandomX, only allow >= 2 outputs, change to the block median used to calculate penalty, v1 coinbases are forbidden, rct sigs in coinbase forbidden, 10 block lock time for incoming outputs
2210000 2020-10-17 v13 v0.17.0.0 v0.17.3.2 New CLSAG transaction format
2210720 2020-10-18 v14 v0.17.1.1 v0.17.3.2 forbid old MLSAG transaction format
2688888 2022-08-13 v15 v0.18.0.0 v0.18.5.1 ringsize = 16, bulletproofs+, view tags, adjusted dynamic block weight algorithm
2689608 2022-08-14 v16 v0.18.0.0 v0.18.5.1 forbid old v14 transaction format
XXXXXXX XXX-XX-XX XXX vX.XX.X.X vX.XX.X.X XXX

X's indicate that these details have not been determined as of commit date.

Release staging schedule and protocol

Approximately three months prior to a scheduled software upgrade, a branch from master will be created with the new release version tag. Pull requests that address bugs should then be made to both master and the new release branch. Pull requests that require extensive review and testing (generally, optimizations and new features) should not be made to the release branch.

Compiling Monero from source

Dependencies

The following table summarizes the tools and libraries required to build. A few of the libraries are also included in this repository (marked as "Vendored"). By default, the build uses the library installed on the system and ignores the vendored sources. However, if no library is found installed on the system, then the vendored source will be built and used. The vendored sources are also used for statically-linked builds because distribution packages often include only shared library binaries (.so) but not static library archives (.a).

Dep Min. version Vendored Debian/Ubuntu pkg Arch pkg Void pkg Fedora pkg Optional Purpose
GCC 7 NO build-essential base-devel base-devel gcc NO
CMake 3.10 NO cmake cmake cmake cmake NO
pkg-config any NO pkg-config base-devel base-devel pkgconf NO
Boost 1.69 NO libboost-all-dev boost boost-devel boost-devel NO C++ libraries
OpenSSL 1.1.1 NO libssl-dev openssl openssl-devel openssl-devel NO cryptography
libzmq 4.2.0 NO libzmq3-dev zeromq zeromq-devel zeromq-devel NO ZeroMQ library
libunbound 1.4.16 NO libunbound-dev unbound unbound-devel unbound-devel NO DNS resolver
libsodium ? NO libsodium-dev libsodium libsodium-devel libsodium-devel NO cryptography
libunwind any NO libunwind-dev libunwind libunwind-devel libunwind-devel YES Stack traces
libreadline 6.3.0 NO libreadline-dev readline readline-devel readline-devel YES Input editing
GTest 1.5 YES libgtest-dev gtest gtest-devel gtest-devel YES Test suite
ccache any NO ccache ccache ccache ccache YES Compil. cache
Doxygen any NO doxygen doxygen doxygen doxygen YES Documentation
Graphviz any NO graphviz graphviz graphviz graphviz YES Documentation
libhidapi ? NO libhidapi-dev hidapi hidapi-devel hidapi-devel YES Hardware wallet
libusb ? NO libusb-1.0-0-dev libusb libusb-devel libusb1-devel YES Hardware wallet
libprotobuf ? NO libprotobuf-dev protobuf protobuf-devel protobuf-devel YES Hardware wallet
protoc ? NO protobuf-compiler protobuf protobuf protobuf-compiler YES Hardware wallet

Install all dependencies at once on Debian/Ubuntu:

text
sudo apt update && sudo apt install build-essential cmake pkg-config libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind-dev libreadline-dev libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-locale-dev libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-thread-dev python3 ccache doxygen graphviz git curl

Install all dependencies at once on Arch:

text
sudo pacman -Syu --needed base-devel cmake boost boost-libs openssl zeromq unbound libsodium libunwind readline python ccache doxygen graphviz hidapi libusb protobuf

Install all dependencies at once on Fedora:

text
sudo dnf install gcc gcc-c++ cmake pkgconf boost-devel openssl-devel zeromq-devel unbound-devel libsodium-devel libunwind-devel readline-devel ccache doxygen graphviz hidapi-devel libusb1-devel protobuf-devel protobuf-compiler

Install all dependencies at once on openSUSE:

text
sudo zypper ref && sudo zypper in cppzmq-devel libboost_chrono-devel libboost_date_time-devel libboost_filesystem-devel libboost_locale-devel libboost_program_options-devel libboost_regex-devel libboost_serialization-devel libboost_system-devel libboost_thread-devel libsodium-devel libunwind-devel unbound-devel cmake doxygen ccache fdupes gcc-c++ libevent-devel libopenssl-devel pkgconf-pkg-config readline-devel patterns-devel-C-C++-devel_C_C++

Install all dependencies at once on macOS with the provided Brewfile:

text
brew update && brew bundle --file=contrib/brew/Brewfile

FreeBSD one-liner required to build dependencies:

text
pkg install git gmake cmake pkgconf boost-libs libzmq4 libsodium unbound

Cloning the repository

Clone recursively to pull-in needed submodule(s):

text
git clone --recursive https://github.com/monero-project/monero

If you already have a repo cloned, initialize and update:

text
cd monero && git submodule init && git submodule update

Note: If there are submodule differences between branches, you may need to use git submodule sync && git submodule update --init after changing branches to build successfully.

Build instructions

Monero uses the CMake build system and a top-level Makefile that invokes cmake commands as needed.

On Linux and macOS

  • Install the dependencies

  • Change to the root of the source code directory, change to the most recent release branch, and build:

    bash
    cd monero
    git checkout release-v0.18
    make

    Optional: If your machine has several cores and enough memory, enable parallel build by running make -j<number of threads> instead of make. For this to be worthwhile, allow one core and about 2GB of RAM per thread.

    Note: The instructions above will compile the most stable release of the Monero software. If you would like to use and test the most recent software, use git checkout master. The master branch may contain updates that are both unstable and incompatible with release software, though testing is always encouraged.

  • The resulting executables can be found in build/release/bin

  • Add PATH="$PATH:$HOME/monero/build/release/bin" to .profile

  • Run Monero with monerod --detach

  • Optional: build and run the test suite to verify the binaries:

    bash
    make release-test

    NOTE: core_tests test may take a few hours to complete.

  • Optional: to build binaries suitable for debugging:

    bash
    make debug
  • Optional: build documentation in doc/html (omit HAVE_DOT=YES if graphviz is not installed):

    bash
    HAVE_DOT=YES doxygen Doxyfile
  • Optional: use ccache not to rebuild translation units, that haven't really changed. Monero's CMakeLists.txt file automatically handles it

    bash
    sudo apt install ccache

On the Raspberry Pi

Tested on a Raspberry Pi 5B with a clean installation of Raspberry Pi OS (64-bit) with Debian 12 from https://www.raspberrypi.com/software/operating-systems/.

  • apt-get update && apt-get upgrade to install the latest software

  • Install the dependencies for Monero from the 'Debian' column in the table above.

  • Optional: increase the system swap size:

    bash
    sudo /etc/init.d/dphys-swapfile stop
    sudo nano /etc/dphys-swapfile
    CONF_SWAPSIZE=2048
    sudo /etc/init.d/dphys-swapfile start
  • If using an external hard disk without an external power supply, ensure it gets enough power to avoid hardware issues when syncing, by adding the line "usb_max_current_enable=1" to /boot/firmware/config.txt

  • Clone Monero and checkout the most recent release version:

    bash
    git clone --recursive https://github.com/monero-project/monero.git
    cd monero
    git checkout v0.18.5.1
  • Build:

    bash
    USE_SINGLE_BUILDDIR=1 make release
  • Wait a few hours

  • The resulting executables can be found in build/release/bin

  • Add export PATH="$PATH:$HOME/monero/build/release/bin" to $HOME/.profile

  • Run source $HOME/.profile

  • Run Monero with monerod --detach

  • You may wish to reduce the size of the swap file after the build has finished, and delete the boost directory from your home directory

On Windows:

Binaries for Windows can be built on Windows using the MinGW toolchain within MSYS2 environment. The MSYS2 environment emulates a POSIX system. The toolchain runs within the environment and cross-compiles binaries that can run outside of the environment as a regular Windows application.

Preparing the build environment

  • Download and install the MSYS2 installer. Installing MSYS2 requires 64-bit Windows 10 or newer.

  • Open the MSYS shell via the MSYS2 MSYS shortcut

  • Update packages using pacman:

    bash
    pacman -Syu
  • Install dependencies:

    bash
    pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-unbound
  • Open the MingW shell via MSYS2 MINGW64 shortcut.

Cloning

  • To git clone, run:

    bash
    git clone --recursive https://github.com/monero-project/monero.git

Building

  • Change to the cloned directory, run:

    bash
    cd monero
  • If you would like a specific version/tag, do a git checkout for that version. eg. 'v0.18.5.1'. If you don't care about the version and just want binaries from master, skip this step:

    bash
    git checkout v0.18.5.1
  • To build Monero, run:

    bash
    make release-static -j $(nproc)

    The resulting executables can be found in build/release/bin

  • Optional: to build Windows binaries suitable for debugging, run:

    bash
    make debug -j $(nproc)

    The resulting executables can be found in build/debug/bin

On FreeBSD:

The project can be built from scratch by following instructions for Linux above (but use gmake instead of make). If you are running Monero in a jail, you need to add sysvsem="new" to your jail configuration, otherwise lmdb will throw the error message: Failed to open lmdb environment: Function not implemented.

Monero is also available as a port or package as monero-cli.

On OpenBSD:

You will need to add a few packages to your system. pkg_add cmake gmake zeromq libiconv boost libunbound.

The doxygen and graphviz packages are optional and require the xbase set. Running the test suite also requires py3-requests package.

Build monero: gmake

Note: you may encounter the following error when compiling the latest version of Monero as a normal user:

text
LLVM ERROR: out of memory
c++: error: unable to execute command: Abort trap (core dumped)

Then you need to increase the data ulimit size to 2GB and try again: ulimit -d 2000000

On NetBSD:

Check that the dependencies are present: pkg_info -c libexecinfo boost-headers boost-libs protobuf readline libusb1 zeromq git-base pkgconf gmake cmake | more, and install any that are reported missing, using pkg_add or from your pkgsrc tree. Readline is optional but worth having.

Third-party dependencies are usually under /usr/pkg/, but if you have a custom setup, adjust the "/usr/pkg" (below) accordingly.

Clone the monero repository recursively and checkout the most recent release as described above. Then build monero: gmake BOOST_ROOT=/usr/pkg LDFLAGS="-Wl,-R/usr/pkg/lib" release. The resulting executables can be found in build/NetBSD/[Release version]/Release/bin/.

On Solaris:

The default Solaris linker can't be used, you have to install GNU ld, then run cmake manually with the path to your copy of GNU ld:

bash
mkdir -p build/release
cd build/release
cmake -DCMAKE_LINKER=/path/to/ld -D CMAKE_BUILD_TYPE=Release ../..
cd ../..

Then you can run make as usual.

Cross Compiling

You can also cross-compile static binaries on Linux for Windows and macOS with the depends system.

  • make depends target=x86_64-linux-gnu for 64-bit linux binaries.
  • make depends target=x86_64-w64-mingw32 for 64-bit windows binaries.
    • Requires: g++-mingw-w64-x86-64
    • You also need to run:
      shell
      update-alternatives --set x86_64-w64-mingw32-g++ $(which x86_64-w64-mingw32-g++-posix) && \
      update-alternatives --set x86_64-w64-mingw32-gcc $(which x86_64-w64-mingw32-gcc-posix)
  • make depends target=x86_64-apple-darwin for Intel macOS binaries.
    • Requires: clang-19 lld-19
  • make depends target=arm64-apple-darwin for Apple Silicon macOS binaries.
    • Requires: clang-19 lld-19
    • You also need to run:
      shell
      export PATH="/usr/lib/llvm-19/bin/:$PATH"
  • make depends target=i686-linux-gnu for 32-bit linux binaries.
    • Requires: g++-multilib bc
  • make depends target=i686-w64-mingw32 for 32-bit windows binaries.
    • Requires: python3 g++-mingw-w64-i686
  • make depends target=arm-linux-gnueabihf for armv7 binaries.
    • Requires: g++-arm-linux-gnueabihf
  • make depends target=aarch64-linux-gnu for armv8 binaries.
    • Requires: g++-aarch64-linux-gnu
  • make depends target=riscv64-linux-gnu for RISC V 64 bit binaries.
    • Requires: g++-riscv64-linux-gnu
  • make depends target=x86_64-unknown-freebsd for freebsd binaries.
    • Requires: clang
  • make depends target=arm-linux-android for 32bit android binaries
  • make depends target=aarch64-linux-android for 64bit android binaries

The required packages are the names for each toolchain on apt. Depending on your distro, they may have different names.

Using depends might also be easier to compile Monero on Windows than using MSYS. Activate Windows Subsystem for Linux (WSL) with a distro (for example Ubuntu), install the apt build-essentials and follow the depends steps as depicted above.

The produced binaries still link libc dynamically. If the binary is compiled on a current distribution, it might not run on an older distribution with an older installation of libc.

Trezor hardware wallet support

If you have an issue with building Monero with Trezor support, you can disable it by setting USE_DEVICE_TREZOR=OFF

bash
USE_DEVICE_TREZOR=OFF make release

For more information, please check out Trezor src/device_trezor/README.md.

Guix builds

See contrib/guix/README.md.

Building and running monerod with Docker

bash
# Build image
docker build -t monerod .

# Create a directory on the host for the blockchain
mkdir -p /path/to/bitmonero

# Run it
docker run -d --user $(id -u):$(id -g) -v /path/to/bitmonero:/.bitmonero -p 127.0.0.1:18080:18080 -p 127.0.0.1:18081:18081 monerod

Installing Monero from a package

DISCLAIMER: These packages are not part of this repository or maintained by this project's contributors, and as such, do not go through the same review process to ensure their trustworthiness and security.

Packages are available for

  • Debian 12 (Bookworm) or later

    bash
    sudo apt install monero

    More info and versions in the Debian package tracker.

  • Arch Linux:

    bash
    sudo pacman -S monero
  • NixOS:

    bash
    nix-shell -p monero-cli
  • Guix:

    bash
    guix package -i monero
  • Alpine Linux:

    bash
    apk add monero
  • macOS (homebrew)

    bash
    brew install monero

Packaging for your favorite distribution would be a welcome contribution!

Running monerod

The build places the binary in bin/ sub-directory within the build directory from which cmake was invoked (repository root by default). To run in the foreground:

bash
./bin/monerod

To list all available options, run ./bin/monerod --help. Options can be specified either on the command line or in a configuration file passed by the --config-file argument. To specify an option in the configuration file, add a line with the syntax argumentname=value, where argumentname is the name of the argument without the leading dashes, for example, log-level=1.

To run in background:

bash
./bin/monerod --log-file monerod.log --detach

To run as a systemd service, copy monerod.service to /etc/systemd/system/ and monerod.conf to /etc/. The example service assumes that the user monero exists and its home is the data directory specified in the example config.

If you're on Mac, you may need to add the --max-concurrency 1 option to monero-wallet-cli, and possibly monerod, if you get crashes refreshing.

Using Tor

There is a new, still experimental, integration with Tor. The feature allows connecting over IPv4 and Tor simultaneously - IPv4 is used for relaying blocks and relaying transactions received by peers whereas Tor is used solely for relaying transactions received over local RPC. This provides privacy and better protection against surrounding node (sybil) attacks.

While Monero isn't made to integrate with Tor, it can be used wrapped with torsocks, by setting the following configuration parameters and environment variables:

  • --p2p-bind-ip 127.0.0.1 on the command line or p2p-bind-ip=127.0.0.1 in monerod.conf to disable listening for connections on external interfaces.
  • If you use the wallet with a Tor daemon via the loopback IP (eg, 127.0.0.1:9050), then use --untrusted-daemon unless it is your own hidden service.

Example command line to start monerod through Tor:

bash
monerod --proxy 127.0.0.1:9050 --p2p-bind-ip 127.0.0.1

A helper script is in contrib/tor/monero-over-tor.sh. It assumes Tor is installed already, and runs Tor and Monero with the right configuration.

Using Tor on Tails

TAILS ships with a very restrictive set of firewall rules. Therefore, you need to add a rule to allow this connection too, in addition to telling torsocks to allow inbound connections. Full example:

bash
sudo iptables -I OUTPUT 2 -p tcp -d 127.0.0.1 -m tcp --dport 18081 -j ACCEPT
DNS_PUBLIC=tcp torsocks ./monerod --p2p-bind-ip 127.0.0.1 --rpc-bind-ip 127.0.0.1 \
    --data-dir /home/amnesia/Persistent/your/directory/to/the/blockchain

Pruning

As of June 2026, the full Monero blockchain file is about 280 GB. One can store a pruned blockchain, which is about 95 GB. A pruned blockchain can only serve part of the historical chain data to other peers, but is otherwise identical in functionality to the full blockchain. To use a pruned blockchain, it is best to start the initial sync with --prune-blockchain. However, it is also possible to prune an existing blockchain using the monero-blockchain-prune tool or using the --prune-blockchain monerod option with an existing chain. If an existing chain exists, pruning will temporarily require disk space to store both the full and pruned blockchains.

For more detailed information see the 'Pruning' entry in the Moneropedia

Debugging

This section contains general instructions for debugging failed installs or problems encountered with Monero. First, ensure you are running the latest version built from the GitHub repo.

Obtaining stack traces and core dumps on Unix systems

We generally use the tool gdb (GNU debugger) to provide stack trace functionality, and ulimit to provide core dumps in builds which crash or segfault.

  • To use gdb in order to obtain a stack trace for a build that has stalled:

Run the build.

Once it stalls, enter the following command:

bash
gdb /path/to/monerod `pidof monerod`

Type thread apply all bt within gdb in order to obtain the stack trace

  • If however the core dumps or segfaults:

Enter ulimit -c unlimited on the command line to enable unlimited filesizes for core dumps

Enter echo core | sudo tee /proc/sys/kernel/core_pattern to stop cores from being hijacked by other tools

Run the build.

When it terminates with an output along the lines of "Segmentation fault (core dumped)", there should be a core dump file in the same directory as monerod. It may be named just core, or core.xxxx with numbers appended.

You can now analyse this core dump with gdb as follows:

bash
gdb /path/to/monerod /path/to/dumpfile

Print the stack trace with bt

  • If a program crashed and cores are managed by systemd, the following can also get a stack trace for that crash:
bash
coredumpctl -1 gdb

To run Monero within gdb:

Type gdb /path/to/monerod

Pass command-line options with --args followed by the relevant arguments

Type run to run monerod

Analysing memory corruption

There are two tools available:

ASAN

Configure Monero with the -D SANITIZE=ON cmake flag, eg:

bash
cd build/debug && cmake -D SANITIZE=ON -D CMAKE_BUILD_TYPE=Debug ../..

You can then run the monero tools normally. Performance will typically halve.

valgrind

Install valgrind and run as valgrind /path/to/monerod. It will be very slow.

LMDB

Instructions for debugging suspected blockchain corruption as per @HYC

There is an mdb_stat command in the LMDB source that can print statistics about the database but it's not routinely built. This can be built with the following command:

bash
cd ~/monero/external/db_drivers/liblmdb && make

The output of mdb_stat -ea will indicate inconsistencies in the blocks, block_heights and block_info table.

The output of mdb_dump -s blocks and mdb_dump -s block_info is useful for indicating whether blocks and block_info contain the same keys.

These records are dumped as hex data, where the first line is the key and the second line is the data.

Known Issues

Protocols

Socket-based

Because of the nature of the socket-based protocols that drive monero, certain protocol weaknesses are somewhat unavoidable at this time. While these weaknesses can theoretically be fully mitigated, the effort required (the means) may not justify the ends. As such, please consider taking the following precautions if you are a monero node operator:

  • Run monerod on a "secured" machine. If operational security is not your forte, at a very minimum, have a dedicated computer running monerod and do not browse the web, use email clients, or use any other potentially harmful apps on your monerod machine. Do not click links or load URL/MUA content on the same machine. Doing so may potentially exploit weaknesses in commands which accept "localhost" and "127.0.0.1".
  • If you plan on hosting a public "remote" node, start monerod with --restricted-rpc. This is a must.

Blockchain-based

Certain blockchain "features" can be considered "bugs" if misused. Consequently, please consider the following:

  • When receiving monero, be aware that it may be locked for an arbitrary time if the sender elected to, preventing you from spending that monero until the lock time expires. You may want to hold off acting upon such a transaction until the unlock time lapses. To get a sense of that time, you can consider the remaining blocktime until unlock as seen in the show_transfers command.

File: contrib/depends/README.md

Usage

To build dependencies for the current arch+OS, from this working directory:

bash
make

To build for another arch/OS:

bash
make HOST=host-platform-triplet

For example:

bash
make HOST=x86_64-w64-mingw32 -j4

A toolchain will be generated that's suitable for plugging into Monero's
cmake. In the above example, a dir named x86_64-w64-mingw32 will be
created. To use it for Monero, from the top of the Monero source tree:

bash
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=$PWD/../contrib/depends/x86_64-w64-mingw32/share/toolchain.cmake ..

Common host-platform-triplets for cross compilation are:

  • i686-w64-mingw32 for Win32
  • x86_64-w64-mingw32 for Win64
  • x86_64-apple-darwin for MacOSX x86_64
  • arm-linux-gnueabihf for Linux ARM 32 bit
  • aarch64-linux-gnu for Linux ARM 64 bit
  • riscv64-linux-gnu for Linux RISCV 64 bit

No other options are needed, the paths are automatically configured.

Dependency Options:
The following can be set when running make: make FOO=bar

text
SOURCES_PATH: downloaded sources will be placed here
BASE_CACHE: built packages will be placed here
FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up
DEBUG: disable some optimizations and enable more runtime checking
HOST_ID_SALT: Optional salt to use when generating host package ids
BUILD_ID_SALT: Optional salt to use when generating build package ids

Additional targets:

text
download: run 'make download' to fetch all sources without building them
download-osx: run 'make download-osx' to fetch all sources needed for osx builds
download-win: run 'make download-win' to fetch all sources needed for win builds
download-linux: run 'make download-linux' to fetch all sources needed for linux builds

#Mingw builds

Building for 32/64bit mingw requires switching alternatives to a posix mode

bash
update-alternatives --set x86_64-w64-mingw32-g++ x86_64-w64-mingw32-g++-posix
update-alternatives --set x86_64-w64-mingw32-gcc x86_64-w64-mingw32-gcc-posix

Other documentation


File: contrib/epee/README.md

epee - is a small library of helpers, wrappers, tools and so on, used to make my life easier.


File: contrib/guix/README.md

Bootstrappable Monero Builds

This directory contains the files necessary to perform bootstrappable Monero
builds.

Bootstrappability furthers our binary security guarantees by allowing us
to audit and reproduce our toolchain instead of blindly trusting binary
downloads.

We achieve bootstrappability by using Guix as a functional package manager.

Requirements

Conservatively, you will need an x86_64 machine with:

  • 16GB of free disk space on the partition that /gnu/store will reside in
  • 8GB of free disk space per platform triple you're planning on building
    (see the HOSTS environment variable description)

Installation and Setup

If you don't have Guix installed and set up, please follow the instructions in
INSTALL.md

Usage

If you haven't considered your security model yet, please read the relevant
section
before proceeding to perform a build.

Building

The author highly recommends at least reading over the common usage patterns
and examples
section below
before starting a build. For a full list of customization options, see the
recognized environment variables section.

To build Monero reproducibly with all default options, invoke the
following from the top of a clean repository:

sh
./contrib/guix/guix-build

Cleaning intermediate work directories

By default, guix-build leaves all intermediate files or "work directories"
(e.g. depends/work, guix-build-*/distsrc-*) intact at the end of a build so
that they are available to the user (to aid in debugging, etc.). However, these
directories usually take up a large amount of disk space. Therefore, a
guix-clean convenience script is provided which cleans the current git
worktree to save disk space:

text
./contrib/guix/guix-clean

Attesting to build outputs

Much like how Gitian build outputs are attested to in a gitian.sigs
repository, Guix build outputs are attested to in the guix.sigs
repository
.

After you've cloned the guix.sigs repository, to attest to the current
worktree's commit/tag:

text
env GUIX_SIGS_REPO= SIGNER=<gpg-key-name> ./contrib/guix/guix-attest

See ./contrib/guix/guix-attest --help for more information on the various ways
guix-attest can be invoked.

Verifying build output attestations

After at least one other signer has uploaded their signatures to the guix.sigs

text
git -C  pull
env GUIX_SIGS_REPO= ./contrib/guix/guix-verify

Common `guix-build` invocation patterns and examples

Keeping caches outside of the worktree

If you perform a lot of builds and have a bunch of worktrees, you may find it
more efficient to keep the depends tree's download cache and build cache
outside of the worktrees to avoid duplicate downloads and unnecessary builds. To
help with this situation, the guix-build script honours the SOURCES_PATH,
BASE_CACHE environment variables and will pass them on to the
depends tree so that you can do something like:

sh
env SOURCES_PATH="$HOME/depends-SOURCES_PATH" BASE_CACHE="$HOME/depends-BASE_CACHE" ./contrib/guix/guix-build

Note that the paths that these environment variables point to must be
directories
, and NOT symlinks to directories.

See the recognized environment variables section for more
details.

Building a subset of platform triples

Sometimes you only want to build a subset of the supported platform triples, in
which case you can override the default list by setting the space-separated
HOSTS environment variable:

sh
env HOSTS='x86_64-w64-mingw32 x86_64-apple-darwin' ./contrib/guix/guix-build

See the recognized environment variables section for more
details.

Controlling the number of threads used by `guix` build commands

Depending on your system's RAM capacity, you may want to decrease the number of
threads used to decrease RAM usage or vice versa.

By default, the scripts under ./contrib/guix will invoke all guix build
commands with --cores="$JOBS". Note that $JOBS defaults to $(nproc) if not
specified. However, astute manual readers will also notice that guix build
commands also accept a --max-jobs= flag (which defaults to 1 if unspecified).

Here is the difference between --cores= and --max-jobs=:

Note: When I say "derivation," think "package"

--cores=

  • controls the number of CPU cores to build each derivation. This is the value
    passed to make's --jobs= flag.

--max-jobs=

  • controls how many derivations can be built in parallel
  • defaults to 1

Therefore, the default is for guix build commands to build one derivation at a
time, utilizing $JOBS threads.

Specifying the $JOBS environment variable will only modify --cores=, but you
can also modify the value for --max-jobs= by specifying
$ADDITIONAL_GUIX_COMMON_FLAGS. For example, if you have a LOT of memory, you
may want to set:

sh
export ADDITIONAL_GUIX_COMMON_FLAGS='--max-jobs=8'

Which allows for a maximum of 8 derivations to be built at the same time, each
utilizing $JOBS threads.

Or, if you'd like to avoid spurious build failures caused by issues with
parallelism within a single package, but would still like to build multiple
packages when the dependency graph allows for it, you may want to try:

sh
export JOBS=1 ADDITIONAL_GUIX_COMMON_FLAGS='--max-jobs=8'

See the recognized environment variables section for more
details.

Recognized environment variables

  • HOSTS

    Override the space-separated list of platform triples for which to perform a
    bootstrappable build.

    (defaults to "x86_64-linux-gnu aarch64-linux-gnu
    riscv64-linux-gnu x86_64-w64-mingw32 x86_64-unknown-freebsd
    x86_64-apple-darwin arm64-apple-darwin aarch64-linux-android")

  • SOURCES_PATH

    Set the depends tree download cache for sources. This is passed through to the
    depends tree. Setting this to the same directory across multiple builds of the
    depends tree can eliminate unnecessary redownloading of package sources.

    The path that this environment variable points to must be a directory, and
    NOT a symlink to a directory.

  • BASE_CACHE

    Set the depends tree cache for built packages. This is passed through to the
    depends tree. Setting this to the same directory across multiple builds of the
    depends tree can eliminate unnecessary building of packages.

    The path that this environment variable points to must be a directory, and
    NOT a symlink to a directory.

  • JOBS

    Override the number of jobs to run simultaneously, you might want to do so on
    a memory-limited machine. This may be passed to:

    • guix build commands as in guix shell --cores="$JOBS"
    • make as in make --jobs="$JOBS"
    • xargs as in xargs -P"$JOBS"

    See here for
    more details.

    (defaults to the value of nproc outside the container)

  • SOURCE_DATE_EPOCH

    Override the reference UNIX timestamp used for bit-for-bit reproducibility,
    the variable name conforms to standard.

    (defaults to the output of git -c log.showSignature=false log --format=%at -1)

  • V

    If non-empty, will pass V=1 to all make invocations, making make output
    verbose.

    Note that any given value is ignored. The variable is only checked for
    emptiness. More concretely, this means that V= (setting V to the empty
    string) is interpreted the same way as not setting V at all, and that V=0
    has the same effect as V=1.

  • SUBSTITUTE_URLS

    A whitespace-delimited list of URLs from which to download pre-built packages.
    A URL is only used if its signing key is authorized (refer to the substitute
    servers section
    for more details).

  • ADDITIONAL_GUIX_COMMON_FLAGS

    Additional flags to be passed to all guix commands.

  • ADDITIONAL_GUIX_TIMEMACHINE_FLAGS

    Additional flags to be passed to guix time-machine.

  • ADDITIONAL_GUIX_ENVIRONMENT_FLAGS

    Additional flags to be passed to the invocation of guix shell inside
    guix time-machine.

Choosing your security model

No matter how you installed Guix, you need to decide on your security model for
building packages with Guix.

Guix allows us to achieve better binary security by using our CPU time to build
everything from scratch. However, it doesn't sacrifice user choice in pursuit of
this: users can decide whether or not to use substitutes (pre-built
packages).

Option 1: Building with substitutes

Step 1: Authorize the signing keys

Depending on the installation procedure you followed, you may have already
authorized the Guix build farm key. In particular, the official shell installer
script asks you if you want the key installed, and the debian distribution
package authorized the key during installation.

You can check the current list of authorized keys at /etc/guix/acl.

At the time of writing, a /etc/guix/acl with just the Guix build farm key
authorized looks something like:

lisp
(acl
 (entry
  (public-key
   (ecc
    (curve Ed25519)
    (q #8D156F295D24B0D9A86FA5741A840FF2D24F60F7B6C4134814AD55625971B394#)
    )
   )
  (tag
   (guix import)
   )
  )
 )

If you've determined that the official Guix build farm key hasn't been
authorized, and you would like to authorize it, run the following as root:

text
guix archive --authorize < /var/guix/profiles/per-user/root/current-guix/share/guix/ci.guix.gnu.org.pub

If
/var/guix/profiles/per-user/root/current-guix/share/guix/ci.guix.gnu.org.pub
doesn't exist, try:

sh
guix archive --authorize < /share/guix/ci.guix.gnu.org.pub

Where `` is likely:

  • /usr if you installed from a distribution package
  • /usr/local if you installed Guix from source and didn't supply any
    prefix-modifying flags to Guix's ./configure

Removing authorized keys

To remove previously authorized keys, simply edit /etc/guix/acl and remove the
(entry (public-key ...)) entry.

Step 2: Specify the substitute servers

Once its key is authorized, the official Guix build farm at
https://ci.guix.gnu.org is automatically used unless the --no-substitutes flag
is supplied. This default list of substitute servers is overridable both on a
guix-daemon level and when you invoke guix commands.

Option 2: Disabling substitutes on an ad-hoc basis

If you prefer not to use any substitutes, make sure to supply --no-substitutes
like in the following snippet. The first build will take a while, but the
resulting packages will be cached for future builds.

For direct invocations of guix:

sh
guix <cmd> --no-substitutes

For the scripts under ./contrib/guix/:

sh
export ADDITIONAL_GUIX_COMMON_FLAGS='--no-substitutes'

Option 3: Disabling substitutes by default

guix-daemon accepts a --no-substitutes flag, which will make sure that,
unless otherwise overridden by a command line invocation, no substitutes will be
used.

If you start guix-daemon using an init script, you can edit said script to
supply this flag.


File: docs/ANONYMITY_NETWORKS.md

Anonymity Networks with Monero

Currently only Tor and I2P have been integrated into Monero. The usage of
these networks is still considered experimental - there are a few pessimistic
cases where privacy is leaked. The design is intended to maximize privacy of
the source of a transaction by broadcasting it over an anonymity network, while
relying on IPv4 for the remainder of messages to make surrounding node attacks
(via sybil) more difficult.

Behavior

When the --proxy flag is used, monerod sends all external traffic via the
proxy. This includes blockchain syncing, connections to other peers, and update
checks. However, it treats the proxy as the clearnet zone. It does not connect
to hidden services over the proxy.

The --tx-proxy flag is used specifically for anonymity networks and
enables anonymity network mode. If any anonymity network is enabled,
transactions being broadcast that lack
a valid "context" (i.e. the transaction did not come from a P2P connection),
will only be sent to peers on anonymity networks. If an anonymity network is
enabled but no peers over an anonymity network are available, an error is
logged and the transaction is kept for future broadcasting over an anonymity
network. The transaction will not be broadcast unless an anonymity connection
is made or until monerod is shutdown and restarted with only public
connections enabled.

Anonymity networks can also be used with monero-wallet-cli and
monero-wallet-rpc - the wallets will connect to a daemon through a proxy. The
daemon must provide a hidden service for the RPC itself, which is separate from
the hidden service for P2P connections.

P2P Commands

Only handshakes, peer timed syncs and transaction broadcast messages are
supported over anonymity networks. If one --add-exclusive-node P2P address
is specified, then no syncing will take place and only transaction broadcasting
can occur. It is therefore recommended that --add-exclusive-node be combined
with additional exclusive IPv4 address(es).

Usage

Blockchain sync

Monerod does not support synchronizing the blockchain over onion or I2P hidden services.
You may sync the blockchain using a SOCKS4 proxy. Monerod will connect to IPv4
nodes using this proxy to sync the blockchain.

bash
monerod --proxy 127.0.0.1:9050 --p2p-bind-ip 127.0.0.1

You can also combine --proxy with --tx-proxy (see below).

Hidden Services

Hidden services - onion and I2P domains - are available to use for transaction broadcasts.
You may use the below options with or without --proxy.

Outbound Connections

Connecting to an anonymous address requires the command line option
--tx-proxy which tells monerod the ip/port of a socks proxy provided by a
separate process. On most systems the configuration will look like:

bash
monerod \
    --tx-proxy tor,127.0.0.1:9050,10 \
    --tx-proxy i2p,127.0.0.1:4447

which tells monerod to connect to ".onion" P2P addresses using a socks
proxy at IP 127.0.0.1 port 9050 with a max of 10 outgoing connections and
".b32.i2p" P2P addresses using a socks proxy at IP 127.0.0.1 port 4447
with the default max outgoing connections.

If desired, peers can be manually specified:

bash
--add-exclusive-node 5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18084
--add-priority-node 5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18084
--add-peer 5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18084

Either option can be listed multiple times, and can specify any mix of Tor,
I2P, and IPv4 addresses. Using --add-exclusive-node will prevent the usage of
seed nodes on ALL networks, which will typically be undesirable.
If you specify add-exclusive-node for onion or I2P, make sure to do so for clearnet nodes as well, otherwise you will be unable to sync.

Inbound Connections

Receiving anonymity connections is done through the option
--anonymous-inbound. This option tells monerod the inbound address, network
type, and max connections:

bash
--anonymous-inbound 5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18084,127.0.0.1:18084,25 \
--anonymous-inbound cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p,127.0.0.1:18085

which tells monerod that a max of 25 inbound Tor connections are being
received at address "5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18084" and forwarded to monerod
localhost port 18084, and a default max I2P connections are being received at
address "cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p" and
forwarded to monerod localhost port 18085. Using tx-proxy(required), these
addresses will be shared with peers over the same network type, otherwise your
peers will not be notified of your onion or I2P address.

Note: The specified port for anonymous-inbound must be unique (not 18080 etc). anonymous-inbound is not for blockchain sync!
Peers will use their own tx-proxy to relay transactions, which originate on their node,
to your anonymous-inbound.

Wallet RPC

An anonymity network can be configured to forward incoming connections to a
monerod RPC port - which is independent from the configuration for incoming
P2P anonymity connections. The anonymity network (Tor/I2P) is
configured in the same manner as below, except this excludes P2P.

text
HiddenServiceDir /var/lib/tor/data/monero-rpc
HiddenServicePort 18089 127.0.0.1:18089

Then the wallet will be configured to use a Tor/I2P address:

bash
monero-wallet-cli \
    --proxy 127.0.0.1:9050 \
    --daemon-address 5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18089

The proxy must match the address type - a Tor proxy will not work properly with
I2P addresses, etc.

I2P hidden service (b32.i2p) and Tor Hidden service (.onion) addresses provide the information necessary to authenticate and
encrypt the connection from end-to-end. If desired, SSL can also be applied to
the connection with --daemon-address https://5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion which
requires a server certificate that is signed by a "root" certificate on the
machine running the wallet. Alternatively, --daemon-ssl-certificate can be used to
specify a certificate to authenticate the server.

Proxies can also be used to connect to "clearnet" (IPv4 addresses or ICANN
domains), but --daemon-ssl-certificate must be used for authentication and
encryption, or bypassed with --daemon-ssl-allow-any-cert.

Network Types

Tor & I2P

Options --add-exclusive-node, --add-priority-node, and --add-peer recognize ".onion" and
".b32.i2p" addresses, and will properly forward those addresses to the proxy
provided with --tx-proxy tor,... or --tx-proxy i2p,....

Option --anonymous-inbound also recognizes ".onion" and ".b32.i2p" addresses,
and will automatically be sent out to outgoing Tor/I2P connections so the peer
can distribute the address to its other peers.

Configuration

Tor must be configured for hidden services. An example configuration ("torrc")
might look like:

text
# P2P Hidden service
HiddenServiceDir /var/lib/tor/data/monero
HiddenServicePort 18084 127.0.0.1:18084  # anonymous-inbound

# RPC Hidden service
HiddenServiceDir /var/lib/tor/data/monero-rpc
HiddenServicePort 18089 127.0.0.1:18089  # rpc-restricted-bind-port

This will store key information in /var/lib/tor/data/monero and /var/lib/tor/data/monero-rpc
and will forward "Tor port" 18084 and 18089 to ports 18084 and 18089 of ip 127.0.0.1, respectively. The file
/usr/lib/tor/data/monero/hostname will contain the ".onion" address for use with --anonymous-inbound, and
/var/lib/tor/data/monero-rpc/hostname will contain the ".onion" address for use with RPC.

I2P must be configured with a standard server tunnel. Configuration differs by
I2P implementation.
You can find guides for i2pd here.

Example Node Configurations

Please check the monerod reference for more information about these flags.

Clearnet Only

Allows incoming connections and attempts to port forward with UPnP.

bash
monerod

Connect to IPv4 Nodes Over Clearnet and Relay Transactions via Tor

Monerod will connect to IPv4 nodes via clearnet, revealing to your ISP
that you are running a Monero node, but your transactions will be relayed over
Tor.

bash
sudo apt install tor # Or install Tor some other way
systemctl start tor # Or start Tor manually
monerod --tx-proxy tor,127.0.0.1:9050,10

Connect To IPv4 Nodes Over Tor Only

This configuration does not connect to hidden services or accept incoming
connections. Your ISP will see that you are running Tor, but not Monerod.

bash
sudo apt install tor # Or install Tor some other way
systemctl start tor # Or start Tor manually
monerod --proxy 127.0.0.1:9050 --p2p-bind-ip 127.0.0.1

Connect to IPv4 Nodes Over Tor and Connect to Hidden Services

Your ISP will see that you are running Tor and I2P, but not Monerod. Transactions
will be relayed to hidden services. Your node will not accept any incoming
connections (including from Tor and I2P).

bash
monerod --proxy 127.0.0.1:9050 \
    --p2p-bind-ip 127.0.0.1 \
    --tx-proxy tor,127.0.0.1:9050,10 \
    --tx-proxy i2p,127.0.0.1:4447,10

Connect to IPv4 over Tor and Publish Hidden Services

You will need to configure hidden services manually for Tor and I2P.

bash
monerod --proxy 127.0.0.1:9050 \
    --p2p-bind-ip 127.0.0.1 \
    --tx-proxy tor,127.0.0.1:9050,10 \
    --tx-proxy i2p,127.0.0.1:4447,10 \
    --anonymous-inbound=yourlongv3onionaddress.onion:18084,127.0.0.1:18084 \
    --anonymous-inbound=yourlongb32i2paddress.b32.i2p,127.0.0.1:18085

Connect Exclusively to Hidden Services (avoid IPv4 entirely)

This configuration is not currently supported. Monerod relies on IPv4 to sync
the blockchain to make Sybil attacks more difficult.

Privacy Limitations

There are currently some techniques that could be used to possibly identify
the machine that broadcast a transaction over an anonymity network.

Timestamps

The peer timed sync command sends the current time in the message. This value
can be used to link an onion address to an IPv4/IPv6 address. If a peer first
sees a transaction over Tor, it could assume (possibly incorrectly) that the
transaction originated from the peer. If both the Tor connection and an
IPv4/IPv6 connection have timestamps that are approximately close in value they
could be used to link the two connections. This is less likely to happen if the
system clock is fairly accurate - many peers on the Monero network should have
similar timestamps.

Mitigation

Keep the system clock accurate so that fingerprinting is more difficult. In
the future a random offset might be applied to anonymity networks so that if
the system clock is noticeably off (and therefore more fingerprintable),
linking the public IPv4/IPv6 connections with the anonymity networks will be
more difficult.

Intermittent Monero Syncing

If a user only runs monerod to send a transaction then quit, this can also
be used by an ISP to link a user to a transaction.

Mitigation

Run monerod as often as possible to conceal when transactions are being sent.
Future versions will also have peers that first receive a transaction over an
anonymity network delay the broadcast to public peers by a randomized amount.
This will not completely mitigate a user who syncs up sends then quits, in
part because this rule is not enforceable, so this mitigation strategy is
simply a best effort attempt.

Active Bandwidth Shaping

An attacker could attempt to bandwidth shape traffic in an attempt to determine
the source of a Tor/I2P connection. There isn't great mitigation against
this, but I2P should provide better protection against this attack since
the connections are not circuit based.

Mitigation

The best mitigation is to use I2P instead of Tor. However, I2P
has a smaller set of users (less cover traffic) and academic reviews, so there
is a trade off in potential issues. Also, anyone attempting this strategy really
wants to uncover a user, it seems unlikely that this would be performed against
every Tor/I2P user.

I2P/Tor Stream Used Twice

If a single I2P/Tor stream is used 2+ times for transmitting a transaction, the
operator of the hidden service can conclude that both transactions came from the
same source. If the subsequent transactions spend a change output from the
earlier transactions, this will also reveal the "real" spend in the ring
signature. This issue was (primarily) raised by @secparam on Twitter.

Mitigation

monerod currently selects two outgoing connections every 5 minutes for
transmitting transactions over I2P/Tor. Using outgoing connections prevents an
adversary from making many incoming connections to obtain information (this
technique was taken from Dandelion). Outgoing connections also do not have a
persistent public key identity - the creation of a new circuit will generate
a new public key identity. The lock time on a change address is ~20 minutes, so
monerod will have rotated its selected outgoing connections several times in
most cases. However, the number of outgoing connections is typically a small
fixed number, so there is a decent probability of reuse with the same public
key identity.

@secparam (Twitter) recommended changing circuits (Tor) as an additional
precaution. This is likely not a good idea - forcibly requesting Tor to change
circuits is observable by the ISP. Instead, monerod should likely disconnect
from peers occasionally. Tor will rotate circuits every ~10 minutes, so
establishing new connections will use a new public key identity and make it
more difficult for the hidden service to link information. This process will
have to be done carefully because closing/reconnecting connections can also
leak information to hidden services if done improperly.

At the current time, if users need to frequently make transactions, I2P/Tor
will improve privacy from ISPs and other common adversaries, but still have
some metadata leakages to unknown hidden service operators.


File: docs/COMPILING_DEBUGGING_TESTING.md

Compiling, debugging and testing efficiently

This document describes ways of compiling, debugging and testing efficiently for various use cases.
The intended audience are developers, who want to leverage newly added tricks to Monero via CMake. The document will lower the entry point for these developers.
Before reading this document, please consult section "Build instructions" in the main README.md.
Some information from README.md will be repeated here, but the aim is to go beyond it.

Basic compilation

Monero can be compiled via the main Makefile, using one of several targets listed there.
The targets are actually presets for CMake calls with various options, plus make commands for building or in some cases make test for testing.
It is possible to extract these CMake calls and modify them for your specific needs. For example, a minimal external cmake command to compile Monero, executed from within a newly created build directory could look like:

cmake -S "$DIR_SRC" -DCMAKE_BUILD_TYPE=Release && make

where the variable DIR_SRC is expected to store the path to the Monero source code.

Use cases

Test Driven Development (TDD) - shared libraries for release builds

Building shared libraries spares a lot of disk space and linkage time. By default only the debug builds produce shared libraries. If you'd like to produce dynamic libraries for the release build for the same reasons as it's being done for the debug version, then you need to add the BUILD_SHARED_LIBS=ON flag to the CMake call, like the following:

cmake -S "$DIR_SRC" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON && make

A perfect use case for the above call is following the Test Driven Development (TDD) principles. In a nutshell, you'd first write a couple of tests, which describe the (new) requirements of the class/method that you're about to write or modify. The tests will typically compile for quite a long time, so ideally write them once. After you're done with the tests, the only thing left to do is to keep modifying the implementation for as long as the tests are failing. If the implementation is contained properly within a .cpp file, then the only time cost to be paid will be compiling the single source file and generating the implementation's shared library. The test itself will not have to be touched and will pick up the new version of the implementation (via the shared library) upon the next execution of the test.

Project generation for IDEs

CMake allows to generate project files for many IDEs. The list of supported project files can be obtained by writing in the console:

cmake -G

For instance, in order to generate Makefiles and project files for the Code::Blocks IDE, this part of the call would look like the following:

cmake -G "CodeBlocks - Unix Makefiles" (...)

The additional artifact of the above call is the monero.cbp Code::Blocks project file in the build directory.

Debugging in Code::Blocks (CB)

First prepare the build directory for debugging using the following example command, assuming, that the path to the source dir is being held in the DIR_SRC variable, and using 2 cores:

cmake -S "$DIR_SRC" -G "CodeBlocks - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON && make -j 2

After a successful build, open the monero.cbp with CB. From the CB's menu bar select the target, that you want debug. Assuming these are unit tests:

Build -> Select target -> Select target -> unit_tests

In order to lower the turnaround times, we will run a specific portion of code of interest, without having to go through all the time costly initialization and execution of unrelated parts. For this we'll use GTest's capabilities of test filtering. From the build directory run the following command to learn all the registered tests:

tests/unit_tests/unit_tests --gtest_list_tests

For example, if you're only interested in logging, you'd find in the list the label logging. and its subtests. To execute all the logging tests, you'd write in the console:

tests/unit_tests/unit_tests --gtest_filter="logging.*"

This parameter is what we need to transfer to CB, in order to reflect the same behaviour in the CB's debugger. From the main menu select:

Project -> Set program's arguments...

Then in the Program's arguments textbox you'd write in this case:

--gtest_filter="logging.*"

Verify if the expected UTs are being properly executed with F9 or select:

Build -> Build and run

If everything looks fine, then after setting some breakpoints of your choice, the target is ready for debugging in CB via:

Debug -> Start/Continue

To be done (and merged):

Multihost parallel compilation

https://github.com/monero-project/monero/pull/7160

Unity builds

https://github.com/monero-project/monero/pull/7217


File: docs/CONTRIBUTING.md

Contributing to Monero

A good way to help is to test, and report bugs. See
How to Report Bugs Effectively (by Simon Tatham)
if you want to help that way. Testing is invaluable in making a piece
of software solid and usable.

General guidelines

  • Comments are encouraged.
  • If modifying code for which Doxygen headers exist, that header must be modified to match.
  • Tests would be nice to have if you're adding functionality.

Patches are preferably to be sent via a GitHub pull request. If that
can't be done, patches in "git format-patch" format can be sent
(eg, posted to paste.debian.net with a long enough timeout and a link
posted to #monero-dev on irc.libera.chat).

Patches should be self contained. A good rule of thumb is to have
one patch per separate issue, feature, or logical change. Also, no
other changes, such as random whitespace changes, reindentation,
or fixing typos, spelling, or wording, unless user visible.
Following the code style of the particular chunk of code you're
modifying is encouraged. Proper squashing should be done (eg, if
you're making a buggy patch, then a later patch to fix the bug,
both patches should be merged).

If you've made random unrelated changes (either because your editor
is annoying or you made them for other reasons), you can select
what changes go into the coming commit using git add -p, which
walks you through all the changes and asks whether or not to
include this particular change. This helps create clean patches
without any irrelevant changes. git diff will show you the changes
in your tree. git diff --cached will show what is currently staged
for commit. As you add hunks with git add -p, those hunks will
"move" from the git diff output to the git diff --cached output,
so you can see clearly what your commit is going to look like.

Commits and pull requests

Commit messages should be sensible. That means a subject line that
describes the patch, with an optional longer body that gives details,
documentation, etc.

Please reference the current merged PR list for a general subject line
format of the current contributors. As of 2024 the subject line uses the
following format:

subdirectory under src where changes were made: description of change

For example (PR #9189):
cryptonote_core: early out on out of bounds scaling parameter

When submitting a pull request on GitHub, make sure your branch is
rebased. No merge commits nor stray commits from other people in
your submitted branch, please. You may be asked to rebase if there
are conflicts (even trivially resolvable ones).

PGP signing commits is strongly encouraged. That should explain why
the previous paragraph is here.

[Code of Conduct (22/C4.1)](http://rfc.zeromq.org/spec:22)

License

Copyright (c) 2009-2015 Pieter Hintjens.
Copyright (c) 2017-2024, The Monero Project

This Specification is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This Specification is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, see http://www.gnu.org/licenses.

Language

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Design

Preliminaries

  • The project MUST use the git distributed revision control system.
  • The project MUST be hosted on github.com or equivalent, herein called the "Platform".
  • The project MUST use the Platform issue tracker.
    • Non-GitHub example:
      • "Platform" could be a vanilla git repo and Trac hosted on the same machine/network.
      • The Platform issue tracker would be Trac.
  • The project SHOULD have clearly documented guidelines for code style.
  • A "Contributor" is a person who wishes to provide a patch, being a set of commits that solve some clearly identified problem.
  • A "Maintainer" is a person who merges patches to the project. Maintainers are not developers; their job is to enforce process.
  • Contributors MUST NOT have commit access to the repository unless they are also Maintainers.
  • Maintainers MUST have commit access to the repository.
  • Everyone, without distinction or discrimination, MUST have an equal right to become a Contributor under the terms of this contract.

Licensing and ownership

  • The project MUST use a share-alike license, such as BSD-3, the GPLv3 or a variant thereof (LGPL, AGPL), or the MPLv2.
  • All contributions to the project source code ("patches") MUST use the same license as the project.
  • All patches are owned by their authors. There MUST NOT be any copyright assignment process.

Patch requirements

  • Maintainers MUST have a Platform account.
  • Contributors SHOULD have a Platform account.
  • A patch SHOULD be a minimal and accurate answer to exactly one identified and agreed problem.
  • A patch MUST adhere to the code style guidelines of the project if these are defined.
  • A patch MUST adhere to the "Evolution of Public Contracts" guidelines defined below.
  • A patch MUST NOT include non-trivial code from other projects unless the Contributor is the original author of that code.
  • A patch MUST compile cleanly and pass project self-tests on at least the principal target platform.
  • A patch commit message SHOULD consist of a single short (less than 50 character) line summarizing the change, optionally followed by a blank line and then a more thorough description.
  • A "Correct Patch" is one that satisfies the above requirements.

Development process

  • Change on the project MUST be governed by the pattern of accurately identifying problems and applying minimal, accurate solutions to these problems.
  • To request changes, a user SHOULD open an issue on the project Platform issue tracker.
  • The user or Contributor SHOULD write the issue by describing the problem they face or observe.
  • The user or Contributor SHOULD seek consensus on the accuracy of their observation, and the value of solving the problem.
  • Users MUST NOT log feature requests, ideas, or suggestions unrelated to Monero code or Monero's dependency code or Monero's potential/future dependency code or research which successfully implements Monero.
  • Users MUST NOT log any solutions to problems (verifiable or hypothetical) of which are not explicitly documented and/or not provable and/or cannot be reasonably proven.
  • To submit a patch, a Contributor MUST create a Platform pull request back to the project.
  • Patches MUST NOT be committed directly to the project.
  • To discuss a patch, people MAY comment on the Platform pull request, on the commit, or elsewhere.
  • To approve or reject a patch, Contributors MUST use the Platform interface.
  • Maintainers SHOULD NOT merge their own patches unless they were added to the merge queue on irc and have at least 2 approvals from contributors OR unless urgent as defined by the Monero Maintainers Team.
  • Maintainers MUST NOT make value judgments on correct patches unless the Maintainer (as may happen in rare circumstances) is a core code developer.
  • Maintainers MUST NOT merge pull requests in less than 168 hours (1 week) unless deemed urgent by at least 2 Maintainers.
  • The user who created an issue SHOULD close the issue after checking the patch is successful.
  • Maintainers SHOULD ask for improvements to incorrect patches and SHOULD reject incorrect patches if the Contributor does not respond constructively.
  • Any Contributor who has value judgments on a correct patch SHOULD express these via their own patches.
  • Maintainers SHOULD NOT merge patches that have unaddressed comments.

Evolution of public contracts

  • All Public Contracts (APIs or protocols) MUST be documented.
  • All Public Contracts SHOULD have space for extensibility and experimentation.
  • A patch that modifies a stable Public Contract SHOULD not break existing applications unless there is overriding consensus on the value of doing this.
  • A patch that introduces new features to a Public Contract SHOULD do so using new names.
  • Old names SHOULD be deprecated in a systematic fashion by marking new names as "experimental" until they are stable, then marking the old names as "deprecated".
  • When sufficient time has passed, old deprecated names SHOULD be marked "legacy" and eventually removed.
  • Old names MUST NOT be reused by new features.
  • When old names are removed, their implementations MUST provoke an exception (assertion) if used by applications.

Project administration

  • The Monero Core Team MUST act as Administrators to manage the set of project Maintainers.
  • The Administrators MUST ensure their own succession over time by promoting the most effective Maintainers.
  • Administrators MAY remove Maintainers who are inactive for an extended period of time, or who repeatedly fail to apply this process accurately.
  • Administrators SHOULD block or ban "bad actors" who cause stress and pain to others in the project. This should be done after public discussion, with a chance for all parties to speak. A bad actor is someone who repeatedly ignores the rules and culture of the project, who is needlessly argumentative or hostile, or who is offensive, and who is unable to self-correct their behavior when asked to do so by others.
  • Maintainers MUST NOT merge changes to this specification unless they are also Administrators.

File: docs/LEVIN_PROTOCOL.md

Levin Protocol

This is a document explaining the current design of the Levin protocol, as
used by Monero. The protocol is largely inherited from cryptonote, but has
undergone some changes.

This document also may differ from the struct bucket_head2 in Monero's
code slightly - the spec here is slightly more strict to allow for
extensibility.

One of the goals of this document is to clearly indicate what is being sent
"on the wire" to identify metadata that could de-anonymize users over I2P/Tor.
These issues will be addressed as they are found. See ANONYMITY_NETWORKS.md in
the docs folder for any outstanding issues.

This document does not currently list all data being sent by the monero
protocol, that portion is a work-in-progress. Please take the time to do it
if interested in learning about Monero p2p traffic!

This header is sent for every Monero p2p message.

text
0               1               2               3
 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x01     |      0x21     |      0x01     |      0x01     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x01     |      0x01     |      0x01     |      0x01     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             Length                            |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  E. Response  |                   Command
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |                 Return Code
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |Q|S|B|E|               Reserved
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |      0x01     |      0x00     |      0x00     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     0x00      |
+-+-+-+-+-+-+-+-+

Signature

The first 8 bytes are the "signature" which helps identify the protocol (in
case someone connected to the wrong port, etc). The comments indicate that byte
sequence is from "benders nightmare".

This also can be used by deep packet inspection (DPI) engines to identify
Monero when the link is not encrypted. SSL has been proposed as a means to
mitigate this issue, but BIP-151 or the Noise protocol should also be considered.

Length

The length is an unsigned 64-bit little endian integer. The length does not
include the header.

The implementation currently rejects received messages that exceed 100 MB
(base 10) by default.

Expect Response

A zero-byte if no response is expected from the peer, and a non-zero byte if a
response is expected from the peer. Peers must respond to requests with this
flag in the same order that they were received, however, other messages can be
sent between responses.

There are some commands in the
cryptonote protocol where a response is
expected from the peer, but this flag is not set. Those responses are returned
as notify messages and can be sent in any order by the peer.

Command

An unsigned 32-bit little endian integer representing the Monero specific
command being invoked.

Return Code

A signed 32-bit little endian integer representing the response from the peer
from the last command that was invoked. This is 0 for request messages.

Flags

  • Q - Bit is set if the message is a request.
  • S - Bit is set if the message is a response.
  • B - Bit is set if this is a the beginning of a fragmented message.
  • E - Bit is set if this is the end of a fragmented message.

Version

A fixed value of 1 as an unsigned 32-bit little endian integer.

Message Flow

The protocol can be subdivided into: (1) notifications, (2) requests,
(3) responses, (4) fragmented messages, and (5) dummy messages. Response
messages must be sent in the same order that a peer issued a request message.
A peer does not have to send a response immediately following a request - any
other message type can be sent instead.

Notifications

Notifications are one-way messages that can be sent at any time without
an expectation of a response from the peer. The Q bit must be set, the S,
B and E bits must be unset, and the Expect Response field must be zeroed.

Some notifications must be in response to other notifications. This is not
part of the levin messaging layer, and is described in the
commands section.

Requests

Requests are the basis of the admin protocol for Monero. The Q bit must be
set, the S, B and E bits must be unset, and the Expect Response field
must be non-zero. The peer is expected to send a response message with the same
command number.

Responses

Response message can only be sent after a peer first issues a request message.
Responses must have the S bit set, the Q, B and E bits unset, and have
a zeroed Expect Response field. The Command field must be the same value
that was sent in the request message. The Return Code is specific to the
Command being issued (see [commands])(#commands)).

Fragmented

Fragmented messages were introduced for the "white noise" feature for i2p/tor.
A transaction can be sent in fragments to conceal when "real" data is being
sent instead of dummy messages. Only one fragmented message can be sent at a
time, and bits B and E are never set at the same time
(see dummy messages). The re-constructed message must contain a
levin header for a different (non-fragment) message type.

The Q and S bits are never set and the Expect Response field must always
be zero. The first fragment has the B bit set, neither B nor E is set for
"middle" fragments, and E is set for the last fragment.

Dummy

Dummy messages have the B and E bits set, the Q and S bits unset, and
the Expect Response field zeroed. When a message of this type is received, the
contents can be safely ignored.

Commands

P2P (Admin) Commands

(`1001` Request) Handshake

(`1001` Response) Handshake

(`1002` Request) Timed Sync

(`1002` Response) Timed Sync

(`1003` Request) Ping

(`1003` Response) Ping

(`1004` Request) Stat Info

(`1004` Response) Stat Info

(`1005` Request) Network State

(`1005` Response) Network State

(`1006` Request) Peer ID

(`1006` Response) Peer ID

(`1007` Request) Support Flags

(`1007` Response) Support Flags

Cryptonote Protocol Commands

(`2001` Notification) New Block

(`2002` Notification) New Transactions

(`2003` Notification) Request Get Objects

(`2004` Notification) Response Get Objects

(`2006` Notification) Request Chain

(`2007` Notification) Response Chain Entry

(`2008` Notification) New Fluffy Block

(`2009` Notification) Request Fluffy Missing TX


File: docs/PORTABLE_STORAGE.md

Portable Storage Format

Background

Monero makes use of a set of helper classes from a small library named
epee. Part
of this library implements a networking protocol called
Levin,
which internally uses a storage format called Portable
Storage
.
This format (amongst the rest of the
epee
library), is undocumented - or rather relies on the code itself to serve as the
documentation. Unfortunately, whilst the rest of the library is fairly
straightforward to decipher, the Portable Storage is less-so. Hence this
document.

String and Integer Encoding

Integers

With few exceptions, integers serialized in epee portable storage format are serialized
as little-endian.

Varints

Varints are used to pack integers in an portable and space optimized way. Varints are stored as little-endian integers, with the lowest 2 bits storing the amount of bytes required, which means the largest value integer that can be packed into 1 byte is 63
(6 bits).

Byte Sizes

Lowest 2 bits Size value Value range
b00 1 byte 0 to 63
b01 2 bytes 64 to 16383
b10 4 bytes 16384 to 1073741823
b11 8 bytes 1073741824 to 4611686018427387903

Representations of Example Values

Value Byte Representation (hex)
0 00
7 1c
101 95 01
17,000 A2 09 01 00
7,942,319,744 03 BA 98 65 07 00 00 00

Strings

These are simply length (varint) prefixed char strings without a null
terminator (though one can always add one if desired). There is no
specific encoding enforced, and in fact, many times binary blobs are
stored as these strings. This type should not be confused with the keys
in sections, as those are restricted to a maximum length of 255 and
do not use varints to encode the length.

text
"Howdy" => 14 48 6F 77 64 79

Section Keys

These are similar to strings except that they are length limited to 255
bytes, and use a single byte at the front of the string to describe the
length (as opposed to a varint).

text
"Howdy" => 05 48 6F 77 64 79

Binary Format Specification

The format must always start with the following header:

Field Type Value
Signature Part A UInt32 0x01011101
Signature Part B UInt32 0x01020101
Version UInt8 0x01

In total, the 9 byte header will look like this (in hex): 01 11 01 01 01 01 02 01 01

Section

Next we have a root object (or section as the library calls it). This is a map
of name-value pairs called entries. It starts with a count:

Section Type
Entry count varint

Which is followed by the section's name-value entries sequentially:

Entry

Entry Type
Name section key
Type byte
Count1 varint
Value(s) (type-dependent data)

1 Note, this is only present if the entry type has the array flag
(see below).

Entry types

The types defined are:

cpp
#define SERIALIZE_TYPE_INT64                1
#define SERIALIZE_TYPE_INT32                2
#define SERIALIZE_TYPE_INT16                3
#define SERIALIZE_TYPE_INT8                 4
#define SERIALIZE_TYPE_UINT64               5
#define SERIALIZE_TYPE_UINT32               6
#define SERIALIZE_TYPE_UINT16               7
#define SERIALIZE_TYPE_UINT8                8
#define SERIALIZE_TYPE_DOUBLE               9
#define SERIALIZE_TYPE_STRING               10
#define SERIALIZE_TYPE_BOOL                 11
#define SERIALIZE_TYPE_OBJECT               12
#define SERIALIZE_TYPE_ARRAY                13

The entry type can be bitwise OR'ed with a flag:

cpp
#define SERIALIZE_FLAG_ARRAY              0x80

This signals there are multiple values for the entry. Since only one bit is
reserved for specifying an array, we can not directly represent nested arrays.
However, you can place each of the inner arrays inside of a section, and make
the outer array type SERIALIZE_TYPE_OBJECT | SERIALIZE_FLAG_ARRAY. Immediately following the type code byte is a varint specifying the length of the array.
Finally, the all the elements are serialized in sequence with no padding and
without any type information. For example:

type, count,
value1, value2,..., valuen

Entry values

It's important to understand that entry values can be encoded any way in which
an implementation chooses. For example, the integers can be in either big or
little endian byte order.

Entry values which are objects (i.e. SERIALIZE_TYPE_OBJECT), are stored as
sections.

Note, I have not yet seen the type SERIALIZE_TYPE_ARRAY in use. My assumption
is this would be used for untyped arrays and so subsequent entries could be of
any type.

Overall example

Let's put it all together and see what an entire object would look like serialized. To represent our data, let's create a JSON object (since it's a format
that most will be familiar with):

json
{
  "short_quote": "Give me liberty or give me death",
  "long_quote": "Monero is more than just a technology. It's also what the technology stands for.",
  "signed_32bit_int": 20140418,
  "array_of_bools": [true, false, true, true],
  "nested_section": {
    "double": -6.9,
    "unsigned_64bit_int": 11111111111111111111
  }
}

This object would translate into the following bytes when serialized into epee portable storage format. The bytes are represented in hex, with comments and whitespace added for readability.

text
/* Detailed source-code truncated for AI context efficiency. */

Monero specifics

Entry values

Hashes, Keys, Blobs

These are stored as strings, SERIALIZE_TYPE_STRING.

STL containers (vector, list)

These can be arrays of standard integer types, strings or
SERIALIZE_TYPE_OBJECT's for structs.

2. Official Technical Reference & Guides (monero-project/monero-docs)

File: README.md

Monero Docs

This repository contains the source files to Monero Community documentation hosted at docs.getmonero.org

About

Monero Docs intends to be a Knowledge Base and User Guide for interacting with Monero.

Contributing

Contributions are both encouraged and greatly appreciated.

To contribute content, fork this repo and make a pull request to the master branch including your changes.

  1. On GitHub, fork the monero-docs repo
  2. Clone your newly created repo. (Note: replace your-username with your GitHub username)

via ssh:

bash
git clone [email protected]:your-username/monero-docs

via https:

bash
git clone https://github.com/your-username/monero-docs
  1. Navigate to the repo and create a new topic branch
bash
cd monero-docs
git checkout -b foobar
  1. After making modifications, commit and push your changes to your topic branch
  2. Open a PR against the monero-docs master branch

Run the documentation server locally

  • The build process for mkdocs utilizes Python
  • It is recommended to install python pip dependencies inside of a Virtual Environment (venv)

Note: You may need to first install python3-venv or the equivalent for your distribution

  1. Navigate to your monero-docs repo
  2. Create the python virtual environment
bash
python3 -m venv .monero-docs-venv
source .monero-docs-venv/bin/activate
  1. Install mkdocs dependencies to the venv
bash
pip install --require-hashes -r requirements.txt
  1. Run the documentation server locally
bash
python3 -m mkdocs serve
  1. View your changes at http://localhost:8000

License

The documentation is provided under the MIT License.


File: docs/en/cryptography/asymmetric/edwards25519.md


title: Edwards25519 Elliptic Curve

Edwards25519 Elliptic Curve

!!! note
Author is nowhere close to being a cryptographer. Be sceptical on accuracy.

!!! note
This article is only about the underlying curve. Public key derivation and signing algorithm will be treated separately.

Monero employs edwards25519 elliptic curve as a basis for its key pair generation.

The curve comes from the Ed25519 signature scheme. While Monero takes the curve unchanged, it does not exactly follow rest of the Ed25519.

The edwards25519 curve is birationally equivalent to Curve25519.

Definition

This is the standard edwards25519 curve definition, no Monero specific stuff here,
except the naming convention. The convention comes from the CryptoNote
whitepaper and is widely used in Monero literature.

Curve equation

text
โˆ’x^2 + y^2 = 1 โˆ’ (121665/121666) * x^2 * y^2

Note:

  • curve is in two dimensions (nothing fancy, like all the curves is high school)
  • curve is mirrored below y axis due to y^2 part of the equation (not a polynomial)

Base point: `G`

The base point is a specific point on the curve. It is used
as a basis for further calculations. It is an arbitrary choice
by the curve authors, just to standardize the scheme.

Note that it is enough to specify the y value and the sign of the x value.
That's because the specific x can be calculated from the curve equation.

text
G = (x, 4/5)  # take the point with the positive x

# The hex representation of the base point
5866666666666666666666666666666666666666666666666666666666666666

Prime order of the base point: `l`

In laymen terms, the "canvas" where the curve is drawn is assumed
to have a finite "resolution", so point coordinates must "wrap around"
at some point. This is achieved by modulo the l value (lowercase L).
In other words, the l defines the maximum scalar we can use.

text
l = 2^252 + 27742317777372353535851937790883648493
# => 7237005577332262213973186563042994240857116359379907606001950938285454250989

The l is a prime number specified by the curve authors.

In practice this is the private key's strength.

Total number of points on the curve

The total number of points on the curve is also a prime number:

text
q = 2^255 - 19

In practice not all points are "useful" and so the private key strength is limited to l describe above.

Implementation

Monero uses (apparently modified) Ref10 implementation by Daniel J. Bernstein.

Reference


File: docs/en/cryptography/asymmetric/introduction.md


title: Asymmetric Cryptography in Monero

Asymmetric Cryptography in Monero

!!! note
Author is nowhere close to being a cryptographer. Be sceptical on accuracy.

Before we get to Monero specific stuff, a little bit of context. We are talking asymmetric cryptography here.
The "asymmetric" simply means the are two keys:

  • the private key (used primarily for signing data and for decrypting data)
  • the public key (used primarily for signature verification and encrypting data)

This is in contrast to symmetric cryptography which uses a single key. This key is a secret shared among the parties.

Historically, asymmetric cryptography was based on the problem of factorization of a very large integers
back into prime numbers (which is practically impossible for large enough integers).

Recently, asymmetric cryptography is based on a mathematical notion of elliptic curves.
Edwards25519 is a specific, well researched and standardized elliptic curve used in Monero.


File: docs/en/cryptography/asymmetric/key-image.md


title: Monero Private Key Image

Monero Private Key Image

!!! note
Author is nowhere close to being a cryptographer. Be sceptical on accuracy.

Private key image serves to detect double spending attempts.

In Monero funds are always sent to a one-time public key P.
Related one-time private key x is specific to unspent output.

As output can be spent only once (in whole), the related private key can be used only once as well.

Thus, specific private key image I being present on the blockchain means
that related output was already spent, and subsequent attempts must not be allowed.

This whole scheme is necessary because Monero uses Ring Signatures
which make it impossible to know whom exactly signed the transaction.
This is why a simple Bitcoin-like double spending check wouldn't work here.

Definition

text
I = x*Hp(P)

Where:

  • I - private key image (or "key image" for short)
  • x - one-time private key used to unlock an unspent output
  • P - one-time public key of an unspent output
  • Hp() - hash function accepting an EC point as an argument

The P comes from this:

text
P = xG

Where G is the edwards25519 base point.

Substitute P with xG and we get:

text
I = x*Hp(xG)

The key image I is a one-way function of the private key x.

Reference


File: docs/en/cryptography/asymmetric/private-key.md


title: Private Keys in Monero

Private Keys in Monero

!!! note
Author is nowhere close to being a cryptographer. Be sceptical on accuracy.

In Monero, the root private key is generated randomly. Other private keys are derived deterministically from the root private key.

Private key must be kept secret.

Private key is a large integer impossible to guess, like:
108555083659983933209597798445644913612440610624038028786991485007418559037440

Private key is 256 bits long.

Private key is a scalar, meaning it is a single value.

In equations scalars are represented by lowercase letters.

Relation to Ed25519

Being simply a random integer, private key is not specific to any particular asymmetric cryptography scheme.

In context of Monero EC cryptography the private key is a number the base point G is multiplied by.
The result of the multiplication is the public key P (another point on the curve).
Multiplication of a point by a number has a very special definition in EC cryptography.
See this this guide for details.

Key strength

Before deriving the public key, private key is subject to modulo l,
where l is the maximum scalar allowed by the edwards25519 curve.

The l is on the order of 2^252, so the effective key strength is technically 252 bits, not 256 bits.
This is standard for EC cryptography and is more of a cosmetic nuance than any concern.

Encoding

In user-facing contexts, the private key integer is:

  1. Taken modulo l to avoid malleability
  2. Put as array of 32 bytes in a little-endian direction (the first byte is the least significant)
  3. Converted to hexadecimal form, like: b3588a87056fb21dc4d052d59e83b54293882e646b543c29478e4cf45c28a402

Private spend key

Private spend key is used to spend moneros.

More specifically, it is used to build one-time private keys which allow to spend related outputs.

Private view key

Private view key is used to recognize your incoming transactions on the otherwise opaque blockchain.

One-time private keys

One-time private key like construct is used in stealth addresses.


File: docs/en/cryptography/asymmetric/public-key.md


title: Public Keys in Monero

Public Keys in Monero

!!! note
Author is nowhere close to being a cryptographer. Be sceptical on accuracy.

Public key is deterministically derived from private key based on edwards25519 curve with a little Monero-specific twist.

Public key is meant to be shared. Assuming correct implementation, it is not practically possible to recover private key from public key.

Public key is a point (x,y) on the elliptic curve.

In equations points are represented by uppercase letters.

In user-facing contexts, public key is encoded in a little-endian hexadecimal form, like:
016a941812293cf9a86071060fb090ab38d67945e659968cb8cf30e1bc725683

Deriving public key

Say:

  • P is a public key
  • x is a private key
  • G is a "base point"; this is simply a constant specific to edwards25519; this point lies on the elliptic curve

Then:

text
P = xG

The public key is simply the base point (G) multiplied by the private key (x).
Multiplying the point is adding the point to itself a number of times.

However, the addition is not a simple vector addition. It has a very specific
definition nicely described in this article.
What is important is that result of addition is always a point on the curve.
For example, G + G is another point on the curve.

Use cases

Monero address is composed of public spend key and public view key.
These keys are used to build stealth addresses to receive payments.


File: docs/en/cryptography/base58.md


title: Base58

Base58

Base58 is a binary-to-text encoding scheme. It is similar to Base64 but has been modified to avoid both non-alphanumeric characters and letters which might look ambiguous when printed. The characters excluded in relation to Base64 are: IOl0+/

Base58 does not strictly specify the format. This results in some implementations being incompatible with others, for example with regard to alphabet order.

For details, see Wikipedia.

Base58 in Monero

Monero has its own variant of Base58.

In Monero the Base58 encoding is performed in 8-byte blocks, except the last block which is the remaining (8 or less) bytes.

The 8-byte block converts to 11 or less Base58 characters. If the block converted to less than 11 characters, the output is padded with "1"s (0 in Base58). The final block is padded as well to whatever would be the maximum size of this number of bytes encoded in Base58.

The advantage of Monero implementation is that output is of a fixed size which is not the case with plain Base58. The disadvantage is that default libraries won't work.

For details, see the reference C++ Base58 implementation and the unofficial Python and Rust implementations.


File: docs/en/cryptography/index.md


title: Cryptography in Monero

Cryptography in Monero

Monero uses a wide variety of cryptographic primitives for various use cases.

Comparing to altcoins, Monero cryptography is considered conservative, sound and robust.

Comparing to Bitcoin, Monero uses much more primitives, and some of them are more advanced, especially those related to privacy and Proof of Work.
Some choices are deliberately non-standard (for better or worse) - oftentimes a legacy of the CryptoNote protocol.


File: docs/en/cryptography/keccak-256.md


title: Keccak-256 Hash Function

Keccak-256 Hash Function

Monero employs Keccak as a hashing function. In most context specifically Keccak-256 is used,
providing 32-byte hashes.

Keccak is the leading hashing function, designed by non-NSA designers.
Keccak won NIST competition to become the official SHA3.

Use Cases

Monero does not employ Keccak for Proof-of-Work. Instead, Keccak is used for:

  • random number generator
  • block hashing
  • transaction hashing
  • stealth address private key image (for double spend protection)
  • public address checksum
  • RingCT
  • multisig
  • bulletproofs

...and likely a few other things.

Keccak-256 vs SHA3-256

SHA3-256 is Keccak-256, except that NIST changed the padding.
For this reason, the original Keccak-256 gives a different hash value than NIST SHA3-256.

Monero uses original Keccak-256.
The NIST standard was only published on August 2015, while Monero went live on 18 April 2014.

Reference