address derivation for BIP84 works

This commit is contained in:
timlucmiptev 2020-10-30 13:45:38 +02:00 committed by ixv
parent 66f59fab83
commit 84cca6d26f
7 changed files with 142 additions and 87 deletions

View File

@ -23,10 +23,6 @@ abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon
```
=b -build-file %/lib/btc-scratch/hoon
=xpub "zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs"
```
### Getting BIP84 Address from `xpub`
```
(~(address bip84:b %main xpub))
```
@ -188,13 +184,12 @@ Using [BIP 143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#P
Native P2WPKH
```
=btc -build-file %/lib/btc/hoon
=btcs -build-file %/sur/btc/hoon
=input0 (input:tx:btcs [[32 0xfff7.f788.1a80.99af.a694.0d42.d1e7.f636.2bec.3817.1ea3.edf4.3354.1db4.e4ad.969f] 0 0 [4 0xeeff.ffff] [35 0x21.03c9.f483.6b9a.4f77.fc0d.81f7.bcb0.1b7f.1b35.9168.64b9.476c.241c.e9fc.198b.d254.32ac] ~ ~ 625.000.000])
=input1 (input:tx:btcs [[32 0xef51.e1b8.04cc.89d1.82d2.7965.5c3a.a89e.815b.1b30.9fe2.87d9.b2b5.5d57.b90e.c68a] 0 1 [4 0xffff.ffff] [22 0x14.1d0f.172a.0ecb.48ae.e1be.1f26.87d2.963a.e33f.71a1] ~ `[33 0x2.5476.c2e8.3188.368d.a1ff.3e29.2e7a.cafc.db35.66bb.0ad2.53f6.2fc7.0f07.aeee.6357] 600.000.000])
=input0 (input:tx:btc [[32 0xfff7.f788.1a80.99af.a694.0d42.d1e7.f636.2bec.3817.1ea3.edf4.3354.1db4.e4ad.969f] 0 0 [4 0xeeff.ffff] [35 0x21.03c9.f483.6b9a.4f77.fc0d.81f7.bcb0.1b7f.1b35.9168.64b9.476c.241c.e9fc.198b.d254.32ac] ~ ~ 625.000.000])
=input1 (input:tx:btc[[32 0xef51.e1b8.04cc.89d1.82d2.7965.5c3a.a89e.815b.1b30.9fe2.87d9.b2b5.5d57.b90e.c68a] 0 1 [4 0xffff.ffff] [22 0x14.1d0f.172a.0ecb.48ae.e1be.1f26.87d2.963a.e33f.71a1] ~ `[33 0x2.5476.c2e8.3188.368d.a1ff.3e29.2e7a.cafc.db35.66bb.0ad2.53f6.2fc7.0f07.aeee.6357] 600.000.000])
=output0 (output:tx:btcs [[%bech32 'bc1qs2qtxl0n0rdenan0shy457p6w6k85m2e36f7ze'] 112.340.000])
=output1 (output:tx:btcs [[%bech32 'bc1q800y9klw0exmu63pkt2sechszel64q2enddkt4'] 223.450.000])
=utx (unsigned:tx:btcs [1 0x11 ~[input0 input1] ~[output0 output1]])
=output0 (output:tx:btc [[%bech32 'bc1qs2qtxl0n0rdenan0shy457p6w6k85m2e36f7ze'] 112.340.000])
=output1 (output:tx:btc [[%bech32 'bc1q800y9klw0exmu63pkt2sechszel64q2enddkt4'] 223.450.000])
=utx (unsigned:tx:btc [1 0x11 ~[input0 input1] ~[output0 output1]])
(~(sighash unsigned-tx:btc utx) 1)
:: gives [wid=32 dat=0xc37a.f311.16d1.b27c.af68.aae9.e3ac.82f1.4779.2901.4d5b.9176.57d0.eb49.478c.b670]
@ -230,9 +225,9 @@ Signing input index 0 (non-witness)
### A sample legacy address-only transaction
```
=linput0 (input:tx:btcs [[32 0xeccf.7e30.3418.9b85.1985.d871.f913.84b8.ee35.7cd4.7c30.2473.6e56.76eb.2deb.b3f2] 1 0 [4 0xffff.ffff] [25 0x76.a914.0109.6677.6006.953d.5567.439e.5e39.f86a.0d27.3bee.88ac] ~ ~ 100.000.000])
=loutput0 (output:tx:btcs [[%legacy 0c1runeksijzfVxyrpiyCY2LCBvYsSiFsCm] 99.900.000])
=lutx (unsigned:tx:btcs [1 0x0 ~[linput0] ~[loutput0]])
=linput0 (input:tx:btc [[32 0xeccf.7e30.3418.9b85.1985.d871.f913.84b8.ee35.7cd4.7c30.2473.6e56.76eb.2deb.b3f2] 1 0 [4 0xffff.ffff] [25 0x76.a914.0109.6677.6006.953d.5567.439e.5e39.f86a.0d27.3bee.88ac] ~ ~ 100.000.000])
=loutput0 (output:tx:btc [[%legacy 0c1runeksijzfVxyrpiyCY2LCBvYsSiFsCm] 99.900.000])
=lutx (unsigned:tx:btc [1 0x0 ~[linput0] ~[loutput0]])
=lh dat:(~(sighash unsigned-tx:btc lutx) 0)
=lprivkey 0x18e1.4a7b.6a30.7f42.6a94.f811.4701.e7c8.e774.e7f9.a47e.2c20.35db.29a2.0632.1725

70
WALLET.scratch.md Normal file
View File

@ -0,0 +1,70 @@
# btc-wallet-* Scratch Code
## xpub
```
=xpub1 "zpub6r8dKyWJ31XF6n69KKeEwLjVC5ruqAbiJ4QCqLsrV36Mvx9WEjUaiPNPGFLHNCCqgCdy6iZC8ZgHsm6a1AUTVBMVbKGemNcWFcwBGSjJKbD"
=xpub2 "xpub6D7yaZieZEeG617UcKXDhbsDeso6bmxSAiGWkvkASoiwcjaRtrH5HeNRnDT25s7zmxYzj6MtFe32dVqcf9YcBKKgn9THHjwn2uSjkvobK4e"
=bl -build-file %/lib/btc-wallet-store/hoon
```
### add
```
:btc-wallet-store|action [%add-wallet xpub ~ ~]
```
### get address at indices
```
=walt1 (from-xpub:walt:bl xpub1 ~ ~)
=walt2 (from-xpub:walt:bl xpub2 ~ ~)
(get-address:walt1 %0 0)
(get-address:walt2 %0 0)
```
## scratch code, refactor
++ update-address
|= [a=address:btc us=(set utxo)]
^- (quip card _state)
=/ xpubs=(list tape)
%~ tap in
~(key by walts.state)
|- ?~ xpubs `state
=/ w=walt (~(got by walts.state) i.xpubs)
?: (~(has by wach.w) a)
%: send-address-update
i.xpubs
(update-wallet w a us)
a
us
==
$(xpubs t.xpubs)
::
++ update-wallet
|= [w=walt a=address:btc us=(set utxo)]
^- walt
=/ curr-addi=addi
(~(got by wach.w) a)
w(wach (~(put by wach.w) a curr-addi(used %.y, utxos us)))
::
++ send-address-update
|= [xpub=tape =walt a=address:btc us=(set utxo)]
^- (quip card _state)
:_ state(walts (~(put by walts.state) xpub walt))
~[[%give %fact ~[/wallets] %btc-wallet-store-update !>([%address a us])]]
::
++ add-wallet
|= [xpub=tape scan-to=(unit scon) max-gap=(unit @)]
^- (quip card _state)
?: (~(has by walts.state) xpub)
~& >>> "xpub already imported"
`state
=/ wallet=walt
:* (from-extended:bip32 xpub)
(xpub-type:btc xpub)
*wach
[0 0]
%.n
(fall scan-to *scon)
(fall max-gap max-gap.state)
==
`state(walts (~(put by walts.state) xpub wallet))

View File

@ -6,7 +6,7 @@
:: watched address updates
::
/- *btc-wallet-store
/+ dbug, default-agent, bip32, btc
/+ dbug, default-agent, *btc-wallet-store, btc, bip32
|%
+$ versioned-state
$% state-0
@ -73,55 +73,11 @@
^- (quip card _state)
?- -.act
%add-wallet
(add-wallet +.act)
`state
:: (add-wallet +.act)
::
%update-address
(update-address +.act)
==
++ update-address
|= [a=address us=(set utxo)]
^- (quip card _state)
=/ xpubs=(list tape)
%~ tap in
~(key by walts.state)
|- ?~ xpubs `state
=/ w=walt (~(got by walts.state) i.xpubs)
?: (~(has by wach.w) a)
%: send-address-update
i.xpubs
(update-wallet w a us)
a
us
==
$(xpubs t.xpubs)
::
++ update-wallet
|= [w=walt a=address us=(set utxo)]
^- walt
=/ curr-addi=addi
(~(got by wach.w) a)
w(wach (~(put by wach.w) a curr-addi(used %.y, utxos us)))
::
++ send-address-update
|= [xpub=tape =walt a=address us=(set utxo)]
^- (quip card _state)
:_ state(walts (~(put by walts.state) xpub walt))
~[[%give %fact ~[/wallets] %btc-wallet-store-update !>([%address a us])]]
::
++ add-wallet
|= [xpub=tape scan-to=(unit scon) max-gap=(unit @)]
^- (quip card _state)
?: (~(has by walts.state) xpub)
~& >>> "xpub already imported"
`state
=/ wallet=walt
:* (from-extended:bip32 xpub)
(xpub-type:btc xpub)
*wach
[0 0]
%.n
(fall scan-to *scon)
(fall max-gap max-gap.state)
==
`state(walts (~(put by walts.state) xpub wallet))
:: (update-address +.act)
==
--

42
lib/btc-wallet-store.hoon Normal file
View File

@ -0,0 +1,42 @@
/- *btc-wallet-store
/+ bip32, btc
=, secp:crypto
=+ ecc=secp256k1
|%
++ default-max-gap 20
:: xpub
:: wilt
:: bipt: BIP44/49/84
:: wach
:: next: next index to generate address for in non-change/change accounts respectively
:: scanned: whether the wallet's addresses have been checked for prior activity
:: if unscanned, 'next' values won't be valid
:: scan-to
:: max-gap
::
++ walt
|_ [=wilt =bipt =wach next=idxs scanned=? scan-to=scon max-gap=@u]
++ from-xpub
|= [xpub=tape scan-to=(unit scon) max-gap=(unit @u)]
%= +>
wilt (from-extended:bip32 xpub)
bipt (xpub-type:btc xpub)
wach *^wach
next [0 0]
scanned %.n
scan-to (fall scan-to *scon)
max-gap (fall max-gap default-max-gap)
==
++ get-address
|= [=chyg idx=@]
^- address:btc
=/ pubkey=@ux
%- compress-point:ecc
pub:(derive-public:(derive-public:wilt (@u chyg)) idx)
~& > pubkey
?: ?=(%bip84 bipt)
(need (encode-pubkey:bech32:btc %main pubkey))
:: [%legacy (@uc pubkey)]
~|("legacy addresses not supported yet" !!)
--
--

View File

@ -1,4 +1,7 @@
/- *btc
/- sur=btc
^?
=< [sur .]
=, sur
|%
++ xpub-type
|= xpub=tape
@ -264,6 +267,7 @@
(my [[%main "bc"] [%testnet "tb"] ~])
++ charset "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
+$ raw-decoded [hrp=tape data=(list @) checksum=(list @)]
:: below is a port of: https://github.com/bitcoinjs/bech32/blob/master/index.js
::
++ polymod
|= values=(list @)

View File

@ -5,39 +5,27 @@
/- *btc
/+ bip32
|%
:: chyg: stores the state of a change/non-change path
++ max-index (dec (pow 2 32))
:: chyg: whether account is non-change/change
:: idxs: pair of indices (non-change/change)
:: addi: address with metadata inside a change path
:: wach: map for watched addresses
:: scon: indices to initially scan to in non-change/change accounts respectively
:: defaults to 2^32-1 (i.e. all the addresses)
:: defaults to 2^32-1 (i.e. all the addresses, ~4B)
:: wilt: stores xpub; copulates with thousands of indices to form addresses
:: walt: wallet metadata
::
+$ chyg $?(%0 %1)
+$ addi [=chyg idx=@ used=? utxos=(set utxo)]
+$ idxs (pair @u @u)
+$ addi [=chyg idx=@u used=? utxos=(set utxo)]
+$ wach (map address addi)
++ max-index (dec (pow 2 32))
+$ scon $~([max-index max-index] (pair @ @))
+$ scon $~([max-index max-index] idxs)
+$ wilt _bip32
+$ walt
$: :: bipt: BIP44/49/84
:: next: next index to generate address for in non-change/change accounts respectively
:: scanned: whether the wallet's addresses have been checked for prior activity
:: if unscanned, 'next' values won't be valid
::
=wilt
=bipt
=wach
next=(pair @ @)
scanned=?
scan-to=scon
max-gap=@
==
+$ action
$% [%add-wallet xpub=tape scan-to=(unit scon) max-gap=(unit @)]
[%update-address =address utxos=(set utxo)]
+$ action
$% [%add-wallet xpub=tape scan-to=(unit scon) max-gap=(unit @u)]
[%update-address a=address utxos=(set utxo)]
==
+$ update
$% [%address =address utxos=(set utxo)]
$% [%address a=address utxos=(set utxo)]
==
--

View File

@ -4,7 +4,7 @@
+$ bech32-address $%([%bech32 cord])
+$ address ?(legacy-address bech32-address)
+$ bipt $?(%bip44 %bip49 %bip84)
+$ sats @ud ::
+$ sats @ud
+$ hash256 [wid=%32 dat=@ux]
+$ hash160 [wid=%20 dat=@ux]
+$ hash ?(hash256 hash160)