Skip to content

Commit

Permalink
Merge pull request #383 from Plutonomicon/firefrorefiddle/bytestypes
Browse files Browse the repository at this point in the history
Firefrorefiddle/bytestypes
  • Loading branch information
ngua committed May 23, 2022
2 parents c33e939 + 1d78f22 commit a57d657
Show file tree
Hide file tree
Showing 24 changed files with 387 additions and 178 deletions.
2 changes: 1 addition & 1 deletion flake.nix
Expand Up @@ -105,7 +105,7 @@
flake = false;
};
# NOTE
# I don't we need anything from `plutus-apps`, so the following two are
# I don't think we need anything from `plutus-apps`, so the following two are
# not necessary. They might be useful for communicating with the frontend
# however in case this is needed
purescript-bridge = {
Expand Down
12 changes: 7 additions & 5 deletions src/Cardano/Types/Value.purs
Expand Up @@ -89,7 +89,8 @@ import Serialization.Hash
, scriptHashToBytes
)
import ToData (class ToData)
import Types.ByteArray (ByteArray, byteArrayToHex, byteLength, hexToByteArray)
import Types.ByteArray (ByteArray, hexToByteArray, byteArrayToHex)
import Types.CborBytes (byteLength)
import Types.Scripts (MintingPolicyHash(MintingPolicyHash))
import Types.TokenName
( TokenName
Expand Down Expand Up @@ -220,7 +221,7 @@ unsafeAdaSymbol = CurrencySymbol mempty
-- | constructor is not exported
mkCurrencySymbol :: ByteArray -> Maybe CurrencySymbol
mkCurrencySymbol byteArr =
scriptHashFromBytes byteArr *> pure (CurrencySymbol byteArr)
scriptHashFromBytes (wrap byteArr) *> pure (CurrencySymbol byteArr)

-- Do not export. Create an Ada `CurrencySymbol` from a `ByteArray`
mkUnsafeAdaSymbol :: ByteArray -> Maybe CurrencySymbol
Expand Down Expand Up @@ -651,10 +652,10 @@ filterNonAda (Value _ nonAda) = Value mempty nonAda
-- already know is a valid CurrencySymbol
currencyScriptHash :: CurrencySymbol -> ScriptHash
currencyScriptHash (CurrencySymbol byteArray) =
unsafePartial fromJust $ scriptHashFromBytes byteArray
unsafePartial fromJust $ scriptHashFromBytes (wrap byteArray)

scriptHashAsCurrencySymbol :: ScriptHash -> CurrencySymbol
scriptHashAsCurrencySymbol = CurrencySymbol <<< scriptHashAsBytes
scriptHashAsCurrencySymbol = CurrencySymbol <<< unwrap <<< scriptHashAsBytes

-- | The minting policy hash of a currency symbol
currencyMPSHash :: CurrencySymbol -> MintingPolicyHash
Expand All @@ -665,7 +666,8 @@ currencyMPSHash = MintingPolicyHash <<< currencyScriptHash
-- Plutus doesn't use Maybe here.
-- | The currency symbol of a monetary policy hash
mpsSymbol :: MintingPolicyHash -> Maybe CurrencySymbol
mpsSymbol (MintingPolicyHash h) = mkCurrencySymbol $ scriptHashToBytes h
mpsSymbol (MintingPolicyHash h) = mkCurrencySymbol <<< unwrap $
scriptHashToBytes h

-- Like `mapEither` that works with 'These'.
mapThese
Expand Down
74 changes: 37 additions & 37 deletions src/Contract/Transaction.purs
Expand Up @@ -28,6 +28,38 @@ import Prelude
import BalanceTx (UnattachedTransaction)
import BalanceTx (balanceTx) as BalanceTx
import BalanceTx (BalanceTxError) as BalanceTxError
import Contract.Monad (Contract, liftedE, liftedM, wrapContract)
import Data.Either (Either, hush)
import Data.Generic.Rep (class Generic)
import Data.Lens.Getter ((^.))
import Data.Maybe (Maybe)
import Data.Newtype (class Newtype, unwrap, wrap)
import Data.Show.Generic (genericShow)
import Data.Tuple.Nested (type (/\), (/\))
import QueryM
( FeeEstimate(FeeEstimate)
, ClientError(..) -- implicit as this error list will likely increase.
, FinalizedTransaction(FinalizedTransaction)
) as ExportQueryM
import QueryM
( FinalizedTransaction(FinalizedTransaction)
, calculateMinFee
, signTransaction
, signTransactionBytes
, finalizeTx
, submitTxOgmios
) as QueryM
import ReindexRedeemers (reindexSpentScriptRedeemers) as ReindexRedeemers
import ReindexRedeemers
( ReindexErrors(CannotGetTxOutRefIndexForRedeemer)
) as ReindexRedeemersExport
import Types.CborBytes (CborBytes)
import Types.Datum (Datum)
import Types.ScriptLookups (UnattachedUnbalancedTx(UnattachedUnbalancedTx))
import Types.ScriptLookups
( MkUnbalancedTxError(..) -- A lot errors so will refrain from explicit names.
, mkUnbalancedTx
) as ScriptLookups
import Cardano.Types.Transaction (Transaction, _body, _inputs)
import Cardano.Types.Transaction -- Most re-exported, don't re-export `Redeemer` and associated lens.
( AuxiliaryData(AuxiliaryData)
Expand Down Expand Up @@ -103,45 +135,13 @@ import Cardano.Types.Transaction -- Most re-exported, don't re-export `Redeemer`
, _withdrawals
, _witnessSet
) as Transaction
import Contract.Monad (Contract, liftedE, liftedM, wrapContract)
import Data.Either (Either, hush)
import Data.Generic.Rep (class Generic)
import Data.Lens.Getter ((^.))
import Data.Maybe (Maybe)
import Data.Newtype (class Newtype, unwrap, wrap)
import Data.Show.Generic (genericShow)
import Data.Tuple.Nested (type (/\), (/\))
import Plutus.ToPlutusType (toPlutusType)
import Plutus.Types.Transaction
( TransactionOutput(TransactionOutput)
) as PTransaction
import Plutus.Types.Value (Coin)
import QueryM
( FeeEstimate(FeeEstimate)
, ClientError(..) -- implicit as this error list will likely increase.
, FinalizedTransaction(FinalizedTransaction)
) as ExportQueryM
import QueryM
( FinalizedTransaction(FinalizedTransaction)
, calculateMinFee
, signTransaction
, signTransactionBytes
, finalizeTx
, submitTxOgmios
) as QueryM
import Serialization.Address (NetworkId)
import ReindexRedeemers (reindexSpentScriptRedeemers) as ReindexRedeemers
import ReindexRedeemers
( ReindexErrors(CannotGetTxOutRefIndexForRedeemer)
) as ReindexRedeemersExport
import TxOutput (scriptOutputToTransactionOutput) as TxOutput
import Types.ByteArray (ByteArray)
import Types.Datum (Datum)
import Types.ScriptLookups (UnattachedUnbalancedTx(UnattachedUnbalancedTx))
import Types.ScriptLookups
( MkUnbalancedTxError(..) -- A lot errors so will refrain from explicit names.
, mkUnbalancedTx
) as ScriptLookups
import Types.Transaction (TransactionHash)
import Types.Transaction
( DataHash(DataHash)
Expand Down Expand Up @@ -178,13 +178,13 @@ signTransaction = wrapContract <<< QueryM.signTransaction
-- | Signs a `Transaction` with potential failure
signTransactionBytes
:: forall (r :: Row Type)
. ByteArray
-> Contract r (Maybe ByteArray)
. CborBytes
-> Contract r (Maybe CborBytes)
signTransactionBytes = wrapContract <<< QueryM.signTransactionBytes

-- | Submits a Cbor-hex encoded transaction, which is the output of
-- | `signTransactionBytes` or `balanceAndSignTx`
submit :: forall (r :: Row Type). ByteArray -> Contract r TransactionHash
submit :: forall (r :: Row Type). CborBytes -> Contract r TransactionHash
submit = wrapContract <<< map (wrap <<< unwrap) <<< QueryM.submitTxOgmios

-- | Query the Haskell server for the minimum transaction fee
Expand Down Expand Up @@ -243,7 +243,7 @@ reindexSpentScriptRedeemers balancedTx =

newtype BalancedSignedTransaction = BalancedSignedTransaction
{ transaction :: Transaction.Transaction -- the balanced and unsigned transaction to help with logging
, signedTxCbor :: ByteArray -- the balanced and signed cbor ByteArray representation used in `submit`
, signedTxCbor :: CborBytes -- the balanced and signed cbor ByteArray representation used in `submit`
}

derive instance Generic BalancedSignedTransaction _
Expand Down Expand Up @@ -275,7 +275,7 @@ balanceAndSignTx uaubTx@(UnattachedUnbalancedTx { datums }) = do
(finalizeTx balancedTx datums redeemers)
-- Sign the transaction returned as Cbor-hex encoded:
signedTxCbor <- liftedM "balanceAndSignTx: Failed to sign transaction" $
signTransactionBytes txCbor
signTransactionBytes (wrap txCbor)
pure $ pure $ BalancedSignedTransaction
{ transaction: balancedTx, signedTxCbor }

Expand Down
9 changes: 5 additions & 4 deletions src/Deserialization/Transaction.purs
Expand Up @@ -95,7 +95,7 @@ import Data.Bitraversable (bitraverse)
import Data.Either (Either)
import Data.Map as M
import Data.Maybe (Maybe)
import Data.Newtype (wrap)
import Data.Newtype (wrap, unwrap)
import Data.Ratio (Ratio, reduce)
import Data.Traversable (traverse, for)
import Data.Tuple (Tuple)
Expand Down Expand Up @@ -139,6 +139,7 @@ import Serialization.Types (NativeScripts, PlutusScripts)
import Serialization.Types as Csl
import Type.Row (type (+))
import Types.ByteArray (ByteArray)
import Types.CborBytes (CborBytes)
import Types.Int as Int
import Types.TransactionMetadata
( GeneralTransactionMetadata
Expand All @@ -154,10 +155,10 @@ import Cardano.Types.Value
import Untagged.Union (asOneOf)

-- | Deserializes CBOR encoded transaction to a CTL's native type.
-- NOTE: wrt ByteArray type and cbor keyword https://github.com/Plutonomicon/cardano-transaction-lib/issues/234
deserializeTransaction
:: forall (r :: Row Type). { txCbor :: ByteArray } -> Err r T.Transaction
deserializeTransaction { txCbor } = fromBytes' txCbor >>= convertTransaction
:: forall (r :: Row Type). CborBytes -> Err r T.Transaction
deserializeTransaction txCbor = fromBytes' (unwrap txCbor) >>=
convertTransaction

-- | Converts transaction from foreign CSL representation to CTL's one.
convertTransaction
Expand Down
3 changes: 2 additions & 1 deletion src/Deserialization/UnspentOutput.purs
Expand Up @@ -24,6 +24,7 @@ import Data.Bitraversable (bitraverse, ltraverse)
import Data.Map (Map)
import Data.Map as Map
import Data.Maybe (Maybe, fromMaybe)
import Data.Newtype (unwrap)
import Data.Traversable (for, traverse)
import Data.Tuple (Tuple(Tuple))
import Data.Tuple.Nested (type (/\))
Expand Down Expand Up @@ -98,7 +99,7 @@ convertValue value = do
( traverse
( bitraverse
-- scripthash to currency symbol
(scriptHashToBytes >>> T.mkCurrencySymbol)
(scriptHashToBytes >>> unwrap >>> T.mkCurrencySymbol)
-- nested assetname to tokenname
(traverse (ltraverse (T.assetNameName >>> T.mkTokenName)))
)
Expand Down
10 changes: 9 additions & 1 deletion src/FromData.purs
Expand Up @@ -20,7 +20,7 @@ import Data.Either (Either(Left, Right), hush, note)
import Data.Generic.Rep as G
import Data.List (List)
import Data.Maybe (Maybe(Nothing, Just), maybe)
import Data.Newtype (unwrap)
import Data.Newtype (wrap, unwrap)
import Data.NonEmpty (NonEmpty(NonEmpty))
import Data.Ratio (Ratio, reduce)
import Data.Show.Generic (genericShow)
Expand All @@ -44,6 +44,8 @@ import TypeLevel.RowList.Unordered.Indexed
, class GetWithLabel
)
import Types.ByteArray (ByteArray)
import Types.RawBytes (RawBytes)
import Types.CborBytes (CborBytes)
import Types.PlutusData (PlutusData(Bytes, Constr, List, Integer))

-- | Errors
Expand Down Expand Up @@ -290,6 +292,12 @@ instance FromData ByteArray where
fromData (Bytes res) = Just res
fromData _ = Nothing

instance FromData CborBytes where
fromData = map wrap <<< fromData

instance FromData RawBytes where
fromData = map wrap <<< fromData

instance FromData String where
fromData (Bytes bytes) = hush $ decodeUtf8 $ unwrap bytes
fromData _ = Nothing
Expand Down
4 changes: 2 additions & 2 deletions src/Metadata/Cip25.purs
Expand Up @@ -47,7 +47,7 @@ import Metadata.ToMetadata (class ToMetadata, toMetadata, anyToMetadata)
import Metadata.MetadataType (class MetadataType)
import Serialization.Hash (scriptHashFromBytes)
import Types.Scripts (MintingPolicyHash)
import Types.ByteArray (hexToByteArray)
import Types.RawBytes (hexToRawBytes)
import Types.PlutusData (PlutusData(Map))
import Types.TokenName (TokenName, mkTokenName)
import Types.TransactionMetadata (TransactionMetadatum(MetadataMap))
Expand Down Expand Up @@ -288,7 +288,7 @@ instance DecodeAeson Cip25Metadata where
decodePolicyId =
note (TypeMismatch "Expected hex-encoded policy id")
<<< map wrap
<<< (scriptHashFromBytes <=< hexToByteArray)
<<< (scriptHashFromBytes <=< hexToRawBytes)

decodeAssetName :: String -> Either JsonDecodeError TokenName
decodeAssetName =
Expand Down
8 changes: 5 additions & 3 deletions src/Metadata/Seabug.purs
Expand Up @@ -37,7 +37,9 @@ import Type.Proxy (Proxy(Proxy))
import Types.ByteArray
( ByteArray
, hexToByteArray
, hexToByteArrayUnsafe
)
import Types.RawBytes
( hexToRawBytesUnsafe
)
import Types.Natural (Natural)
import Types.PlutusData (PlutusData(Map))
Expand Down Expand Up @@ -209,7 +211,7 @@ instance DecodeAeson SeabugMetadata where
$ unsafePartial
$ fromJust
$ scriptHashFromBytes
$ hexToByteArrayUnsafe
$ hexToRawBytesUnsafe
"00000000000000000000000000000000000000000000000000000000"
, mintPolicy: mempty
, collectionNftCS
Expand All @@ -231,7 +233,7 @@ instance DecodeAeson SeabugMetadata where
decodeScriptHash =
note
(TypeMismatch "Expected hex-encoded script hash")
<<< (scriptHashFromBytes <=< hexToByteArray)
<<< (scriptHashFromBytes <<< wrap <=< hexToByteArray)

newtype SeabugMetadataDelta = SeabugMetadataDelta
{ policyId :: MintingPolicyHash
Expand Down
37 changes: 21 additions & 16 deletions src/Plutus/FromPlutusType.purs
Expand Up @@ -42,6 +42,11 @@ import Plutus.Types.Value (Coin, Value) as Plutus
import Plutus.Types.Value (getValue) as Plutus.Value

import Types.ByteArray (ByteArray, byteArrayFromIntArrayUnsafe)
import Types.CborBytes
( CborBytes
, cborBytesFromIntArrayUnsafe
, rawBytesAsCborBytes
)
import Types.TokenName (adaToken)
import Cardano.Types.Transaction
( TransactionOutput(TransactionOutput)
Expand Down Expand Up @@ -105,55 +110,55 @@ instance FromPlutusType Maybe Plutus.Address Serialization.Address where
PubKeyCredential pkh, Just (StakingHash (PubKeyCredential skh)) ->
Serialization.Address.addressFromBytes $
addrHeader PaymentKeyHashStakeKeyHash
<> ed25519KeyHashToBytes (unwrap pkh)
<> ed25519KeyHashToBytes (unwrap skh)
<> rawBytesAsCborBytes (ed25519KeyHashToBytes (unwrap pkh))
<> rawBytesAsCborBytes (ed25519KeyHashToBytes (unwrap skh))

-- %b0001 | network tag | script hash | key hash
ScriptCredential sh, Just (StakingHash (PubKeyCredential skh)) ->
Serialization.Address.addressFromBytes $
addrHeader ScriptHashStakeKeyHash
<> scriptHashToBytes (unwrap sh)
<> ed25519KeyHashToBytes (unwrap skh)
<> rawBytesAsCborBytes (scriptHashToBytes (unwrap sh))
<> rawBytesAsCborBytes (ed25519KeyHashToBytes (unwrap skh))

-- %b0010 | network tag | key hash | script hash
PubKeyCredential pkh, Just (StakingHash (ScriptCredential sh)) ->
Serialization.Address.addressFromBytes $
addrHeader PaymentKeyHashScriptHash
<> ed25519KeyHashToBytes (unwrap pkh)
<> scriptHashToBytes (unwrap sh)
<> rawBytesAsCborBytes (ed25519KeyHashToBytes (unwrap pkh))
<> rawBytesAsCborBytes (scriptHashToBytes (unwrap sh))

-- %b0011 | network tag | script hash | script hash
ScriptCredential sh, Just (StakingHash (ScriptCredential sh')) ->
Serialization.Address.addressFromBytes $
addrHeader ScriptHashScriptHash
<> scriptHashToBytes (unwrap sh)
<> scriptHashToBytes (unwrap sh')
<> rawBytesAsCborBytes (scriptHashToBytes (unwrap sh))
<> rawBytesAsCborBytes (scriptHashToBytes (unwrap sh'))

-- %b0100 | network tag | key hash | pointer
PubKeyCredential pkh, Just (StakingPtr ptr) ->
Serialization.Address.addressFromBytes $
addrHeader PaymentKeyHashPointer
<> ed25519KeyHashToBytes (unwrap pkh)
<> rawBytesAsCborBytes (ed25519KeyHashToBytes (unwrap pkh))
<> pointerToBytes ptr

-- %b0101 | network tag | script hash | pointer
ScriptCredential sh, Just (StakingPtr ptr) ->
Serialization.Address.addressFromBytes $
addrHeader ScriptHashPointer
<> scriptHashToBytes (unwrap sh)
<> rawBytesAsCborBytes (scriptHashToBytes (unwrap sh))
<> pointerToBytes ptr

-- %b0110 | network tag | key hash
PubKeyCredential pkh, Nothing ->
Serialization.Address.addressFromBytes $
addrHeader PaymentKeyHash
<> ed25519KeyHashToBytes (unwrap pkh)
<> rawBytesAsCborBytes (ed25519KeyHashToBytes (unwrap pkh))

-- %b0111 | network tag | script hash
ScriptCredential sh, Nothing ->
Serialization.Address.addressFromBytes $
addrHeader ScriptHash
<> scriptHashToBytes (unwrap sh)
<> rawBytesAsCborBytes (scriptHashToBytes (unwrap sh))
where
rec
:: { addressCredential :: Credential
Expand All @@ -163,13 +168,13 @@ instance FromPlutusType Maybe Plutus.Address Serialization.Address where

-- | Encodes the address type along with the network tag (%b0001 - Mainnet)
-- | as a one-element byte array.
addrHeader :: AddressHeaderType -> ByteArray
addrHeader :: AddressHeaderType -> CborBytes
addrHeader headerType =
byteArrayFromIntArrayUnsafe <<< singleton <<< toInt $
cborBytesFromIntArrayUnsafe <<< singleton <<< toInt $
(addrHeaderTypeUInt headerType `shl` fromInt 4) + fromInt 1

pointerToBytes :: Serialization.Address.Pointer -> ByteArray
pointerToBytes ptr =
pointerToBytes :: Serialization.Address.Pointer -> CborBytes
pointerToBytes ptr = wrap $
toVarLengthUInt ptr.slot <> toVarLengthUInt ptr.txIx <>
toVarLengthUInt ptr.certIx

Expand Down

0 comments on commit a57d657

Please sign in to comment.