{"id":16153732,"url":"https://github.com/moneroexamples/lmdbcpp-scan-txs","last_synced_at":"2025-04-06T23:41:31.235Z","repository":{"id":70343553,"uuid":"58683889","full_name":"moneroexamples/lmdbcpp-scan-txs","owner":"moneroexamples","description":null,"archived":false,"fork":false,"pushed_at":"2016-05-13T01:17:58.000Z","size":213,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-13T05:41:27.986Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/moneroexamples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-12T23:24:48.000Z","updated_at":"2021-06-05T17:59:04.000Z","dependencies_parsed_at":"2023-02-22T23:45:11.477Z","dependency_job_id":null,"html_url":"https://github.com/moneroexamples/lmdbcpp-scan-txs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moneroexamples%2Flmdbcpp-scan-txs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moneroexamples%2Flmdbcpp-scan-txs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moneroexamples%2Flmdbcpp-scan-txs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moneroexamples%2Flmdbcpp-scan-txs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moneroexamples","download_url":"https://codeload.github.com/moneroexamples/lmdbcpp-scan-txs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247569129,"owners_count":20959758,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-10T01:14:20.097Z","updated_at":"2025-04-06T23:41:31.213Z","avatar_url":"https://github.com/moneroexamples.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lmdbcpp-scan-txs\n\nMonero is using [lmdb databases](http://symas.com/mdb/) to store its blockchain.\n\nAlthough one can interact directly with the blockchain to get information\nfrom it using Monero C++ libraries,\nsearching and retrieving some information maybe be not very efficient.\n\nThis in this example, it is shown how to use [previously created](https://github.com/moneroexamples/lmdbcpp-monero) custom lmdb databases\nbased on information from the blockchain using [lmdb++](https://github.com/bendiken/lmdbxx)\ninterface to the lmdb database.\n\n## Custom databases\n\nThe example uses the following lmdb database based on the information\navailable in the blockchain:\n- `output_info` - key: output public key as string; value: struct {tx_hash as hash,\ntx_pub_key as public_key, amount as uint64_t, index_in_tx as uint64_t}\n\n## Prerequisite\n\nEverything here was done and tested using Monero 0.9.4 on\nXubuntu 16.04 x86_64.\n\nInstruction for Monero 0.9 compilation and Monero headers and libraries setup are\nas shown here:\n - [Compile Monero 0.9 on Ubuntu 16.04 x64](https://github.com/moneroexamples/compile-monero-09-on-ubuntu-16-04)\n - [lmdbcpp-monero](https://github.com/moneroexamples/lmdbcpp-monero) \n\n## C++ code\nThe main part of the example is main.cpp.\n\n```c++\nint main(int ac, const char* av[])  {\n\n\n    // get command line options\n    xmreg::CmdLineOptions opts {ac, av};\n\n    auto help_opt = opts.get_option\u003cbool\u003e(\"help\");\n\n    // if help was chosen, display help text and finish\n    if (*help_opt)\n    {\n        return EXIT_SUCCESS;\n    }\n\n    // get other options\n    auto bc_path_opt  = opts.get_option\u003cstring\u003e(\"bc-path\");\n    auto testnet_opt  = opts.get_option\u003cbool\u003e(\"testnet\");\n    auto search_opt   = opts.get_option\u003cbool\u003e(\"search\");\n\n    bool testnet         = *testnet_opt;\n\n    string xmr_address_str {\"43A7NUmo5HbhJoSKbw9bRWW4u2b8dNfhKheTR5zxoRwQ7bULK5TgUQeAvPS5EVNLAJYZRQYqXCmhdf26zG2Has35SpiF1FP\"};\n    string viewkey_str    {\"9c2edec7636da3fbb343931d6c3d6e11bcd8042ff7e11de98a8d364f31976c04\"};\n\n    // parse string representing given monero address\n    cryptonote::account_public_address address;\n\n    if (!xmreg::parse_str_address(xmr_address_str,  address, 0))\n    {\n        cerr \u003c\u003c \"Cant parse string address: \" \u003c\u003c xmr_address_str \u003c\u003c endl;\n        return EXIT_FAILURE;\n    }\n\n    // parse string representing given private viewkey\n    crypto::secret_key prv_view_key;\n\n    if (!xmreg::parse_str_secret_key(viewkey_str, prv_view_key))\n    {\n        cerr \u003c\u003c \"Cant parse view key: \" \u003c\u003c viewkey_str \u003c\u003c endl;\n        return EXIT_FAILURE;\n    }\n\n\n\n    path blockchain_path;\n\n    if (!xmreg::get_blockchain_path(bc_path_opt, blockchain_path))\n    {\n        // if problem obtaining blockchain path, finish.\n        return 1;\n    }\n\n\n    fmt::print(\"Blockchain path: {:s}\\n\", blockchain_path);\n\n\n    // the directory MUST already exist. Make it manually\n    path mylmdb_location  = blockchain_path.parent_path() / path(\"lmdb2\");\n\n    // instance of MyLMDB class that interacts with the custom database\n    xmreg::MyLMDB mylmdb {mylmdb_location.string()};\n\n    uint64_t out_idx = {0};\n\n    auto output_search = [\u0026](crypto::public_key\u0026 out_pubkey,\n                             xmreg::output_info\u0026 out_info) -\u003e bool\n    {\n\n        // public transaction key is combined with our viewkey\n        // to create, so called, derived key.\n        crypto::key_derivation derivation;\n\n        bool r = generate_key_derivation(out_info.tx_pub_key,\n                                         prv_view_key,\n                                         derivation);\n\n        if (r)\n        {\n\n            // get the tx output public key\n            // that normally would be generated for us,\n            // if someone had sent us some xmr.\n            crypto::public_key generated_pubkey;\n\n            derive_public_key(derivation,\n                              out_info.index_in_tx,\n                              address.m_spend_public_key,\n                              generated_pubkey);\n\n            // check if generated public key matches the current output's key\n            bool mine_output = (out_pubkey == generated_pubkey);\n\n            if (++out_idx % 1000 == 0)\n            {\n                cout \u003c\u003c \"Checkign outout: \"\u003c\u003c out_idx \u003c\u003c endl;\n            }\n\n            if (mine_output)\n            {\n                cout \u003c\u003c \"Found mine output: \" \u003c\u003c out_pubkey \u003c\u003c \" \\n\"\n                     \u003c\u003c \"\\t - deriviation : \" \u003c\u003c derivation \u003c\u003c \"\\n\"\n                     \u003c\u003c \"\\t - tx_hash     : \" \u003c\u003c out_info.tx_hash \u003c\u003c \"\\n\"\n                     \u003c\u003c \"\\t - tx_pub_key  : \" \u003c\u003c out_info.tx_pub_key \u003c\u003c \"\\n\"\n                     \u003c\u003c \"\\t - amount      : \" \u003c\u003c XMR_AMOUNT(out_info.amount) \u003c\u003c \"\\n\"\n                     \u003c\u003c \"\\t - index_in_tx : \" \u003c\u003c out_info.index_in_tx\n                     \u003c\u003c endl;\n            }\n\n            //xmreg::wait_for_enter();\n        }\n        else\n        {\n            cerr \u003c\u003c \"Cant get dervied key for: \"  \u003c\u003c \"\\n\"\n                 \u003c\u003c \"pub_tx_key: \" \u003c\u003c out_info.tx_pub_key \u003c\u003c \" and \"\n                 \u003c\u003c \"prv_view_key\" \u003c\u003c prv_view_key \u003c\u003c endl;\n        }\n\n        return true;\n    };\n\n    mylmdb.for_all_outputs(output_search);\n\n    return EXIT_SUCCESS;\n}\n```\n\n\n\n## Compile this example\nThe dependencies are same as those for Monero, so I assume Monero compiles\ncorrectly. If so then to download and compile this example, the following\nsteps can be executed:\n\n```bash\n# download the source code\ngit clone https://github.com/moneroexamples/lmdbcpp-scan-txs.git\n\n# enter the downloaded sourced code folder\ncd lmdbcpp-scan-txs\n\n# create the makefile\ncmake .\n\n# compile\nmake\n```\n\n## Other examples\nOther examples can be found on  [github](https://github.com/moneroexamples?tab=repositories).\nPlease know that some of the examples/repositories are not\nfinished and may not work as intended.\n\n## How can you help?\n\nConstructive criticism, code and website edits are always good. They can be made through github.\n\nSome Monero are also welcome:\n```\n48daf1rG3hE1Txapcsxh6WXNe9MLNKtu7W7tKTivtSoVLHErYzvdcpea2nSTgGkz66RFP4GKVAsTV14v6G3oddBTHfxP6tU\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoneroexamples%2Flmdbcpp-scan-txs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoneroexamples%2Flmdbcpp-scan-txs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoneroexamples%2Flmdbcpp-scan-txs/lists"}