<p>before I can answer there is an important distinction that must be done</p>
<p><strong>on-chain code can be serialized, off-chain code stays &quot;off the chain&quot; so there is nothing to serialize</strong></p>
<p>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 <code>Contract</code> monad to javascript thanks to the <code>cardano-serialization-library</code>) unfortunately there is nothing to do</p>
<h2>serialize the on-chain code</h2>
<p>from the chain point of view there is no difference between <code>Validator</code>s and <code>MintingPolicy</code>(ies) and <code>StakeValidator</code></p>
<p>all of them are <code>Script</code>s for the chain, treated differently based on the <code>ScriptPourpose</code> of that transaction</p>
<p>so you first need to get the raw <code>Script</code> of your smart contract</p>
<p>you can do that with the following functions (all form <a href="https://playground.plutus.iohkdev.io/doc/haddock/plutus-ledger-api/html/Plutus-V1-Ledger-Api.html" rel="nofollow noreferrer"><code>Plutus.V1.Ledger.Api</code> module</a>)</p>
<pre><code>unValidatorScript :: Validator -&gt; Script
getMintingPolicy :: MintingPolicy -&gt; Script
getStakeValidator :: StakeValidator -&gt; Script
</code></pre>
<p>once you have your <code>Script</code> the process is always the same</p>
<p><code>Script</code> has an instance of the <code>Srialize</code> typeclass which conviniently exposes the <code>serialise</code> function:</p>
<pre><code>serialise :: forall a. Serialise a =&gt; a -&gt; ByteString
</code></pre>
<p>then we need to <strong>strictly evaluate</strong> the byte-string and make sure the values do fit in <code>short</code>s types, this can be done by concatenating the following two functions</p>
<pre><code>import qualified Data.ByteString.Short          as SBS
import qualified Data.ByteString.Lazy           as LBS

-- LBS.toStrict :: ByteString -&gt; ByteString
-- SBS.toShort :: ByteString -&gt; ShortByteString
asStrictBS :: ByteString -&gt; ShortByteString
asStrictBS = SBS.toShort . LBS.toStrict
</code></pre>
<p>then we have to specify how to interpret the <code>ShortByteString</code> we have:</p>
<pre><code>-- PlutusScriptSerialized is a constrctor
PlutusScriptSerialized :: ShortByteString -&gt; PlutusScript PlutusScriptV1
</code></pre>
<p>and finally get our <code>Script</code> into a file, which can be done thanks to the <code>writeFileTextEnvelope</code> from the <code>Cardano.Api.SerialiseTextEnvelope</code> module:</p>
<pre><code>writeFileTextEnvelope :: forall a.
HasTextEnvelope a =&gt;
FilePath
-&gt; Maybe TextEnvelopeDescr -&gt; a -&gt; IO (Either (FileError ()) ())
</code></pre>
<p>I usually do all this whit the following utility funciutons:</p>
<pre><code>getAndWriteScript :: ( willBeScript -&gt; Ledger.Script ) -&gt; FilePath -&gt; willBeScript -&gt; IO (Either (FileError ()) ())
getAndWriteScript getScript filePath =
--                          PlutusScript PlutusScriptV1 instance of HasTextEnvelope  
    writeFileTextEnvelope @(PlutusScript PlutusScriptV1) filePath
    Nothing -- Maybe TextEnvelopeDescr ( Nothing =&gt; default )
    . PlutusScriptSerialised . SBS.toShort . LBS.toStrict . serialise . getScript

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

writeValidator :: FilePath -&gt; Scripts.Validator -&gt; IO (Either (FileError ()) ())
writeValidator = getAndWriteScript Ledger.unValidatorScript
</code></pre>

CC BY-SA 4.0
2022-06-23T07:20:58.503Z
Also have a look at https://playground.plutus.iohkdev.io/doc/haddock/plutus-ledger-api/html/Plutus-V2-Ledger-Api.html#v:validateScript. This functions checks if a `SerializedScript` is correctly serialized.
Fermat
CC BY-SA 4.0
2022-06-22T19:09:57.507Z
2022-06-22T19:09:57.507Z
Michele Nuzzi
<p>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?</p>
<p>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?</p>

CC BY-SA 4.0
2022-06-22T16:52:01.730Z
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
CC BY-SA 4.0
2022-06-22T17:19:29.180Z
Okay thanks for the input, I'll rewrite it when I'm on my laptop
KryptoKing
<cardano-serialization-lib><smart-contract>
How to Securely Serialise a Plutus Smart Contract Endpoint?
# How to Securely Serialise a Plutus Smart Contract Endpoint?

(Asked by: username_0 on 2022-06-22)

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?

**Tags:** cardano-serialization-lib, smart-contract

> **Comments:**
> **username_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?  
> **username_0**: Okay thanks for the input, I'll rewrite it when I'm on my laptop  

---

## 1 answers

### Answer by username_2 on 2022-06-22. Score: 2 | Accepted answer

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 `Validator`s and `MintingPolicy`(ies) and `StakeValidator`

all of them are `Script`s 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](https://playground.plutus.iohkdev.io/doc/haddock/plutus-ledger-api/html/Plutus-V1-Ledger-Api.html))

```
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 `short`s 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 =>
FilePath
-> 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

```

> **Comments:**
> **username_1**: Also have a look at https://playground.plutus.iohkdev.io/doc/haddock/plutus-ledger-api/html/Plutus-V2-Ledger-Api.html#v:validateScript. This functions checks if a `SerializedScript` is correctly serialized.  

---

