content: {-# LANGUAGE AllowAmbiguousTypes #-}
  {-# LANGUAGE DataKinds #-}
  {-# LANGUAGE DeriveAnyClass #-}
  {-# LANGUAGE DeriveFunctor #-}
  {-# LANGUAGE DeriveGeneric #-}
  {-# LANGUAGE DerivingStrategies #-}
  {-# LANGUAGE DuplicateRecordFields #-}
  {-# LANGUAGE FlexibleContexts #-}
  {-# LANGUAGE FlexibleInstances #-}
  {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  {-# LANGUAGE OverloadedStrings #-}
  {-# LANGUAGE RecordWildCards #-}
  {-# LANGUAGE ScopedTypeVariables #-}
  {-# LANGUAGE TypeApplications #-}
  {-# LANGUAGE TypeFamilies #-}
  
  {-# OPTIONS_GHC -fno-warn-orphans #-}
  {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
  
  module Cardano.Address.Style.ShelleySpec
      ( spec
      ) where
  
  import Prelude
  
  import Cardano.Address
      ( Address
      , ChainPointer (..)
      , HasNetworkDiscriminant (..)
      , bech32
      , bech32With
      , fromBech32
      , unAddress
      , unsafeMkAddress
      )
  import Cardano.Address.Derivation
      ( Depth (..)
      , DerivationType (..)
      , GenMasterKey (..)
      , HardDerivation (..)
      , Index (..)
      , Pub
      , SoftDerivation (..)
      , XPrv
      , XPub
      , hashCredential
      , indexFromWord32
      , pubFromBytes
      , pubToBytes
      , toXPub
      , unsafeMkIndex
      , xprvPrivateKey
      , xprvToBytes
      , xpubFromBytes
      , xpubToBytes
      , xpubToPub
      )
  import Cardano.Address.KeyHash
      ( GovernanceType (..), KeyHash (..), KeyRole (..), keyHashToText )
  import Cardano.Address.Script
      ( Script (..), ScriptHash (..), toScriptHash )
  import Cardano.Address.Style.Shelley
      ( Credential (..)
      , Role (..)
      , Shelley (..)
      , delegationAddress
      , deriveCCColdPrivateKey
      , deriveCCHotPrivateKey
      , deriveDRepPrivateKey
      , deriveDelegationPrivateKey
      , liftPub
      , liftXPub
      , mkNetworkDiscriminant
      , paymentAddress
      , pointerAddress
      , roleFromIndex
      , roleToIndex
      )
  import Cardano.Mnemonic
      ( SomeMnemonic, mkSomeMnemonic )
  import Codec.Binary.Encoding
      ( AbstractEncoding (..), encode, fromBase16 )
  import Control.Monad
      ( (<=<) )
  import Crypto.Hash
      ( hashWith )
  import Crypto.Hash.Algorithms
      ( SHA3_256 (SHA3_256) )
  import Data.Aeson
      ( ToJSON, Value (..) )
  import Data.ByteArray
      ( ByteArrayAccess, ScrubbedBytes )
  import Data.ByteString
      ( ByteString )
  import Data.Either
      ( rights )
  import Data.Function
      ( (&) )
  import Data.Maybe
      ( fromMaybe, isNothing )
  import Data.Text
      ( Text )
  import Data.Word
      ( Word32 )
  import GHC.Generics
      ( Generic )
  import Test.Arbitrary
      ()
  import Test.Hspec
      ( Spec, SpecWith, describe, it, shouldBe )
  import Test.Hspec.Golden
      ( Golden (..) )
  import Test.Hspec.QuickCheck
      ( prop )
  import Test.QuickCheck
      ( Arbitrary (..)
      , Property
      , choose
      , counterexample
      , label
      , property
      , vector
      , (===)
      )
  import Text.Pretty.Simple
      ( defaultOutputOptionsNoColor, pShowOpt )
  
  import qualified Cardano.Address.Style.Shelley as Shelley
  import qualified Cardano.Codec.Bech32.Prefixes as CIP5
  import qualified Data.Aeson.Encode.Pretty as Aeson
  import qualified Data.ByteArray as BA
  import qualified Data.ByteArray.Encoding as BAE
  import qualified Data.ByteString as BS
  import qualified Data.ByteString.Lazy as BL
  import qualified Data.Char as Char
  import qualified Data.Text as T
  import qualified Data.Text.Encoding as T
  import qualified Data.Text.Lazy as TL
  import qualified Data.Text.Lazy.Encoding as TLE
  import qualified Data.Text.Lazy.IO as TL
  
  spec :: Spec
  spec = do
      describe "BIP-0044 Derivation Properties" $ do
          it "deriveAccountPrivateKey works for various indexes" $
              property prop_accountKeyDerivation
          it "N(CKDpriv((kpar, cpar), i)) === CKDpub(N(kpar, cpar), i) for any key" $
              property prop_publicChildKeyDerivation
  
      describe "Role indices" $ do
          it "Calling indexFromWord32 for invalid value fails)" $
              property prop_fromWord32Role
          it "Roundtrip index" $ property prop_roundtripIndexRole
  
      describe "Proper pointer addresses construction" $ do
          it "Using different numbers in DelegationPointerAddress does not fail"
              (property prop_pointerAddressConstruction)
  
      describe "Text Encoding Roundtrips" $ do
          prop "bech32 . fromBech32 - Shelley - payment address" $
              prop_roundtripTextEncoding bech32 fromBech32
  
          prop "bech32 . fromBech32 - Shelley - delegation address" $
              prop_roundtripTextEncodingDelegation bech32 fromBech32
  
          prop "bech32 . fromBech32 - Shelley - pointer address" $
              prop_roundtripTextEncodingPointer bech32 fromBech32
  
      describe "Golden tests" $ do
          goldenTestPointerAddress GoldenTestPointerAddress
              {  verKey = "1a2a3a4a5a6a7a8a"
              ,  stakePtr = ChainPointer 128 2 3
              ,  netTag = 0
              ,  expectedAddr =
                      "408a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d481000203"
              }
          goldenTestPointerAddress GoldenTestPointerAddress
              {  verKey = "1a2a3a4a5a6a7a8a"
              ,  stakePtr = ChainPointer 128 2 3
              ,  netTag = 1
              ,  expectedAddr =
                      "418a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d481000203"
              }
          goldenTestEnterpriseAddress GoldenTestEnterpriseAddress
              {  verKey = "1a2a3a4a5a6a7a8a"
              ,  netTag = 0
              ,  expectedAddr =
                      "608a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d4"
              }
          goldenTestEnterpriseAddress GoldenTestEnterpriseAddress
              {  verKey = "1a2a3a4a5a6a7a8a"
              ,  netTag = 1
              ,  expectedAddr =
                      "618a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d4"
              }
          goldenTestEnterpriseAddressKeyHash GoldenTestEnterpriseAddress
              {  verKey = "1a2a3a4a5a6a7a8a"
              ,  netTag = 0
              ,  expectedAddr =
                      "608a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d4"
              }
          goldenTestEnterpriseAddressKeyHash GoldenTestEnterpriseAddress
              {  verKey = "1a2a3a4a5a6a7a8a"
              ,  netTag = 1
              ,  expectedAddr =
                      "618a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d4"
              }
          goldenTestBaseAddressPayFromXPub GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 0
              ,  expectedAddr =
                      "008a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressPayFromXPub GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 1
              ,  expectedAddr =
                      "018a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressPayFromPub GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 0
              ,  expectedAddr =
                      "008a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressPayFromPub GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 1
              ,  expectedAddr =
                      "018a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressPayFromKeyHash GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 0
              ,  expectedAddr =
                      "008a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressPayFromKeyHash GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 1
              ,  expectedAddr =
                      "018a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressStakeFromKeyHash GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 0
              ,  expectedAddr =
                      "008a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressStakeFromKeyHash GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 1
              ,  expectedAddr =
                      "018a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressStakeFromPub GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 0
              ,  expectedAddr =
                      "008a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressStakeFromPub GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 1
              ,  expectedAddr =
                      "018a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressBothFromKeyHash GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 0
              ,  expectedAddr =
                      "008a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressBothFromKeyHash GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 1
              ,  expectedAddr =
                      "018a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressBothFromPub GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 0
              ,  expectedAddr =
                      "008a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestBaseAddressBothFromPub GoldenTestBaseAddress
              {  verKeyPayment = "1a2a3a4a5a6a7a8a"
              ,  verKeyStake = "1c2c3c4c5c6c7c8c"
              ,  netTag = 1
              ,  expectedAddr =
                      "018a4d111f71a79169c50bcbc27e1e20b6e13e87ff8f33edc3cab419d408b2d658668c2e341ee5bda4477b63c5aca7ec7ae4e3d196163556a4"
              }
          goldenTestGovernance GoldenTestGovernance
              {  mnemonic = [ "test", "walk", "nut", "penalty", "hip", "pave", "soap",
                              "entry", "language", "right", "filter", "choice" ]
              ,  accountIx = 0x80000000
              ,  expectedKeysHashes = KeysHashes
                     { drepXsk = "drep_xsk14rjh4rs2dzm6k5xxe5f73cypzuv02pknfl9xwnsjws8a7ulp530xztarpdlyh05csw2cmnekths7dstq0se3wtza84m4fueffezsjfgassgs9xtfzgehrn0fn7c82uc0rkj06s0w0t80hflzz8cwyry3eg9066uj"
                     , drepXskHex = "a8e57a8e0a68b7ab50c6cd13e8e0811718f506d34fca674e12740fdf73e1a45e612fa30b7e4bbe9883958dcf365de1e6c1607c33172c5d3d7754f3294e4509251d8411029969123371cde99fb075730f1da4fd41ee7acefba7e211f0e20c91ca"
                     , drepSk = "drep_sk14rjh4rs2dzm6k5xxe5f73cypzuv02pknfl9xwnsjws8a7ulp530xztarpdlyh05csw2cmnekths7dstq0se3wtza84m4fueffezsjfglsqmad"
                     , drepSkHex = "a8e57a8e0a68b7ab50c6cd13e8e0811718f506d34fca674e12740fdf73e1a45e612fa30b7e4bbe9883958dcf365de1e6c1607c33172c5d3d7754f3294e450925"
                     , drepXvk = "drep_xvk17axh4sc9zwkpsft3tlgpjemfwc0u5mnld80r85zw7zdqcst6w543mpq3q2vkjy3nw8x7n8asw4es78dyl4q7u7kwlwn7yy0sugxfrjs6z25qe"
                     , drepXvkHex = "f74d7ac30513ac1825715fd0196769761fca6e7f69de33d04ef09a0c417a752b1d8411029969123371cde99fb075730f1da4fd41ee7acefba7e211f0e20c91ca"
                     , drepVk = "drep_vk17axh4sc9zwkpsft3tlgpjemfwc0u5mnld80r85zw7zdqcst6w54sdv4a4e"
                     , drepVkHex = "f74d7ac30513ac1825715fd0196769761fca6e7f69de33d04ef09a0c417a752b"
                     , drep = "drep1y2jmg4g450lced7q9n34rq6d5vjwkm0ugx6h0894u6ur92s9txn3a"
                     , drepHex = "a5b45515a3ff8cb7c02ce351834da324eb6dfc41b5779cb5e6b832aa"
                     , drepScript1 = "drep16pjhzfkm7rqntfezfkgu5p50t0mkntmdruwlp089zu8v22aculf"
                     , drepScript1Hex = "d0657126dbf0c135a7224d91ca068f5bf769af6d1f1df0bce5170ec5"
                     , drepScript2 = "drep14edv7pg3y4wkglyykvvy5t2j906ld3dhdwvf7jda8qaa670f745"
                     , drepScript2Hex = "ae5acf0511255d647c84b3184a2d522bf5f6c5b76b989f49bd383bdd"
                     , ccColdXsk = "cc_cold_xsk1dp84kjq9qa647wr70e2yedzt8e27kwugh8mfw675re0hgm8p530z3d9230cjjzyyzlq04hn94x9q2m9um2tvp2y8fn7tau9l2wfj5ykxqxtgua0lxpf0lfn44md2afyl7dktyvpkmug9u28p6v452flxeuca0v7w"
                     , ccColdXskHex = "684f5b480507755f387e7e544cb44b3e55eb3b88b9f6976bd41e5f746ce1a45e28b4aa8bf129088417c0fade65a98a056cbcda96c0a8874cfcbef0bf53932a12c601968e75ff3052ffa675aedaaea49ff36cb23036df105e28e1d32b4527e6cf"
                     , ccColdSk = "cc_cold_sk1dp84kjq9qa647wr70e2yedzt8e27kwugh8mfw675re0hgm8p530z3d9230cjjzyyzlq04hn94x9q2m9um2tvp2y8fn7tau9l2wfj5yslmdl88"
                     , ccColdSkHex = "684f5b480507755f387e7e544cb44b3e55eb3b88b9f6976bd41e5f746ce1a45e28b4aa8bf129088417c0fade65a98a056cbcda96c0a8874cfcbef0bf53932a12"
                     , ccColdXvk = "cc_cold_xvk149up407pvp9p36lldlp4qckqqzn6vm7u5yerwy8d8rqalse3t04vvqvk3e6l7vzjl7n8ttk646jflumvkgcrdhcstc5wr5etg5n7dnc8nqv5d"
                     , ccColdXvkHex = "a9781abfc1604a18ebff6fc35062c000a7a66fdca1323710ed38c1dfc3315beac601968e75ff3052ffa675aedaaea49ff36cb23036df105e28e1d32b4527e6cf"
                     , ccColdVk = "cc_cold_vk149up407pvp9p36lldlp4qckqqzn6vm7u5yerwy8d8rqalse3t04q7qsvwl"
                     , ccColdVkHex = "a9781abfc1604a18ebff6fc35062c000a7a66fdca1323710ed38c1dfc3315bea"
                     , ccCold = "cc_cold1ztl0h9vka4ns45kfj7xh3ljwkd46yn9m5znzlfxd6rpdeagw6p59q"
                     , ccColdHex = "fefb9596ed670ad2c9978d78fe4eb36ba24cbba0a62fa4cdd0c2dcf5"
                     , ccColdScript1 = "cc_cold14ehj5f64f40xju0086fnunctulkh46mq7munm7upe4hpc434cg3"
                     , ccColdScript1Hex = "ae6f2a27554d5e6971ef3e933e4f0be7ed7aeb60f6f93dfb81cd6e1c"
                     , ccColdScript2 = "cc_cold1zxwzpnk0ah7m5ptjjtmkhvgs4736k3e0ns66shd0fy33vkd39j0"
                     , ccColdScript2Hex = "119c20cecfedfdba057292f76bb110afa3ab472f9c35a85daf492316"
                     , ccHotXsk = "cc_hot_xsk1mpt30ys7v2ykqms4c83wuednh4hvy3lr27yfhgtp0rhdka8p5300j4d2z77sq2t3kp082qzgkanwkm05mp2u2nwja3ad3pgw9l34a0j5sl5yd6d8pze8dqwksd069kkfdqggk0yytcmet96fre45w64qkgyxl0dt"
                     , ccHotXskHex = "d85717921e6289606e15c1e2ee65b3bd6ec247e357889ba16178eedb74e1a45ef955aa17bd002971b05e750048b766eb6df4d855c54dd2ec7ad8850e2fe35ebe5487e846e9a708b27681d6835fa2dac968108b3c845e379597491e6b476aa0b2"
                     , ccHotSk = "cc_hot_sk1mpt30ys7v2ykqms4c83wuednh4hvy3lr27yfhgtp0rhdka8p5300j4d2z77sq2t3kp082qzgkanwkm05mp2u2nwja3ad3pgw9l34a0sdh7u7e"
                     , ccHotSkHex = "d85717921e6289606e15c1e2ee65b3bd6ec247e357889ba16178eedb74e1a45ef955aa17bd002971b05e750048b766eb6df4d855c54dd2ec7ad8850e2fe35ebe"
                     , ccHotXvk = "cc_hot_xvk10y48lq72hypxraew74lwjjn9e2dscuwphckglh2nrrpkgweqk5h4fplggm56wz9jw6qadq6l5tdvj6qs3v7ggh3hjkt5j8ntga42pvs5rvh0a"
                     , ccHotXvkHex = "792a7f83cab90261f72ef57ee94a65ca9b0c71c1be2c8fdd5318c3643b20b52f5487e846e9a708b27681d6835fa2dac968108b3c845e379597491e6b476aa0b2"
                     , ccHotVk = "cc_hot_vk10y48lq72hypxraew74lwjjn9e2dscuwphckglh2nrrpkgweqk5hschnzv5"
                     , ccHotVkHex = "792a7f83cab90261f72ef57ee94a65ca9b0c71c1be2c8fdd5318c3643b20b52f"
                     , ccHot = "cc_hot1qtmd98q0w9jdxasse0m8kyn2nya7kf9qwmgx20cl5p543rcdtr4dz"
                     , ccHotHex = "f6d29c0f7164d37610cbf67b126a993beb24a076d0653f1fa069588f"
                     , ccHotScript1 = "cc_hot16fayy2wf9myfvxmtl5e2suuqmnhy5zx80vxkezen7xqws04z0n8"
                     , ccHotScript1Hex = "d27a4229c92ec8961b6bfd32a87380dcee4a08c77b0d6c8b33f180e8"
                     , ccHotScript2 = "cc_hot1vts8nrrsxmlntp3v7sh5u7k6qmmlkkmyv5uspq4xjxlpgr6svrf"
                     , ccHotScript2Hex = "62e0798c7036ff35862cf42f4e7ada06f7fb5b6465390082a691be14"
                     }
              }
          goldenTestGovernance GoldenTestGovernance
              {  mnemonic = [ "test", "walk", "nut", "penalty", "hip", "pave", "soap",
                              "entry", "language", "right", "filter", "choice" ]
              ,  accountIx = 0x80000100
              ,  expectedKeysHashes = KeysHashes
                     { drepXsk = "drep_xsk1zracgd4mqt32f5cj0ps0wudf78u6lumz7gprgm3j8zec5ahp530weq4z9ayj6jzj33lpj86jkk2gnt0ns0d5sywteexxehvva7gugz99ydmpemzpsfnj49vjvw88q9a2s2hxc9ggxal5q6xsqz5vaat2xqsha72w"
                     , drepXskHex = "10fb8436bb02e2a4d3127860f771a9f1f9aff362f202346e3238b38a76e1a45eec82a22f492d48528c7e191f52b59489adf383db4811cbce4c6cdd8cef91c408a523761cec4182672a9592638e7017aa82ae6c1508377f4068d000a8cef56a30"
                     , drepSk = "drep_sk1zracgd4mqt32f5cj0ps0wudf78u6lumz7gprgm3j8zec5ahp530weq4z9ayj6jzj33lpj86jkk2gnt0ns0d5sywteexxehvva7gugzqjur0zk"
                     , drepSkHex = "10fb8436bb02e2a4d3127860f771a9f1f9aff362f202346e3238b38a76e1a45eec82a22f492d48528c7e191f52b59489adf383db4811cbce4c6cdd8cef91c408"
                     , drepXvk = "drep_xvk1wq6ylcpjnwavhveey855tkhdrqdav6yfxvltw0emky9d3erxn9m22gmkrnkyrqn8922eycuwwqt64q4wds2ssdmlgp5dqq9gem6k5vq23ph3c"
                     , drepXvkHex = "70344fe0329bbacbb33921e945daed181bd66889333eb73f3bb10ad8e4669976a523761cec4182672a9592638e7017aa82ae6c1508377f4068d000a8cef56a30"
                     , drepVk = "drep_vk1wq6ylcpjnwavhveey855tkhdrqdav6yfxvltw0emky9d3erxn9mqdrlerg"
                     , drepVkHex = "70344fe0329bbacbb33921e945daed181bd66889333eb73f3bb10ad8e4669976"
                     , drep = "drep1yg0dx99005ll3lxnyrrnadv9ynthfj3cwvlwqr4u4qdavwshx0yl0"
                     , drepHex = "1ed314af7d3ff8fcd320c73eb58524d774ca38733ee00ebca81bd63a"
                     , drepScript1 = "drep18cgl8kdnjculhww4n3h0a3ahc85ahjcsg53u0f93jnz9cqnvdpd"
                     , drepScript1Hex = "3e11f3d9b39639fbb9d59c6efec7b7c1e9dbcb104523c7a4b194c45c"
                     , drepScript2 = "drep1hwj9yuvzxc623w5lmwvp44md7qkdywz2fcd583qmyu62jrsw2xy"
                     , drepScript2Hex = "bba45271823634a8ba9fdb981ad76df02cd2384a4e1b43c41b2734a9"
                     , ccColdXsk = "cc_cold_xsk1dppxrjspxrjj5e5xrmh6yaw6w30arsl5lqcsp09ynyzwwulp530q4tlvug79xx6ja3u32fu9jyy84p6erjmza6twrackm9kfsdpc3ap7uxpempqjftx74qwxnmn7d6pg8pl9zpnc0rese26pfmzl9cmtgg8xsxvu"
                     , ccColdXskHex = "684261ca0130e52a66861eefa275da745fd1c3f4f83100bca49904e773e1a45e0aafece23c531b52ec7915278591087a87591cb62ee96e1f716d96c9834388f43ee1839d84124acdea81c69ee7e6e828387e51067878f30cab414ec5f2e36b42"
                     , ccColdSk = "cc_cold_sk1dppxrjspxrjj5e5xrmh6yaw6w30arsl5lqcsp09ynyzwwulp530q4tlvug79xx6ja3u32fu9jyy84p6erjmza6twrackm9kfsdpc3aqr79jja"
                     , ccColdSkHex = "684261ca0130e52a66861eefa275da745fd1c3f4f83100bca49904e773e1a45e0aafece23c531b52ec7915278591087a87591cb62ee96e1f716d96c9834388f4"
                     , ccColdXvk = "cc_cold_xvk1e2mquwugpwnykfftjs4mv3w4uk80f4hjgd2zls5vusz3zuqhr7gnacvrnkzpyjkda2qud8h8um5zswr72yr8s78npj45znk97t3kkssryhkyv"
                     , ccColdXvkHex = "cab60e3b880ba64b252b942bb645d5e58ef4d6f243542fc28ce4051170171f913ee1839d84124acdea81c69ee7e6e828387e51067878f30cab414ec5f2e36b42"
                     , ccColdVk = "cc_cold_vk1e2mquwugpwnykfftjs4mv3w4uk80f4hjgd2zls5vusz3zuqhr7gs3qg4hr"
                     , ccColdVkHex = "cab60e3b880ba64b252b942bb645d5e58ef4d6f243542fc28ce4051170171f91"
                     , ccCold = "cc_cold1zt5nwd86uuvwjxalghyxlrxcreledplxellyeygd6xjvxcqy66a7t"
                     , ccColdHex = "e93734fae718e91bbf45c86f8cd81e7f9687e6cffe4c910dd1a4c360"
                     , ccColdScript1 = "cc_cold1prtcxdlu75dz48lf8hh86gt8ng7z39yvmyqcg92sgze7gpt2gga"
                     , ccColdScript1Hex = "08d78337fcf51a2a9fe93dee7d21679a3c28948cd90184155040b3e4"
                     , ccColdScript2 = "cc_cold1969h0m92nuqrj7x74pj3tnhxh97lfhl4y2vwvqvc6kecwkq6xe5"
                     , ccColdScript2Hex = "2e8b77ecaa9f003978dea86515cee6b97df4dff52298e60198d5b387"
                     , ccHotXsk = "cc_hot_xsk15pt89wppyhr9eqgm5nnu7tna3dfmqxa2u45e4g7krzp9u78p530pez36k8k9n0gw08hn6drxlwxxsgc4jsejv6hvcnkd7gd3zxhstpe3vzde6e98zql6n2cmekklm63dydnt80szdr0h768dexeklrfspc5lznuz"
                     , ccHotXskHex = "a05672b82125c65c811ba4e7cf2e7d8b53b01baae5699aa3d618825e78e1a45e1c8a3ab1ec59bd0e79ef3d3466fb8c6823159433266aecc4ecdf21b111af058731609b9d64a7103fa9ab1bcdadfdea2d2366b3be0268df7f68edc9b36f8d300e"
                     , ccHotSk = "cc_hot_sk15pt89wppyhr9eqgm5nnu7tna3dfmqxa2u45e4g7krzp9u78p530pez36k8k9n0gw08hn6drxlwxxsgc4jsejv6hvcnkd7gd3zxhstpc7gujxf"
                     , ccHotSkHex = "a05672b82125c65c811ba4e7cf2e7d8b53b01baae5699aa3d618825e78e1a45e1c8a3ab1ec59bd0e79ef3d3466fb8c6823159433266aecc4ecdf21b111af0587"
                     , ccHotXvk = "cc_hot_xvk10qawpxlz7eytt9yr4xlwtjkw345v0ehzsxdlkks6qralyp975phrzcymn4j2wypl4x43hnddlh4z6gmxkwlqy6xl0a5wmjdnd7xnqrsvak8ry"
                     , ccHotXvkHex = "783ae09be2f648b59483a9bee5cace8d68c7e6e2819bfb5a1a00fbf204bea06e31609b9d64a7103fa9ab1bcdadfdea2d2366b3be0268df7f68edc9b36f8d300e"
                     , ccHotVk = "cc_hot_vk10qawpxlz7eytt9yr4xlwtjkw345v0ehzsxdlkks6qralyp975phqx538xn"
                     , ccHotVkHex = "783ae09be2f648b59483a9bee5cace8d68c7e6e2819bfb5a1a00fbf204bea06e"
                     , ccHot = "cc_hot1qtgaf67mr95fa90qj7gehkr3y3q73x6pasmdu3algq6ylpgfamj02"
                     , ccHotHex = "d1d4ebdb19689e95e097919bd8712441e89b41ec36de47bf40344f85"
                     , ccHotScript1 = "cc_hot1hheftszv4jw83f5megrvhrevl7lwwmtnjav7srkqngr92348jvr"
                     , ccHotScript1Hex = "bdf295c04cac9c78a69bca06cb8f2cffbee76d739759e80ec09a0655"
                     , ccHotScript2 = "cc_hot1dg9jdwlsxzakctywv2cw7a7ggj2dwu0gz5tueu2rf40zv05atgs"
                     , ccHotScript2Hex = "6a0b26bbf030bb6c2c8e62b0ef77c84494d771e81517ccf1434d5e26"
                     }
              }
          goldenTestGovernance GoldenTestGovernance
              {  mnemonic = [ "excess", "behave", "track", "soul", "table", "wear",
                              "ocean", "cash", "stay", "nature", "item", "turtle",
                              "palm", "soccer", "lunch", "horror", "start", "stumble",
                              "month", "panic", "right", "must", "lock", "dress" ]
              ,  accountIx = 0x80000000
              ,  expectedKeysHashes = KeysHashes
                     { drepXsk = "drep_xsk17pwn6d7pu0d6sfzysyk5taux99f5tdqsct7zzthgljyd5zs33azej0tm5ny7ksunthqu84tqg832md6vs3hm392agwx3auhvyjtzxr2l6c0dj47k6zedl4kgugneu04j64fc5uueayydmufdrdaled9k4qllaka6"
                     , drepXskHex = "f05d3d37c1e3dba82444812d45f786295345b410c2fc212ee8fc88da0a118f45993d7ba4c9eb43935dc1c3d56041e2adb74c846fb8955d438d1ef2ec2496230d5fd61ed957d6d0b2dfd6c8e2279e3eb2d5538a7399e908ddf12d1b7bfcb4b6a8"
                     , drepSk = "drep_sk17pwn6d7pu0d6sfzysyk5taux99f5tdqsct7zzthgljyd5zs33azej0tm5ny7ksunthqu84tqg832md6vs3hm392agwx3auhvyjtzxrgwyexuy"
                     , drepSkHex = "f05d3d37c1e3dba82444812d45f786295345b410c2fc212ee8fc88da0a118f45993d7ba4c9eb43935dc1c3d56041e2adb74c846fb8955d438d1ef2ec2496230d"
                     , drepXvk = "drep_xvk15j30gk0uex88lc9vh6sfda93lv6zede65mzp7ck56m9pgeqhnht9l4s7m9tad59jmltv3c38nclt942n3feen6ggmhcj6xmmlj6td2qu4ce82"
                     , drepXvkHex = "a4a2f459fcc98e7fe0acbea096f4b1fb342cb73aa6c41f62d4d6ca1464179dd65fd61ed957d6d0b2dfd6c8e2279e3eb2d5538a7399e908ddf12d1b7bfcb4b6a8"
                     , drepVk = "drep_vk15j30gk0uex88lc9vh6sfda93lv6zede65mzp7ck56m9pgeqhnhtqvs6j8t"
                     , drepVkHex = "a4a2f459fcc98e7fe0acbea096f4b1fb342cb73aa6c41f62d4d6ca1464179dd6"
                     , drep = "drep1yge7tpltrazw286rqlhw6lk7vxgq30zdrsevrqye6cm8x2gf38vlv"
                     , drepHex = "33e587eb1f44e51f4307eeed7ede619008bc4d1c32c18099d6367329"
                     , drepScript1 = "drep17fql6ztxyk63taryk2e4mh47jw3wdchv9e7u4jxg4edrxg8enef"
                     , drepScript1Hex = "f241fd096625b515f464b2b35ddebe93a2e6e2ec2e7dcac8c8ae5a33"
                     , drepScript2 = "drep10qp23w0gppuvc7chc3g7saudlmhj9jmm9ssrrzzm3qwksrn4cul"
                     , drepScript2Hex = "7802a8b9e80878cc7b17c451e8778dfeef22cb7b2c2031885b881d68"
                     , ccColdXsk = "cc_cold_xsk1hqtevrzlhtcglwvt5pmgct8ssqx37vjjf3wuydpd6flyqrg33azacap5w5mclacmuycx3xgrtstxgrpzcncf6l840t0klmywc69ryd9zf95taaaseka98yakuj2048slnuekw22qm58majt8alhs438eecehquu0"
                     , ccColdXskHex = "b817960c5fbaf08fb98ba0768c2cf0800d1f32524c5dc2342dd27e400d118f45dc743475378ff71be1306899035c16640c22c4f09d7cf57adf6fec8ec68a3234a24968bef7b0cdba5393b6e494fa9e1f9f33672940dd0fbec967efef0ac4f9ce"
                     , ccColdSk = "cc_cold_sk1hqtevrzlhtcglwvt5pmgct8ssqx37vjjf3wuydpd6flyqrg33azacap5w5mclacmuycx3xgrtstxgrpzcncf6l840t0klmywc69rydqvncuyc"
                     , ccColdSkHex = "b817960c5fbaf08fb98ba0768c2cf0800d1f32524c5dc2342dd27e400d118f45dc743475378ff71be1306899035c16640c22c4f09d7cf57adf6fec8ec68a3234"
                     , ccColdXvk = "cc_cold_xvk13wc4cvvr266t4rxm9wyel4deeqxyylvjzjdk5w74lva2xm0dhxt6yjtghmmmpnd62wfmdey5l20pl8envu55phg0hmyk0ml0ptz0nns9cqjlk"
                     , ccColdXvkHex = "8bb15c318356b4ba8cdb2b899fd5b9c80c427d92149b6a3bd5fb3aa36dedb997a24968bef7b0cdba5393b6e494fa9e1f9f33672940dd0fbec967efef0ac4f9ce"
                     , ccColdVk = "cc_cold_vk13wc4cvvr266t4rxm9wyel4deeqxyylvjzjdk5w74lva2xm0dhxtsfpa2qu"
                     , ccColdVkHex = "8bb15c318356b4ba8cdb2b899fd5b9c80c427d92149b6a3bd5fb3aa36dedb997"
                     , ccCold = "cc_cold1ztc2kq7xa0vdrdz3tg7umg724srnw6yac0zschqdl0rerushdm3cm"
                     , ccColdHex = "f0ab03c6ebd8d1b4515a3dcda3caac0737689dc3c50c5c0dfbc791f2"
                     , ccColdScript1 = "cc_cold15z7ynn7fuqu55hh850962vrrg7tcdncl8spnjtrxjjm06lpsfgc"
                     , ccColdScript1Hex = "a0bc49cfc9e0394a5ee7a3cba53063479786cf1f3c03392c6694b6fd"
                     , ccColdScript2 = "cc_cold1ahw3qh3ledhxp0frga9aawfkxpu0qstte9nmem0phqqegzf9lp3"
                     , ccColdScript2Hex = "eddd105e3fcb6e60bd23474bdeb9363078f0416bc967bcede1b80194"
                     , ccHotXsk = "cc_hot_xsk1wzamzchtj7m79mjfpg3c02m534ugej5ac0p3s2sresr7vys33azktmjva6flctprqu6m4k4w459x9qkfsz2ahgy5ganjn23djhhkg5e5eyhu7fjxl6tpxtmzh7e2ftuj4qgmawsmcl7sqesn8e0pmh97zs3c3fqj"
                     , ccHotXskHex = "70bbb162eb97b7e2ee490a2387ab748d788cca9dc3c3182a03cc07e612118f4565ee4cee93fc2c230735badaaead0a6282c98095dba094476729aa2d95ef645334c92fcf2646fe96132f62bfb2a4af92a811beba1bc7fd0066133e5e1ddcbe14"
                     , ccHotSk = "cc_hot_sk1wzamzchtj7m79mjfpg3c02m534ugej5ac0p3s2sresr7vys33azktmjva6flctprqu6m4k4w459x9qkfsz2ahgy5ganjn23djhhkg5cmwegml"
                     , ccHotSkHex = "70bbb162eb97b7e2ee490a2387ab748d788cca9dc3c3182a03cc07e612118f4565ee4cee93fc2c230735badaaead0a6282c98095dba094476729aa2d95ef6453"
                     , ccHotXvk = "cc_hot_xvk1tazd6lvnf2c9j8m58h6xy56uuyhkee526jgxj2ylaextl0xamd4nfjf0eunydl5kzvhk90aj5jhe92q3h6aph3laqpnpx0j7rhwtu9qe7dhsc"
                     , ccHotXvkHex = "5f44dd7d934ab0591f743df462535ce12f6ce68ad49069289fee4cbfbcdddb6b34c92fcf2646fe96132f62bfb2a4af92a811beba1bc7fd0066133e5e1ddcbe14"
                     , ccHotVk = "cc_hot_vk1tazd6lvnf2c9j8m58h6xy56uuyhkee526jgxj2ylaextl0xamd4swmuygc"
                     , ccHotVkHex = "5f44dd7d934ab0591f743df462535ce12f6ce68ad49069289fee4cbfbcdddb6b"
                     , ccHot = "cc_hot1qtp2wn5mef3ypk2872d7kl0djczfwsqkmgk53ca8cdjye3qehdsy0"
                     , ccHotHex = "c2a74e9bca6240d947f29beb7ded9604974016da2d48e3a7c3644cc4"
                     , ccHotScript1 = "cc_hot1tmwlec0twwvl29h6pgvew5mf4recsxtktev9g07xm37fvvupdmd"
                     , ccHotScript1Hex = "5eddfce1eb7399f516fa0a19975369a8f38819765e58543fc6dc7c96"
                     , ccHotScript2 = "cc_hot1c77thg5lrahy0he4q6glsk8vgsp45gt75k3pq09d02u8gvktfzw"
                     , ccHotScript2Hex = "c7bcbba29f1f6e47df350691f858ec44035a217ea5a2103cad7ab874"
                     }
              }
          goldenTestGovernance GoldenTestGovernance
              {  mnemonic = [ "excess", "behave", "track", "soul", "table", "wear",
                              "ocean", "cash", "stay", "nature", "item", "turtle",
                              "palm", "soccer", "lunch", "horror", "start", "stumble",
                              "month", "panic", "right", "must", "lock", "dress" ]
              ,  accountIx = 0x80000100
              ,  expectedKeysHashes = KeysHashes
                     { drepXsk = "drep_xsk14z6a7nd2q5r03s4gxsrujc59sg757vqqcwxeuc5s874c2rq33az37lwkxpxvh5s4a94sncxp6y7m73pxsuknt7gvethhue5jk5vc5n2hrg95mynhw7mtrshxr5mpku4v8x6lpm05nznrqej70u0fllgfkusexdkv"
                     , drepXskHex = "a8b5df4daa0506f8c2a83407c96285823d4f3000c38d9e62903fab850c118f451f7dd6304ccbd215e96b09e0c1d13dbf4426872d35f90ccaef7e6692b5198a4d571a0b4d927777b6b1c2e61d361b72ac39b5f0edf498a630665e7f1e9ffd09b7"
                     , drepSk = "drep_sk14z6a7nd2q5r03s4gxsrujc59sg757vqqcwxeuc5s874c2rq33az37lwkxpxvh5s4a94sncxp6y7m73pxsuknt7gvethhue5jk5vc5ngl9zhrx"
                     , drepSkHex = "a8b5df4daa0506f8c2a83407c96285823d4f3000c38d9e62903fab850c118f451f7dd6304ccbd215e96b09e0c1d13dbf4426872d35f90ccaef7e6692b5198a4d"
                     , drepXvk = "drep_xvk14dwjrplj73qeggdsg4lh4j9tp495asyq9t6augwaue8kqvjg5wq4wxstfkf8waakk8pwv8fkrde2cwd47rklfx9xxpn9ulc7nl7sndcvdjh2m"
                     , drepXvkHex = "ab5d2187f2f4419421b0457f7ac8ab0d4b4ec0802af5de21dde64f603248a381571a0b4d927777b6b1c2e61d361b72ac39b5f0edf498a630665e7f1e9ffd09b7"
                     , drepVk = "drep_vk14dwjrplj73qeggdsg4lh4j9tp495asyq9t6augwaue8kqvjg5wqskrq5yn"
                     , drepVkHex = "ab5d2187f2f4419421b0457f7ac8ab0d4b4ec0802af5de21dde64f603248a381"
                     , drep = "drep1ytq6xshsm7uzhy729e45q6avkpyq9a74d2va3726sz5td3gqrgcll"
                     , drepHex = "c1a342f0dfb82b93ca2e6b406bacb04802f7d56a99d8f95a80a8b6c5"
                     , drepScript1 = "drep1ckr4x9293myuyz5379wndh4ag00c787htnzwzxxmpfnfzaqtayp"
                     , drepScript1Hex = "c5875315458ec9c20a91f15d36debd43df8f1fd75cc4e118db0a6691"
                     , drepScript2 = "drep1wgly5zd539aam7yxr7trxy48dhupswmwusutm4q40dwkc07n3y8"
                     , drepScript2Hex = "723e4a09b4897bddf8861f963312a76df8183b6ee438bdd4157b5d6c"
                     , ccColdXsk = "cc_cold_xsk1hqe5kcsq59mx4t9nxrctmth0ppz9gda0gnppyll3h9rxcyq33az4uy3u6qhzuhjsstzca9awgsx27j07hxhrkrk6487nvywp0ag669m4v6lj3knq7e6pxaujy98akn5exhgk44ftruepkte0hdm74dd8zceqnk2h"
                     , ccColdXskHex = "b8334b6200a1766aacb330f0bdaeef08445437af44c2127ff1b9466c10118f455e123cd02e2e5e5082c58e97ae440caf49feb9ae3b0edaa9fd3611c17f51ad177566bf28da60f674137792214fdb4e9935d16ad52b1f321b2f2fbb77eab5a716"
                     , ccColdSk = "cc_cold_sk1hqe5kcsq59mx4t9nxrctmth0ppz9gda0gnppyll3h9rxcyq33az4uy3u6qhzuhjsstzca9awgsx27j07hxhrkrk6487nvywp0ag669c5qtm3p"
                     , ccColdSkHex = "b8334b6200a1766aacb330f0bdaeef08445437af44c2127ff1b9466c10118f455e123cd02e2e5e5082c58e97ae440caf49feb9ae3b0edaa9fd3611c17f51ad17"
                     , ccColdXvk = "cc_cold_xvk1lmqejccjpxsd9cl4uavxj0jryjlfk5r8wemr0d8saal49lttp2482e4l9rdxpan5zdmeyg20md8fjdw3dt2jk8ejrvhjlwmha266w9syf55nr"
                     , ccColdXvkHex = "fec199631209a0d2e3f5e758693e4324be9b5067767637b4f0ef7f52fd6b0aaa7566bf28da60f674137792214fdb4e9935d16ad52b1f321b2f2fbb77eab5a716"
                     , ccColdVk = "cc_cold_vk1lmqejccjpxsd9cl4uavxj0jryjlfk5r8wemr0d8saal49lttp24q6lw08l"
                     , ccColdVkHex = "fec199631209a0d2e3f5e758693e4324be9b5067767637b4f0ef7f52fd6b0aaa"
                     , ccCold = "cc_cold1zfxtx2h8qhanhw3u4jt5ydtgsry39gm2ff7v5ax5j4k87sgmkas3l"
                     , ccColdHex = "4cb32ae705fb3bba3cac9742356880c912a36a4a7cca74d4956c7f41"
                     , ccColdScript1 = "cc_cold1qlk7rgkd5n6ga8enwk08vwtmlklhzfnmjtjlzlwed62tulgk75f"
                     , ccColdScript1Hex = "07ede1a2cda4f48e9f33759e76397bfdbf71267b92e5f17dd96e94be"
                     , ccColdScript2 = "cc_cold1a4qmd5d3dqppxtq5wcuuaa3xfe868vyn46afvktz5ucxzauy6tg"
                     , ccColdScript2Hex = "ed41b6d1b16802132c147639cef6264e4fa3b093aeba965962a73061"
                     , ccHotXsk = "cc_hot_xsk14rzh5lvtdhvum6vjfvkwp73mz9gl426cj04xfavnjgmdxrq33azugz0k9sekf2eg70lr34rg5aclr54v30za77xn945kncdm0le6lutxlr5ar355u5awqt2hkmdurv4qv64cmpg39zq2ahjxqken8vk62qunx4hl"
                     , ccHotXskHex = "a8c57a7d8b6dd9cde9924b2ce0fa3b1151faab5893ea64f5939236d30c118f45c409f62c3364ab28f3fe38d468a771f1d2ac8bc5df78d32d6969e1bb7ff3aff166f8e9d1c694e53ae02d57b6dbc1b2a066ab8d85112880aede4605b333b2da50"
                     , ccHotSk = "cc_hot_sk14rzh5lvtdhvum6vjfvkwp73mz9gl426cj04xfavnjgmdxrq33azugz0k9sekf2eg70lr34rg5aclr54v30za77xn945kncdm0le6lugud8v57"
                     , ccHotSkHex = "a8c57a7d8b6dd9cde9924b2ce0fa3b1151faab5893ea64f5939236d30c118f45c409f62c3364ab28f3fe38d468a771f1d2ac8bc5df78d32d6969e1bb7ff3aff1"
                     , ccHotXvk = "cc_hot_xvk1g2925ntunmthw66sr8t7v3qe7fls4575wput3936cguzk7m6w4fkd78f68rffef6uqk40dkmcxe2qe4t3kz3z2yq4m0yvpdnxwed55q798msd"
                     , ccHotXvkHex = "428aaa4d7c9ed7776b5019d7e64419f27f0ad3d47078b8963ac2382b7b7a755366f8e9d1c694e53ae02d57b6dbc1b2a066ab8d85112880aede4605b333b2da50"
                     , ccHotVk = "cc_hot_vk1g2925ntunmthw66sr8t7v3qe7fls4575wput3936cguzk7m6w4fs0zjxf8"
                     , ccHotVkHex = "428aaa4d7c9ed7776b5019d7e64419f27f0ad3d47078b8963ac2382b7b7a7553"
                     , ccHot = "cc_hot1q257k3xs4gww24vm0s3zwzkz850xr0ewz9xa3edyfmf622g5zjp8w"
                     , ccHotHex = "a9eb44d0aa1ce5559b7c22270ac23d1e61bf2e114dd8e5a44ed3a529"
                     , ccHotScript1 = "cc_hot1n42mr24e22eyspa7m0y6lq5rk8tesq35xt6gfgkezcxluez2snm"
                     , ccHotScript1Hex = "9d55b1aab952b24807bedbc9af8283b1d798023432f484a2d9160dfe"
                     , ccHotScript2 = "cc_hot1gfqmx4g0czk2nz2m2rfawg4me283jl7wz4wfssup03av2aynvs9"
                     , ccHotScript2Hex = "4241b3550fc0aca9895b50d3d722bbca8f197fce155c9843817c7ac5"
                     }
              }
      describe "Test vectors" $ do
          testVectors
              [ "test", "child", "burst", "immense", "armed", "parrot"
              , "company", "walk", "dog" ]
          testVectors
              [ "test", "walk", "nut", "penalty", "hip", "pave", "soap",
              "entry", "language", "right", "filter", "choice" ]
          testVectors
              [ "art", "forum", "devote", "street", "sure", "rather",
              "head", "chuckle", "guard", "poverty", "release",
              "quote", "oak", "craft", "enemy"]
          testVectors
              [ "churn", "shaft", "spoon", "second", "erode", "useless",
              "thrive", "burst", "group", "seed", "element", "sign",
              "scrub", "buffalo", "jelly", "grace", "neck", "useless" ]
          testVectors
              [ "draft", "ability", "female", "child", "jump", "maid",
              "roof", "hurt", "below", "live", "topple", "paper",
              "exclude", "ordinary", "coach", "churn", "sunset",
              "emerge", "blame", "ketchup", "much" ]
          testVectors
              [ "excess", "behave", "track", "soul", "table", "wear",
              "ocean", "cash", "stay", "nature", "item", "turtle",
              "palm", "soccer", "lunch", "horror", "start", "stumble",
              "month", "panic", "right", "must", "lock", "dress" ]
  
  {-------------------------------------------------------------------------------
                                   Properties
  -------------------------------------------------------------------------------}
  
  prop_publicChildKeyDerivation
      :: (SomeMnemonic, SndFactor)
      -> Role
      -> Index 'Soft 'PaymentK
      -> Property
  prop_publicChildKeyDerivation (mw, (SndFactor sndFactor)) cc ix =
      addrXPub1 === addrXPub2
    where
      rootXPrv = genMasterKeyFromMnemonic mw sndFactor :: Shelley 'RootK XPrv
      accXPrv  = deriveAccountPrivateKey rootXPrv minBound
      addrXPub1 = toXPub <$> deriveAddressPrivateKey accXPrv cc ix
      addrXPub2 = deriveAddressPublicKey (toXPub <$> accXPrv) cc ix
  
  prop_accountKeyDerivation
      :: (SomeMnemonic, SndFactor)
      -> Index 'Hardened 'AccountK
      -> Property
  prop_accountKeyDerivation (mw, (SndFactor sndFactor)) ix =
      accXPrv `seq` property ()
    where
      rootXPrv = genMasterKeyFromMnemonic mw sndFactor :: Shelley 'RootK XPrv
      accXPrv = deriveAccountPrivateKey rootXPrv ix
  
  prop_fromWord32Role :: Int -> Property
  prop_fromWord32Role n =
      isNothing (toRole n)
      ===
      (n > fromRole maxBound || n < fromRole minBound)
    where
      fromRole = fromIntegral . indexToWord32 . roleToIndex
      toRole = roleFromIndex . unsafeMkIndex . fromIntegral
  
  prop_roundtripIndexRole :: Role -> Property
  prop_roundtripIndexRole ix = (roleFromIndex . roleToIndex) ix === Just ix
  
  prop_pointerAddressConstruction
      :: (SomeMnemonic, SndFactor)
      -> Role
      -> Index 'Soft 'PaymentK
      -> NetworkDiscriminant Shelley
      -> ChainPointer
      -> Property
  prop_pointerAddressConstruction (mw, (SndFactor sndFactor)) cc ix net ptr =
      pointerAddr `seq` property ()
    where
      rootXPrv = genMasterKeyFromMnemonic mw sndFactor :: Shelley 'RootK XPrv
      accXPrv  = deriveAccountPrivateKey rootXPrv minBound
      addrXPub = toXPub <$> deriveAddressPrivateKey accXPrv cc ix
      pointerAddr = pointerAddress net (PaymentFromExtendedKey addrXPub) ptr
  
  
  {-------------------------------------------------------------------------------
                               Golden tests
  -------------------------------------------------------------------------------}
  -- | Definitions: Let's assume we have private key         < xprv | pub | cc >
  -- Then, extended private key should be understood as      < xprv |     | cc >
  --       extended public key  should be understood as      <      | pub | cc >
  --       verification public key should be understood as   <      | pub |    >
  
  data GoldenTestPointerAddress = GoldenTestPointerAddress
      {
        -- | The verification public key as string to be encoded into base16 form
        -- After that it should have 32-byte length
         verKey :: Text
  
        -- | Location of stake cerificate in the blockchain
      ,  stakePtr :: ChainPointer
  
        -- | Network tag
      ,  netTag :: Integer
  
        -- | Expected address as encoded into base16 form
      ,  expectedAddr :: Text
      }
  
  goldenTestPointerAddress :: GoldenTestPointerAddress -> SpecWith ()
  goldenTestPointerAddress GoldenTestPointerAddress{..} =
      it ("pointer address for networkId " <> show netTag) $ do
          let (Just xPub) = xpubFromBytes $ b16encode $ T.append verKey verKey
          let addrXPub = liftXPub xPub :: Shelley 'PaymentK XPub
          let (Right tag) = mkNetworkDiscriminant netTag
          let ptrAddr = pointerAddress tag (PaymentFromExtendedKey addrXPub) stakePtr
          let (Right bytes) = b16decode expectedAddr
          ptrAddr `shouldBe` unsafeMkAddress bytes
  
  data GoldenTestEnterpriseAddress = GoldenTestEnterpriseAddress
      {
        -- | The verification public key as string to be encoded into base16 form
        -- After that it should have 32-byte length
         verKey :: Text
  
        -- | Network tag
      ,  netTag :: Integer
  
        -- | Expected address as encoded into base16 form
      ,  expectedAddr :: Text
      }
  
  goldenTestEnterpriseAddress :: GoldenTestEnterpriseAddress -> SpecWith ()
  goldenTestEnterpriseAddress GoldenTestEnterpriseAddress{..} =
      it ("enterprise address for networkId " <> show netTag) $ do
          let (Just xPub) = xpubFromBytes $ b16encode $ T.append verKey verKey
          let addrXPub = liftXPub xPub :: Shelley 'PaymentK XPub
          let (Right tag) = mkNetworkDiscriminant netTag
          let enterpriseAddr = Shelley.paymentAddress tag (PaymentFromExtendedKey addrXPub)
          let (Right bytes) = b16decode expectedAddr
          enterpriseAddr `shouldBe` unsafeMkAddress bytes
  
  goldenTestEnterpriseAddressKeyHash :: GoldenTestEnterpriseAddress -> SpecWith ()
  goldenTestEnterpriseAddressKeyHash GoldenTestEnterpriseAddress{..} =
      it ("enterprise address for networkId " <> show netTag) $ do
          let bs = b16encode $ T.append verKey verKey
          let (Just xPub) = xpubFromBytes bs
          let addrXPub = liftXPub xPub :: Shelley 'PaymentK XPub
          let (Right tag) = mkNetworkDiscriminant netTag
          let enterpriseAddrFromKey =
                  Shelley.paymentAddress tag (PaymentFromExtendedKey addrXPub)
          let keyHashDigest = hashCredential $ BS.take 32 bs
          let keyHash = KeyHash Payment keyHashDigest
          let enterpriseAddrFromKeyHash =
                  Shelley.paymentAddress tag (PaymentFromKeyHash keyHash)
          enterpriseAddrFromKey `shouldBe` enterpriseAddrFromKeyHash
  
  data GoldenTestBaseAddress = GoldenTestBaseAddress
      {
        -- | The verification public key as string to be encoded into base16 form
        -- After that it should have 32-byte length
         verKeyPayment :: Text
  
        -- | The verification public key as string to be encoded into base16 form
        -- After that it should have 32-byte length
      ,  verKeyStake :: Text
  
        -- | Network tag
      ,  netTag :: Integer
  
        -- | Expected address as encoded into base16 form
      ,  expectedAddr :: Text
      }
  
  goldenTestBaseAddressPayFromXPub :: GoldenTestBaseAddress -> SpecWith ()
  goldenTestBaseAddressPayFromXPub GoldenTestBaseAddress{..} =
      it ("base address for networkId " <> show netTag) $ do
          let (Just xPub1) =
                  xpubFromBytes $ b16encode $ T.append verKeyPayment verKeyPayment
          let addrXPub = liftXPub xPub1 :: Shelley 'PaymentK XPub
          let (Just xPub2) =
                  xpubFromBytes $ b16encode $ T.append verKeyStake verKeyStake
          let stakeXPub = liftXPub xPub2 :: Shelley 'DelegationK XPub
          let (Right tag) = mkNetworkDiscriminant netTag
          let baseAddr =
                  delegationAddress tag (PaymentFromExtendedKey addrXPub)
                  (DelegationFromExtendedKey stakeXPub)
          let (Right bytes) = b16decode expectedAddr
          baseAddr `shouldBe` unsafeMkAddress bytes
  
  goldenTestBaseAddressPayFromPub :: GoldenTestBaseAddress -> SpecWith ()
  goldenTestBaseAddressPayFromPub GoldenTestBaseAddress{..} =
      it ("base address for networkId " <> show netTag) $ do
          let (Just pub1) =
                  pubFromBytes $ b16encode verKeyPayment
          let addrPub = liftPub pub1 :: Shelley 'PaymentK Pub
          let (Just xPub2) =
                  xpubFromBytes $ b16encode $ T.append verKeyStake verKeyStake
          let stakeXPub = liftXPub xPub2 :: Shelley 'DelegationK XPub
          let (Right tag) = mkNetworkDiscriminant netTag
          let baseAddr =
                  delegationAddress tag (PaymentFromKey addrPub)
                  (DelegationFromExtendedKey stakeXPub)
          let (Right bytes) = b16decode expectedAddr
          baseAddr `shouldBe` unsafeMkAddress bytes
  
  goldenTestBaseAddressPayFromKeyHash :: GoldenTestBaseAddress -> SpecWith ()
  goldenTestBaseAddressPayFromKeyHash GoldenTestBaseAddress{..} =
      it ("base address for networkId " <> show netTag) $ do
          let paymentBs = b16encode $ T.append verKeyPayment verKeyPayment
          let (Just xPub1) = xpubFromBytes paymentBs
          let addrXPub = liftXPub xPub1 :: Shelley 'PaymentK XPub
          let (Just xPub2) =
                  xpubFromBytes $ b16encode $ T.append verKeyStake verKeyStake
          let stakeXPub = liftXPub xPub2 :: Shelley 'DelegationK XPub
          let (Right tag) = mkNetworkDiscriminant netTag
          let baseAddrPayFromKey =
                  delegationAddress tag (PaymentFromExtendedKey addrXPub)
                  (DelegationFromExtendedKey stakeXPub)
          let keyHashDigest = hashCredential $ BS.take 32 paymentBs
          let keyHash = KeyHash Payment keyHashDigest
          let baseAddrPayFromKeyHash =
                  delegationAddress tag (PaymentFromKeyHash keyHash)
                  (DelegationFromExtendedKey stakeXPub)
          baseAddrPayFromKey `shouldBe` baseAddrPayFromKeyHash
  
  goldenTestBaseAddressStakeFromKeyHash :: GoldenTestBaseAddress -> SpecWith ()
  goldenTestBaseAddressStakeFromKeyHash GoldenTestBaseAddress{..} =
      it ("base address for networkId " <> show netTag) $ do
          let paymentBs = b16encode $ T.append verKeyPayment verKeyPayment
          let (Just xPub1) = xpubFromBytes paymentBs
          let addrXPub = liftXPub xPub1 :: Shelley 'PaymentK XPub
          let stakeBs = b16encode $ T.append verKeyStake verKeyStake
          let (Just xPub2) = xpubFromBytes stakeBs
          let stakeXPub = liftXPub xPub2 :: Shelley 'DelegationK XPub
          let (Right tag) = mkNetworkDiscriminant netTag
          let baseAddrStakeFromKey =
                  delegationAddress tag (PaymentFromExtendedKey addrXPub)
                  (DelegationFromExtendedKey stakeXPub)
          let keyHashDigest = hashCredential $ BS.take 32 stakeBs
          let keyHash = KeyHash Delegation keyHashDigest
          let baseAddrStakeFromKeyHash =
                  delegationAddress tag (PaymentFromExtendedKey addrXPub)
                  (DelegationFromKeyHash keyHash)
          baseAddrStakeFromKey `shouldBe` baseAddrStakeFromKeyHash
  
  goldenTestBaseAddressStakeFromPub :: GoldenTestBaseAddress -> SpecWith ()
  goldenTestBaseAddressStakeFromPub GoldenTestBaseAddress{..} =
      it ("base address for networkId " <> show netTag) $ do
          let paymentBs = b16encode $ T.append verKeyPayment verKeyPayment
          let (Just xPub1) = xpubFromBytes paymentBs
          let addrXPub = liftXPub xPub1 :: Shelley 'PaymentK XPub
          let stakeBs = b16encode $ T.append verKeyStake verKeyStake
          let (Just xPub2) = xpubFromBytes stakeBs
          let stakeXPub = liftXPub xPub2 :: Shelley 'DelegationK XPub
          let (Right tag) = mkNetworkDiscriminant netTag
          let baseAddrStakeFromExtendedKey =
                  delegationAddress tag (PaymentFromExtendedKey addrXPub)
                  (DelegationFromExtendedKey stakeXPub)
          let stakeBs1 = b16encode verKeyStake
          let (Just pub2) = pubFromBytes stakeBs1
          let stakePub = liftPub pub2 :: Shelley 'DelegationK Pub
          let baseAddrStakeFromKey =
                  delegationAddress tag (PaymentFromExtendedKey addrXPub)
                  (DelegationFromKey stakePub)
          baseAddrStakeFromExtendedKey `shouldBe` baseAddrStakeFromKey
  
  goldenTestBaseAddressBothFromKeyHash :: GoldenTestBaseAddress -> SpecWith ()
  goldenTestBaseAddressBothFromKeyHash GoldenTestBaseAddress{..} =
      it ("base address for networkId " <> show netTag) $ do
          let paymentBs = b16encode $ T.append verKeyPayment verKeyPayment
          let (Just xPub1) = xpubFromBytes paymentBs
          let addrXPub = liftXPub xPub1 :: Shelley 'PaymentK XPub
          let stakeBs = b16encode $ T.append verKeyStake verKeyStake
          let (Just xPub2) = xpubFromBytes stakeBs
          let stakeXPub = liftXPub xPub2 :: Shelley 'DelegationK XPub
          let (Right tag) = mkNetworkDiscriminant netTag
          let baseAddrBothFromKey =
                  delegationAddress tag (PaymentFromExtendedKey addrXPub)
                  (DelegationFromExtendedKey stakeXPub)
          let paymentKeyHashDigest = hashCredential $ BS.take 32 paymentBs
          let paymentKeyHash = KeyHash Payment paymentKeyHashDigest
          let stakeKeyHashDigest = hashCredential $ BS.take 32 stakeBs
          let stakeKeyHash = KeyHash Delegation stakeKeyHashDigest
          let baseAddrBothFromKeyHash =
                  delegationAddress tag (PaymentFromKeyHash paymentKeyHash)
                  (DelegationFromKeyHash stakeKeyHash)
          baseAddrBothFromKey `shouldBe` baseAddrBothFromKeyHash
  
  goldenTestBaseAddressBothFromPub :: GoldenTestBaseAddress -> SpecWith ()
  goldenTestBaseAddressBothFromPub GoldenTestBaseAddress{..} =
      it ("base address for networkId " <> show netTag) $ do
          let paymentBs = b16encode $ T.append verKeyPayment verKeyPayment
          let (Just xPub1) = xpubFromBytes paymentBs
          let addrXPub = liftXPub xPub1 :: Shelley 'PaymentK XPub
          let stakeBs = b16encode $ T.append verKeyStake verKeyStake
          let (Just xPub2) = xpubFromBytes stakeBs
          let stakeXPub = liftXPub xPub2 :: Shelley 'DelegationK XPub
          let (Right tag) = mkNetworkDiscriminant netTag
          let baseAddrBothFromKey =
                  delegationAddress tag (PaymentFromExtendedKey addrXPub)
                  (DelegationFromExtendedKey stakeXPub)
          let paymentBs1 = b16encode verKeyPayment
          let (Just pub1) = pubFromBytes paymentBs1
          let addrPub = liftPub pub1 :: Shelley 'PaymentK Pub
          let stakeBs1 = b16encode verKeyStake
          let (Just pub2) = pubFromBytes stakeBs1
          let stakePub = liftPub pub2 :: Shelley 'DelegationK Pub
          let baseAddrBothFromPub =
                  delegationAddress tag (PaymentFromKey addrPub)
                  (DelegationFromKey stakePub)
          baseAddrBothFromKey `shouldBe` baseAddrBothFromPub
  
  data KeysHashes = KeysHashes
      {  -- | CIP-1852’s DRep extended signing key (Ed25519-bip32 extended private key), bech32 encoded prefixed with 'drep_xsk'
        drepXsk :: Text
  
          -- | CIP-1852’s DRep extended signing key (Ed25519-bip32 extended private key), base16 encoded
      , drepXskHex :: Text
  
         -- | CIP-1852’s DRep signing key (Ed25519-bip32 non-extended private key), bech32 encoded prefixed with 'drep_sk'
      , drepSk :: Text
  
         -- | CIP-1852’s DRep signing key (Ed25519-bip32 non-extended private key), base16 encoded
      , drepSkHex :: Text
  
         -- | CIP-1852’s DRep extended verification key (Ed25519 public key with chain code), bech32 encoded prefixed with 'drep_xvk'
      , drepXvk :: Text
  
         -- | CIP-1852’s DRep extended verification key (Ed25519 public key with chain code), base16 encoded
      , drepXvkHex :: Text
  
         -- | CIP-1852’s DRep verification key (Ed25519 public key), bech32 encoded prefixed with 'drep_vk'
      , drepVk :: Text
  
         -- | CIP-1852’s DRep verification key (Ed25519 public key), base16 encoded
      , drepVkHex :: Text
  
         -- | Delegate representative verification key hash (DRep ID) (blake2b_224 digest of a delegate representative verification key), bech32 encoded prefixed with 'drep'
      , drep :: Text
  
         -- | Delegate representative verification key hash (DRep ID) (blake2b_224 digest of a delegate representative verification key), base16 encoded
      , drepHex :: Text
  
         -- | Delegate representative script hash (DRep ID) (blake2b_224 digest of a serialized delegate representative script prepended with 00100011 byte), bech32 encoded prefixed with 'drep'
         -- script: all [drep, active_from 5001]
      , drepScript1 :: Text
  
         -- | Delegate representative script hash (DRep ID) (blake2b_224 digest of a serialized delegate representative script), base16 encoded
         -- script: all [drep, active_from 5001]
      , drepScript1Hex :: Text
  
         -- | Delegate representative script hash (DRep ID) (blake2b_224 digest of a serialized delegate representative script prepended with 00100011 byte), bech32 encoded prefixed with 'drep'
         -- script: any [drep, all [active_from 5001, active_until 6001]]
      , drepScript2 :: Text
  
         -- | Delegate representative script hash (DRep ID) (blake2b_224 digest of a serialized delegate representative script), base16 encoded
         -- script: any [drep, all [active_from 5001, active_until 6001]]
      , drepScript2Hex :: Text
  
         -- | CIP-1852’s constitutional committee cold extended signing key (Ed25519-bip32 extended private key), bech32 encoded prefixed with 'cc_cold_xsk'
      , ccColdXsk :: Text
  
         -- | CIP-1852’s constitutional committee cold extended signing key (Ed25519-bip32 extended private key), base16 encoded
      , ccColdXskHex :: Text
  
         -- | CIP-1852’s constitutional committee cold signing key (Ed25519-bip32 non-extended private key), bech32 encoded prefixed with 'cc_cold_sk'
      , ccColdSk :: Text
  
         -- | CIP-1852’s constitutional committee cold signing key (Ed25519-bip32 non-extended private key), base16 encoded
      , ccColdSkHex :: Text
  
         -- | CIP-1852’s constitutional committee extended cold verification signing key (Ed25519 public key with chain code), bech32 encoded prefixed with 'cc_cold_xvk'
      , ccColdXvk :: Text
  
         -- | CIP-1852’s constitutional committee extended cold verification signing key (Ed25519 public key with chain code), base16 encoded
      , ccColdXvkHex :: Text
  
         -- | CIP-1852’s constitutional committee cold verification signing key (Ed25519 private key), bech32 encoded prefixed with 'cc_cold_vk'
      , ccColdVk :: Text
  
         -- | CIP-1852’s constitutional committee cold verification signing key (Ed25519 private key), base16 encoded
      , ccColdVkHex :: Text
  
         -- | Constitutional committee cold verification key hash (cold credential) (blake2b_224 digest of a consitutional committee cold verification key), bech32 encoded prefixed with 'cc_cold'
      , ccCold :: Text
  
         -- | Constitutional committee cold verification key hash (cold credential) (blake2b_224 digest of a consitutional committee cold verification key), base16 encoded
      , ccColdHex :: Text
  
         -- | Constitutional committee cold script hash (cold credential) (blake2b_224 digest of a serialized constitutional committee cold script prepended with 00010011 byte), bech32 encoded prefixed with 'cc_cold'
         -- script: all [ccCold, active_from 5001]
      , ccColdScript1 :: Text
  
         -- | Constitutional committee cold script hash (cold credential) (blake2b_224 digest of a serialized constitutional committee cold script), base16 encoded
         -- script: all [ccCold, active_from 5001]
      , ccColdScript1Hex :: Text
  
         -- | Constitutional committee cold script hash (cold credential) (blake2b_224 digest of a serialized constitutional committee cold script prepended with 00010011 byte), bech32 encoded prefixed with 'cc_cold'
         -- script: any [ccCold, all [active_from 5001, active_until 6001]]
      , ccColdScript2 :: Text
  
         -- | Constitutional committee cold script hash (cold credential) (blake2b_224 digest of a serialized constitutional committee cold script), base16 encoded
         -- script: any [ccCold, all [active_from 5001, active_until 6001]]
      , ccColdScript2Hex :: Text
  
         -- | CIP-1852’s constitutional committee hot extended signing key (Ed25519-bip32 extended private key), bech32 encoded prefixed with 'cc_hot_xsk'
      , ccHotXsk :: Text
  
         -- | CIP-1852’s constitutional committee hot extended signing key (Ed25519-bip32 extended private key), base16 encoded
      , ccHotXskHex :: Text
  
         -- | CIP-1852’s constitutional committee hot signing key (Ed25519-bip32 non-extended private key), bech32 encoded prefixed with 'cc_hot_sk'
      , ccHotSk :: Text
  
         -- | CIP-1852’s constitutional committee hot signing key (Ed25519-bip32 non-extended private key), base16 encoded
      , ccHotSkHex :: Text
  
         -- | CIP-1852’s constitutional committee extended hot verification signing key (Ed25519 public key with chain code), bech32 encoded prefixed with 'cc_hot_xvk'
      , ccHotXvk :: Text
  
         -- | CIP-1852’s constitutional committee extended hot verification signing key (Ed25519 public key with chain code), base16 encoded
      , ccHotXvkHex :: Text
  
         -- | CIP-1852’s constitutional committee hot verification signing key (Ed25519 private key), bech32 encoded prefixed with 'cc_hot_vk'
      , ccHotVk :: Text
  
         -- | CIP-1852’s constitutional committee hot verification signing key (Ed25519 private key), base16 encoded
      , ccHotVkHex :: Text
  
         -- | Constitutional committee hot verification key hash (hot credential) (blake2b_224 digest of a consitutional committee hot verification key), bech32 encoded prefixed with 'cc_hot'
      , ccHot :: Text
  
         -- | Constitutional committee hot verification key hash (hot credential) (blake2b_224 digest of a consitutional committee hot verification key), base16 encoded
      , ccHotHex :: Text
  
         -- | Constitutional committee hot script hash (hot credential) (blake2b_224 digest of a serialized constitutional committee hot script prepended with 00000011 byte), bech32 encoded prefixed with 'cc_hot'
         -- script: all [ccHot, active_from 5001]
      , ccHotScript1 :: Text
  
         -- | Constitutional committee hot script hash (hot credential) (blake2b_224 digest of a serialized constitutional committee hot script), base16 encoded
         -- script: all [ccHot, active_from 5001]
      , ccHotScript1Hex :: Text
  
         -- | Constitutional committee hot script hash (hot credential) (blake2b_224 digest of a serialized constitutional committee hot script prepended with 00000011 byte), bech32 encoded prefixed with 'cc_hot'
         -- script: any [ccHot, all [active_from 5001, active_until 6001]]
      , ccHotScript2 :: Text
  
             -- | Constitutional committee hot script hash (hot credential) (blake2b_224 digest of a serialized constitutional committee hot script), base16 encoded
         -- script: any [ccHot, all [active_from 5001, active_until 6001]]
      , ccHotScript2Hex :: Text
  
      } deriving (Eq, Show)
  
  data GoldenTestGovernance = GoldenTestGovernance
      {
        -- | Mnemonic
        mnemonic :: [Text]
  
        -- | Account ix
      , accountIx :: Word32
  
        -- | Expected Keys and Hashes
      , expectedKeysHashes :: KeysHashes
      }
  
  goldenTestGovernance :: GoldenTestGovernance -> SpecWith ()
  goldenTestGovernance GoldenTestGovernance{..} =
      it ("governance keys/hashes for " <> show mnemonic <> " and accIx="<>show accountIx) $ do
          let (Right mw) = mkSomeMnemonic @'[9,12,15,18,21,24] mnemonic
          let sndFactor = mempty
          let rootXPrv = genMasterKeyFromMnemonic mw sndFactor :: Shelley 'RootK XPrv
  
          let Just accIx = indexFromWord32 @(Index 'Hardened _) accountIx
          let acctXPrv = deriveAccountPrivateKey rootXPrv accIx
  
          let drepXPrv = deriveDRepPrivateKey acctXPrv
          let drepXPrvTxt = bech32With CIP5.drep_xsk  $ getExtendedKeyAddr drepXPrv
          let drepXPrvTxtHex = tob16text . unAddress $ getExtendedKeyAddr drepXPrv
          let drepPrvTxt = bech32With CIP5.drep_sk  $ getPrivateKeyAddr drepXPrv
          let drepPrvTxtHex = T.decodeUtf8 $ encode EBase16 $ unAddress $ getPrivateKeyAddr drepXPrv
          let drepXPubTxt = bech32With CIP5.drep_xvk $ getPublicKeyAddr $ toXPub <$> drepXPrv
          let drepXPubTxtHex = tob16text . unAddress $ getPublicKeyAddr $ toXPub <$> drepXPrv
          let drepPubTxt = bech32With CIP5.drep_vk $ getVerKey $ toXPub <$> drepXPrv
          let drepPubTxtHex = tob16text . unAddress $ getVerKey $ toXPub <$> drepXPrv
          let drepKeyHash = toKeyHash Representative $ toXPub <$> drepXPrv
          let drepTxt = keyHashToText drepKeyHash CIP0129
          let drepTxtHex = tob16text . digest $ drepKeyHash
          let drepScriptHash1 = toScriptHash (script1 drepKeyHash)
          let drepScript1Txt = toScriptTxt drepScriptHash1 CIP5.drep
          let drepScript1TxtHex = tob16text . unScriptHash $ drepScriptHash1
          let drepScriptHash2 = toScriptHash (script2 drepKeyHash)
          let drepScript2Txt = toScriptTxt drepScriptHash2 CIP5.drep
          let drepScript2TxtHex = tob16text . unScriptHash $ drepScriptHash2
  
          let coldXPrv = deriveCCColdPrivateKey acctXPrv
          let coldXPrvTxt = bech32With CIP5.cc_cold_xsk $ getExtendedKeyAddr coldXPrv
          let coldXPrvTxtHex = tob16text . unAddress $ getExtendedKeyAddr coldXPrv
          let coldPrvTxt = bech32With CIP5.cc_cold_sk  $ getPrivateKeyAddr coldXPrv
          let coldPrvTxtHex = T.decodeUtf8 $ encode EBase16 $ unAddress $ getPrivateKeyAddr coldXPrv
          let coldXPubTxt = bech32With CIP5.cc_cold_xvk $ getPublicKeyAddr $ toXPub <$> coldXPrv
          let coldXPubTxtHex = tob16text . unAddress  $ getPublicKeyAddr $ toXPub <$> coldXPrv
          let coldPubTxt = bech32With CIP5.cc_cold_vk $ getVerKey $ toXPub <$> coldXPrv
          let coldPubTxtHex = tob16text . unAddress $ getVerKey $ toXPub <$> coldXPrv
          let coldKeyHash = toKeyHash CommitteeCold $ toXPub <$> coldXPrv
          let coldTxt = keyHashToText coldKeyHash CIP0129
          let coldTxtHex = tob16text . digest $ coldKeyHash
          let coldScriptHash1 = toScriptHash (script1 coldKeyHash)
          let coldScript1Txt = toScriptTxt coldScriptHash1 CIP5.cc_cold
          let coldScript1TxtHex = tob16text . unScriptHash $ coldScriptHash1
          let coldScriptHash2 = toScriptHash (script2 coldKeyHash)
          let coldScript2Txt = toScriptTxt coldScriptHash2 CIP5.cc_cold
          let coldScript2TxtHex = tob16text . unScriptHash $ coldScriptHash2
  
          let hotXPrv = deriveCCHotPrivateKey acctXPrv
          let hotXPrvTxt = bech32With CIP5.cc_hot_xsk  $ getExtendedKeyAddr hotXPrv
          let hotXPrvTxtHex = tob16text . unAddress $ getExtendedKeyAddr hotXPrv
          let hotPrvTxt = bech32With CIP5.cc_hot_sk  $ getPrivateKeyAddr hotXPrv
          let hotPrvTxtHex = T.decodeUtf8 $ encode EBase16 $ unAddress $ getPrivateKeyAddr hotXPrv
          let hotXPubTxt = bech32With CIP5.cc_hot_xvk $ getPublicKeyAddr $ toXPub <$> hotXPrv
          let hotXPubTxtHex = tob16text . unAddress  $ getPublicKeyAddr $ toXPub <$> hotXPrv
          let hotPubTxt = bech32With CIP5.cc_hot_vk $ getVerKey $ toXPub <$> hotXPrv
          let hotPubTxtHex = tob16text . unAddress $ getVerKey $ toXPub <$> hotXPrv
          let hotKeyHash = toKeyHash CommitteeHot $ toXPub <$> hotXPrv
          let hotTxt = keyHashToText hotKeyHash CIP0129
          let hotTxtHex = tob16text . digest $ hotKeyHash
          let hotScriptHash1 = toScriptHash (script1 hotKeyHash)
          let hotScript1Txt = toScriptTxt hotScriptHash1 CIP5.cc_hot
          let hotScript1TxtHex = tob16text . unScriptHash $ hotScriptHash1
          let hotScriptHash2 = toScriptHash (script2 hotKeyHash)
          let hotScript2Txt = toScriptTxt hotScriptHash2 CIP5.cc_hot
          let hotScript2TxtHex = tob16text . unScriptHash $ hotScriptHash2
  
          let derivedKeysHashes = KeysHashes
                  { drepXsk = drepXPrvTxt
                  , drepXskHex = drepXPrvTxtHex
                  , drepSk = drepPrvTxt
                  , drepSkHex = drepPrvTxtHex
                  , drepXvk = drepXPubTxt
                  , drepXvkHex = drepXPubTxtHex
                  , drepVk = drepPubTxt
                  , drepVkHex = drepPubTxtHex
                  , drep = drepTxt
                  , drepHex = drepTxtHex
                  , drepScript1 = drepScript1Txt
                  , drepScript1Hex = drepScript1TxtHex
                  , drepScript2 = drepScript2Txt
                  , drepScript2Hex = drepScript2TxtHex
                  , ccColdXsk = coldXPrvTxt
                  , ccColdXskHex = coldXPrvTxtHex
                  , ccColdSk = coldPrvTxt
                  , ccColdSkHex = coldPrvTxtHex
                  , ccColdXvk = coldXPubTxt
                  , ccColdXvkHex = coldXPubTxtHex
                  , ccColdVk = coldPubTxt
                  , ccColdVkHex = coldPubTxtHex
                  , ccCold = coldTxt
                  , ccColdHex = coldTxtHex
                  , ccColdScript1 = coldScript1Txt
                  , ccColdScript1Hex = coldScript1TxtHex
                  , ccColdScript2 = coldScript2Txt
                  , ccColdScript2Hex = coldScript2TxtHex
                  , ccHotXsk = hotXPrvTxt
                  , ccHotXskHex = hotXPrvTxtHex
                  , ccHotSk = hotPrvTxt
                  , ccHotSkHex = hotPrvTxtHex
                  , ccHotXvk = hotXPubTxt
                  , ccHotXvkHex = hotXPubTxtHex
                  , ccHotVk = hotPubTxt
                  , ccHotVkHex = hotPubTxtHex
                  , ccHot = hotTxt
                  , ccHotHex = hotTxtHex
                  , ccHotScript1 = hotScript1Txt
                  , ccHotScript1Hex = hotScript1TxtHex
                  , ccHotScript2 = hotScript2Txt
                  , ccHotScript2Hex = hotScript2TxtHex
                  }
          derivedKeysHashes `shouldBe` expectedKeysHashes
    where
      getVerKey = unsafeMkAddress . pubToBytes . xpubToPub . getKey
      toKeyHash role =
            KeyHash role
          . hashCredential
          . pubToBytes
          . xpubToPub
          . getKey
      script1 keyhash =
          RequireAllOf [RequireSignatureOf keyhash, ActiveFromSlot 5001]
      script2 keyhash =
          RequireAnyOf [ RequireSignatureOf keyhash
                       , RequireAllOf [ ActiveFromSlot 5001, ActiveUntilSlot 6001]
                       ]
      toScriptTxt (ScriptHash bytes) hrp =
          bech32With hrp $
          unsafeMkAddress bytes
  
  data TestVector = TestVector
      {
        -- | The extended root private key, bech32 encoded prefixed with 'root_xsk'
        rootXPrv :: Text
  
        -- | The extended 0th account private key, bech32 encoded prefixed with 'acct_xsk'
      , accXPrv0 :: Text
  
        -- | The extended 1st account private key, bech32 encoded prefixed with 'acct_xsk'
      , accXPrv1 :: Text
  
        -- | The extended 0th address private key, bech32 encoded prefixed with 'addr_xsk'
      , addrXPrv0 :: Text
  
        -- | The extended 0th address public key, bech32 encoded prefixed with 'addr_xvk'
      , addrXPub0 :: Text
  
        -- | The extended 1st address private key, bech32 encoded prefixed with 'addr_xsk'
      , addrXPrv1 :: Text
  
        -- | The extended 1st address public key, bech32 encoded prefixed with 'addr_xvk'
      , addrXPub1 :: Text
  
        -- | The extended 1442nd address private key, bech32 encoded prefixed with 'addr_xsk'
      , addrXPrv1442 :: Text
  
        -- | The extended 1442nd address public key, bech32 encoded prefixed with 'addr_xvk'
      , addrXPub1442 :: Text
  
        -- | The payment address for 0th address key, with a networking tag 0, 3 and 6, respectively.
        -- Each bech32 encoded prefixed with 'addr'
      , paymentAddr0 :: [Text]
  
        -- | The payment address for 1st address key, with a networking tag 0, 3 and 6, respectively.
        -- Each bech32 encoded prefixed with 'addr'
      , paymentAddr1 :: [Text]
  
        -- | The payment address for 1442nd address key, with a networking tag 0, 3 and 6, respectively.
        -- Each bech32 encoded prefixed with 'addr'
      , paymentAddr1442 :: [Text]
  
        -- | Delegation addresses for the 0th address key and the 0th account delegation key,
        -- with a networking tag 0, 3 and 6, respectively. Each bech32 encoded prefixed with 'addr'
       , delegationAddr0Stake0 :: [Text]
  
        -- | Delegation addresses for the 1st address key and the 0th account delegation key,
        -- with a networking tag 0, 3 and 6, respectively. Each bech32 encoded prefixed with 'addr'
       , delegationAddr1Stake0 :: [Text]
  
        -- | Delegation addresses for the 1442nd address key and the 0th account delegation key,
        -- with a networking tag 0, 3 and 6, respectively. Each bech32 encoded prefixed with 'addr'
       , delegationAddr1442Stake0 :: [Text]
  
        -- | Delegation addresses for the 0th address key and the 1st account delegation key,
        -- with a networking tag 0, 3 and 6, respectively. Each bech32 encoded prefixed with 'addr'
       , delegationAddr0Stake1 :: [Text]
  
        -- | Delegation addresses for the 1st address key and the 1st account delegation key,
        -- with a networking tag 0, 3 and 6, respectively. Each bech32 encoded prefixed with 'addr'
       , delegationAddr1Stake1 :: [Text]
  
        -- | Delegation addresses for the 1442nd address key and the 1st account delegation key,
        -- with a networking tag 0, 3 and 6, respectively. Each bech32 encoded prefixed with 'addr'
       , delegationAddr1442Stake1 :: [Text]
  
        -- | Pointer addresses for the 0th address key and the delegation certificate located in slot 1,
        -- transaction index 2, certificte list index 3, with a networking tag 0, 3 and 6, respectively.
        -- Each bech32 encoded prefixed with 'addr'
       , pointerAddr0Slot1 :: [Text]
  
        -- | Pointer addresses for the 0th address key and the delegation certificate located in slot 24157,
        -- transaction index 177, certificte list index 42, with a networking tag 0, 3 and 6, respectively.
        -- Each bech32 encoded prefixed with 'addr'
       , pointerAddr0Slot2 :: [Text]
  
        -- | Corresponding Mnemonic
      , mnemonic :: [Text]
  
      } deriving Show
  
  data InspectVector a = InspectVector
      { addrXPub0 :: a
      , addrXPub1 :: a
      , addrXPub1442 :: a
      , paymentAddr0 :: [a]
      , paymentAddr1 :: [a]
      , paymentAddr1442 :: [a]
      , delegationAddr0Stake0 :: [a]
      , delegationAddr1Stake0 :: [a]
      , delegationAddr1442Stake0 :: [a]
      , delegationAddr0Stake1 :: [a]
      , delegationAddr1Stake1 :: [a]
      , delegationAddr1442Stake1 :: [a]
      , pointerAddr0Slot1 :: [a]
      , pointerAddr0Slot2 :: [a]
      } deriving (Generic, Show, Functor)
      deriving anyclass ToJSON
  
  testVectors :: [Text] -> SpecWith ()
  testVectors mnemonic = describe (show $ T.unpack <$> mnemonic) $ do
      let (Right mw) = mkSomeMnemonic @'[9,12,15,18,21,24] mnemonic
      let sndFactor = mempty
      let rootK = genMasterKeyFromMnemonic mw sndFactor :: Shelley 'RootK XPrv
      let rootXPrv = bech32With CIP5.root_xsk $ getExtendedKeyAddr rootK
  
      let Just accIx0 = indexFromWord32 @(Index 'Hardened _) 0x80000000
      let acctK0 = deriveAccountPrivateKey rootK accIx0
      let accXPrv0 = bech32With CIP5.acct_xsk  $ getExtendedKeyAddr acctK0
      let Just accIx1 = indexFromWord32 @(Index 'Hardened _) 0x80000001
      let acctK1 = deriveAccountPrivateKey rootK accIx1
      let accXPrv1 = bech32With CIP5.acct_xsk $ getExtendedKeyAddr acctK1
  
      let Just addIx0 = indexFromWord32 @(Index 'Soft _) 0x00000000
      let addrK0prv = deriveAddressPrivateKey acctK0 UTxOExternal addIx0
      let addrXPrv0 = bech32With CIP5.addr_xsk $ getExtendedKeyAddr addrK0prv
      let addrXPub0 = bech32With CIP5.addr_xvk $ getPublicKeyAddr $ toXPub <$> addrK0prv
  
      let Just addIx1 = indexFromWord32 @(Index 'Soft _) 0x00000001
      let addrK1prv = deriveAddressPrivateKey acctK0 UTxOExternal addIx1
      let addrXPrv1 = bech32With CIP5.addr_xsk $ getExtendedKeyAddr addrK1prv
      let addrXPub1 = bech32With CIP5.addr_xvk $ getPublicKeyAddr $ toXPub <$> addrK1prv
      let Just addIx1442 = indexFromWord32 @(Index 'Soft _) 0x000005a2
      let addrK1442prv = deriveAddressPrivateKey acctK0 UTxOExternal addIx1442
      let addrXPrv1442 = bech32With CIP5.addr_xsk $ getExtendedKeyAddr addrK1442prv
      let addrXPub1442 = bech32With CIP5.addr_xvk $ getPublicKeyAddr $ toXPub <$> addrK1442prv
  
      let networkTags = rights $ mkNetworkDiscriminant <$> [0,3,6]
      let paymentAddr0 = getPaymentAddr addrK0prv <$> networkTags
      let paymentAddr1 = getPaymentAddr addrK1prv <$> networkTags
      let paymentAddr1442 = getPaymentAddr addrK1442prv <$> networkTags
  
      let slot1 = ChainPointer 1 2 3
      let pointerAddr0Slot1 = getPointerAddr addrK0prv slot1 <$> networkTags
      let slot2 = ChainPointer 24157 177 42
      let pointerAddr0Slot2 = getPointerAddr addrK0prv slot2 <$> networkTags
  
      let stakeKPub0 = toXPub <$> deriveDelegationPrivateKey acctK0
      let delegationAddr0Stake0 = getDelegationAddr addrK0prv (DelegationFromExtendedKey stakeKPub0) <$> networkTags
      let delegationAddr1Stake0 = getDelegationAddr addrK1prv (DelegationFromExtendedKey stakeKPub0) <$> networkTags
      let delegationAddr1442Stake0 = getDelegationAddr addrK1442prv (DelegationFromExtendedKey stakeKPub0) <$> networkTags
      let stakeKPub1 = toXPub <$> deriveDelegationPrivateKey acctK1
      let delegationAddr0Stake1 = getDelegationAddr addrK0prv (DelegationFromExtendedKey stakeKPub1) <$> networkTags
      let delegationAddr1Stake1 = getDelegationAddr addrK1prv (DelegationFromExtendedKey stakeKPub1) <$> networkTags
      let delegationAddr1442Stake1 = getDelegationAddr addrK1442prv (DelegationFromExtendedKey stakeKPub1) <$> networkTags
      let vec = TestVector {..}
      let inspectVec = InspectVector {..}
      it "should generate correct addresses" $ do
          goldenTextLazy ("addresses_" <> shortHex (T.intercalate "_" mnemonic))
              (pShowOpt defaultOutputOptionsNoColor vec)
      it "should inspect correctly" $ do
          goldenByteStringLazy ("inspects_" <> shortHex (T.intercalate "_" mnemonic)) $
              goldenEncodeJSON $ toInspect <$> inspectVec
    where
      getPaymentAddr addrKPrv net =  bech32 $ paymentAddress net (PaymentFromExtendedKey (toXPub <$> addrKPrv))
      getPointerAddr addrKPrv ptr net =  bech32 $ pointerAddress net (PaymentFromExtendedKey (toXPub <$> addrKPrv)) ptr
      getDelegationAddr addrKPrv stakeKPub net =
          bech32 $ delegationAddress net (PaymentFromExtendedKey (toXPub <$> addrKPrv)) stakeKPub
      toInspect :: Text -> Value
      toInspect = fromMaybe (String "couldn't inspect") .
          (Shelley.inspectAddress Nothing <=< fromBech32)
  
  -- | Make a short name for a mnemonic by hashing it and taking the first 8 characters
  shortHex :: Text -> Text
  shortHex = T.take 8 . T.decodeUtf8 . BAE.convertToBase BAE.Base16 . hashByteString . T.encodeUtf8
    where
      hashByteString :: ByteString -> ByteString
      hashByteString = BA.convert . hashWith SHA3_256
  
  getExtendedKeyAddr :: Shelley depth XPrv -> Address
  getExtendedKeyAddr = unsafeMkAddress . xprvToBytes . getKey
  
  getPrivateKeyAddr :: Shelley depth XPrv -> Address
  getPrivateKeyAddr = unsafeMkAddress . xprvPrivateKey . getKey
  
  getPublicKeyAddr :: Shelley depth XPub -> Address
  getPublicKeyAddr = unsafeMkAddress . xpubToBytes . getKey
  
  goldenEncodeJSON :: ToJSON a => a -> BL.ByteString
  goldenEncodeJSON = Aeson.encodePretty' cfg
    where
      cfg = Aeson.defConfig { Aeson.confCompare = compare }
  
  prop_roundtripTextEncoding
      :: (Address -> Text)
          -- ^ encode to 'Text'
      -> (Text -> Maybe Address)
          -- ^ decode from 'Text'
      -> Shelley 'PaymentK XPub
          -- ^ An arbitrary public key
      -> NetworkDiscriminant Shelley
          -- ^ An arbitrary network discriminant
      -> Property
  prop_roundtripTextEncoding encode' decode addXPub discrimination =
      (result == pure address)
          & counterexample (unlines
              [ "Address " <> T.unpack (encode' address)
              , "↳       " <> maybe "ø" (T.unpack . encode') result
              ])
          & label (show $ addressDiscrimination @Shelley discrimination)
    where
      address = paymentAddress discrimination (PaymentFromExtendedKey addXPub)
      result  = decode (encode' address)
  
  prop_roundtripTextEncodingDelegation
      :: (Address -> Text)
          -- ^ encode to 'Text'
      -> (Text -> Maybe Address)
          -- ^ decode from 'Text'
      -> Shelley 'PaymentK XPub
          -- ^ An arbitrary address public key
      -> Shelley 'DelegationK XPub
          -- ^ An arbitrary delegation public key
      -> NetworkDiscriminant Shelley
          -- ^ An arbitrary network discriminant
      -> Property
  prop_roundtripTextEncodingDelegation encode' decode addXPub delegXPub discrimination =
      (result == pure address)
          & counterexample (unlines
              [ "Address " <> T.unpack (encode' address)
              , "↳       " <> maybe "ø" (T.unpack . encode') result
              ])
          & label (show $ addressDiscrimination @Shelley discrimination)
    where
      address = delegationAddress discrimination (PaymentFromExtendedKey addXPub) (DelegationFromExtendedKey delegXPub)
      result  = decode (encode' address)
  
  prop_roundtripTextEncodingPointer
      :: (Address -> Text)
          -- ^ encode to 'Text'
      -> (Text -> Maybe Address)
          -- ^ decode from 'Text'
      -> Shelley 'PaymentK XPub
          -- ^ An arbitrary address public key
      -> ChainPointer
          -- ^ An arbitrary delegation key locator
      -> NetworkDiscriminant Shelley
          -- ^ An arbitrary network discriminant
      -> Property
  prop_roundtripTextEncodingPointer encode' decode addXPub ptr discrimination =
      (result == pure address)
          & counterexample (unlines
              [ "Address " <> T.unpack (encode' address)
              , "↳       " <> maybe "ø" (T.unpack . encode') result
              ])
          & label (show $ addressDiscrimination @Shelley discrimination)
    where
      address = pointerAddress discrimination (PaymentFromExtendedKey addXPub) ptr
      result  = decode (encode' address)
  
  goldenTextLazy :: Text -> TL.Text -> Golden TL.Text
  goldenTextLazy name output =
      Golden
      { output = output
      , encodePretty = TL.unpack
      , writeToFile = TL.writeFile
      , readFromFile = TL.readFile
      , testName = T.unpack name
      , directory = "test/golden"
      , failFirstTime = False
      }
  
  goldenByteStringLazy :: Text -> BL.ByteString -> Golden BL.ByteString
  goldenByteStringLazy name output =
      Golden
      { output = output
      , encodePretty = TL.unpack . TLE.decodeUtf8
      , writeToFile = \ fp -> BL.writeFile fp . normalizeLBS
      , readFromFile = fmap normalizeLBS . BL.readFile
      , testName = T.unpack name
      , directory = "test/golden"
      , failFirstTime = False
      }
  
  -- This should be sufficent to convert Windows "\r\n" newlines to UNIX "\n" newlines
  -- as used by both Mac and Linux.
  normalizeLBS :: BL.ByteString -> BL.ByteString
  normalizeLBS = BL.filter (/= fromIntegral (Char.ord '\r'))
  
  {-------------------------------------------------------------------------------
                               Arbitrary Instances
  -------------------------------------------------------------------------------}
  
  newtype SndFactor = SndFactor ScrubbedBytes
      deriving stock (Eq, Show)
      deriving newtype (ByteArrayAccess)
  
  instance Arbitrary SndFactor where
      arbitrary = do
          n <- choose (0, 64)
          bytes <- BS.pack <$> vector n
          return $ SndFactor $ BA.convert bytes
  
  tob16text :: ByteString -> Text
  tob16text =  T.decodeUtf8 . encode EBase16
  
  b16encode :: Text -> ByteString
  b16encode = encode EBase16 . T.encodeUtf8
  
  b16decode :: Text -> Either String ByteString
  b16decode = fromBase16 . T.encodeUtf8
  