Add research code written primarily by Danny, Anton and me

This commit is contained in:
Christian Reitter 2024-12-16 12:29:31 +01:00
parent 9d864c564e
commit ea709bca69
16 changed files with 1077 additions and 0 deletions

View File

@ -0,0 +1,14 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
coincurve = "*"
bip-utils = "*"
psycopg2 = "*"
[dev-packages]
[requires]
python_version = "3.8"

View File

@ -0,0 +1,366 @@
{
"_meta": {
"hash": {
"sha256": "6436240a5d46aca559fe140b081f93de7e637c218b9e097bc5fc73fd6c57f2cd"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.8"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"asn1crypto": {
"hashes": [
"sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c",
"sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"
],
"version": "==1.5.1"
},
"bip-utils": {
"hashes": [
"sha256:20d710e56f384188f33d5941354ac8aafff5caabdfd7b79a4b56d0e6baf1cfd3",
"sha256:aa7acb890154332a86413706bc05a846f07afb92656656488a323b65ecc305ca"
],
"index": "pypi",
"version": "==2.7.1"
},
"cbor2": {
"hashes": [
"sha256:0b956f19e93ba3180c336282cd1b6665631f2d3a196a9c19b29a833bf979e7a4",
"sha256:0bd12c54a48949d11f5ffc2fa27f5df1b4754111f5207453e5fae3512ebb3cab",
"sha256:0d2b926b024d3a1549b819bc82fdc387062bbd977b0299dd5fa5e0ea3267b98b",
"sha256:1618d16e310f7ffed141762b0ff5d8bb6b53ad449406115cc465bf04213cefcf",
"sha256:181ac494091d1f9c5bb373cd85514ce1eb967a8cf3ec298e8dfa8878aa823956",
"sha256:1835536e76ea16e88c934aac5e369ba9f93d495b01e5fa2d93f0b4986b89146d",
"sha256:1c12c0ab78f5bc290b08a79152a8621822415836a86f8f4b50dadba371736fda",
"sha256:24144822f8d2b0156f4cda9427f071f969c18683ffed39663dc86bc0a75ae4dd",
"sha256:309fffbb7f561d67f02095d4b9657b73c9220558701c997e9bfcfbca2696e927",
"sha256:3316f09a77af85e7772ecfdd693b0f450678a60b1aee641bac319289757e3fa0",
"sha256:3545b16f9f0d5f34d4c99052829c3726020a07be34c99c250d0df87418f02954",
"sha256:39452c799453f5bf33281ffc0752c620b8bfa0b7c13070b87d370257a1311976",
"sha256:3950be57a1698086cf26d8710b4e5a637b65133c5b1f9eec23967d4089d8cfed",
"sha256:456cdff668a50a52fdb8aa6d0742511e43ed46d6a5b463dba80a5a720fa0d320",
"sha256:4b9f3924da0e460a93b3674c7e71020dd6c9e9f17400a34e52a88c0af2dcd2aa",
"sha256:4bbbdb2e3ef274865dc3f279aae109b5d94f4654aea3c72c479fb37e4a1e7ed7",
"sha256:4ce1a2c272ba8523a55ea2f1d66e3464e89fa0e37c9a3d786a919fe64e68dbd7",
"sha256:56dfa030cd3d67e5b6701d3067923f2f61536a8ffb1b45be14775d1e866b59ae",
"sha256:6709d97695205cd08255363b54afa035306d5302b7b5e38308c8ff5a47e60f2a",
"sha256:6e1b5aee920b6a2f737aa12e2b54de3826b09f885a7ce402db84216343368140",
"sha256:6f9c702bee2954fffdfa3de95a5af1a6b1c5f155e39490353d5654d83bb05bb9",
"sha256:78304df140b9e13b93bcbb2aecee64c9aaa9f1cadbd45f043b5e7b93cc2f21a2",
"sha256:79e048e623846d60d735bb350263e8fdd36cb6195d7f1a2b57eacd573d9c0b33",
"sha256:7bbd3470eb685325398023e335be896b74f61b014896604ed45049a7b7b6d8ac",
"sha256:80ac8ba450c7a41c5afe5f7e503d3092442ed75393e1de162b0bf0d97edf7c7f",
"sha256:9394ca49ecdf0957924e45d09a4026482d184a465a047f60c4044eb464c43de9",
"sha256:94f844d0e232aca061a86dd6ff191e47ba0389ddd34acb784ad9a41594dc99a4",
"sha256:96087fa5336ebfc94465c0768cd5de0fcf9af3840d2cf0ce32f5767855f1a293",
"sha256:b893500db0fe033e570c3adc956af6eefc57e280026bd2d86fd53da9f1e594d7",
"sha256:c285a2cb2c04004bfead93df89d92a0cef1874ad337d0cb5ea53c2c31e97bfdb",
"sha256:d2984a488f350aee1d54fa9cb8c6a3c1f1f5b268abbc91161e47185de4d829f3",
"sha256:d54bd840b4fe34f097b8665fc0692c7dd175349e53976be6c5de4433b970daa4",
"sha256:db9eb582fce972f0fa429d8159b7891ff8deccb7affc4995090afc61ce0d328a",
"sha256:e5094562dfe3e5583202b93ef7ca5082c2ba5571accb2c4412d27b7d0ba8a563",
"sha256:e73ca40dd3c7210ff776acff9869ddc9ff67bae7c425b58e5715dcf55275163f",
"sha256:ff95b33e5482313a74648ca3620c9328e9f30ecfa034df040b828e476597d352"
],
"markers": "python_version >= '3.7'",
"version": "==5.4.6"
},
"cffi": {
"hashes": [
"sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5",
"sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef",
"sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104",
"sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426",
"sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405",
"sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375",
"sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a",
"sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e",
"sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc",
"sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf",
"sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185",
"sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497",
"sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3",
"sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35",
"sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c",
"sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83",
"sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21",
"sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca",
"sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984",
"sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac",
"sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd",
"sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee",
"sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a",
"sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2",
"sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192",
"sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7",
"sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585",
"sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f",
"sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e",
"sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27",
"sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b",
"sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e",
"sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e",
"sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d",
"sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c",
"sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415",
"sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82",
"sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02",
"sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314",
"sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325",
"sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c",
"sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3",
"sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914",
"sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045",
"sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d",
"sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9",
"sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5",
"sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2",
"sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c",
"sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3",
"sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2",
"sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8",
"sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d",
"sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d",
"sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9",
"sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162",
"sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76",
"sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4",
"sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e",
"sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9",
"sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6",
"sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b",
"sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01",
"sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"
],
"version": "==1.15.1"
},
"coincurve": {
"hashes": [
"sha256:0503326963916c85b61d16f611ea0545f03c9e418fa8007c233c815429e381e8",
"sha256:1013c1597b65684ae1c3e42497f9ef5a04527fa6136a84a16b34602606428c74",
"sha256:25dfa105beba24c8de886f8ed654bb1133866e4e22cfd7ea5ad8438cae6ed924",
"sha256:30dd44d1039f1d237aaa2da6d14a455ca88df3bcb00610b41f3253fdca1be97b",
"sha256:3d694ad194bee9e8792e2e75879dc5238d8a184010cde36c5ad518fcfe2cd8f2",
"sha256:4ea057f777842396d387103c606babeb3a1b4c6126769cc0a12044312fc6c465",
"sha256:51e56373ac79f4ec1cfc5da53d72c55f5e5ac28d848b0849ef5e687ace857888",
"sha256:630388080da3026e0b0176cc6762eaabecba857ee3fc85767577dea063ea7c6e",
"sha256:68da55aff898702952fda3ee04fd6ed60bb6b91f919c69270786ed766b548b93",
"sha256:698efdd53e4fe1bbebaee9b75cbc851be617974c1c60098e9145cb7198ae97fb",
"sha256:6aec70238dbe7a5d66b5f9438ff45b08eb5e0990d49c32ebb65247c5d5b89d7a",
"sha256:73f39579dd651a9fc29da5a8fc0d8153d872bcbc166f876457baced1a1c01501",
"sha256:747215254e51dd4dfbe6dded9235491263da5d88fe372d66541ca16b51ea078f",
"sha256:74cedb3d3a1dc5abe0c9c2396e1b82cc64496babc5b42e007e72e185cb1edad8",
"sha256:8852dc01af4f0fe941ffd04069f7e4fecdce9b867a016f823a02286a1a1f07b5",
"sha256:896b01941254f0a218cf331a9bddfe2d43892f7f1ba10d6e372e2eb744a744c2",
"sha256:8c571445b166c714af4f8155e38a894376c16c0431e88963f2fff474a9985d87",
"sha256:a80a207131813b038351c5bdae8f20f5f774bbf53622081f208d040dd2b7528f",
"sha256:abbd9d017a7638dc38a3b9bb4851f8801b7818d4e5ac22e0c75e373b3c1dbff0",
"sha256:abbefc9ccb170cb255a31df32457c2e43084b9f37589d0694dacc2dea6ddaf7c",
"sha256:ac8c87d6fd080faa74e7ecf64a6ed20c11a254863238759eb02c3f13ad12b0c4",
"sha256:ad2f6df39ba1e2b7b14bb984505ffa7d0a0ecdd697e8d7dbd19e04bc245c87ed",
"sha256:b1bef812da1da202cdd601a256825abcf26d86e8634fac3ec3e615e3bb3ff08c",
"sha256:b88642edf7f281649b0c0b6ffade051945ccceae4b885e40445634877d0b3049",
"sha256:b956b0b2c85e25a7d00099970ff5d8338254b45e46f0a940f4a2379438ce0dde",
"sha256:c71caffb97dd3d0c243beb62352669b1e5dafa3a4bccdbb27d36bd82f5e65d20",
"sha256:d154e2eb5711db8c5ef52fcd80935b5a0e751c057bc6ffb215a7bb409aedef03",
"sha256:d24284d17162569df917a640f19d9654ba3b43cf560ced8864f270da903f73a5",
"sha256:db874c5c1dcb1f3a19379773b5e8cffc777625a7a7a60dd9a67206e31e62e2e9",
"sha256:dfd4fab857bcd975edc39111cb5f5c104f138dac2e9ace35ea8434d37bcea3be",
"sha256:e2c2e8a1f0b1f8e48049c891af4ae3cad65d115d358bde72f6b8abdbb8a23170",
"sha256:e4beef321fd6434448aab03a0c245f31c4e77f43b54b82108c0948d29852ac7e",
"sha256:f1ef72574aa423bc33665ef4be859164a478bad24d48442da874ef3dc39a474d",
"sha256:f47806527d3184da3e8b146fac92a8ed567bbd225194f4517943d8cdc85f9542"
],
"index": "pypi",
"version": "==17.0.0"
},
"crcmod": {
"hashes": [
"sha256:50586ab48981f11e5b117523d97bb70864a2a1af246cf6e4f5c4a21ef4611cd1",
"sha256:69a2e5c6c36d0f096a7beb4cd34e5f882ec5fd232efb710cdb85d4ff196bd52e",
"sha256:737fb308fa2ce9aed2e29075f0d5980d4a89bfbec48a368c607c5c63b3efb90e",
"sha256:dc7051a0db5f2bd48665a990d3ec1cc305a466a77358ca4492826f41f283601e"
],
"version": "==1.7"
},
"ecdsa": {
"hashes": [
"sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49",
"sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd"
],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.18.0"
},
"ed25519-blake2b": {
"hashes": [
"sha256:d1a1cb9032ec307ce95b41c619440fd4d3fcecc18f224035cc7d6dc7a7d8ef40"
],
"version": "==1.4"
},
"psycopg2": {
"hashes": [
"sha256:11aca705ec888e4f4cea97289a0bf0f22a067a32614f6ef64fcf7b8bfbc53744",
"sha256:1861a53a6a0fd248e42ea37c957d36950da00266378746588eab4f4b5649e95f",
"sha256:2362ee4d07ac85ff0ad93e22c693d0f37ff63e28f0615a16b6635a645f4b9214",
"sha256:36c941a767341d11549c0fbdbb2bf5be2eda4caf87f65dfcd7d146828bd27f39",
"sha256:53f4ad0a3988f983e9b49a5d9765d663bbe84f508ed655affdb810af9d0972ad",
"sha256:869776630c04f335d4124f120b7fb377fe44b0a7645ab3c34b4ba42516951889",
"sha256:a8ad4a47f42aa6aec8d061fdae21eaed8d864d4bb0f0cade5ad32ca16fcd6258",
"sha256:b81fcb9ecfc584f661b71c889edeae70bae30d3ef74fa0ca388ecda50b1222b7",
"sha256:d24ead3716a7d093b90b27b3d73459fe8cd90fd7065cf43b3c40966221d8c394",
"sha256:ded2faa2e6dfb430af7713d87ab4abbfc764d8d7fb73eafe96a24155f906ebf5",
"sha256:f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011",
"sha256:f75001a1cbbe523e00b0ef896a5a1ada2da93ccd752b7636db5a99bc57c44494",
"sha256:f7a7a5ee78ba7dc74265ba69e010ae89dae635eea0e97b055fb641a01a31d2b1"
],
"index": "pypi",
"version": "==2.9.6"
},
"py-sr25519-bindings": {
"hashes": [
"sha256:0441381c2a6f532831d560a1f2ae8a917c7190cf27f5428d9b0528fa28a72e2d",
"sha256:0931ac85331aae33bef67460a3cce554ef5c1f7dfec0ebe2f5b9ea57c5bee65c",
"sha256:0c2fe92b7cdcebf6c5611a90054f8ba6ea90b68b8832896d2dc565537bc40b0c",
"sha256:101ee46368da149ad332aea225d4ff2907dffce574e8f8f7fe56f5c29211f333",
"sha256:16b36d9fe8bda873ab8376f3a4d0894b8d4ab2d702665afc3ab3ca69f0dc9495",
"sha256:1e09ac91f4b2e2b9c50e268f6ee292d9fa447c5b7cc6327cfeae7750d716f49e",
"sha256:1f63580a224607e68b861eb03421465091c3104b6309e5fca7448f5aa6dbda60",
"sha256:251ff9cef5dafd96ff241b77ff471912c40249b6df31e71c6c32de6a26a8dbc6",
"sha256:28b904739147c4f797627bd3b44d1e64d061533253abd1882c6d3b8944e7bbd8",
"sha256:297ad50e3cace5c89dbf5bd916b714aac3ebe6bc76f85382dac228cbeb71449e",
"sha256:2e06a2d1119a2ad063f11448bb27ec4f4ba77416043d98ae28ef30624cf0e12d",
"sha256:302bd20e75d900d98e7961934b03958e8acc8784eed594ab48f9bb298396c734",
"sha256:37b999075b76cae8e84d5f19f2c8f28d3f24c93ba858ad49e58bcf22afe0406b",
"sha256:37f11ffee535c624bf5ddc6109c2cdca9a2dbd10f7d310bcd1dd97f6121c532f",
"sha256:38db0ee90bd676b9df7ddd03fcb2113b5a5e9d9c984d82426728acc0e9d54277",
"sha256:392b8b9875c89c9302930ad3d59567b62176f33adeee96a55ff61ba17fb7aac2",
"sha256:422d62ca74ebe5065eca88607552b9a5f1dc4abff0c597cc3793dd8adfb8c4ea",
"sha256:44bede0dd42f75cf849d3ccb4e443d6425218035bc00a6330b11dc2cc1146f3b",
"sha256:453c9088e39dd04b07bf3ada6c473a5349c4dfd965009a35124b2c807117eda8",
"sha256:458c7e6d7447bd267a6f870a8801e995d710952566a0a52634f408bf804cf27a",
"sha256:47d21382ea24f7f25e72cdddaca2f013ce46cc7983bcfebc611c795cea177eff",
"sha256:4e1b553a6b1cc1b0aa9da2d7157329713cc7f299acb12a052d326f9b594b145c",
"sha256:5102c94e97d316009ad4482f24d9a933fc0b7eb0bb88e6a784a820cd1bd25827",
"sha256:54e8c41081a4c23eca4b19f52de2514c48ddec6f49844dff7ad4cfac0bc11712",
"sha256:55b1f67fdaeab91481fda54432dffdf87ed516d26461d31e70911c7ea55d6164",
"sha256:5dfe767069d5c5e8a313e77b6bd681ea4f6b5988b09b6b4c9399e255fe4a7c53",
"sha256:6406cb0aeb5cbb8cfaa37d59d15d7640c0d812a1cbb55657bee52fd3d9e92aa9",
"sha256:6c73bd1a87849db9cd0e664b2d2e14208183dd8d11ac083d70e688fc28283a71",
"sha256:758761b605f90e4238304df7520155a3358b13cc55ee18c5113632da17343163",
"sha256:7b56b5cbbfb36b41ddfa462989a03386590ac036f3a755ef64fffeb2fed88654",
"sha256:7e69bf7bdc9920013c1a2bea25a8b02df9588d9856cb20270f4d8d95b8e83f52",
"sha256:7f00236a802d6d3f3705713d5352ba968c0ce353a20519c445e66ce19869bfdc",
"sha256:86cc1a571852a4f2ade827ebf211e066b23ab805d3e864cbe213a3d8cd53f7d5",
"sha256:8f06ea3237e06666e3a4ff4719b4fba415472943831b229428753c37d5ecd1b4",
"sha256:909f13f63f67f1e5595d4d495cf8a3c95e392626c08f94550cbf8f0e8ea1c743",
"sha256:942a6b52e871d6e152dda80a60ed338dccedc69b6375e080e496bf886f2556c0",
"sha256:9c1448cf55bbf6f52d2e24766a8a84ba6d77100a991897e8519711ccd7409830",
"sha256:a8e462d2442726d9db07854dc2eb640b1a8a548948b1ff3aa580771ab739bab8",
"sha256:a9aac20a196416b8daf764704a9cee71ddee16bc705d12b5c6bcb6f51e81ac6e",
"sha256:b24307c34a06209d0e34ca15ab4c0275617538dfdac1eac8aa25e792fa9f4108",
"sha256:b3f86e4aad6c2b8ff74af76f38fde7fbaf9dd83bc4a7c259709092008c3b8e5d",
"sha256:b477b18940f472d4e25e141f19503a6e55aadff31b4822228a491c9638096baf",
"sha256:b9da73447c8f5b8392a8229c2b65d742709c6aa2d0c6b32e39b635fb245145f1",
"sha256:bfe52e73d7f0237820f7a935397d5004733a1d890464701f2c3c71be6033c442",
"sha256:c3de899a1e911b8945f09e6389f8d2df68924c12c78e3e66fedb15f1e4ff56ad",
"sha256:ca9794f9d4fc37cdc8cbb6724d5432a064d22c26ecde312928154b6bc691f4d3",
"sha256:cd8da64f9e42ff973b394ed9164f1e9a454279a058eed08ac8d006fcbd61093b",
"sha256:d1b0ed9a4dded60f671f34fdd81c974dad159e98f43bcab21833f984e05920f9",
"sha256:d44ab4d150c9bdd1641ccad49942ecf2d0ef61bd66a7da41094bb4a9cbaca529",
"sha256:d473199c0dbad846b0723c6663b1b6a04040ccdca700cb1609acac3e621f2087",
"sha256:d62af30b2022f5fa787e46c06823c35a21abe791bf55012f498f9ba8e4baabc8",
"sha256:d64253d7d08fd6073e7b79bba9cff78687e76698cc210d3c6f236b90766b9421",
"sha256:dc436a34e17037833c3909062722ee3d46e28288972c87f619d163d00054d68e",
"sha256:df7e2fad636831919bfa479cd4b6fffdd429cde778da72b1834c1434dadaf982",
"sha256:e1471134450e6189b7e38d245ab16b06f3de900b6d07aa66b1e6973cdbc00d01",
"sha256:e162687189cf765f602178aa195a2be4284107622141ff746e92e14e266cf3b7",
"sha256:ec11493d59075ba75fe0bc0312d502ffdc45b641a46fb084bf8b04906597688b",
"sha256:f0b6dcf1328027dba1f9236bd3432cc3cce1de55a12c1a3a4ea7a8dc3ab3e857",
"sha256:f12122a18b688e4a4bf0e74d3969d9e3f6f83d2b01fe88ab5f19c969e95192a2",
"sha256:f2815ecc958f6edbad79fee76899bd33b8950caa7106c1db08c828ec90e16fa7",
"sha256:f4ebeb2aac26a39160f2fad8ffc40ff98da835af57618c0446637bf182b9c927",
"sha256:f8951d1a6e310a682a6253d547e44a9e7a606476dbc18dea3f121d98bdb81042",
"sha256:fc27c847dd4df727388aaadc3870aeb472f2d5c35717536d319792fe08f6120a"
],
"version": "==0.2.0"
},
"pycparser": {
"hashes": [
"sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9",
"sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"
],
"version": "==2.21"
},
"pycryptodome": {
"hashes": [
"sha256:01489bbdf709d993f3058e2996f8f40fee3f0ea4d995002e5968965fa2fe89fb",
"sha256:10da29526a2a927c7d64b8f34592f461d92ae55fc97981aab5bbcde8cb465bb6",
"sha256:12600268763e6fec3cefe4c2dcdf79bde08d0b6dc1813887e789e495cb9f3403",
"sha256:157c9b5ba5e21b375f052ca78152dd309a09ed04703fd3721dce3ff8ecced148",
"sha256:16bfd98dbe472c263ed2821284118d899c76968db1a6665ade0c46805e6b29a4",
"sha256:363dd6f21f848301c2dcdeb3c8ae5f0dee2286a5e952a0f04954b82076f23825",
"sha256:3811e31e1ac3069988f7a1c9ee7331b942e605dfc0f27330a9ea5997e965efb2",
"sha256:422c89fd8df8a3bee09fb8d52aaa1e996120eafa565437392b781abec2a56e14",
"sha256:4604816adebd4faf8810782f137f8426bf45fee97d8427fa8e1e49ea78a52e2c",
"sha256:4944defabe2ace4803f99543445c27dd1edbe86d7d4edb87b256476a91e9ffa4",
"sha256:51eae079ddb9c5f10376b4131be9589a6554f6fd84f7f655180937f611cd99a2",
"sha256:53aee6be8b9b6da25ccd9028caf17dcdce3604f2c7862f5167777b707fbfb6cb",
"sha256:62a1e8847fabb5213ccde38915563140a5b338f0d0a0d363f996b51e4a6165cf",
"sha256:6f4b967bb11baea9128ec88c3d02f55a3e338361f5e4934f5240afcb667fdaec",
"sha256:78d863476e6bad2a592645072cc489bb90320972115d8995bcfbee2f8b209918",
"sha256:795bd1e4258a2c689c0b1f13ce9684fa0dd4c0e08680dcf597cf9516ed6bc0f3",
"sha256:7a3d22c8ee63de22336679e021c7f2386f7fc465477d59675caa0e5706387944",
"sha256:83c75952dcf4a4cebaa850fa257d7a860644c70a7cd54262c237c9f2be26f76e",
"sha256:928078c530da78ff08e10eb6cada6e0dff386bf3d9fa9871b4bbc9fbc1efe024",
"sha256:957b221d062d5752716923d14e0926f47670e95fead9d240fa4d4862214b9b2f",
"sha256:9ad6f09f670c466aac94a40798e0e8d1ef2aa04589c29faa5b9b97566611d1d1",
"sha256:9c8eda4f260072f7dbe42f473906c659dcbadd5ae6159dfb49af4da1293ae380",
"sha256:b1d9701d10303eec8d0bd33fa54d44e67b8be74ab449052a8372f12a66f93fb9",
"sha256:b6a610f8bfe67eab980d6236fdc73bfcdae23c9ed5548192bb2d530e8a92780e",
"sha256:c9adee653fc882d98956e33ca2c1fb582e23a8af7ac82fee75bd6113c55a0413",
"sha256:cb1be4d5af7f355e7d41d36d8eec156ef1382a88638e8032215c215b82a4b8ec",
"sha256:d1497a8cd4728db0e0da3c304856cb37c0c4e3d0b36fcbabcc1600f18504fc54",
"sha256:d20082bdac9218649f6abe0b885927be25a917e29ae0502eaf2b53f1233ce0c2",
"sha256:e8ad74044e5f5d2456c11ed4cfd3e34b8d4898c0cb201c4038fe41458a82ea27",
"sha256:f022a4fd2a5263a5c483a2bb165f9cb27f2be06f2f477113783efe3fe2ad887b",
"sha256:f21efb8438971aa16924790e1c3dba3a33164eb4000106a55baaed522c261acf",
"sha256:fc0a73f4db1e31d4a6d71b672a48f3af458f548059aa05e83022d5f61aac9c08"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==3.18.0"
},
"pynacl": {
"hashes": [
"sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858",
"sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d",
"sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93",
"sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1",
"sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92",
"sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff",
"sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba",
"sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394",
"sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b",
"sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"
],
"markers": "python_version >= '3.6'",
"version": "==1.5.0"
},
"six": {
"hashes": [
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.16.0"
}
},
"develop": {}
}

View File

@ -0,0 +1,20 @@
# Documentation
Experimental code to invoke `bx mnemonic-new` to generate weak mnemonics, and derive some addresses from them.
Uses the PostgreSQL database for storing results.
## Usage
Not documented.
## Status
This is experimental, unmaintained code. Use only as research inspiration.
## License
Licensed under either of `Apache License, Version 2.0` or `MIT` license at your option.
## Credits
Written by Daniel Grove.

View File

@ -0,0 +1,98 @@
import psycopg2
from psycopg2.pool import SimpleConnectionPool
from psycopg2.extras import execute_values
from bip_utils import Bip39SeedGenerator
from bip_utils import Bip44
from bip_utils import Bip44Changes
from bip_utils import Bip44Coins
def gen_addresses(
ts: str,
mnemonic: str,
coin: Bip44Coins = Bip44Coins.BITCOIN
) -> list[tuple[str, str, str, str, str]]:
return gen_bip44_addresses(ts, mnemonic, coin=coin)
def gen_bip44_addresses(
ts: str,
mnemonic: str,
coin: Bip44Coins = Bip44Coins.BITCOIN,
account_number: int = 0
) -> list[tuple[str, str, str, str, str]]:
ADDR_NUM: int = 100
account_type: str = "bip44"
seed_bytes = Bip39SeedGenerator(mnemonic).Generate()
bip44_mst_ctx = Bip44.FromSeed(seed_bytes, coin)
# Derive BIP44 account keys: m/44'/0'/0'
bip44_acc_ctx = bip44_mst_ctx.Purpose().Coin().Account(account_number)
coin_name = bip44_acc_ctx.m_coin_conf.CoinNames().Name()
# Derive BIP44 chain keys: m/44'/0'/0'/0
bip39_account_path = f"m/44'/0'/0'/{account_number}"
bip44_chg_ctx = bip44_acc_ctx.Change(Bip44Changes.CHAIN_EXT)
addresses: list[tuple[str, str, str, str, str]] = []
for i in range(ADDR_NUM):
bip44_addr_ctx = bip44_chg_ctx.AddressIndex(i)
address = bip44_addr_ctx.PublicKey().ToAddress()
bip39_address_path = f"{bip39_account_path}/{i}"
address_tpl = (
"{0:0.9f}".format(ts),
coin_name,
account_type,
bip39_address_path,
address
)
addresses.append(address_tpl)
return addresses
def batch_insert_addresses(cursor, accounts: list[tuple[str, str, str, str, str]]):
stmt = """INSERT INTO addresses
(ts, coin, address_type, address_path, address)
VALUES
%s
ON CONFLICT ON CONSTRAINT unique_coin_address DO NOTHING;
"""
print(f"Inserting {len(accounts)} rows")
execute_values(cursor, stmt, accounts)
def main(pool):
mnemonics_query = "SELECT * FROM mnemonics"
if(pool):
print("Connection pool created")
stream_conn = pool.getconn()
stream_cursor = stream_conn.cursor("mnemonics_stream")
stream_cursor.execute(mnemonics_query)
for row in stream_cursor:
ts = row[1]
mnemonic = row[2]
print(f"Generating addresses for: {ts}")
addresses = gen_bip44_addresses(ts, mnemonic)
print(f"Inserting addresses for: {ts}")
ps_conn = pool.getconn()
ps_cursor = ps_conn.cursor()
batch_insert_addresses(ps_cursor, addresses)
ps_cursor.close()
ps_conn.commit()
pool.putconn(ps_conn)
print("Interated all mnemonics, shutting down...")
stream_cursor.close()
pool.putconn(stream_conn)
postgresql_pool = None
try:
postgresql_pool = SimpleConnectionPool(1,5)
main(postgresql_pool)
except (Exception, psycopg2.DatabaseError) as error:
print("Error", error)
finally:
if postgresql_pool:
postgresql_pool.closeall
print("PostgreSQL connection pool is closed")

View File

@ -0,0 +1,20 @@
#!/bin/bash
set -euo pipefail
# Define default values
: "${INITIAL_VALUE:=0.000000000}"
: "${INCREMENT_STEP:=0.000000001}"
: "${END_VALUE:=4.294967296}"
psql -f ./sql/mnemonics.psql
# Loop until the current value reaches the end value
while (( $(echo "$INITIAL_VALUE <= $END_VALUE" | bc -l) )); do
# Output the current value with desired formatting (e.g., 9 decimal places)
seed=$(LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 FAKETIME_FMT=%s FAKETIME=$(printf "%.9f\n" $INITIAL_VALUE) bx seed -b 256 | bx mnemonic-new)
printf "%.9f | %s\n" $INITIAL_VALUE "$seed"
psql -c "insert into mnemonics (ts, mnemonic) values ('$INITIAL_VALUE', '$seed');"
# Increment the current value
INITIAL_VALUE=$(echo "$INITIAL_VALUE + $INCREMENT_STEP" | bc -l)
done

View File

@ -0,0 +1,10 @@
CREATE TABLE IF NOT EXISTS addresses(
id SERIAL PRIMARY KEY,
ts DECIMAL,
address_path VARCHAR(100),
address_type VARCHAR(20),
coin VARCHAR(100),
address VARCHAR(200),
CONSTRAINT unique_coin_address UNIQUE (ts,coin,address),
CONSTRAINT fk_ts FOREIGN KEY(ts) REFERENCES mnemonics(ts)
);

View File

@ -0,0 +1 @@
COPY mnemonics(ts, mnemonic) FROM STDIN DELIMITER '|';

View File

@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS mnemonics(
id SERIAL,
ts decimal UNIQUE PRIMARY KEY,
mnemonic TEXT
);

View File

@ -0,0 +1,280 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "bech32"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dabbe35f96fb9507f7330793dc490461b2962659ac5d427181e451a623751d1"
[[package]]
name = "bitcoin"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6742ec672d3f12506f4ac5c0d853926ff1f94e675f60ffd3224039972bf663f1"
dependencies = [
"bech32",
"bitcoin_hashes",
"secp256k1",
]
[[package]]
name = "bitcoin_hashes"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ce18265ec2324ad075345d5814fbeed4f41f0a660055dc78840b74d19b874b1"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bs58"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
[[package]]
name = "cc"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "hd-derivation"
version = "0.1.0"
dependencies = [
"bitcoin",
"bs58",
"structopt",
]
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
dependencies = [
"proc-macro2",
]
[[package]]
name = "secp256k1"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a"
dependencies = [
"secp256k1-sys",
]
[[package]]
name = "secp256k1-sys"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036"
dependencies = [
"cc",
]
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "structopt"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
dependencies = [
"clap",
"lazy_static",
"structopt-derive",
]
[[package]]
name = "structopt-derive"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "unicode-ident"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@ -0,0 +1,11 @@
[package]
name = "hd-derivation"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bitcoin = "0.26.2"
bs58 = "0.4.0"
structopt = "0.3"

View File

@ -0,0 +1,18 @@
# HDD - Hierarchical Deterministic Derivations
A simple lib to derive child addresses based on `xpriv` key as input.
Goes from `xpriv` to address, using standard derivation paths.
## Usage
`cargo run -- -x "put-some-xprv-here" -p "m/0"`
## Status
This is experimental, unmaintained code. Use only as research inspiration.
## License
Licensed under either of `Apache License, Version 2.0` or `MIT` license at your option.
## Credits
Written by Daniel Grove.

View File

@ -0,0 +1,39 @@
extern crate bitcoin;
extern crate bs58;
extern crate structopt;
use bitcoin::Network;
use bitcoin::util::address::Address;
use bitcoin::util::bip32::{XPriv, DerivationPath};
use bitcoin::util::key::PublicKey;
use bitcoin::secp256k1::Secp256k1;
use std::str::FromStr;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(name = "hdd", about = "An HD derivation tool.")]
pub struct Opt {
#[structopt(short = "x", long = "xpriv")]
pub xpriv: String,
#[structopt(short = "p", long = "path")]
pub path: String,
}
pub fn derive_child_address(xpriv: &str, path: &str) -> Result<String, Box<dyn std::error::Error>> {
let secp = Secp256k1::new();
let decoded_xpriv = XPriv::from_str(xpriv)?;
let child_path = DerivationPath::from_str(path)?;
let child_key = decoded_xpriv.derive_priv(&secp, &child_path)?;
let public_key = PublicKey::from_private_key(&secp, &child_key.private_key);
let address = Address::p2pkh(&public_key, Network::Bitcoin);
Ok(address.to_string())
}
fn main() {
let opt = Opt::from_args();
match derive_child_address(&opt.xpriv, &opt.path) {
Ok(address) => println!("Derived address: {}", address),
Err(e) => println!("Error: {}", e),
}
}

View File

@ -0,0 +1,13 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
pybloom_live = "*"
click = "*"
[dev-packages]
[requires]
python_version = "3.8"

View File

@ -0,0 +1,40 @@
# Bloom Filter Generator
Allows the creation of a bloom filter based on a data set.
Also allows checking if an address is in the filter.
The input data set should be `/n` delineated `.txt` file that looks something like:
```
firstaddress
secondaddress
thirdaddress
```
The resulting bloom filter can be "checked against" with an address, and will respond whether that address exists in the bloom filter set or not.
It's important to keep in mind that bloom filters are probabilistic data structures and as such result in false positives usually at a rate of ~1%, which can be adjusted for by increasing the data set size, but at typical parameters which result from an optimized bloom filter, balancing false positives and size, 1% is the usual rate we encounter.
## Generate bloom filter
`python bloom-util.py create --filter_file filter.pkl --addresses_file addresses.txt`
## Check if address is in bloom filter
`python bloom-util.py check --filter_file filter.pkl --address firstaddress`
$ Address firstaddress is in the filter
`python bloom-util.py check --filter_file filter.pkl --address fourthaddress`
$ Address fourthaddress is not in the filter
## Status
This is experimental, unmaintained code. Use only as research inspiration.
## License
Licensed under either of `Apache License, Version 2.0` or `MIT` license at your option.
## Credits
Written by Anton Livaja, improved by Christian Reitter.

View File

@ -0,0 +1,3 @@
firstaddress
secondaddress
thirdaddress

View File

@ -0,0 +1,139 @@
import argparse
import hashlib
import pickle
from pybloom_live import BloomFilter
import csv
import sys
def construct_bloom_filter(addresses_file, filter_file):
# false positive: 0.000000001 = 4 out of 4 billion
# TODO max capacity is hardcoded
# TODO error rate is hardcoded
# this is a problem when using larger or significantly smaller data sets
bloom_filter = BloomFilter(capacity=1180626779, error_rate=0.000000001)
with open(addresses_file, 'r') as file:
for line in file:
address = line.strip()
bloom_filter.add(address.encode())
with open(filter_file, 'wb') as f:
pickle.dump(bloom_filter, f)
print(f'Bloom filter created and saved as {filter_file}')
def check_address(filter_file, address):
with open(filter_file, 'rb') as f:
bloom_filter = pickle.load(f)
if address.encode() in bloom_filter:
print(f'Address {address} is in the filter')
return True
else:
print(f'Address {address} is not in the filter')
return False
def check_address_csv(filter_file, address_csv_file, skip_lines = 0):
# TODO output discovered results to another file
with open(filter_file, 'rb') as f:
bloom_filter = pickle.load(f)
status_print_every = 10_000_000
print("unpickled bloom filter file")
sys.stdout.flush()
i = 0
found = 0
skip_lines_remaining = skip_lines
with open(address_csv_file, 'r') as file:
csvreader = csv.reader(file, delimiter=',')
for dataline in csvreader:
if skip_lines_remaining > 0:
skip_lines_remaining -= 1
i += 1
continue
address_id = ""
address = ""
try:
address_id = dataline[0]
address = dataline[1]
except e:
# likely hit end-of-file with incomplete CSV entry
print("broken input, skipping")
continue
if address.encode() in bloom_filter:
found += 1
print(str(address_id) + "," + address)
sys.stdout.flush()
i += 1
# regular print
if i % status_print_every == 0:
print("read " + str(i) + " lines")
sys.stdout.flush()
print("found " + str(found) + " address hits in total against the bloom filter")
# for address in addresses:
# if address.encode() in bloom_filter:
# print(f'Address {address} is in the filter')
# else:
# print(f'Address {address} is not in the filter')
def check_address_benchmark_bulk(filter_file, addresses):
with open(filter_file, 'rb') as f:
bloom_filter = pickle.load(f)
for address in addresses:
if address.encode() in bloom_filter:
print(f'Address {address} is in the filter')
else:
print(f'Address {address} is not in the filter')
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Bloom filter operations')
parser.add_argument('operation', choices=['create', 'check', 'check_csv_bulk', 'benchmark'], help='Operation to perform')
parser.add_argument('-f', '--filter_file', required=True, help='File to save/load Bloom filter')
parser.add_argument('-a', '--address', help='Bitcoin address for checking')
parser.add_argument('-af', '--addresses_file', help='File containing Bitcoin addresses for creating Bloom filter')
parser.add_argument('-csv', '--addresses_csv_file', help='File containing index,address CSV pairs to check in bulk')
parser.add_argument('-s', '--skip-input-lines', help='Skip n lines from input')
args = parser.parse_args()
if args.operation == 'create':
if args.addresses_file is None:
print('You must provide an address file for creating a Bloom filter.')
else:
construct_bloom_filter(args.addresses_file, args.filter_file)
elif args.operation == 'check':
# TODO require filter file
if args.address is None:
print('You must provide an address for checking.')
else:
check_address(args.filter_file, args.address)
elif args.operation == 'check_csv_bulk':
# TODO require filter file
if args.addresses_csv_file is None:
print('You must provide an address CSV file for checking.')
else:
skip_lines = 0
if args.skip_input_lines is not None:
skip_lines = int(args.skip_input_lines)
print("skipping " + str(skip_lines) + " lines")
check_address_csv(args.filter_file, args.addresses_csv_file, skip_lines)
elif args.operation == 'benchmark':
# TODO require filter file
if args.address is None:
print('You must provide an address for benchmark.')
else:
addresses = []
# run lookup 1M times
# this is primitive and re-uses the same lookup, not ideal benchmark
for i in range(1000000):
addresses.append(args.address)
check_address_benchmark_bulk(args.filter_file, addresses)