Bitcoin-Core

v0.21 和 v22.0 中新 SQLite 描述符錢包的佈局?

  • December 20, 2021

我正在嘗試探索 Bitcoin Core v0.21 和 v22.0 中新描述符錢包的數據庫格式,但我不太明白。我創建了一個新的描述符錢包並使用 SQLite 查看器轉儲了它的內容:

{wallet.dat}.main.{minversion} = ac970200
{wallet.dat}.main.{walletdescriptorkey, 5bc2366434...be2be5636f} = d63081d302...eb80b8a63f
{wallet.dat}.main.{walletdescriptorcache, 5bc2366434...bc00000000} = 4a0481d4f2...e2b5797bc6
{wallet.dat}.main.{walletdescriptorlhcache, 5bc2366434...bc00000000} = 4a0334157e...3cd72210c0
{wallet.dat}.main.{activeexternalspk, 00} = 5bc2366434...17e16409bc
{wallet.dat}.main.{walletdescriptorkey, 179b711c2e...be2be5636f} = d63081d302...eb80b8a63f
{wallet.dat}.main.{walletdescriptorcache, 179b711c2e...3a00000000} = 4a04c1b8ae...534fc80e4a
{wallet.dat}.main.{walletdescriptorlhcache, 179b711c2e...3a00000000} = 4a03774319...6b8a432640
{wallet.dat}.main.{activeexternalspk, 01} = 179b711c2e...5fffee163a
{wallet.dat}.main.{walletdescriptorkey, 7cf4a0f984...be2be5636f} = d63081d302...eb80b8a63f
{wallet.dat}.main.{walletdescriptorcache, 7cf4a0f984...4b00000000} = 4a045ffe0a...0d113a8596
{wallet.dat}.main.{walletdescriptorlhcache, 7cf4a0f984...4b00000000} = 4a03673c1f...e647a32c18
{wallet.dat}.main.{activeexternalspk, 02} = 7cf4a0f984...8c3dd80a4b
{wallet.dat}.main.{walletdescriptorkey, 7457e8edcb...be2be5636f} = d63081d302...eb80b8a63f
{wallet.dat}.main.{walletdescriptorcache, 7457e8edcb...d300000000} = 4a0481d4f2...c713790faf
{wallet.dat}.main.{walletdescriptorlhcache, 7457e8edcb...d300000000} = 4a0334157e...3cd72210c0
{wallet.dat}.main.{activeinternalspk, 00} = 7457e8edcb...d76c288ed3
{wallet.dat}.main.{walletdescriptorkey, ccd36c1209...be2be5636f} = d63081d302...eb80b8a63f
{wallet.dat}.main.{walletdescriptorcache, ccd36c1209...9400000000} = 4a04c1b8ae...18821059e5
{wallet.dat}.main.{walletdescriptorlhcache, ccd36c1209...9400000000} = 4a03774319...6b8a432640
{wallet.dat}.main.{activeinternalspk, 01} = ccd36c1209...ef094d8e94
{wallet.dat}.main.{walletdescriptorkey, db2cf1cdc6...be2be5636f} = d63081d302...eb80b8a63f
{wallet.dat}.main.{walletdescriptorcache, db2cf1cdc6...6d00000000} = 4a045ffe0a...497189e5c3
{wallet.dat}.main.{walletdescriptorlhcache, db2cf1cdc6...6d00000000} = 4a03673c1f...e647a32c18
{wallet.dat}.main.{flags} = 0000000004000000
{wallet.dat}.main.{activeinternalspk, 02} = db2cf1cdc6...0129f3106d
{wallet.dat}.main.{walletdescriptor, db2cf1cdc6...0129f3106d} = wpkh(tpubD...)#znsakxap, 13159b6100...00e8030000
{wallet.dat}.main.{walletdescriptor, 7457e8edcb...d76c288ed3} = pkh(tpubD6...)#25g5mpq6, 12159b6100...00e8030000
{wallet.dat}.main.{walletdescriptor, 5bc2366434...17e16409bc} = pkh(tpubD6...)#mqd4x5sz, 11159b6100...00e8030000
{wallet.dat}.main.{walletdescriptor, 179b711c2e...5fffee163a} = sh(wpkh(tp...)#0v4dg3a0, 11159b6100...00e8030000
{wallet.dat}.main.{walletdescriptor, 7cf4a0f984...8c3dd80a4b} = wpkh(tpubD...)#n84utnde, 12159b6100...00e8030000
{wallet.dat}.main.{walletdescriptor, ccd36c1209...ef094d8e94} = sh(wpkh(tp...)#f0agnukm, 13159b6100...00e8030000
{wallet.dat}.main.{bestblock} = 605b030000
{wallet.dat}.main.{bestblock_nomerkle} = 605b030021...0900000000

描述符欄位清楚地顯示tpubs,並且欄位中可能存在私鑰*spk。但是為了進行 BIP32 派生,你需要一個私鑰和一個鏈碼。

即使給定私鑰,我似乎也無法tprvs從. tpubs我查看了送出 4018e23的程式碼,對它的構造方式有一些模糊的想法,但似乎無法弄清楚哪些欄位包含私鑰和鏈碼,或者只是一個tprv.

也有可能密鑰值本身實際上是在數據庫中靜態加密的,但我假設這些將使用walletdescriptorckey欄位而crypted-key不是walletdescriptorkey欄位。請注意,我的轉儲僅包含*rkey欄位而沒有rckey欄位。

我意識到下一個版本將公開tprvin the futurelistdescriptors命令,但我試圖弄清楚PR#21500是如何做到的。

創建 SQL 轉儲文件的程式碼是……本質上是:

from sqlite_utils import Database

if __name__ == "__main__":
   db=Database("wallet.dat")
   for row in db['main'].rows:
       key = fmt_key(row['key'])
       value = fmt_key(row['value'])
       
       pref = "{wallet.dat}.main."
       print(f"{pref}{{{key}}} = {value}")

程式碼數據的完整副本可以在這裡找到:

  • <https://github.com/brianddk/reddit/blob/master/python/sqldump.py>
  • <https://github.com/brianddk/reddit/blob/master/python/sqldump.txt>

如果你缺乏足夠的業力來評論或回答,我已經在 reddit 上發布了這個問題

擴展公鑰包含鏈碼,因此不會單獨儲存。因此tpub,您找到的 s 將包含鏈碼。

私鑰未加密,未加密的私鑰使用 DER 序列化儲存。此方法生成一個 214 字節的私鑰,其中絕大多數數據是不相關的。私鑰總是以字節開頭d63081d30201010420。然後接下來的 32 個字節是私鑰的字節。之後的一切都可以丟棄。

獲得私鑰後,將其與00(所以它將是00&lt;private key&gt;)連接起來,並將其插入到解碼的 tpub 中以代替公鑰。將其重新編碼為 tprv,您應該擁有您找到的公鑰的相應擴展私鑰。

引用自:https://bitcoin.stackexchange.com/questions/110942