Assuming I made an arbitrary smart contract and want to serialise the endpoint after I have the validator hash and address hash, what should I do to ensure that the serialisation is as safe as possible?

are there steps I should follow to make minimum security guarantees or some software I can use to test it? How do I know that the serialisation is done correctly?

  • 1
    The current format of the question is a bit vague. Could you try to rephrase it? Are you trying to assert if you contract is safe to use from a design perspective? Or if the serialization does what it is meant to do?
    – Fermat
    Jun 22, 2022 at 16:52
  • 1
    Okay thanks for the input, I'll rewrite it when I'm on my laptop
    – KryptoKing
    Jun 22, 2022 at 17:19

1 Answer 1


before I can answer there is an important distinction that must be done

on-chain code can be serialized, off-chain code stays "off the chain" so there is nothing to serialize

so if you are searching for a way to serialize your off-chain code (which can be written in any language, from Haskell with the Contract monad to javascript thanks to the cardano-serialization-library) unfortunately there is nothing to do

serialize the on-chain code

from the chain point of view there is no difference between Validators and MintingPolicy(ies) and StakeValidator

all of them are Scripts for the chain, treated differently based on the ScriptPourpose of that transaction

so you first need to get the raw Script of your smart contract

you can do that with the following functions (all form Plutus.V1.Ledger.Api module)

unValidatorScript :: Validator -> Script
getMintingPolicy :: MintingPolicy -> Script
getStakeValidator :: StakeValidator -> Script

once you have your Script the process is always the same

Script has an instance of the Srialize typeclass which conviniently exposes the serialise function:

serialise :: forall a. Serialise a => a -> ByteString

then we need to strictly evaluate the byte-string and make sure the values do fit in shorts types, this can be done by concatenating the following two functions

import qualified Data.ByteString.Short          as SBS
import qualified Data.ByteString.Lazy           as LBS

-- LBS.toStrict :: ByteString -> ByteString
-- SBS.toShort :: ByteString -> ShortByteString
asStrictBS :: ByteString -> ShortByteString
asStrictBS = SBS.toShort . LBS.toStrict

then we have to specify how to interpret the ShortByteString we have:

-- PlutusScriptSerialized is a constrctor
PlutusScriptSerialized :: ShortByteString -> PlutusScript PlutusScriptV1

and finally get our Script into a file, which can be done thanks to the writeFileTextEnvelope from the Cardano.Api.SerialiseTextEnvelope module:

writeFileTextEnvelope :: forall a.
HasTextEnvelope a =>
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())

I usually do all this whit the following utility funciutons:

getAndWriteScript :: ( willBeScript -> Ledger.Script ) -> FilePath -> willBeScript -> IO (Either (FileError ()) ())
getAndWriteScript getScript filePath =
--                          PlutusScript PlutusScriptV1 instance of HasTextEnvelope  
    writeFileTextEnvelope @(PlutusScript PlutusScriptV1) filePath
    Nothing -- Maybe TextEnvelopeDescr ( Nothing => default )
    . PlutusScriptSerialised . SBS.toShort . LBS.toStrict . serialise . getScript

writeMintingPolicy :: FilePath -> Scripts.MintingPolicy -> IO (Either (FileError ()) ())
writeMintingPolicy = getAndWriteScript Ledger.getMintingPolicy

writeValidator :: FilePath -> Scripts.Validator -> IO (Either (FileError ()) ())
writeValidator = getAndWriteScript Ledger.unValidatorScript

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.