Skip to content

Commit

Permalink
SCP-2506: Moved functions from plutus-ledger-api to plutus-ledger
Browse files Browse the repository at this point in the history
  • Loading branch information
koslambrou committed Jul 21, 2021
1 parent db4cf45 commit 66619a9
Show file tree
Hide file tree
Showing 24 changed files with 276 additions and 214 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions plutus-ledger-api/plutus-ledger-api.cabal
Expand Up @@ -61,8 +61,6 @@ library
cborg -any,
containers -any,
cryptonite >=0.25,
cardano-crypto -any,
cardano-crypto-class -any,
flat -any,
hashable -any,
plutus-core -any,
Expand Down
16 changes: 2 additions & 14 deletions plutus-ledger-api/src/Plutus/V1/Ledger/Address.hs
Expand Up @@ -10,9 +10,7 @@

module Plutus.V1.Ledger.Address (
Address (..),
pubKeyAddress,
pubKeyHashAddress,
scriptAddress,
scriptHashAddress,
toPubKeyHash,
toValidatorHash,
Expand All @@ -25,7 +23,7 @@ import Data.Aeson (FromJSON, FromJSONKey (..), ToJSON
import Data.Hashable (Hashable)
import Data.Text.Prettyprint.Doc
import GHC.Generics (Generic)
import qualified PlutusTx as PlutusTx
import qualified PlutusTx
import qualified PlutusTx.Bool as PlutusTx
import qualified PlutusTx.Eq as PlutusTx

Expand All @@ -35,7 +33,7 @@ import Plutus.V1.Ledger.Orphans ()
import Plutus.V1.Ledger.Scripts

-- | Address with two kinds of credentials, normal and staking
data Address = Address{ addressCredential :: Credential, addressStakingCredential :: (Maybe StakingCredential)}
data Address = Address{ addressCredential :: Credential, addressStakingCredential :: Maybe StakingCredential }
deriving stock (Eq, Ord, Show, Generic)
deriving anyclass (ToJSON, FromJSON, ToJSONKey, FromJSONKey, Serialise, Hashable, NFData)

Expand All @@ -44,17 +42,11 @@ instance Pretty Address where
let staking = maybe "no staking credential" pretty stakingCred in
"addressed to" <+> pretty cred <+> parens staking


instance PlutusTx.Eq Address where
Address cred stakingCred == Address cred' stakingCred' =
cred PlutusTx.== cred'
PlutusTx.&& stakingCred PlutusTx.== stakingCred'

{-# INLINABLE pubKeyAddress #-}
-- | The address that should be targeted by a transaction output locked by the given public key.
pubKeyAddress :: PubKey -> Address
pubKeyAddress pk = Address (PubKeyCredential (pubKeyHash pk)) Nothing

{-# INLINABLE pubKeyHashAddress #-}
-- | The address that should be targeted by a transaction output locked by the public key with the given hash.
pubKeyHashAddress :: PubKeyHash -> Address
Expand All @@ -72,10 +64,6 @@ toValidatorHash :: Address -> Maybe ValidatorHash
toValidatorHash (Address (ScriptCredential k) _) = Just k
toValidatorHash _ = Nothing

-- | The address that should be used by a transaction output locked by the given validator script.
scriptAddress :: Validator -> Address
scriptAddress validator = Address (ScriptCredential (validatorHash validator)) Nothing

{-# INLINABLE scriptHashAddress #-}
-- | The address that should be used by a transaction output locked by the given validator script hash.
scriptHashAddress :: ValidatorHash -> Address
Expand Down
4 changes: 0 additions & 4 deletions plutus-ledger-api/src/Plutus/V1/Ledger/Api.hs
Expand Up @@ -79,18 +79,14 @@ module Plutus.V1.Ledger.Api (
, mkValidatorScript
, unValidatorScript
, ValidatorHash (..)
, validatorHash
, MintingPolicy (..)
, mkMintingPolicyScript
, unMintingPolicyScript
, MintingPolicyHash (..)
, mintingPolicyHash
, Redeemer (..)
, RedeemerHash (..)
, redeemerHash
, Datum (..)
, DatumHash (..)
, datumHash
-- * Data
, PLC.Data (..)
, BuiltinData (..)
Expand Down
10 changes: 1 addition & 9 deletions plutus-ledger-api/src/Plutus/V1/Ledger/Contexts.hs
Expand Up @@ -32,8 +32,6 @@ module Plutus.V1.Ledger.Contexts
, findContinuingOutputs
, getContinuingOutputs
-- ** Hashes (see note [Hashes in validator scripts])
, scriptCurrencySymbol
, pubKeyHash
-- * Validator functions
-- ** Signatures
, txSignedBy
Expand Down Expand Up @@ -64,14 +62,13 @@ import qualified Plutus.V1.Ledger.Ada as Ada
import Plutus.V1.Ledger.Address (Address (..), toPubKeyHash)
import Plutus.V1.Ledger.Bytes (LedgerBytes (..))
import Plutus.V1.Ledger.Credential (Credential (..), StakingCredential)
import Plutus.V1.Ledger.Crypto (PubKey (..), PubKeyHash (..), Signature (..), pubKeyHash)
import Plutus.V1.Ledger.Crypto (PubKey (..), PubKeyHash (..), Signature (..))
import Plutus.V1.Ledger.DCert (DCert (..))
import Plutus.V1.Ledger.Scripts
import Plutus.V1.Ledger.Time (POSIXTimeRange)
import Plutus.V1.Ledger.Tx (TxOut (..), TxOutRef (..))
import Plutus.V1.Ledger.TxId
import Plutus.V1.Ledger.Value (CurrencySymbol (..), Value)
import qualified Plutus.V1.Ledger.Value as Value

{- Note [Script types in pending transactions]
To validate a transaction, we have to evaluate the validation script of each of
Expand Down Expand Up @@ -181,11 +178,6 @@ them from the correct types in Haskell, and for comparing them (in
-}

{-# INLINABLE scriptCurrencySymbol #-}
-- | The 'CurrencySymbol' of a 'MintingPolicy'
scriptCurrencySymbol :: MintingPolicy -> CurrencySymbol
scriptCurrencySymbol scrpt = let (MintingPolicyHash hsh) = mintingPolicyHash scrpt in Value.currencySymbol hsh

{-# INLINABLE txSignedBy #-}
-- | Check if a transaction was signed by the given public key.
txSignedBy :: TxInfo -> PubKeyHash -> Bool
Expand Down
87 changes: 2 additions & 85 deletions plutus-ledger-api/src/Plutus/V1/Ledger/Crypto.hs
Expand Up @@ -5,56 +5,32 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}

{-# OPTIONS_GHC -fno-omit-interface-pragmas #-}

module Plutus.V1.Ledger.Crypto(
PubKey(..)
, PubKeyHash(..)
, pubKeyHash
, PrivateKey(..)
, Signature(..)
, signedBy
, sign
, signTx
, fromHex
, toPublicKey
-- $privateKeys
, knownPrivateKeys
, privateKey1
, privateKey2
, privateKey3
, privateKey4
, privateKey5
, privateKey6
, privateKey7
, privateKey8
, privateKey9
, privateKey10
) where

import Cardano.Crypto.Hash as Crypto
import Codec.Serialise.Class (Serialise)
import Control.DeepSeq (NFData)
import Control.Newtype.Generics (Newtype)
import qualified Crypto.ECC.Ed25519Donna as ED25519
import Crypto.Error (throwCryptoError)
import Data.Aeson (FromJSON (parseJSON), FromJSONKey, FromJSONKeyFunction (FromJSONKeyValue),
ToJSON (toJSON), ToJSONKey, ToJSONKeyFunction (ToJSONKeyValue),
genericParseJSON, genericToJSON, (.:))
import qualified Data.Aeson as JSON
import qualified Data.Aeson.Extras as JSON
import qualified Data.ByteArray as BA
import qualified Data.ByteString as BS
import Data.Either.Extras (unsafeFromEither)
import Data.Hashable (Hashable)
import Data.String
import Data.Text.Prettyprint.Doc
import GHC.Generics (Generic)
import Plutus.V1.Ledger.Bytes (LedgerBytes (..))
import qualified Plutus.V1.Ledger.Bytes as KB
import Plutus.V1.Ledger.Orphans ()
import Plutus.V1.Ledger.TxId
import qualified PlutusTx as PlutusTx
import qualified PlutusTx
import qualified PlutusTx.Builtins as Builtins
import PlutusTx.Lift (makeLift)
import qualified PlutusTx.Prelude as P
Expand Down Expand Up @@ -83,13 +59,6 @@ newtype PubKeyHash = PubKeyHash { getPubKeyHash :: BS.ByteString }
deriving (Show, Pretty) via LedgerBytes
makeLift ''PubKeyHash

-- | Compute the hash of a public key.
pubKeyHash :: PubKey -> PubKeyHash
pubKeyHash (PubKey (LedgerBytes bs)) =
PubKeyHash
$ Crypto.hashToBytes
$ Crypto.hashWith @Crypto.Blake2b_224 id bs

-- | A cryptographic private key.
newtype PrivateKey = PrivateKey { getPrivateKey :: LedgerBytes }
deriving stock (Eq, Ord, Generic)
Expand Down Expand Up @@ -123,55 +92,3 @@ instance FromJSON Signature where
pure . Signature $ bytes

makeLift ''Signature

-- | Check whether the given 'Signature' was signed by the private key corresponding to the given public key.
signedBy :: Signature -> PubKey -> TxId -> Bool
signedBy (Signature s) (PubKey k) txId =
let k' = ED25519.publicKey $ KB.getLedgerBytes k
s' = ED25519.signature s
in throwCryptoError $ ED25519.verify <$> k' <*> pure (getTxId txId) <*> s' -- TODO: is this what we want

-- | Sign the hash of a transaction using a private key.
signTx :: TxId -> PrivateKey -> Signature
signTx (TxId txId) = sign txId

-- | Sign a message using a private key.
sign :: BA.ByteArrayAccess a => a -> PrivateKey -> Signature
sign msg (PrivateKey privKey) =
let k = ED25519.secretKey $ KB.getLedgerBytes privKey
pk = ED25519.toPublic <$> k
salt :: BS.ByteString
salt = "" -- TODO: do we need better salt?
convert = Signature . BS.pack . BA.unpack
in throwCryptoError $ fmap convert (ED25519.sign <$> k <*> pure salt <*> pk <*> pure msg)

fromHex :: BS.ByteString -> Either String PrivateKey
fromHex = fmap PrivateKey . KB.fromHex

toPublicKey :: PrivateKey -> PubKey
toPublicKey = PubKey . KB.fromBytes . BS.pack . BA.unpack . ED25519.toPublic . f . KB.bytes . getPrivateKey where
f = throwCryptoError . ED25519.secretKey

-- $privateKeys
-- 'privateKey1', 'privateKey2', ... 'privateKey10' are ten predefined 'PrivateKey' values.
--
-- The private keys can be found in the 'sign.input' file linked from
-- http://ed25519.cr.yp.to/software.html.

privateKey1, privateKey2, privateKey3, privateKey4, privateKey5, privateKey6, privateKey7, privateKey8, privateKey9, privateKey10 :: PrivateKey
privateKey1 = unsafeFromEither $ fromHex "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"
privateKey2 = unsafeFromEither $ fromHex "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb"
privateKey3 = unsafeFromEither $ fromHex "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7"
privateKey4 = unsafeFromEither $ fromHex "691865bfc82a1e4b574eecde4c7519093faf0cf867380234e3664645c61c5f79"
privateKey5 = unsafeFromEither $ fromHex "3b26516fb3dc88eb181b9ed73f0bcd52bcd6b4c788e4bcaf46057fd078bee073"
privateKey6 = unsafeFromEither $ fromHex "edc6f5fbdd1cee4d101c063530a30490b221be68c036f5b07d0f953b745df192"
privateKey7 = unsafeFromEither $ fromHex "a980f892db13c99a3e8971e965b2ff3d41eafd54093bc9f34d1fd22d84115bb6"
privateKey8 = unsafeFromEither $ fromHex "9acad959d216212d789a119252ebfe0c96512a23c73bd9f3b202292d6916a738"
privateKey9 = unsafeFromEither $ fromHex "d5aeee41eeb0e9d1bf8337f939587ebe296161e6bf5209f591ec939e1440c300"
privateKey10 = unsafeFromEither $ fromHex "0a47d10452ae2febec518a1c7c362890c3fc1a49d34b03b6467d35c904a8362d"

-- | A list of 10 private keys.
-- TODO: Generate random private keys (I couldn't find a way to
-- do this in 'Crypto.ECC.Ed25519Donna' in 'cardano-crypto')
knownPrivateKeys :: [PrivateKey]
knownPrivateKeys = [privateKey1, privateKey2, privateKey3, privateKey4, privateKey5, privateKey6, privateKey7, privateKey8, privateKey9, privateKey10]
32 changes: 1 addition & 31 deletions plutus-ledger-api/src/Plutus/V1/Ledger/Scripts.hs
Expand Up @@ -14,6 +14,7 @@
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ViewPatterns #-}

{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# OPTIONS_GHC -fno-specialise #-}

Expand Down Expand Up @@ -46,18 +47,13 @@ module Plutus.V1.Ledger.Scripts(
RedeemerHash(..),
ValidatorHash(..),
MintingPolicyHash (..),
datumHash,
redeemerHash,
validatorHash,
mintingPolicyHash,
-- * Example scripts
unitRedeemer,
unitDatum,
) where

import qualified Prelude as Haskell

import qualified Cardano.Crypto.Hash as Crypto
import Codec.CBOR.Decoding (decodeBytes)
import Codec.Serialise (Serialise, decode, encode, serialise)
import Control.DeepSeq (NFData)
Expand Down Expand Up @@ -314,32 +310,6 @@ newtype MintingPolicyHash =
deriving newtype (Haskell.Eq, Haskell.Ord, Eq, Ord, Hashable, IsData)
deriving anyclass (FromJSON, ToJSON, ToJSONKey, FromJSONKey)

datumHash :: Datum -> DatumHash
datumHash = DatumHash . Builtins.sha2_256 . BA.convert

redeemerHash :: Redeemer -> RedeemerHash
redeemerHash = RedeemerHash . Builtins.sha2_256 . BA.convert

validatorHash :: Validator -> ValidatorHash
validatorHash vl =
ValidatorHash
$ Crypto.hashToBytes
$ Crypto.hashWith @Crypto.Blake2b_224 id
$ Crypto.hashToBytes
$ Crypto.hashWith @Crypto.Blake2b_224 id
$ BSL.toStrict
$ serialise vl

mintingPolicyHash :: MintingPolicy -> MintingPolicyHash
mintingPolicyHash vl =
MintingPolicyHash
$ Crypto.hashToBytes
$ Crypto.hashWith @Crypto.Blake2b_224 id
$ Crypto.hashToBytes
$ Crypto.hashWith @Crypto.Blake2b_224 id
$ BSL.toStrict
$ serialise vl

-- | Information about the state of the blockchain and about the transaction
-- that is currently being validated, represented as a value in 'Data'.
newtype Context = Context BuiltinData
Expand Down

0 comments on commit 66619a9

Please sign in to comment.