Skip to content

Commit 54a3036

Browse files
authored
Merge pull request #10 from zkFold/6-zkpass-final
zkPass final (server)
2 parents 37edefd + 5f3e407 commit 54a3036

File tree

12 files changed

+189
-99
lines changed

12 files changed

+189
-99
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@
88
* Initial release backend & client for zkPass-cardano
99
* Keeping CHANGELOG's versions for backend & client in sync
1010
* Backend's repo: https://github.com/zkFold/zkpass-cardano
11-
* Client's repo: https://github.com/zkFold/zkpass-client
11+
* Client's repo: https://github.com/zkFold/zkpass-client
12+
13+
## 0.1.1
14+
15+
* 'SetupParams' are now saved on zkpass server.

app/Main.hs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
{-# OPTIONS_GHC -Wno-unused-imports #-}
2-
31
module Main where
42

5-
import GeniusYield.GYConfig (coreConfigIO, withCfgProviders)
3+
import GeniusYield.GYConfig (coreConfigIO, withCfgProviders)
64
import Network.Wai.Handler.Warp
75
import Prelude
8-
import System.Environment (getArgs)
9-
import Test.QuickCheck.Arbitrary (Arbitrary (..))
10-
import Test.QuickCheck.Gen (generate)
6+
import System.Directory (createDirectoryIfMissing)
7+
import System.Environment (getArgs)
8+
import System.FilePath ((</>))
119

12-
import ZkPass.Api (app)
13-
import ZkPass.Api.Context (Ctx (..), SetupParams (..))
14-
import ZkPass.Utils (logSetupParams)
10+
import ZkPass.Api (app)
11+
import ZkPass.Api.Context (Ctx (..))
1512

1613

1714
-- | Getting path for our core configuration.
@@ -24,20 +21,17 @@ parseArgs = do
2421

2522
main :: IO ()
2623
main = do
24+
let path = "."
25+
assetsPath = path </> "assets"
26+
createDirectoryIfMissing True assetsPath
27+
2728
putStrLn "parsing Config ..."
2829
coreCfgPath <- parseArgs
2930
coreCfg <- coreConfigIO coreCfgPath
3031

31-
x <- generate arbitrary
32-
ps <- generate arbitrary
33-
let setupParams = SetupParams x ps
34-
35-
-- Uncomment to log setup parameters:
36-
-- logSetupParams setupParams
37-
3832
putStrLn "Loading Providers ..."
3933
withCfgProviders coreCfg "api-server" $ \providers -> do
4034
let port = 8080
4135
ctx = Ctx coreCfg providers
4236
putStrLn $ "Serving on http://localhost:" ++ show port
43-
run port $ app ctx setupParams
37+
run port $ app ctx assetsPath

app/ZkPass/Api.hs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ import Servant
1111

1212
import ZkPass.Api.Burn (BurnInput, handleBurn)
1313
import ZkPass.Api.Context (Ctx (..), OwnAddress,
14-
OwnAddresses, SetupParams,
15-
UnsignedTxResponse, handleOwnAddr)
14+
OwnAddresses, UnsignedTxResponse,
15+
handleOwnAddr)
1616
import ZkPass.Api.Mint (MintInput, ZkPassResponse,
1717
handleMint)
18+
import ZkPass.Api.SaveScriptsRef (SaveRefInput, SaveRefResponse,
19+
handleSaveRef)
1820
import ZkPass.Api.Setup (SetupInput, SetupResponse,
1921
handleSetup)
2022
import ZkPass.Api.Transfer (TransferInput, handleTransfer)
@@ -26,6 +28,8 @@ import ZkPass.Api.Tx (AddWitAndSubmitParams,
2628
-- | Type for our Servant API.
2729
type API = "setup" :> ReqBody '[JSON] SetupInput
2830
:> Post '[JSON] SetupResponse
31+
:<|> "save-ref" :> ReqBody '[JSON] SaveRefInput
32+
:> Post '[JSON] SaveRefResponse
2933
:<|> "transfer" :> ReqBody '[JSON] TransferInput
3034
:> Post '[JSON] UnsignedTxResponse
3135
:<|> "mint" :> ReqBody '[JSON] MintInput
@@ -38,18 +42,19 @@ type API = "setup" :> ReqBody '[JSON] SetupInput
3842
:> Post '[JSON] OwnAddress
3943

4044
-- | Server Handler
41-
server :: Ctx -> SetupParams -> ServerT API IO
42-
server ctx sp = handleSetup ctx sp
43-
:<|> handleTransfer ctx
44-
:<|> handleMint ctx sp
45-
:<|> handleBurn ctx sp
46-
:<|> handleAddWitAndSubmitTx ctx
47-
:<|> handleOwnAddr
45+
server :: Ctx -> FilePath -> ServerT API IO
46+
server ctx path = handleSetup ctx path
47+
:<|> handleSaveRef path
48+
:<|> handleTransfer ctx path
49+
:<|> handleMint ctx path
50+
:<|> handleBurn ctx path
51+
:<|> handleAddWitAndSubmitTx ctx
52+
:<|> handleOwnAddr
4853

4954
appApi :: Proxy API
5055
appApi = Proxy
5156

52-
app :: Ctx -> SetupParams -> Application
53-
app ctx sp = cors (const $ Just simpleCorsResourcePolicy { corsRequestHeaders = [HttpTypes.hContentType] }) $
57+
app :: Ctx -> FilePath -> Application
58+
app ctx path = cors (const $ Just simpleCorsResourcePolicy { corsRequestHeaders = [HttpTypes.hContentType] }) $
5459
serve appApi $ hoistServer appApi (Handler . ExceptT . try) $
55-
server ctx sp
60+
server ctx path

app/ZkPass/Api/Burn.hs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@ module ZkPass.Api.Burn where
22

33
import Control.Exception (throwIO)
44
import Data.Aeson
5+
import qualified Data.ByteString.Lazy as BL
6+
import Data.Maybe (fromJust)
57
import Data.String (fromString)
68
import GeniusYield.GYConfig (GYCoreConfig (..))
79
import GeniusYield.TxBuilder
810
import GeniusYield.Types
911
import GHC.Generics
1012
import PlutusLedgerApi.V3 (toBuiltinData)
1113
import Prelude
14+
import System.FilePath ((</>))
15+
import Test.QuickCheck.Arbitrary (Arbitrary (..))
16+
import Test.QuickCheck.Gen (generate)
17+
1218
import qualified ZkFold.Cardano.OnChain.BLS12_381.F as F
1319
import ZkFold.Cardano.OnChain.Plonkup.Data (ProofBytes (..))
1420
import ZkPass.Cardano.Example.IdentityCircuit (identityCircuitVerificationBytes)
@@ -20,20 +26,25 @@ import ZkPass.Cardano.UPLC.ZkPassToken (forwardingMintCompiled,
2026

2127
-- | Burning input parameters.
2228
data BurnInput = BurnInput
23-
{ biUsedAddrs :: ![GYAddress]
24-
, biChangeAddr :: !GYAddress
25-
, biTaskId :: !Integer
26-
, biZkPassToken :: !String
27-
, biScriptsTxOutRef :: !String
29+
{ biUsedAddrs :: ![GYAddress]
30+
, biChangeAddr :: !GYAddress
31+
, biZkPassToken :: !String
2832
} deriving stock (Show, Generic)
2933
deriving anyclass FromJSON
3034

31-
handleBurn :: Ctx -> SetupParams -> BurnInput -> IO UnsignedTxResponse
32-
handleBurn Ctx{..} SetupParams{..} BurnInput{..} = do
35+
handleBurn :: Ctx -> FilePath -> BurnInput -> IO UnsignedTxResponse
36+
handleBurn Ctx{..} path BurnInput{..} = do
37+
SetupParams x fmTag mref <- fromJust . decode <$> BL.readFile (path </> "setup-params.json")
38+
ps <- generate arbitrary
39+
40+
scriptsRefTxId <- case mref of
41+
Just ref -> pure ref
42+
Nothing -> throwIO $ userError "Missing scripts' reference TxId."
43+
3344
let nid = cfgNetworkId ctxCoreCfg
3445
providers = ctxProviders
3546

36-
let forwardingMintValidator = validatorFromPlutus @PlutusV3 $ forwardingMintCompiled biTaskId
47+
let forwardingMintValidator = validatorFromPlutus @PlutusV3 $ forwardingMintCompiled fmTag
3748
forwardingMintAddr = addressFromValidator nid forwardingMintValidator
3849

3950
let zkpassAsset = fromString biZkPassToken :: GYAssetClass
@@ -51,11 +62,11 @@ handleBurn Ctx{..} SetupParams{..} BurnInput{..} = do
5162

5263
case utxosAtFMList of
5364
utxoAtFM : _ -> do
54-
let (setup, _, _) = identityCircuitVerificationBytes spX spPS
65+
let (setup, _, _) = identityCircuitVerificationBytes x ps
5566
zkPassTokenValidator = validatorFromPlutus @PlutusV3 $ zkPassTokenCompiled setup
5667

57-
let setupTxOutRef = txOutRefFromTuple (fromString biScriptsTxOutRef, 0)
58-
forwardTxOutRef = txOutRefFromTuple (fromString biScriptsTxOutRef, 1)
68+
let setupTxOutRef = txOutRefFromTuple (scriptsRefTxId, 0)
69+
forwardTxOutRef = txOutRefFromTuple (scriptsRefTxId, 1)
5970

6071
let setupRef = GYBuildPlutusScriptReference @PlutusV3 setupTxOutRef zkPassTokenValidator
6172
forwardRef = GYBuildPlutusScriptReference @PlutusV3 forwardTxOutRef forwardingMintValidator

app/ZkPass/Api/Context.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import GeniusYield.Types
77
import GHC.Generics
88
import Prelude
99

10-
import ZkFold.Base.Algebra.EllipticCurve.BLS12_381 (BLS12_381_G1, Fr)
11-
import ZkFold.Base.Protocol.Plonkup.Prover.Secret (PlonkupProverSecret)
10+
import ZkFold.Base.Algebra.EllipticCurve.BLS12_381 (Fr)
1211

1312

1413
------------------------- :Context & Setup: -------------------------
@@ -21,16 +20,17 @@ data Ctx = Ctx
2120

2221
-- | Setup parameters.
2322
data SetupParams = SetupParams
24-
{ spX :: !Fr
25-
, spPS :: !(PlonkupProverSecret BLS12_381_G1)
23+
{ spX :: !Fr
24+
, spFMTag :: !Integer
25+
, spScriptsRef :: !(Maybe GYTxId)
2626
} deriving stock (Show, Generic)
2727
deriving anyclass (ToJSON, FromJSON)
2828

2929
------------------------- :Unsigned response: -------------------------
3030

3131
data UnsignedTxResponse = UnsignedTxResponse
32-
{ urspTxBodyHex :: !T.Text -- ^ Unsigned transaction cbor.
33-
, urspTxFee :: !(Maybe Integer) -- ^ Tx fees.
32+
{ urspTxBodyHex :: !T.Text -- ^ Unsigned transaction cbor.
33+
, urspTxFee :: !(Maybe Integer) -- ^ Tx fees.
3434
} deriving stock (Show, Generic)
3535
deriving anyclass ToJSON
3636

app/ZkPass/Api/Mint.hs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,26 @@ import Cardano.Api (AssetName (..),
44
parseAddressAny)
55
import Control.Exception (throwIO)
66
import Data.Aeson
7+
import qualified Data.ByteString.Char8 as BS8
8+
import qualified Data.ByteString.Lazy as BL
79
import Data.Coerce (coerce)
810
import qualified Data.Map.Strict as Map
11+
import Data.Maybe (fromJust)
912
import Data.String (fromString)
1013
import GeniusYield.GYConfig (GYCoreConfig (..))
1114
import GeniusYield.TxBuilder
1215
import GeniusYield.Types
1316
import GHC.Generics
14-
import PlutusLedgerApi.V3 (fromBuiltin)
17+
import PlutusLedgerApi.V3 (fromBuiltin, toBuiltin)
1518
import Prelude
19+
import System.FilePath ((</>))
20+
import Test.QuickCheck.Arbitrary (Arbitrary (..))
21+
import Test.QuickCheck.Gen (generate)
1622
import Text.Parsec (parse)
1723

1824
import ZkFold.Cardano.OffChain.Utils (byteStringAsHex)
1925
import qualified ZkFold.Cardano.OnChain.BLS12_381.F as F
26+
import ZkFold.Cardano.OnChain.Utils (dataToBlake)
2027
import ZkPass.Api.Context
2128
import ZkPass.Cardano.Example.IdentityCircuit (zkPassResultVerificationBytes)
2229
import ZkPass.Cardano.Example.ZkPassResult (zkPassResult)
@@ -29,7 +36,7 @@ data MintInput = MintInput
2936
{ miUsedAddrs :: ![GYAddress]
3037
, miChangeAddr :: !GYAddress
3138
, miBeneficiaryAddr :: !String
32-
, miScriptsTxOutRef :: !String
39+
, miResult :: !(Maybe String)
3340
} deriving stock (Show, Generic)
3441
deriving anyclass FromJSON
3542

@@ -42,16 +49,27 @@ data ZkPassResponse = ZkPassResponse
4249
} deriving stock (Show, Generic)
4350
deriving anyclass ToJSON
4451

45-
handleMint :: Ctx -> SetupParams -> MintInput -> IO ZkPassResponse
46-
handleMint Ctx{..} SetupParams{..} MintInput{..} = do
52+
handleMint :: Ctx -> FilePath -> MintInput -> IO ZkPassResponse
53+
handleMint Ctx{..} path MintInput{..} = do
4754
let nid = cfgNetworkId ctxCoreCfg
4855
providers = ctxProviders
4956

5057
case parse parseAddressAny "" miBeneficiaryAddr of
5158
Right benAddr -> do
52-
zkpr <- zkPassResult
59+
SetupParams x _ mref <- fromJust . decode <$> BL.readFile (path </> "setup-params.json")
60+
ps <- generate arbitrary
5361

54-
let (setup, input, proof) = zkPassResultVerificationBytes spX spPS $ F.toInput zkpr
62+
scriptsRefTxId <- case mref of
63+
Just ref -> pure ref
64+
Nothing -> throwIO $ userError "Missing scripts' reference TxId."
65+
66+
zkpr <- case miResult of
67+
Just res -> pure . toBuiltin $ BS8.pack res
68+
Nothing -> zkPassResult
69+
70+
let md = maybe Nothing (metadataMsg . fromString) miResult
71+
72+
let (setup, input, proof) = zkPassResultVerificationBytes x ps . F.toInput $ dataToBlake zkpr
5573
zkPassTokenValidator = validatorFromPlutus @PlutusV3 $ zkPassTokenCompiled setup
5674
zkPassPolicyId = mintingPolicyId zkPassTokenValidator
5775
zkPassTokenName = coerce @AssetName @GYTokenName . AssetName . fromBuiltin $ F.fromInput input
@@ -60,10 +78,11 @@ handleMint Ctx{..} SetupParams{..} MintInput{..} = do
6078
tokens = valueMake $ Map.singleton zkPassToken 1
6179
redeemer = redeemerFromPlutusData proof
6280

63-
let txOutRefSetup = txOutRefFromTuple (fromString miScriptsTxOutRef, 0)
81+
let txOutRefSetup = txOutRefFromTuple (scriptsRefTxId, 0)
6482
refScript = GYMintReference @PlutusV3 txOutRefSetup zkPassTokenValidator
6583
skeleton = mustHaveOutput (GYTxOut (addressFromApi benAddr) tokens Nothing Nothing)
6684
<> mustMint refScript redeemer zkPassTokenName 1
85+
<> mustHaveTxMetadata md
6786

6887
txBody <- runGYTxBuilderMonadIO nid
6988
providers

app/ZkPass/Api/SaveScriptsRef.hs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
module ZkPass.Api.SaveScriptsRef where
2+
3+
import Control.Exception (throwIO)
4+
import Data.Aeson
5+
import qualified Data.ByteString.Lazy as BL
6+
import Data.Maybe (fromJust)
7+
import Data.String (fromString)
8+
import GHC.Generics
9+
import Prelude
10+
import System.FilePath ((</>))
11+
12+
import ZkPass.Api.Context
13+
14+
15+
-- | Input with scripts' reference TxId.
16+
data SaveRefInput = SaveRefInput { sriTxId :: !String }
17+
deriving stock (Show, Generic)
18+
deriving anyclass FromJSON
19+
20+
-- | Boolean response.
21+
data SaveRefResponse = SaveRefResponse { srSaved :: !Bool }
22+
deriving stock (Show, Generic)
23+
deriving anyclass ToJSON
24+
25+
-- | Handle to save scripts' reference TxId.
26+
handleSaveRef :: FilePath -> SaveRefInput -> IO SaveRefResponse
27+
handleSaveRef path SaveRefInput{..} = do
28+
let setupFile = path </> "setup-params.json"
29+
30+
SetupParams x tag mref <- fromJust . decode <$> BL.readFile setupFile
31+
32+
case mref of
33+
Just _ -> throwIO $ userError "Unexpected: scripts' reference TxId already saved."
34+
35+
Nothing -> do
36+
let completeSetupParams = SetupParams x tag (Just $ fromString sriTxId)
37+
38+
BL.writeFile setupFile $ encode completeSetupParams
39+
40+
return $ SaveRefResponse { srSaved = True }

0 commit comments

Comments
 (0)