En 2-av-3 multisig-lommebok med alle tre seed-frasene i hånden burde være umulig å miste. Likevel viser veiledning publisert 21. september 2026, og oppdatert 13. oktober samme år, at nettopp dette skjer med jevne mellomrom: brukere sitter med gyldige nøkler, men mangler metadataen som sier hvordan nøklene skal settes sammen til en fungerende lommebok. Den manglende biten kalles en deskriptor, og den er definert i Bitcoin Improvement Proposal 380 (BIP-380).
Denne typen feil blir ikke mindre vanlig med tiden, den blir mer vanlig. Flere lommebøker har gått fra enkle, enkeltsignatur-oppsett til multisig med flere scripttyper, flere derivasjonsstier og i mange tilfeller flere hardware-leverandører i samme oppsett. Hver ekstra variabel er en ny mulighet for at backupen din beskriver noe annet enn det lommeboken faktisk ser etter. Det gjelder uavhengig av om du bruker multisig for privat kaldlagring, for et firmaoppsett, eller for en arveplan med flere betrodde parter.
Problemet er strukturelt, ikke tilfeldig. En seed-frase beskriver bare nøkkelmaterialet til én part i oppsettet. Den sier ingenting om hvilke andre offentlige nøkler som er med, hvilken skripttype som brukes (wpkh, wsh, tr), hvilken terskel som gjelder (2-av-3, 3-av-5) eller hvilke derivasjonsstier hver part har brukt. Uten denne policyen kan du eie alle de riktige private nøklene og fortsatt ikke finne pengene dine. Denne artikkelen går gjennom hvordan du eksporterer, validerer, krypterer og tester gjenoppretting av en BIP-380-deskriptor for en Bitcoin-multisig, i 12 konkrete steg du kan følge uavhengig av om du bruker hardware-lommebok eller programvarelommebok som cosigner.
Målgruppen er Bitcoin-brukere som allerede har satt opp en multisig, enten via air-gapped kaldlagring eller via et oppsett for arv og tidslåste utbetalinger. Hvis du planlegger et helt nytt multisig-oppsett fra scratch, er grunnarbeidet (fordeling av cosignere, valg av terskel, air-gapping) allerede dekket i tidligere artikler. Her går vi rett på selve gjenopprettingslogikken, med ekte bitcoin-cli-kommandoer og et komplett Python-prosjekt du kan kjøre selv.
Hvorfor dette har blitt mer aktuelt i andre halvdel av 2026
For noen år tilbake eksporterte de fleste lommebøker rett og slett en liste med xpub-er når du ba om en backup. Det fungerte greit for enkeltsignatur, men ga lite informasjon om hvordan flere nøkler skulle settes sammen i et multisig-oppsett. Gjennom 2025 og 2026 har stadig flere programvare- og maskinvareleverandører gått over til å eksportere og importere fullstendige deskriptorer i stedet, nettopp fordi formatet kan bære med seg terskel, scripttype og derivasjonssti i én samlet streng. Det løser et reelt problem, men det flytter også ansvaret: nå må brukeren faktisk ta vare på denne strengen, ikke bare seed-ordene.
Den oppdaterte veiledningen fra 21. september og 13. oktober 2026 pekte på nettopp dette gapet. Den advarte om at en seed-only-backup kan være ufullstendig for lommebøker som bruker flere scripttyper eller flere derivasjonsstier samtidig, noe som er mer vanlig enn mange tror ettersom brukere migrerer fra eldre wpkh-oppsett til nyere Taproot-varianter uten å rydde opp i gamle backuper. Resultatet er at en bruker kan ha tre komplette seed-fraser, riktig terskel i minnet, og fortsatt stå fast fordi ingen av backupene faktisk sier hvilken kombinasjon av scripttype og sti som ble brukt til å ta imot de siste innskuddene.
Hva er en BIP-380-deskriptor, og hvorfor dukket den opp nå
En output-deskriptor er en kompakt tekststreng som beskriver nøyaktig hvilke scripts en lommebok skal gjenkjenne. Et enkelt eksempel for en enkeltsignatur-lommebok ser slik ut: wpkh(xpub6CUGRU.../0/*). Strengen sier at adressene er av typen native segwit (wpkh), at den offentlige nøkkelen er den angitte xpub-en, og at stien 0/* brukes for mottaksadresser. Ifølge referansedokumentasjonen hos We Are Bitcoin inneholder en deskriptor altså scripttype, nøkkelkilde, derivasjonssti og hvilken gren som er mottak versus veksel, altså alt en lommebok trenger for å bygge opp hele settet av adresser på nytt.
Legg merke til stjernen i /0/*. Den gjør deskriptoren til en såkalt range-descriptor, som betyr at den beskriver en uendelig serie med adresser, ikke bare én enkelt adresse. Lommeboken avleder adresse 0, 1, 2 og så videre etter behov. Noen nyere wallet-eksporter samler mottak og veksling i én og samme streng med notasjonen <0;1>/*, der 0 betyr mottak og 1 betyr veksling innenfor samme deskriptor. Andre krever at du holder to separate deskriptorer, én for hver gren. Begge er gyldige etter BIP-380, men de ser forskjellige ut, og det er lett å anta feil format hvis du bytter programvare uten å dobbeltsjekke.
For multisig blir dette kritisk. En sortedmulti-deskriptor for en 2-av-3-wsh-lommebok ser typisk ut som wsh(sortedmulti(2,[fp1/48h/0h/0h/2h]xpub1.../0/*,[fp2/48h/0h/0h/2h]xpub2.../0/*,[fp3/48h/0h/0h/2h]xpub3.../0/*)). Den samler fingeravtrykk, derivasjonssti og offentlig nøkkel for alle tre cosignerne i én linje. Uten denne nøyaktige kombinasjonen, inkludert sorteringen av nøklene, genererer programvaren andre adresser enn de du faktisk brukte til å ta imot bitcoin. Du kan ha riktige private nøkler og fortsatt stå med tomme kontoer fordi lommeboken ser på feil adresser.
Standarden er egentlig ikke ny, men er utvidet gjennom en serie forslag fra BIP-380 til BIP-386, som dekker alt fra generell syntaks til Taproot-spesifikke descriptors (tr()). Coldcards egen dokumentasjon peker på disse som blant de viktigste BIP-ene for noen som driver med kaldlagring i 2026, nettopp fordi flere lommebokprodusenter nå eksporterer og importerer descriptors som standard backup-format i stedet for bare xpub-lister. BIP-388 går et skritt videre og definerer wallet policies, en strukturert måte å beskrive nøkler og betingelser som gjør det enklere for maskinvarelommebøker å vise brukeren nøyaktig hva de signerer på.
Det finnes også en kryptering-side av saken. En egen BIP, referert til som BIP-138 av Coin Brief, dekker kryptering av nettopp denne typen metadata, altså delen av en lommebokbackup som ikke er selve seed-frasen. Tanken er at descriptor-filer, som kan inneholde både offentlige og i noen tilfeller private nøkler, bør få samme beskyttelsesnivå som seeden selv, men lagres og distribueres separat fra den.
Det er lett å blande sammen de ulike BIP-numrene i denne familien, siden de ble publisert over flere år og dekker litt forskjellige deler av samme problem. Tabellen under samler dem slik d-central.tech og Coldcards egen BIP-oversikt grupperer dem, og kan brukes som oppslagsverk når du leser videre dokumentasjon fra lommebokleverandøren din.
| BIP | Dekker | Relevant for |
|---|---|---|
| BIP-380 | Generell syntaks for output-deskriptorer | Alle lommebøker som bruker descriptor-format |
| BIP-381 til 383 | Spesifikke scripttyper (blant annet sh, wsh, kombinasjoner) | Multisig og nested-script-oppsett |
| BIP-386 | Taproot-spesifikk descriptor-syntaks (tr()) | Nyere enkeltsignatur- og multisig-oppsett med Taproot |
| BIP-388 | Wallet policies, strukturert beskrivelse av nøkler og betingelser | Maskinvarelommebøker som skal vise lesbar signeringskontekst |
| BIP-138 | Kryptering av metadata i en lommebokbackup utover selve seeden | Sikker lagring av descriptor- og policy-filer |
Forutsetninger: programvare, versjoner og testmiljø
Du trenger ikke dyrt utstyr for denne øvelsen, men du trenger noen spesifikke verktøy installert og et sted å teste uten å røre faktiske midler. Bruk alltid testnet eller signet først, og flytt aldri skarpe nøkler inn i et skript du ikke har lest hele veien gjennom.
| Verktøy | Minimumsversjon | Rolle i denne guiden |
|---|---|---|
| Bitcoin Core | 28 eller nyere | Kjører getdescriptorinfo, deriveaddresses, importdescriptors |
| Python | 3.10 eller nyere | Kjører valideringsskriptet fra steg 11 |
| GnuPG (gpg) | Siste stabile versjon | Krypterer descriptor-backupen separat fra seed-backup |
| Sparrow Wallet eller Specter | Siste stabile versjon | Grafisk import/eksport av descriptors og watch-only-visning |
| Maskinvarelommebok (per cosigner) | Nyeste fastvare for din modell | Signerer og eksporterer egen del av multisig-policyen |
| USB-minnepenn eller SD-kort (kryptert) | – | Fysisk lagring av descriptor-backup, separat fra seed-backup |
Sett opp Bitcoin Core i testnet- eller signet-modus (bitcoin.conf med signet=1) før du rører noe som helst. Hele poenget med denne gjennomgangen er å øve på gjenoppretting uten risiko, slik Coldcards egen anbefaling også legger vekt på: test alltid med en lommebok uten reelle midler før du stoler på en backup-prosedyre med skarpe penger.
Signet er normalt å foretrekke over det eldre testnet-nettverket til denne typen øvelse, siden det er mer stabilt og mindre utsatt for store, uforutsigbare svingninger i blokkproduksjon. Du trenger ikke mine eller kjøpe testmynter for å gjennomføre selve descriptor-valideringen, siden getdescriptorinfo og deriveaddresses er rene beregninger som ikke krever at noe faktisk er sendt til adressene. Først når du vil teste en reell overføring, for eksempel for å øve på hele flyten fra signering til bekreftet transaksjon, trenger du noen småbeløp i signet-mynter, som er enkle å få tak i fra offentlige signet-faucets.
Steg 1-4: Fra kartlegging til validert sjekksum
Steg 1: Kartlegg multisig-oppsettet ditt
Skriv ned, på papir eller i et kryptert dokument, nøyaktig hvilken terskel lommeboken bruker (for eksempel 2-av-3), hvilken scripttype (wpkh for single-sig, wsh for script-basert multisig, eller tr for Taproot), og hvilke enheter som er cosignere. Dette er ikke selve deskriptoren, men grunnlaget du skal bygge den fra. Mange brukere oppdager først i dette steget at de aldri har skrevet ned om vekslingen går til intern sti 1/* eller om lommeboken bruker en samlet sti med range-notasjon som <0;1>/*.
Steg 2: Eksporter offentlig deskriptor fra hver cosigner
De fleste moderne maskinvarelommebøker og programvareløsninger som Sparrow og Specter har en funksjon for å eksportere et offentlig deskriptor-fragment direkte, uten å eksponere private nøkler. I Sparrow finner du dette under lommebokinnstillinger, som regel merket “Export Wallet” eller “Descriptor”. Resultatet er en fil eller streng som denne for én cosigner:
[a1b2c3d4/48h/0h/0h/2h]xpub6DXnmdWp3s9Fz8VioBdKBQw...fNPybr/0/*
Gjør dette for alle cosignerne i oppsettet og lagre hvert fragment separat, merket tydelig med hvilken enhet og hvilken person fragmentet kommer fra. Pass på at du eksporterer den offentlige varianten (ingen privat nøkkel skal være med) med mindre du eksplisitt skal lagre en signeringskapabel backup for deg selv.
Steg 3: Sett sammen sortedmulti-deskriptoren
Kombiner fragmentene i riktig syntaks. For en 2-av-3 segwit-multisig blir det:
wsh(sortedmulti(2,
[a1b2c3d4/48h/0h/0h/2h]xpub6DXnmdWp.../0/*,
[b5c6d7e8/48h/0h/0h/2h]xpub6ELkqR7t.../0/*,
[c9d0e1f2/48h/0h/0h/2h]xpub6FMowgU8.../0/*
))
Rekkefølgen på nøklene spiller egentlig ingen rolle her fordi sortedmulti sorterer dem internt ved adressegenerering, men alle tre fragmentene må være riktige og fra samme opprinnelige oppsett. Terskelen (2) må matche det du skrev ned i steg 1.
Steg 4: Valider sjekksum med Bitcoin Core
BIP-380 definerer et sjekksumformat på åtte tegn, lagt til etter et #-tegn, som fanger opp transkripsjonsfeil. Du trenger ikke beregne dette manuelt. Bitcoin Core gjør det for deg:
bitcoin-cli getdescriptorinfo "wsh(sortedmulti(2,[a1b2c3d4/48h/0h/0h/2h]xpub6DXnmdWp.../0/*,[b5c6d7e8/48h/0h/0h/2h]xpub6ELkqR7t.../0/*,[c9d0e1f2/48h/0h/0h/2h]xpub6FMowgU8.../0/*))"
Svaret inneholder et felt descriptor med sjekksummen allerede lagt til, samt isrange, issolvable og hasprivatekeys. Lagre den komplette strengen inkludert sjekksum. Hvis issolvable kommer tilbake som false, er det en feil i syntaksen eller en av xpub-ene, og du må gå tilbake til steg 2 og sjekke eksportene på nytt.
Steg 5-7: Fra fingeravtrykk til avledede adresser
Steg 5: Sammenlign fingeravtrykk og derivasjonsstier
Hvert fragment starter med et fingeravtrykk i hakeparentes, som [a1b2c3d4/48h/0h/0h/2h]. Dette identifiserer hvilken fysisk enhet nøkkelen kommer fra. Sjekk at fingeravtrykket i deskriptoren matcher det enheten selv rapporterer (de fleste maskinvarelommebøker viser fingeravtrykket i menyen for “wallet info” eller “device info”). Hvis et fingeravtrykk ikke stemmer, har du kanskje blandet sammen fragmenter fra to ulike multisig-oppsett, noe som er lettere å gjøre enn man tror når man har flere lommebøker fra samme produsent.
Steg 6: Importer deskriptoren til en ren watch-only-lommebok
Lag en ny, tom lommebok i Bitcoin Core eller Sparrow som ikke har noen tilknytning til det opprinnelige oppsettet. Dette er testen på om deskriptoren faktisk er selvstendig nok til å gjenoppbygge lommeboken fra bunnen.
bitcoin-cli createwallet "recovery_test" true true
bitcoin-cli -rpcwallet=recovery_test importdescriptors '[{
"desc": "wsh(sortedmulti(2,[a1b2c3d4/48h/0h/0h/2h]xpub6DXnmdWp.../0/*,[b5c6d7e8/48h/0h/0h/2h]xpub6ELkqR7t.../0/*,[c9d0e1f2/48h/0h/0h/2h]xpub6FMowgU8.../0/*))#checksum",
"active": true,
"timestamp": "now",
"range": [0, 100]
}]'
Den andre “true” i createwallet markerer lommeboken som watch-only, slik at det aldri er noen risiko for at private nøkler lekker inn i testmiljøet.
Steg 7: Avled adresser og sammenlign mot originalen
Bruk deriveaddresses til å generere de samme indeksene du vet ble brukt i produksjon, og sammenlign med adresser du har fra den opprinnelige lommeboken (for eksempel fra et tidligere mottatt beløp):
bitcoin-cli deriveaddresses "wsh(sortedmulti(2,[a1b2c3d4/48h/0h/0h/2h]xpub6DXnmdWp.../0/*,[b5c6d7e8/48h/0h/0h/2h]xpub6ELkqR7t.../0/*,[c9d0e1f2/48h/0h/0h/2h]xpub6FMowgU8.../0/*))#checksum" "[0,5]"
Hvis adresse 0 i testen matcher adresse 0 i produksjonslommeboken, er deskriptoren bekreftet korrekt for mottaksgrenen. Gjenta med vekslingsstien (ofte 1/* eller den andre halvdelen av en <0;1>/*-range) for å bekrefte at du også finner tilbake til vekslingsmidler.
Steg 8-10: Kryptering, testgjenoppretting og dokumentasjon
Steg 8: Krypter descriptor-backupen separat fra seed-backupen
En deskriptor uten private nøkler er i utgangspunktet bare informasjon om struktur, men kombinert med de riktige seed-frasene gir den full tilgang til midlene. Lagre den derfor like beskyttet som seeden, men fysisk et annet sted. Krypter filen før den lagres på en USB-penn eller skrives ut:
gpg --symmetric --cipher-algo AES256 --output multisig_descriptor.gpg multisig_descriptor.txt
shred -u multisig_descriptor.txt
Bruk en passfrase for denne krypteringen som er forskjellig fra både seed-passfrasen (det 25. ordet, se vår egen gjennomgang av passfrase-lommebøker) og eventuelle PIN-koder på enhetene. Målet er at ingen enkelt kompromittert faktor gir tilgang til alt.
Steg 9: Kjør en nullverdi- eller testnet-gjenopprettingsøvelse
Gå gjennom hele kjeden på nytt, fra kryptert fil til ferdig watch-only-lommebok, uten å se på notatene fra forrige gjennomgang. Tidsmål hvor lang tid prosessen tar, og skriv ned hvert sted du måtte slå opp dokumentasjon. Dette er den eneste måten å finne ut om instruksjonene faktisk er fullstendige nok til at en annen person, for eksempel en arving, kan gjennomføre dem under stress.
Noter deg gjerne hvor mange trinn som krevde deg å huske noe utenfor selve dokumentasjonen, som et passord lagret i hodet eller en antagelse om hvilken programvareversjon du brukte sist. Hver slik avhengighet er et svakhetspunkt du bør rette opp før du erklærer prosedyren som ferdig. Målet er en instruksjon som er fullstendig i seg selv, slik at den fungerer selv om du har flyttet, byttet datamaskin, eller ikke er tilgjengelig for å svare på spørsmål.
Steg 10: Dokumenter hvilken backup er watch-only og hvilken er signeringskapabel
En deskriptor kan enten være rent observerende (bare offentlige nøkler), i stand til å bygge transaksjoner, eller i verste fall inneholde private nøkler og dermed være fullt signeringskapabel. Merk hver fysisk kopi tydelig med hvilken kategori den tilhører. Dette hindrer at en arving eller medsigner ved et uhell behandler en sensitiv fil som om den var ufarlig, eller omvendt kaster bort en viktig watch-only-backup fordi de trodde den var ubrukelig uten nøkler.
Steg 11-12: Geografisk lagring og periodisk verifisering
Steg 11: Fordel backupene etter 3-2-1-prinsippet
Lagre minst tre kopier, på to forskjellige medietyper, hvorav minst én på et annet geografisk sted. For en multisig betyr dette i praksis at seed-backup og descriptor-backup bør ligge på ulike steder, slik at en brann, et innbrudd eller en vannskade ikke tar begge samtidig. Hvis du allerede har et arveoppsett med tidslås, bør descriptor-filen inngå i den samme planen, ikke behandles som et eget, løsere vedlegg.
Steg 12: Sett opp en periodisk verifiseringsrutine
Sett en fast påminnelse, for eksempel hver sjette måned, for å gjenta steg 6 og 7 med den lagrede backupen. Programvare endrer seg, lommebøker bytter leverandør, og en fil som fungerte for to år siden kan vise seg uforståelig for en nyere versjon av programvaren hvis formatet har driftet. Den periodiske testen er det som gjør at du vet, i stedet for tror, at gjenopprettingen fortsatt virker.
Spesielle hensyn ved arv, bedrifter og flerpersonoppsett
Alt over gjelder like mye om du er eneeier av en 2-av-3-multisig som om du deler terskelen med familie, forretningspartnere eller en arveplan. Forskjellen ligger i hvem som trenger tilgang til hvilken del av informasjonen, og når. I et rent personlig oppsett kan du trygt være den eneste som kjenner til både deskriptoren og alle seed-frasene. I en arveplan derimot må minst én annen person, typisk en arving eller en advokat, kunne finne og tolke descriptor-backupen etter at du selv ikke lenger kan forklare den.
Her lønner det seg å skrive en kort, separat instruksjon som følger descriptor-filen, der du forklarer hva en deskriptor er, hvilket oppsett den beskriver, og nøyaktig hvilke verktøy (Bitcoin Core, Sparrow, eller en spesifikk maskinvarelommebok) som kan lese den. Uten denne konteksten er en gyldig BIP-380-streng fortsatt ganske ubrukelig for en arving som aldri har sett en descriptor før. Kombiner dette med tidslåsen og fordelingen du allerede har beskrevet i arveoppsettet med multisig, slik at descriptor-filen havner i samme juridiske og praktiske plan som resten av arven, ikke som et teknisk vedlegg ingen vet hva de skal gjøre med.
For bedrifter som bruker multisig til en driftskonto eller en treasury, er det verdt å skille klart mellom hvem som har tilgang til watch-only-deskriptoren (for eksempel regnskapsavdelingen, som bare trenger å se saldo og historikk) og hvem som har tilgang til signeringskapable nøkler. En watch-only-deskriptor kan trygt deles bredere internt, siden den ikke kan flytte midler, mens tilgangen til faktiske signeringsnøkler bør holdes like begrenset som i dag.
Komplett fungerende prosjekt: valider deskriptoren din med Python
Under følger et komplett, kjørbart skript som automatiserer steg 4 til 7 for deg. Skriptet leser cosigner-fragmentene fra en lokal JSON-fil, bygger sortedmulti-deskriptoren, kaller Bitcoin Core for sjekksum og avledede adresser, og sammenligner resultatet mot et lagret øyeblikksbilde for å varsle om noe har endret seg siden forrige kjøring. Lagre filen som descriptor_check.py og kjør den med Python 3.10 eller nyere.
#!/usr/bin/env python3
import json
import subprocess
import sys
from pathlib import Path
CONFIG_FILE = Path("cosigners.json")
SNAPSHOT_FILE = Path("address_snapshot.json")
def run_bitcoin_cli(*args):
result = subprocess.run(
["bitcoin-cli", "-signet", *args],
capture_output=True, text=True, check=True
)
return json.loads(result.stdout)
def build_descriptor(cosigners, threshold, script_type="wsh"):
inner = ",".join(c["fragment"] for c in cosigners)
multi = f"sortedmulti({threshold},{inner})"
return f"{script_type}({multi})" if script_type != "wsh" else f"wsh({multi})"
def main():
config = json.loads(CONFIG_FILE.read_text())
descriptor = build_descriptor(config["cosigners"], config["threshold"])
info = run_bitcoin_cli("getdescriptorinfo", descriptor)
if not info.get("issolvable", False):
print("FEIL: deskriptoren er ikke losbar. Sjekk fragmentene.")
sys.exit(1)
full_descriptor = info["descriptor"]
print(f"Sjekksum OK: {full_descriptor.split('#')[-1]}")
receive = run_bitcoin_cli("deriveaddresses", full_descriptor, "[0,9]")
change_descriptor = full_descriptor.replace("/0/*", "/1/*")
change = run_bitcoin_cli("deriveaddresses", change_descriptor, "[0,9]")
current = {"receive": receive, "change": change}
if SNAPSHOT_FILE.exists():
previous = json.loads(SNAPSHOT_FILE.read_text())
if previous != current:
print("ADVARSEL: avledede adresser har endret seg siden forrige korsel!")
sys.exit(2)
print("Bekreftet: alle adresser matcher forrige snapshot.")
else:
print("Ingen tidligere snapshot funnet, lagrer dette som referanse.")
SNAPSHOT_FILE.write_text(json.dumps(current, indent=2))
if __name__ == "__main__":
main()
Konfigurasjonsfilen cosigners.json skal se slik ut, med ett fragment per cosigner:
{
"threshold": 2,
"cosigners": [
{"fragment": "[a1b2c3d4/48h/0h/0h/2h]xpub6DXnmdWp.../0/*"},
{"fragment": "[b5c6d7e8/48h/0h/0h/2h]xpub6ELkqR7t.../0/*"},
{"fragment": "[c9d0e1f2/48h/0h/0h/2h]xpub6FMowgU8.../0/*"}
]
}
Kjør skriptet mot en signet-node første gang for å etablere en referanse-snapshot, krypter deretter både konfigurasjonsfilen og snapshot-filen med samme gpg-kommando som i steg 8, og legg kjøringen inn i den periodiske rutinen fra steg 12. Hvis skriptet en dag feiler med advarselen i avsnitt to, har enten programvareversjonen din endret hvordan den tolker en range-descriptor, eller en av konfigurasjonsfilene er korrupt. Begge er verdt å undersøke umiddelbart, ikke ignorere.
Fem vanlige fallgruver ved deskriptor-backup
De fleste feilene i denne prosessen oppstår ikke fordi brukeren gjorde noe dramatisk feil, men fordi en liten detalj i en lang tekststreng ble oversett. Under følger de fem feilene som dukker opp oftest når folk setter opp descriptor-backup for første gang, basert på hvordan feilene typisk manifesterer seg i bitcoin-cli og i grensesnittene til Sparrow og Specter.
- Å blande fragmenter fra to ulike oppsett. Hvis du har flere multisig-lommebøker med enheter fra samme produsent, er det lett å kopiere feil fragment inn i riktig fil. Sjekk alltid fingeravtrykket mot enheten før du lagrer, og merk hver eksportert fil med navnet på oppsettet den hører til, ikke bare navnet på enheten.
- Å lagre descriptor og seed på samme fysiske sted. Da har du i praksis bare én backup, ikke to uavhengige. En descriptor har liten verdi hvis angriperen som fant den også fant seed-frasene i samme skuff eller safe.
- Å stole på en gyldig sjekksum som bevis på riktighet. Sjekksummen fanger opp skrivefeil, men den fanger ikke opp at du har limt inn feil xpub fra riktig produsent men feil enhet. Bare en faktisk adressesammenligning (steg 7) avdekker det, og det er derfor denne guiden insisterer på en reell testkjøring i stedet for bare en syntaktisk validering.
- Å hoppe over testkjøringen fordi “det ser riktig ut”. Syntaktisk gyldige deskriptorer med feil nøkkelrekkefølge, feil derivasjonssti eller feil scripttype ser akkurat like riktige ut som korrekte deskriptorer helt til du faktisk avleder adresser og sammenligner dem mot midler du vet eksisterer.
- Å glemme vekslingsgrenen. Mange tester bare mottaksadresser (sti 0/*) og antar at veksling (sti 1/*) fungerer på samme måte. Noen eldre lommebokeksporter bruker en annen notasjon for veksling, og det oppdages først når du faktisk trenger å bruke midlene og transaksjonen ikke finner vekslingsadressen.
- Å oppdatere én cosigners fastvare uten å eksportere på nytt. En fastvareoppgradering endrer normalt ikke nøkkelmaterialet, men enkelte produsenter har endret eksportformatet mellom versjoner. Hvis du oppgraderer en enhet, er det god praksis å eksportere fragmentet på nytt og kjøre validering (steg 4) igjen, i stedet for å anta at den gamle eksporten fortsatt er representativ.
Feilsøking: åtte problemer du kan møte på
De fleste feilmeldingene i denne prosessen er heldigvis informative nok til at du kan spore dem tilbake til et konkret steg. Tabellen under samler de problemene som dukker opp oftest, sammen med den vanligste årsaken og hvordan du retter det, slik at du slipper å feilsøke fra scratch hver gang.
| Problem | Sannsynlig årsak | Løsning |
|---|---|---|
| getdescriptorinfo returnerer “issolvable”: false | Feil antall nøkler i forhold til terskel, eller ugyldig xpub | Sjekk at antall fragmenter matcher det som står i sortedmulti(N,…), og valider hver xpub separat |
| Avledede adresser matcher ikke produksjonslommeboken | Feil derivasjonssti eller feil scripttype (wpkh vs wsh) | Gå tilbake til enhetens egen eksport og bekreft sti og scripttype direkte fra kildeenheten |
| importdescriptors feiler med JSON-parsefeil | Manglende escaping av anførselstegn i terminal | Lagre JSON-en i en egen fil og referer til filen i stedet for en inline-streng |
| Fingeravtrykket i fragmentet matcher ikke enheten | Fragment fra feil enhet eller feil lommebok ble kopiert inn | Eksporter fragmentet på nytt direkte fra riktig enhet og sammenlign fingeravtrykket manuelt |
| Sjekksum endrer seg hver gang du kjører getdescriptorinfo | Du limer inn deskriptoren med en gammel eller manuelt gjettet sjekksum i strengen | Fjern alt etter # før du sender strengen inn, og la Bitcoin Core beregne sjekksummen selv |
| Watch-only-lommeboken viser saldo 0 selv om midler finnes | Range i importdescriptors er for lite til å dekke brukte indekser | Øk range-verdien (for eksempel til [0,1000]) og kjør rescanblockchain |
| Python-skriptet feiler med FileNotFoundError på bitcoin-cli | bitcoin-cli ligger ikke i PATH, eller noden kjører med annet datakatalog-flagg | Bruk fullt filsti til bitcoin-cli, eller legg til -datadir i subprocess-kallet |
| gpg-dekryptering ber om passfrase du ikke kjenner | Forveksling mellom descriptor-passfrasen og seed-passfrasen (25. ord) | Bruk separate, tydelig merkede passordhvelv for hver passfrase, aldri gjenbruk mellom dem |
Avanserte tips: wallet policies, miniscript og maskinvareeksport
Når grunnarbeidet sitter, er neste nivå å se på BIP-388, som definerer wallet policies. En policy er en strukturert beskrivelse av nøkler og betingelser, designet for at en maskinvarelommebok skal kunne vise deg i klartekst hva du signerer, i stedet for bare en rå deskriptorstreng. Flere nyere maskinvarelommebøker støtter nå import og registrering av policies direkte på enheten, noe som gjør at enheten selv kan bekrefte at en innkommende signeringsforespørsel matcher det oppsettet den forventer, før den viser deg noe å godkjenne.
Praktisk betyr dette at hvis du registrerer en wallet policy på en maskinvarelommebok og senere kobler den til en koordinator-app som prøver å signere en transaksjon fra en annen policy enn den registrerte, vil enheten normalt varsle om avviket i stedet for å signere blindt. Dette er en reell forbedring sammenlignet med eldre flyter der enheten stolte fullstendig på hva koordinator-programvaren viste på skjermen, uten noen egen referanse å sjekke mot. Registrer derfor policyen på enheten så snart multisig-oppsettet er stabilt, og oppdater registreringen hvis du legger til eller fjerner en cosigner.
For mer avanserte oppsett enn standard sortedmulti kan du også se på miniscript, et språk for å bygge mer kompliserte spending-betingelser (for eksempel ulike terskler avhengig av tidslås) som fortsatt kan representeres som en gyldig BIP-380-deskriptor. D-Centrals referanseoversikt over BIP-380 til BIP-392 er et godt utgangspunkt hvis du vil gå videre enn den rene multisig-casen som er dekket her, for eksempel kombinasjoner med relativ tidslås for arveoppsett.
Et praktisk tips for Taproot-brukere: deskriptoren for en tr()-basert multisig ser annerledes ut enn wsh-varianten, og bruker en kombinasjon av en intern nøkkel og script-path-alternativer. Hvis du migrerer fra en eldre wsh-multisig til en Taproot-basert løsning, skal du behandle dette som et helt nytt oppsett, med sin egen deskriptor, sitt eget valideringsløp og sin egen testkjøring. Anta aldri at prosedyren fra den gamle scripttypen er direkte overførbar.
Et siste råd for de som drifter flere multisig-lommebøker samtidig: hold en egen, oppdatert oversikt over hvilken deskriptor-versjon som er aktiv for hvert oppsett, og dato for siste validerte test. Dette blir raskt uoverkommelig å huske fra minnet når antallet lommebøker passerer tre eller fire, og en enkel tabell i et kryptert dokument er langt mer pålitelig enn å stole på at du husker riktig sist du faktisk testet gjenoppretting for en bestemt lommebok.
Et siste punkt verdt å planlegge for er kompatibilitet mellom leverandører. Ikke alle lommebøker eksporterer eller importerer deskriptorer på nøyaktig samme måte, selv når de i teorien følger samme BIP. Noen inkluderer alltid sjekksummen i eksporten, andre lar deg legge den til selv. Noen bruker range-notasjonen <0;1>/* for å samle mottak og veksling i én descriptor, mens andre krever to separate deskriptorer, én per gren. Når du setter opp en multisig med enheter fra flere ulike produsenter, test derfor hele importkjeden i et watch-only-miljø før du flytter reelle midler inn, selv om hver enkelt leverandør hevder å støtte “standard BIP-380”.
Sjekkliste: er backupen din faktisk gjenopprettbar?
Før du regner multisig-oppsettet ditt som ferdig sikret, bør du kunne svare ja på alle punktene under. Dette er i praksis en kortversjon av de 12 stegene, samlet som en rask sjekk du kan ta igjen om noen måneder.
- Du har en samlet, validert deskriptor med korrekt sjekksum lagret, ikke bare individuelle xpub-fragmenter.
- Deskriptoren er bekreftet mot en ekte watch-only-import, med adresser som faktisk matcher produksjonslommeboken din.
- Både mottaks- og vekslingsgrenen er testet, ikke bare den første.
- Deskriptor-backupen ligger fysisk et annet sted enn seed-backupen, og begge er kryptert med ulike passfraser.
- Du eller en annen involvert part har gjennomført en full, tidsmålt gjenopprettingsøvelse uten å se på gamle notater.
- Hver fysiske kopi er merket med om den er watch-only eller signeringskapabel.
- Du har satt en fast, tilbakevendende påminnelse for å gjenta testen, ikke bare gjort den én gang ved oppsett.
Deskriptorer versus seed-fraser: hva bør du egentlig lagre?
De to formatene løser ulike problemer, og svaret er ikke å velge én av dem. Tabellen under oppsummerer hva hver av dem faktisk dekker.
| Egenskap | Seed-frase (BIP-39) | BIP-380-deskriptor |
|---|---|---|
| Beskriver nøkkelmateriale for | Én enkelt signerer | Alle cosignere i oppsettet samlet |
| Inneholder scripttype (wpkh/wsh/tr) | Nei | Ja |
| Inneholder terskel (f.eks. 2-av-3) | Nei | Ja, i sortedmulti(N,…) |
| Kan være rent watch-only | Nei, representerer alltid en signeringsnøkkel | Ja, hvis kun offentlige nøkler er inkludert |
| Tilstrekkelig alene for enkeltsignatur-lommebok | Ja | Ja, men uten private nøkler kan den ikke signere |
| Tilstrekkelig alene for multisig-gjenoppretting | Nei, mangler policy for de andre signererne | Ja, kombinert med de nødvendige private nøklene |
Konklusjonen av tabellen er enkel å følge: for enkeltsignatur-lommebøker holder seed-frasen alene lenge, fordi en god Shamir-delt backup allerede dekker gjenoppretting. For multisig derimot må du lagre begge deler, seed for hver signerer og en egen, validert deskriptor for hele policyen. Det er nettopp kombinasjonen som manglet i tilfellene denne artikkelen startet med, der brukere satt med gyldige nøkler men ingen fungerende vei tilbake til midlene.
Ofte stilte spørsmål
Må jeg ha en deskriptor hvis jeg bare bruker en enkel, enkeltsignatur-lommebok?
Nei. For enkeltsignatur holder en god seed-backup normalt lenge, siden det ikke finnes noen cosigner-policy å miste. Deskriptorer blir viktige først når flere nøkler, flere scripttyper eller flere derivasjonsstier er involvert.
Kan en deskriptor stjeles og brukes til å tømme lommeboken min?
En rent offentlig deskriptor (uten private nøkler) kan ikke brukes til å flytte midler, men den avslører hvor mange midler lommeboken har og hvilken struktur den bruker. Behandle den som sensitiv informasjon selv om den ikke er direkte like kritisk som seeden.
Hvorfor matchet ikke adressene mine selv om sjekksummen var gyldig?
En gyldig sjekksum beviser bare at teksten ikke har transkripsjonsfeil, ikke at innholdet beskriver riktig lommebok. Feil derivasjonssti, feil scripttype eller feil nøkkelrekkefølge gir alle en gyldig, men feil, deskriptor.
Bør jeg lagre deskriptoren i samme safe som seed-frasene?
Nei, prinsippet er motsatt. Lagre dem fysisk separat, slik at én hendelse (brann, innbrudd, vannskade) ikke rammer begge samtidig. Krypter begge, men med ulike passfraser.
Fungerer denne fremgangsmåten også for Taproot-multisig (tr())?
Prinsippene er de samme, men selve deskriptor-syntaksen er annerledes for tr()-baserte oppsett. Behandle en Taproot-migrering som et eget prosjekt med sin egen testkjøring, ikke som en enkel variant av wsh-oppsettet.
Hvor ofte bør jeg teste gjenopprettingen på nytt?
Minimum hver sjette måned, og alltid etter at du har byttet ut en av maskinvarelommebøkene eller oppgradert programvaren som holder deskriptoren. Programvare drifter over tid, og en prosedyre som fungerte for et år siden er ikke garantert å fungere i dag.
Hva skjer hvis jeg har mistet descriptor-filen men fortsatt har alle seed-frasene?
Du kan i mange tilfeller rekonstruere deskriptoren manuelt ved å eksportere fragmenter på nytt fra hver enhet, forutsatt at du fortsatt har tilgang til dem og vet terskelen og scripttypen. Dette er nettopp grunnen til at steg 1 i denne guiden (kartlegging) er så viktig å dokumentere separat.
Kan jeg bruke denne metoden sammen med en DAO-treasury eller et Safe-oppsett?
De underliggende prinsippene om separat lagring og testet gjenoppretting gjelder også der, men Safe-baserte oppsett bruker smartkontrakter på Ethereum i stedet for Bitcoin-descriptors, og har derfor sin egen gjenopprettingslogikk som ikke er identisk med det som er beskrevet her.
Trenger jeg Bitcoin Core, eller holder det med en lommebok-app på mobilen?
Du kan validere og teste med en app som Sparrow eller Specter alene, men å kjøre en egen Bitcoin Core-node i signet-modus gir deg full kontroll over testmiljøet og lar deg bruke Python-skriptet i denne guiden direkte via bitcoin-cli, uten å være avhengig av en tredjeparts-API.
Hva om cosignerne mine bruker forskjellige lommebokmerker?
Det er et vanlig oppsett og fungerer fint, siden descriptor-formatet er merkeuavhengig. Du må likevel kontrollere at hver enhet eksporterer fragmentet i et format Bitcoin Core eller Sparrow faktisk gjenkjenner, siden eksportformatet kan variere litt mellom produsenter selv når alle følger BIP-380.
Kan jeg gjøre hele denne prosessen uten å eie en egen Bitcoin Core-node?
Ja, i stor grad. Sparrow Wallet har innebygd støtte for descriptor-import, sjekksumvalidering og adresseavledning i et grafisk grensesnitt, og kan kobles til en ekstern node eller til Sparrows egen Electrum-server i stedet for en node du drifter selv. Python-skriptet i denne guiden er likevel enklest å kjøre mot en lokal bitcoin-cli, siden det gir deg full kontroll over hvilken node og hvilket nettverk (signet, testnet eller mainnet) kommandoene kjører mot.
