From 1c4fb77acdb19c1bb490f1ea23b3d358f54b3044 Mon Sep 17 00:00:00 2001 From: TomZ Date: Tue, 8 Apr 2025 19:43:03 +0200 Subject: [PATCH] Start --- CMakeLists.txt | 56 ++++++++++++++++++ design | 137 +++++++++++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 31 ++++++++++ src/Processor.cpp | 12 ++++ src/Processor.h | 18 ++++++ src/main.cpp | 19 +++++++ 6 files changed, 273 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 design create mode 100644 src/CMakeLists.txt create mode 100644 src/Processor.cpp create mode 100644 src/Processor.h create mode 100644 src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..cb8bb6c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,56 @@ +# This file is part of the Flowee project +# Copyright (C) 2025 Tom Zander +# +# This program 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 program 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 . + +cmake_minimum_required (VERSION 3.21) +project (registry) + +set(COPYRIGHT_YEAR 2025) +set(CLIENT_VERSION_MAJOR ${COPYRIGHT_YEAR}) +set(CLIENT_VERSION_MINOR 1) +set(CLIENT_VERSION_REVISION 1) + +# ------------------------------------------------------------------------------------ + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6Core REQUIRED) + +if (CMAKE_VERSION VERSION_GREATER "3.29.9") + # use the upstream boost info instead of the cmake-shipped one for finding + # this policy was introduced in cmake 3.30 + cmake_policy(SET CMP0167 NEW) +endif() +find_package(Boost 1.74.0 REQUIRED filesystem thread iostreams) + +if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to 'ReleaseWithDebugInfo' as none was specified.") + set(CMAKE_BUILD_TYPE RELWITHDEBINFO) + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo") +elseif (NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Built type is ${CMAKE_BUILD_TYPE}") +endif () + +find_package(Flowee REQUIRED) + +if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + add_definitions(-DBCH_NO_DEBUG_OUTPUT) +else () + add_definitions(-DBCH_LOGCONTEXT) +endif () + +add_subdirectory(src) diff --git a/design b/design new file mode 100644 index 0000000..7bd61fd --- /dev/null +++ b/design @@ -0,0 +1,137 @@ +Bitcoin-Cash Metadata-Registry, Cashing server. + +Users can create metadata and store that somewhere on the web. +On DNS in a standard location on their webserver. +On IPFS or a http(s) url. + + +Terminology: + +category-id: a cash-token unique token +commitment: in combination with a category, a unique NFT +auth-base: an ID of an owner. Sometimes the same as category-id. + + + + +the base for a compatible end-points server can be this existing bcmr +indexer: +https://github.com/paytaca/bcmr-indexer/blob/master/README.md#api-endpoints + + API endpoints + /api/tokens/ --> will give specific token metadata for FTs and generic token info for NFTs + /api/tokens/// --> will give token metadata for NFT types + /api/registries//latest/ --> will give the latest registry record for the given category ID + +moria by category: +https://bcmr.paytaca.com/api/tokens/4046913cba6b70b2214a048a3df92252849f481ffa1455ed7faf17243c36bf67/ +https://bcmr.paytaca.com/api/registries/4046913cba6b70b2214a048a3df92252849f481ffa1455ed7faf17243c36bf67/latest/ + + +Having a server for such registries then gives a feature list like this; + +- allow download/lookup of a metadata file which we cache. + - by the hash of the file + - by the auth-base + - maybe maybe by tokenid + +- Allow quick check for validity. + A permissioned server would be able to say the ID is unknown or actually a known scam + +- The system should allow users to do an initial-publish of their + metadata in a way that the URL stored on the blockchain is + served by us, and we also serve the cached version, obviously. + +- Integration with a full node means we can find the auth-head updates and + schedule them for checking. + Should the auth-base be known, we simply handle them, + if the server is configured to be permissioned we put them in the + untrusted list. + +- Have a 'metadata on the metadata' view. + similar to what paytaca did on its bcmr server with /api/tokens/ + - if its a token + - does it have an icon. + - etc. + 202504-TOMZ: actually, the point of the new bcmr format is to make this unneeded. + +- For a auth-base and an optional auth-head, provide the missing parts + and a merkle-root of the tip tx. + +----- + +Usage by flowee pay; + - a token arrives, we locate the server and we fetch the metadata. + This means some C++ classes to parse the JSON. + + - a payment-request arrives with a bcmr claim. We need to fetch the metadata. + TODO: how do we validate the ownership? + + - a watch-only wallet with a list of utxo-s is needed to follow auth-heads. + + +---------- +We need an upload / hosting server. + +Users should have a web interface to interactively create a bcmr and at one point "commit" it which creates the json. +The creation of the json is technically all it does. +But, you add a hosting BCMR server, you can reserve a short url and pass that to +the user. So the user can put it on-chain. +Maybe we can have each bcmr-hash not just as [hash].json, but also a short 10 +byte hash that we then base64 encode to have reasonably short filenames. Which +makes it easier to put them on chain. + +As such, hosting and uploading are not relevant to this project. + +------- + +The database is essentially a raw directory structure that +can be put in git and pushed to a webserver. + +Basic idea; most things are hashes. So you have [my-category].json +as a file in there. + + +- listing by category. + This is tricky. Any auth-head can claim any category. Any cached json can claim same. + An auth-chain is 'official', a category is secondary. + I think we need to have a generated document here that lists the + auth-head(s) that claim the category and maybe some sort of certainty score. + + * list 'trust'. A category being a known spam should be noted here. + * list all hashes of documents that claim the category. + Metadata added is (mis)trust, date claimed in document and original url. + +- listing by auth-base. + this is a single json that should be formatted similar to the category one. + it also lists each hash of the bcmrs owned by this auth-base over time. + We could make '/latest.json' a symlink to the latest bcmr file. + Possibly add a '/proof' file which lists a list of transactions and a merkle-proof. + +- listing by bcmr-hash.json + Basically the document, with its sha256 hash as its filename. + + +What about an app that takes as input a directory (git repo) +of all known bcmr files. +input: +bcmrs/ + hash + hash.tx (the raw auth-head transaction) +trust/ + category-hash + with a trust-level. Really only if it is known spam. + auth-base-hash + with trust level. + bcmr-hash + with trust-level. Used only if the doc comes from a dns. +resources/ + bcmr-hash/ + file [jpg] +inbox/ + for not yet processed bcmrs. If there is a + need for a incremental update system. + +The app then takes that input and generates a (git) repo of of all +the different files. Mostly stored in the + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..6e096da --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,31 @@ +# This file is part of the Flowee project +# Copyright (C) 2025 Tom Zander +# +# This program 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 program 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 . + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +add_executable(processor + main.cpp + Processor.h Processor.cpp +) +target_compile_definitions(processor PRIVATE LOG_DEFAULT_SECTION=40000) +target_link_libraries(processor + flowee_utils + Qt6::Core +) +install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/processor DESTINATION ${CMAKE_BINARY_DIR}/bin) + diff --git a/src/Processor.cpp b/src/Processor.cpp new file mode 100644 index 0000000..7f03fc3 --- /dev/null +++ b/src/Processor.cpp @@ -0,0 +1,12 @@ +#include "Processor.h" + +Processor::Processor(const QString &inDir, const QString &outDir) + : m_inDir(inDir), + m_outDir(outDir) +{ +} + +int Processor::run() +{ + +} diff --git a/src/Processor.h b/src/Processor.h new file mode 100644 index 0000000..8f14b71 --- /dev/null +++ b/src/Processor.h @@ -0,0 +1,18 @@ +#ifndef PROCESSOR_H +#define PROCESSOR_H + +#include + + +class Processor +{ +public: + Processor(const QString &inDir, const QString &outDir); + + int run(); + +private: + const QString m_inDir, m_outDir; +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..f2b290e --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,19 @@ +#include "Processor.h" + +#include +#include + +int main(int x, char **y) { + QCoreApplication app(x, y); + QCommandLineParser parser; + parser.addHelpOption(); + parser.addVersionOption(); + parser.setApplicationDescription("Processor for the cashing BCM-Registry"); + parser.parse(app.arguments()); + auto args = parser.positionalArguments(); + if (args.size() != 2) { + return 1; + } + Processor processor(args.at(0), args.at(1)); + return processor.run(); +}