Skip to content

Commit 802cb7a

Browse files
committed
feat(cose): serialize pkh+sh addresses, set "address" map entry size
1 parent f7c59e5 commit 802cb7a

File tree

2 files changed

+75
-27
lines changed

2 files changed

+75
-27
lines changed

src/HydraAuctionOnchain/Lib/Cose.hs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,21 @@ module HydraAuctionOnchain.Lib.Cose
55
import HydraAuctionOnchain.Lib.Serialization (pserializeAddress)
66
import Plutarch.Api.V2 (PAddress)
77
import Plutarch.Extra.Maybe (pjust, pnothing)
8+
import Plutarch.Monadic qualified as P
89

910
pmkSigStructure :: Term s (PAddress :--> PByteString :--> PByteString :--> PMaybe PByteString)
1011
pmkSigStructure = phoistAcyclic $
1112
plam $ \addr payload payloadLength -> P.do
1213
pmatch (pserializeAddress # addr) $ \case
1314
PNothing -> pnothing
14-
PJust addrBytes ->
15+
PJust addrSerialized -> P.do
16+
addrSerializedFields <- pletFields @["addrCbor", "addrMapEntrySize"] addrSerialized
1517
pjust
1618
# mconcat
1719
[ phexByteStr "846a5369676e61747572653158"
18-
, phexByteStr "46" -- FIXME
19-
, phexByteStr "A201276761646472657373"
20-
, addrBytes
20+
, addrSerializedFields.addrMapEntrySize
21+
, phexByteStr "A201276761646472657373" -- 61646472657373 = "address"
22+
, addrSerializedFields.addrCbor
2123
, phexByteStr "4058"
2224
, payloadLength
2325
, payload

src/HydraAuctionOnchain/Lib/Serialization.hs

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,77 +7,123 @@ import Plutarch.Api.V2
77
( PAddress
88
, PMaybeData (PDJust, PDNothing)
99
, PPubKeyHash
10+
, PScriptHash
1011
, PStakingCredential (PStakingHash, PStakingPtr)
1112
)
13+
import Plutarch.DataRepr (PDataFields)
1214
import Plutarch.Extra.Maybe (pjust, pnothing)
1315
import Plutarch.Monadic qualified as P
1416

1517
data PAddressConfiguration (s :: S)
1618
= PAddressConfig'PaymentKeyHash'StakeKeyHash (Term s PPubKeyHash) (Term s PPubKeyHash)
19+
| PAddressConfig'PaymentKeyHash'ScriptHash (Term s PPubKeyHash) (Term s PScriptHash)
1720
| PAddressConfig'PaymentKeyHash (Term s PPubKeyHash)
1821
deriving stock (Generic)
1922
deriving anyclass (PlutusType, PShow, PEq)
2023

2124
instance DerivePlutusType PAddressConfiguration where
2225
type DPTStrat _ = PlutusTypeScott
2326

24-
pserializeAddress :: Term s (PAddress :--> PMaybe PByteString)
27+
data PSerializedAddress (s :: S)
28+
= PSerializedAddress
29+
( Term
30+
s
31+
( PDataRecord
32+
'[ "addrCbor" ':= PByteString
33+
, "addrMapEntrySize" ':= PByteString
34+
]
35+
)
36+
)
37+
deriving stock (Generic)
38+
deriving anyclass (PlutusType, PIsData, PDataFields, PShow, PEq)
39+
40+
instance DerivePlutusType PSerializedAddress where
41+
type DPTStrat _ = PlutusTypeData
42+
43+
pserializeAddress :: Term s (PAddress :--> PMaybe PSerializedAddress)
2544
pserializeAddress = phoistAcyclic $
2645
plam $ \addr ->
2746
pmatch (pmkAddrConfig # addr) $ \case
2847
PNothing -> pnothing
29-
PJust addrConfig ->
30-
pjust
31-
# mconcat
32-
[ phexByteStr "58" -- byte string (one-byte uint8_t for n, and then n bytes follow)
33-
, paddrConfigAddrSize # addrConfig
34-
, paddrConfigAddrHeaderForTestnet # addrConfig
35-
, paddrConfigAddrBody # addrConfig
36-
]
48+
PJust addrConfig -> P.do
49+
PPair addrSize addrMapEntrySize <- pmatch $ paddrConfigAddrSize # addrConfig
50+
addrCbor <-
51+
plet $
52+
mconcat
53+
[ phexByteStr "58" -- byte string (one-byte uint8_t for n, and then n bytes follow)
54+
, addrSize
55+
, paddrConfigAddrHeaderForTestnet # addrConfig
56+
, paddrConfigAddrBody # addrConfig
57+
]
58+
pjust #$ pcon $
59+
PSerializedAddress $
60+
pdcons # pdata addrCbor #$ pdcons # pdata addrMapEntrySize # pdnil
3761

3862
pmkAddrConfig :: Term s (PAddress :--> PMaybe PAddressConfiguration)
3963
pmkAddrConfig = phoistAcyclic $
4064
plam $ \addr -> P.do
4165
creds <- pletFields @["credential", "stakingCredential"] addr
4266
pmatch creds.credential $ \case
4367
PScriptCredential _ -> pnothing
44-
PPubKeyCredential rec -> P.do
45-
let pkh = pfield @"_0" # rec
68+
PPubKeyCredential pkhRec -> P.do
69+
let pkh = pfield @"_0" # pkhRec
4670
pmatch creds.stakingCredential $ \case
4771
PDNothing _ -> pjust # pcon (PAddressConfig'PaymentKeyHash pkh)
48-
PDJust rec ->
49-
pmatch (pfield @"_0" # rec) $ \case
50-
PStakingHash rec ->
51-
pmatch (pfield @"_0" # rec) $ \case
52-
PScriptCredential _ -> pnothing
53-
PPubKeyCredential rec -> P.do
54-
let skh = pfield @"_0" # rec
72+
PDJust stakingCredRec ->
73+
pmatch (pfield @"_0" # stakingCredRec) $ \case
74+
PStakingHash stakingHashRec ->
75+
pmatch (pfield @"_0" # stakingHashRec) $ \case
76+
PScriptCredential shRec -> P.do
77+
let sh = pfield @"_0" # shRec
78+
pjust # pcon (PAddressConfig'PaymentKeyHash'ScriptHash pkh sh)
79+
PPubKeyCredential skhRec -> P.do
80+
let skh = pfield @"_0" # skhRec
5581
pjust # pcon (PAddressConfig'PaymentKeyHash'StakeKeyHash pkh skh)
5682
PStakingPtr _ -> pnothing
5783

58-
paddrConfigAddrSize :: Term s (PAddressConfiguration :--> PByteString)
84+
-- Get hex-encoded size for given address configuration.
85+
--
86+
-- PaymentKeyHash, StakeKeyHash, and ScriptHash are blake2b-224 hash
87+
-- digests and all have size of 224 bits (28 bytes).
88+
-- https://github.com/cardano-foundation/CIPs/blob/d66f7d0a0bcd06c425a6b7a41c6d18c922deff7e/CIP-0019/README.md?plain=1#L95-L97
89+
paddrConfigAddrSize :: Term s (PAddressConfiguration :--> PPair PByteString PByteString)
5990
paddrConfigAddrSize = phoistAcyclic $
6091
plam $ \addrConfig ->
6192
pmatch addrConfig $ \case
6293
PAddressConfig'PaymentKeyHash'StakeKeyHash _ _ ->
63-
phexByteStr "39" -- 57 = 1 (header) + 28 (pkh) + 28 (skh)
94+
-- 0x39 = 57 = 1 (header) + 28 (pkh) + 28 (skh)
95+
pcon $ PPair (phexByteStr "39") (phexByteStr "46")
96+
PAddressConfig'PaymentKeyHash'ScriptHash _ _ ->
97+
-- 0x39 = 57 = 1 (header) + 28 (pkh) + 28 (sh)
98+
pcon $ PPair (phexByteStr "39") (phexByteStr "46")
6499
PAddressConfig'PaymentKeyHash _ ->
65-
phexByteStr "1D" -- 29 = 1 (header) + 28 (pkh)
100+
-- 0x1D = 29 = 1 (header) + 28 (pkh)
101+
pcon $ PPair (phexByteStr "1D") (phexByteStr "2A")
66102

103+
-- Get hex-encoded network tag + header type for given address
104+
-- configuration.
105+
-- https://github.com/cardano-foundation/CIPs/blob/d66f7d0a0bcd06c425a6b7a41c6d18c922deff7e/CIP-0019/README.md?plain=1#L70-L93
67106
paddrConfigAddrHeaderForTestnet :: Term s (PAddressConfiguration :--> PByteString)
68107
paddrConfigAddrHeaderForTestnet = phoistAcyclic $
69108
plam $ \addrConfig ->
70109
pmatch addrConfig $ \case
71110
PAddressConfig'PaymentKeyHash'StakeKeyHash _ _ ->
72-
phexByteStr "00" -- 0b0000_0000
111+
-- 0x00 = 0b0000_0000
112+
phexByteStr "00"
113+
PAddressConfig'PaymentKeyHash'ScriptHash _ _ ->
114+
-- 0x20 = 0b0010_0000
115+
phexByteStr "20"
73116
PAddressConfig'PaymentKeyHash _ ->
74-
phexByteStr "60" -- 0b0110_0000
117+
-- 0x60 = 0b0110_0000
118+
phexByteStr "60"
75119

76120
paddrConfigAddrBody :: Term s (PAddressConfiguration :--> PByteString)
77121
paddrConfigAddrBody = phoistAcyclic $
78122
plam $ \addrConfig ->
79123
pmatch addrConfig $ \case
80124
PAddressConfig'PaymentKeyHash'StakeKeyHash pkh skh ->
81125
pto pkh <> pto skh
126+
PAddressConfig'PaymentKeyHash'ScriptHash pkh sh ->
127+
pto pkh <> pto sh
82128
PAddressConfig'PaymentKeyHash pkh ->
83129
pto pkh

0 commit comments

Comments
 (0)