Skip to content

Commit 6cf0228

Browse files
authored
Merge pull request #130 from zkFold/129-simple-rollup
feat(#129): rollup validator
2 parents 8403f73 + 17f2cf5 commit 6cf0228

File tree

10 files changed

+463
-10
lines changed

10 files changed

+463
-10
lines changed

zkfold-cardano-scripts-common/data/compiled-scripts/rollup-simple.blueprint

Lines changed: 266 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module ZkFold.Cardano.UPLC.RollupSimple.CompiledScript (
2+
rollupSimpleBPFile,
3+
) where
4+
5+
import Data.ByteString (ByteString)
6+
import Data.FileEmbed
7+
import Prelude
8+
9+
rollupSimpleBPFile :: ByteString
10+
rollupSimpleBPFile = $(makeRelativeToProject "./data/compiled-scripts/rollup-simple.blueprint" >>= embedFile)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{-# LANGUAGE TemplateHaskell #-}
2+
{-# LANGUAGE UndecidableInstances #-}
3+
4+
module ZkFold.Cardano.UPLC.RollupSimple.Types (
5+
RollupState (..),
6+
RollupSimpleRed,
7+
) where
8+
9+
import GHC.Generics (Generic)
10+
import PlutusTx.Blueprint
11+
import qualified PlutusTx.Blueprint.TH
12+
import PlutusTx.Prelude hiding (toList, (*), (+))
13+
import Prelude (Show)
14+
15+
import ZkFold.Cardano.OnChain.Plonkup.Data (ProofBytes)
16+
17+
data RollupState = RollupState
18+
{ previousStateHash :: Integer
19+
, utxoTreeRoot :: Integer
20+
, chainLength :: Integer
21+
, bridgeInCommitment :: Integer
22+
, bridgeOutCommitment :: Integer
23+
}
24+
deriving stock (Show, Generic)
25+
deriving anyclass HasBlueprintDefinition
26+
27+
PlutusTx.Blueprint.TH.makeIsDataSchemaIndexed ''RollupState [('RollupState, 0)]
28+
29+
type RollupSimpleRed = ProofBytes

zkfold-cardano-scripts-common/zkfold-cardano-scripts-common.cabal

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ license: MIT
88
build-type: Simple
99
data-dir: data
1010
data-files:
11+
compiled-scripts/rollup-simple.blueprint
1112
compiled-scripts/smart-wallet.blueprint
1213

1314
common lang
@@ -56,6 +57,8 @@ library
5657
import: lang
5758
default-language: Haskell2010
5859
exposed-modules:
60+
ZkFold.Cardano.UPLC.RollupSimple.CompiledScript
61+
ZkFold.Cardano.UPLC.RollupSimple.Types
5962
ZkFold.Cardano.UPLC.Wallet.CompiledScript
6063
ZkFold.Cardano.UPLC.Wallet.Types
6164

@@ -67,4 +70,3 @@ library
6770
plutus-ledger-api,
6871
plutus-tx,
6972
zkfold-cardano,
70-

zkfold-cardano-scripts/app/Main.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
module Main (main) where
22

33
import Prelude
4-
import System.FilePath ((</>))
4+
import System.FilePath ((</>))
55

6-
import ZkFold.Cardano.UPLC.Wallet.Compile (writeSmartWalletBP)
6+
import ZkFold.Cardano.UPLC.RollupSimple.Compile (writeRollupSimpleBP)
7+
import ZkFold.Cardano.UPLC.Wallet.Compile (writeSmartWalletBP)
78

89
-- To be executed from root of zkfold-cardano repository.
910
main :: IO ()
1011
main =
1112
let getPath fn = "zkfold-cardano-scripts-common" </> "data" </> "compiled-scripts" </> fn <> ".blueprint"
1213
in do
1314
writeSmartWalletBP $ getPath "smart-wallet"
15+
writeRollupSimpleBP $ getPath "rollup-simple"

zkfold-cardano-scripts/src/ZkFold/Cardano/UPLC/Rollup.hs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Prelude (Show)
2323
import ZkFold.Cardano.OnChain.BLS12_381.F (F (..), toF)
2424
import ZkFold.Cardano.OnChain.Plonkup (PlonkupPlutus)
2525
import ZkFold.Cardano.OnChain.Plonkup.Data (ProofBytes, SetupBytes)
26-
import ZkFold.Cardano.OnChain.Utils (dataToBlake)
26+
import ZkFold.Cardano.OnChain.Utils (dataToBlake, findOwnInput')
2727
import ZkFold.Protocol.NonInteractiveProof (NonInteractiveProof (..))
2828

2929
data RollupSetup = RollupSetup
@@ -61,10 +61,6 @@ data RollupInfo = RollupInfo
6161

6262
makeIsDataIndexed ''RollupInfo [('RollupInfo,0)]
6363

64-
{-# INLINABLE findOwnInput' #-}
65-
findOwnInput' :: [TxInInfo] -> TxOutRef -> Maybe TxInInfo
66-
findOwnInput' txInfoInputs txOutRef = find (\TxInInfo{txInInfoOutRef} -> txInInfoOutRef == txOutRef) txInfoInputs
67-
6864
-- | Plutus script for verifying a rollup state transition.
6965
{-# INLINABLE untypedRollup #-}
7066
untypedRollup :: RollupSetup -> BuiltinData -> BuiltinUnit
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{-# LANGUAGE TemplateHaskell #-}
2+
{-# LANGUAGE UndecidableInstances #-}
3+
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
4+
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
5+
{-# OPTIONS_GHC -fplugin-opt PlutusTx.Plugin:conservative-optimisation #-}
6+
{-# OPTIONS_GHC -fplugin-opt PlutusTx.Plugin:profile-all #-}
7+
8+
{-# HLINT ignore "Unused LANGUAGE pragma" #-}
9+
10+
module ZkFold.Cardano.UPLC.RollupSimple (
11+
rollupSimple,
12+
module ZkFold.Cardano.UPLC.RollupSimple.Types,
13+
) where
14+
import Data.Function ((&))
15+
import PlutusLedgerApi.V1 (valueOf)
16+
import PlutusLedgerApi.V3
17+
import qualified PlutusTx.Builtins.Internal as BI
18+
import PlutusTx.Prelude hiding (toList, (*), (+))
19+
20+
import ZkFold.Cardano.OnChain.BLS12_381 (toF)
21+
import ZkFold.Cardano.OnChain.Plonkup (PlonkupPlutus)
22+
import ZkFold.Cardano.OnChain.Plonkup.Data (SetupBytes)
23+
import ZkFold.Cardano.OnChain.Utils (findOwnInput')
24+
import ZkFold.Cardano.UPLC.RollupSimple.Types (RollupSimpleRed, RollupState (..))
25+
import ZkFold.Protocol.NonInteractiveProof (NonInteractiveProof (..))
26+
27+
{-# INLINEABLE rollupSimple #-}
28+
rollupSimple ::
29+
-- | Setup bytes.
30+
BuiltinData ->
31+
-- | NFT Currency Symbol.
32+
BuiltinData ->
33+
-- | NFT Token Name.
34+
BuiltinData ->
35+
-- | Script context.
36+
BuiltinData ->
37+
BuiltinUnit
38+
rollupSimple (unsafeFromBuiltinData -> (setupBytes :: SetupBytes)) (unsafeFromBuiltinData -> (nftCurrencySymbol :: CurrencySymbol)) (unsafeFromBuiltinData -> (nftTokenName :: TokenName)) scData = check $
39+
trySpend == 1
40+
&& valueOf (txOutValue ownInputOutput) nftCurrencySymbol nftTokenName == 1
41+
&& verify @PlonkupPlutus setupBytes (toF <$> [previousStateHash oldState, utxoTreeRoot oldState, chainLength oldState, bridgeInCommitment oldState, bridgeOutCommitment oldState, previousStateHash newState, utxoTreeRoot newState, chainLength newState, bridgeInCommitment newState, bridgeOutCommitment newState, 1]) proofBytes
42+
where
43+
44+
txInfoL = BI.unsafeDataAsConstr scData & BI.snd
45+
txInfo = txInfoL & BI.head & BI.unsafeDataAsConstr & BI.snd
46+
txInfoInputs = BI.head txInfo & unsafeFromBuiltinData @[TxInInfo]
47+
txInfoOutputs = txInfo & BI.tail & BI.tail & BI.head & unsafeFromBuiltinData @[TxOut]
48+
redL = txInfoL & BI.tail
49+
proofBytes = redL & BI.head & unsafeFromBuiltinData
50+
-- Extracting ScriptInfo
51+
scriptInfo = redL & BI.tail & BI.head & BI.unsafeDataAsConstr
52+
trySpend = BI.fst scriptInfo
53+
spendFields = scriptInfo & BI.snd
54+
spendRef = spendFields & BI.head & unsafeFromBuiltinData @TxOutRef
55+
Just (unsafeFromBuiltinData . getDatum -> (oldState :: RollupState)) = spendFields & BI.tail & BI.head & unsafeFromBuiltinData @(Maybe Datum)
56+
Just ownInput = findOwnInput' txInfoInputs spendRef
57+
ownInputOutput = txInInfoResolved ownInput
58+
Just continuingOutput = find (\txOut -> txOutAddress txOut == txOutAddress ownInputOutput && valueOf (txOutValue txOut) nftCurrencySymbol nftTokenName == 1) txInfoOutputs
59+
OutputDatum (unsafeFromBuiltinData . getDatum -> (newState :: RollupState)) = txOutDatum continuingOutput
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
2+
module ZkFold.Cardano.UPLC.RollupSimple.Compile (
3+
writeRollupSimpleBP,
4+
rollupSimpleSerialisedScript,
5+
rollupSimpleCompiledCode,
6+
) where
7+
8+
import Data.ByteString (ByteString)
9+
import Data.ByteString.Short (fromShort)
10+
import Data.Function ((&))
11+
import Data.Maybe (Maybe (..))
12+
import qualified Data.Set as Set
13+
import PlutusLedgerApi.V3
14+
import qualified PlutusTx
15+
import PlutusTx.Blueprint
16+
import qualified PlutusTx.Prelude as PlutusTx
17+
import Prelude (FilePath, IO, ($))
18+
19+
import ZkFold.Cardano.OnChain.Plonkup.Data (SetupBytes)
20+
import ZkFold.Cardano.UPLC.RollupSimple
21+
22+
rollupSimpleBP :: ContractBlueprint
23+
rollupSimpleBP =
24+
MkContractBlueprint
25+
{ contractId = Just "rollup-simple"
26+
, contractPreamble =
27+
MkPreamble
28+
{ preambleTitle = "Rollup Simple"
29+
, preambleDescription = Just "Validators related to zkFold's Rollup Simple. Visit https://zkfold.io/ for more details"
30+
, preambleVersion = "0.1.0"
31+
, preamblePlutusVersion = commonPlutusVersion
32+
, preambleLicense = Just "MIT"
33+
}
34+
, contractValidators =
35+
Set.fromList
36+
[ MkValidatorBlueprint
37+
{ validatorTitle = "rollupSimple"
38+
, validatorRedeemer =
39+
MkArgumentBlueprint
40+
{ argumentTitle = Just "RollupSimpleRed"
41+
, argumentSchema = definitionRef @RollupSimpleRed
42+
, argumentPurpose = Set.singleton Spend
43+
, argumentDescription = Nothing
44+
}
45+
, validatorParameters =
46+
[ MkParameterBlueprint
47+
{ parameterTitle = Just "SetupBytes"
48+
, parameterSchema = definitionRef @SetupBytes
49+
, parameterPurpose = Set.singleton Spend
50+
, parameterDescription = Nothing
51+
}
52+
, MkParameterBlueprint
53+
{ parameterTitle = Just "CurrencySymbol"
54+
, parameterSchema = definitionRef @CurrencySymbol
55+
, parameterPurpose = Set.singleton Spend
56+
, parameterDescription = Nothing
57+
}
58+
, MkParameterBlueprint
59+
{ parameterTitle = Just "TokenName"
60+
, parameterSchema = definitionRef @TokenName
61+
, parameterPurpose = Set.singleton Spend
62+
, parameterDescription = Nothing
63+
}
64+
]
65+
, validatorDescription = Just "Rollup Simple validator"
66+
, validatorDatum = Nothing
67+
, validatorCompiled = Just $ compiledValidator commonPlutusVersion rollupSimpleSerialisedScript
68+
}
69+
]
70+
, contractDefinitions = deriveDefinitions @'[SetupBytes, CurrencySymbol, TokenName, RollupState, RollupSimpleRed] }
71+
where
72+
commonPlutusVersion = PlutusV3
73+
74+
writeRollupSimpleBP :: FilePath -> IO ()
75+
writeRollupSimpleBP fp = writeBlueprint fp rollupSimpleBP
76+
77+
rollupSimpleSerialisedScript :: ByteString
78+
rollupSimpleSerialisedScript = serialiseCompiledCode rollupSimpleCompiledCode & fromShort
79+
80+
rollupSimpleCompiledCode :: PlutusTx.CompiledCode (PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> PlutusTx.BuiltinUnit)
81+
rollupSimpleCompiledCode = $$(PlutusTx.compile [||rollupSimple||])

zkfold-cardano-scripts/zkfold-cardano-scripts.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ library
7777
ZkFold.Cardano.UPLC.Rollup
7878
ZkFold.Cardano.UPLC.RollupData
7979
ZkFold.Cardano.UPLC.RollupDeposit
80+
ZkFold.Cardano.UPLC.RollupSimple
81+
ZkFold.Cardano.UPLC.RollupSimple.Compile
8082
ZkFold.Cardano.UPLC.PlonkupVerifierTx
8183
ZkFold.Cardano.UPLC.UtxoAccumulator
8284
ZkFold.Cardano.UPLC.Wallet

zkfold-cardano/src/ZkFold/Cardano/OnChain/Utils.hs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
{-# LANGUAGE NamedFieldPuns #-}
12
module ZkFold.Cardano.OnChain.Utils where
23

3-
import PlutusLedgerApi.V3 (BuiltinByteString, Credential, CurrencySymbol, ScriptPurpose (..), ToData (..))
4+
import PlutusLedgerApi.V3 (BuiltinByteString, Credential, CurrencySymbol, ScriptPurpose (..), ToData (..),
5+
TxInInfo (..), TxOutRef)
46
import PlutusTx.Builtins (Integer, blake2b_224, serialiseData)
5-
import PlutusTx.Prelude (Bool (..), Eq (..), (.))
7+
import PlutusTx.Prelude (Bool (..), Eq (..), Maybe, find, (.))
68

79
type ScriptLabel = Integer -- Implements distinct addresses for scripts
810

@@ -22,3 +24,7 @@ eqRewardingPurpose _ _ = False
2224
eqMintingPurpose :: CurrencySymbol -> ScriptPurpose -> Bool
2325
eqMintingPurpose a (Minting b) = a == b
2426
eqMintingPurpose _ _ = False
27+
28+
{-# INLINABLE findOwnInput' #-}
29+
findOwnInput' :: [TxInInfo] -> TxOutRef -> Maybe TxInInfo
30+
findOwnInput' txInfoInputs txOutRef = find (\TxInInfo{txInInfoOutRef} -> txInInfoOutRef == txOutRef) txInfoInputs

0 commit comments

Comments
 (0)