From a4901b7efaeb162c8948f0bc835a70a8050918c5 Mon Sep 17 00:00:00 2001 From: timlucmiptev Date: Fri, 16 Oct 2020 14:02:55 +0300 Subject: [PATCH] bech32 uses real address type checks --- bippy-scratch.md | 8 ++++---- lib/btc.hoon | 45 ++++++++++++++++++++++++--------------------- sur/btc.hoon | 2 +- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/bippy-scratch.md b/bippy-scratch.md index b58f65c690..79fdf0c759 100644 --- a/bippy-scratch.md +++ b/bippy-scratch.md @@ -151,22 +151,22 @@ The below code also shows how to convert from bech32 back to a 20-byte hash. Thi ``` =pubkey 0x2.79be.667e.f9dc.bbac.55a0.6295.ce87.0b07.029b.fcdb.2dce.28d9.59f2.815b.16f8.1798 (encode-pubkey:bech32:btc %main pubkey) -:: should be [~ "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"] +:: gives [~ %bech32 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4'] `[@ @ux]`(hash-160:btc pubkey) :: gives [20 0x751e.76e8.1991.96d4.5494.1c45.d1b3.a323.f143.3bd6] (encode-hash-160:bech32:btc %main (hash-160:btc pubkey)) -:: gives [~ "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"] +:: gives [~ %bech32 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4'] ``` ### Decode Bech32 to hex Return val as `byts` to preserve leading zeros. ``` -(decode-raw:bech32:btc "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4") +(decode-raw:bech32:btc [%bech32 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4']) :: prints data: ~[0 14 20 15 7 13 26 0 25 18 6 11 13 8 21 4 20 3 17 2 29 3 12 29 3 4 15 24 20 6 14 30 22] -`[@ @ux]`(to-hex:bech32:btc "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4") +(to-hex:bech32:btc [%bech32 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4']) :: gives [20 0x751e.76e8.1991.96d4.5494.1c45.d1b3.a323.f143.3bd6] ``` diff --git a/lib/btc.hoon b/lib/btc.hoon index b3791fe471..23187e9bc3 100644 --- a/lib/btc.hoon +++ b/lib/btc.hoon @@ -24,17 +24,17 @@ %- sha256 [(met 3 pubkey) pubkey] :: ++ to-script-pubkey - |= script=buffer:tx ^- buffer:tx + |= script=^buffer ^- ^buffer %- zing :~ ~[0x19 0x76 0xa9 0x14] script ~[0x88 0xac] == ++ address-to-script-pubkey - |= =address ^- buffer:tx + |= =address ^- ^buffer ?. ?=(%bech32 -.address) ~|("Only bech32 addresses supported right now" !!) - =/ hex=byts (to-hex:bech32 (trip +.address)) + =/ hex=byts (to-hex:bech32 address) ?. =(wid.hex 20) ~|("Only 20-byte P2WPKH bech32 supported" !!) (to-script-pubkey (from-byts:buffer hex)) @@ -44,7 +44,7 @@ ++ buffer |% ++ from-byts - |= =byts ^- buffer:tx + |= =byts ^- ^buffer =/ b=(list @ux) (flop (rip 3 dat.byts)) =/ pad=@ (sub wid.byts (lent b)) @@ -54,16 +54,16 @@ :: 0xff11 with wid=8 becomes ~[0x11 0xff 0x0 0x0 0x0 0x0 0x0 0x0] :: ++ from-atom-le - |= [wid=@ a=@] ^- buffer:tx + |= [wid=@ a=@] ^- ^buffer =/ b=(list @ux) (rip 3 a) =/ pad=@ (sub wid (lent b)) (weld b (reap pad 0x0)) :: ++ to-byts - |= b=buffer:tx ^- byts + |= b=^buffer ^- byts [(lent b) (rep 3 (flop b))] ++ concat-as-byts - |= bs=(list buffer:tx) ^- byts + |= bs=(list ^buffer) ^- byts %- to-byts (zing bs) -- :: @@ -71,17 +71,17 @@ =, buffer |_ ut=unsigned:tx ++ prevouts-buffer - |= =input:tx ^- buffer:tx + |= =input:tx ^- ^buffer %+ weld (from-byts tx-hash.input) (from-atom-le 4 witness-ver.input) :: ++ sequence-buffer - |= =input:tx ^- buffer:tx + |= =input:tx ^- ^buffer (from-byts sequence.input) :: ++ outputs-buffer - |= =output:tx ^- buffer:tx + |= =output:tx ^- ^buffer %+ weld (from-atom-le 8 value.output) (address-to-script-pubkey address.output) @@ -104,11 +104,13 @@ (turn inputs.ut sequence-buffer) =/ outputs=byts %- concat-as-byts (turn outputs.ut outputs-buffer) - =/ script-code=buffer:tx + :: all the variables + =/ script-code=^buffer %- to-script-pubkey (slag 2 (from-byts script-pubkey.input)) - =/ amount=buffer:tx + =/ amount=^buffer (from-atom-le 8 value.input) + =/ n-sequence=^buffer (sequence-buffer input) ~& > [prevouts=(dsha256 prevouts) sequences=(dsha256 sequences) outputs=(dsha256 outputs)] [0 0x0] :: @@ -243,14 +245,16 @@ :: ++ encode-raw |= [hrp=tape data=(list @)] - ^- tape + ^- bech32-address =/ combined=(list @) - (weld data (checksum hrp data)) + (weld data (checksum hrp data)) + :- %bech32 + %- crip (zing ~[hrp "1" (tape (murn combined value-to-charset))]) ++ decode-raw - |= bech=tape + |= b=bech32-address ^- (unit raw-decoded) - =. bech (cass bech) :: to lowercase + =/ bech (cass (trip +.b)) :: to lowercase =/ pos (flop (fand "1" bech)) ?~ pos ~ =/ last-1=@ i.pos @@ -271,9 +275,8 @@ :: goes from a bech32 address to hex. Returns byts to preserve leading 0s :: ++ to-hex - |= bech=tape - ^- byts - =/ d=(unit raw-decoded) (decode-raw bech) + |= b=bech32-address ^- hash + =/ d=(unit raw-decoded) (decode-raw b) ?~ d ~|("Invalid bech32 address" !!) =/ bs=(list @) (from-digits:bits 5 (slag 1 data.u.d)) @@ -284,7 +287,7 @@ :: ++ encode-pubkey |= [=network pubkey=@ux] - ^- (unit tape) + ^- (unit bech32-address) ?. =(33 (met 3 pubkey)) ~|('pubkey must be a 33 byte ECC compressed public key' !!) =/ prefix (~(get by prefixes) network) @@ -294,7 +297,7 @@ [0 (convert:bits 5 (zeros-brip:bits 160 dat:(hash-160 pubkey)))] ++ encode-hash-160 |= [=network h160=byts] - ^- (unit tape) + ^- (unit bech32-address) =/ prefix (~(get by prefixes) network) ?~ prefix ~ :- ~ diff --git a/sur/btc.hoon b/sur/btc.hoon index 3da5371515..c6a77a32c2 100644 --- a/sur/btc.hoon +++ b/sur/btc.hoon @@ -5,9 +5,9 @@ +$ address ?(legacy-address bech32-address) +$ sats @ud +$ hash [wid=@ dat=@ux] ++$ buffer (list @ux) ++ tx |% - +$ buffer (list @ux) +$ unsigned $: inputs=(list input) outputs=(list output)