From 992309b445184f3d072b65a464fa92f3bcc8c8a2 Mon Sep 17 00:00:00 2001 From: colll78 Date: Wed, 18 Dec 2024 00:41:01 -0800 Subject: [PATCH] Onchain code for programmable tokens (#4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * onchain code and export scripts * onchain code and export scripts * onchain code and export scripts * Use library from input-output-hk/catalyst-onchain-libs * Clean up cabal file, export lists, warnings * Run export-smart-tokens * Include nixconfig to to use cache (#6) * Otherwise ghc and friends will be compiled from source. * There is a nix failure independent of this change which can be fixed by deleting the .pre-commit-config.yaml. This should be checked. * Remove pre-commit-config yaml (#7) * This file should be auto-generated and its existence prevents nix flake development environments being created. * Add catalyst-onchain-libs to sha256map; ignore pre-commit-yaml * fix scripts and finish directory linked list implementation * fix scripts after rebase * Quality of life changes (#8) * Stylish Haskell configuration included * Disabled nixpkgs-fmt (currently no idea why it breaks in the hook) * nonix pre-commit-hook (not tested myself) * Delete txt file, address warnings * Update dependency --------- Co-authored-by: Jann Müller Co-authored-by: Christian Hoener zu Siederdissen --- .gitignore | 2 + .pre-commit-config.yaml.nonix | 58 + .stylish-haskell.yaml | 32 + cabal.project | 9 +- compiled/alwaysFail.json | 5 + compiled/directoryNodeMintingPolicy.json | 5 + compiled/directorySpending.json | 5 + compiled/freezeAndSeizeTransfer.json | 5 + compiled/permissionedMinting.json | 5 + compiled/permissionedTransfer.json | 5 + compiled/programmableLogicBase.json | 5 + compiled/programmableTokenMinting.json | 5 + compiled/protocolParametersNFTMinting.json | 5 + flake.lock | 2374 +++++++++++++++++ flake.nix | 54 + hei.yaml | 12 + nix/outputs.nix | 9 + nix/project.nix | 29 + nix/shell.nix | 27 + src/exe/export-smart-tokens/Main.hs | 80 + src/exe/{ => wst-poc}/Main.hs | 0 src/lib/Profile.hs | 32 + .../Contracts/ExampleTransferLogic.hs | 201 ++ src/lib/SmartTokens/Contracts/Issuance.hs | 102 + .../Contracts/ProgrammableLogicBase.hs | 405 +++ .../SmartTokens/Contracts/ProtocolParams.hs | 69 + src/lib/SmartTokens/Core/Scripts.hs | 42 + src/lib/SmartTokens/LinkedList/Common.hs | 318 +++ .../SmartTokens/LinkedList/MintDirectory.hs | 62 + .../SmartTokens/LinkedList/SpendDirectory.hs | 81 + src/lib/SmartTokens/Types/Constants.hs | 22 + src/lib/SmartTokens/Types/PTokenDirectory.hs | 217 ++ src/lib/SmartTokens/Types/ProtocolParams.hs | 51 + src/lib/Types/Constants.hs | 31 + src/wst-poc.cabal | 79 +- 35 files changed, 4424 insertions(+), 19 deletions(-) create mode 100644 .pre-commit-config.yaml.nonix create mode 100644 .stylish-haskell.yaml create mode 100644 compiled/alwaysFail.json create mode 100644 compiled/directoryNodeMintingPolicy.json create mode 100644 compiled/directorySpending.json create mode 100644 compiled/freezeAndSeizeTransfer.json create mode 100644 compiled/permissionedMinting.json create mode 100644 compiled/permissionedTransfer.json create mode 100644 compiled/programmableLogicBase.json create mode 100644 compiled/programmableTokenMinting.json create mode 100644 compiled/protocolParametersNFTMinting.json create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 hei.yaml create mode 100644 nix/outputs.nix create mode 100644 nix/project.nix create mode 100644 nix/shell.nix create mode 100644 src/exe/export-smart-tokens/Main.hs rename src/exe/{ => wst-poc}/Main.hs (100%) create mode 100644 src/lib/Profile.hs create mode 100644 src/lib/SmartTokens/Contracts/ExampleTransferLogic.hs create mode 100644 src/lib/SmartTokens/Contracts/Issuance.hs create mode 100644 src/lib/SmartTokens/Contracts/ProgrammableLogicBase.hs create mode 100644 src/lib/SmartTokens/Contracts/ProtocolParams.hs create mode 100644 src/lib/SmartTokens/Core/Scripts.hs create mode 100644 src/lib/SmartTokens/LinkedList/Common.hs create mode 100644 src/lib/SmartTokens/LinkedList/MintDirectory.hs create mode 100644 src/lib/SmartTokens/LinkedList/SpendDirectory.hs create mode 100644 src/lib/SmartTokens/Types/Constants.hs create mode 100644 src/lib/SmartTokens/Types/PTokenDirectory.hs create mode 100644 src/lib/SmartTokens/Types/ProtocolParams.hs create mode 100644 src/lib/Types/Constants.hs diff --git a/.gitignore b/.gitignore index cde4093..dd86fbb 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ haddocks/ .envrc get-protocol-parameters.sh protocol-parameters-mainnet.json +.pre-commit-config.yaml +tags diff --git a/.pre-commit-config.yaml.nonix b/.pre-commit-config.yaml.nonix new file mode 100644 index 0000000..0936c59 --- /dev/null +++ b/.pre-commit-config.yaml.nonix @@ -0,0 +1,58 @@ +# DO NOT MODIFY +# This file was generated by git-hooks.nix +{ + "default_stages": [ + "pre-commit" + ], + "repos": [ + { + "hooks": [ + { + "always_run": false, + "args": [], + "entry": "/nix/store/l85yyds9b2jzv5swfq4hpjwv21dq7ylr-cabal-fmt-exe-cabal-fmt-0.1.12/bin/cabal-fmt --inplace ", + "exclude": "^$", + "exclude_types": [], + "fail_fast": false, + "files": "\\.(cabal)$", + "id": "cabal-fmt", + "language": "system", + "name": "cabal-fmt", + "pass_filenames": true, + "require_serial": false, + "stages": [ + "pre-commit" + ], + "types": [ + "file" + ], + "types_or": [], + "verbose": false + }, + { + "always_run": false, + "args": [], + "entry": "/nix/store/in4rzg7z6mkblbasxxsg6dik44jkngbj-stylish-haskell-exe-stylish-haskell-0.14.6.0/bin/stylish-haskell --inplace --config .stylish-haskell.yaml ", + "exclude": "^$", + "exclude_types": [], + "fail_fast": false, + "files": "\\.(hs|lhs)$", + "id": "stylish-haskell", + "language": "system", + "name": "stylish-haskell", + "pass_filenames": true, + "require_serial": false, + "stages": [ + "pre-commit" + ], + "types": [ + "file" + ], + "types_or": [], + "verbose": false + } + ], + "repo": "local" + } + ] +} diff --git a/.stylish-haskell.yaml b/.stylish-haskell.yaml new file mode 100644 index 0000000..9bc95c0 --- /dev/null +++ b/.stylish-haskell.yaml @@ -0,0 +1,32 @@ +steps: + + - simple_align: + cases: never + top_level_patterns: never + records: never + multi_way_if: never + + - imports: + align: none + post_qualify: true + + - language_pragmas: + remove_redundant: false + + - trailing_whitespace: {} + +columns: 80 + +newline: native + +language_extensions: + - GeneralizedNewtypeDeriving + - ImportQualifiedPost + - NumericUnderscores + - OverloadedStrings + - BangPatterns ## stylish-haskell reports an error when and expression starts with `!` + - TypeOperators ## stylish-haskell reports an error when importing type operators such as `import Prelude (type (~))` + +# stylish-haskell doesn't understand Cabal common-stanzas, so let's just +# disable it. +cabal: false diff --git a/cabal.project b/cabal.project index ad87a39..57f4e62 100644 --- a/cabal.project +++ b/cabal.project @@ -26,8 +26,15 @@ packages: source-repository-package type: git location: https://github.com/colll78/plutarch-plutus - tag: 548cb641378b4c00bc02abfdcd723821b08141f5 + tag: b2379767c7f1c70acf28206bf922f128adc02f28 subdir: . plutarch-ledger-api plutarch-extra + +source-repository-package + type: git + location: https://github.com/input-output-hk/catalyst-onchain-libs + tag: 650a3435f8efbd4bf36e58768fac266ba5beede4 + subdir: + src/plutarch-onchain-lib diff --git a/compiled/alwaysFail.json b/compiled/alwaysFail.json new file mode 100644 index 0000000..93e4082 --- /dev/null +++ b/compiled/alwaysFail.json @@ -0,0 +1,5 @@ +{ + "cborHex": "5840583e010000225335738921314c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f746f636f6c506172616d732e68733a36395d001601", + "description": "Always Fail", + "type": "PlutusScriptV3" +} \ No newline at end of file diff --git a/compiled/directoryNodeMintingPolicy.json b/compiled/directoryNodeMintingPolicy.json new file mode 100644 index 0000000..2a23da1 --- /dev/null +++ b/compiled/directoryNodeMintingPolicy.json @@ -0,0 +1,5 @@ +{ + "cborHex": "59253c592539010000225335738921314c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f4d696e744469726563746f72792e68733a36375d00132323232323232323232323253335734664a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3239375d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294454cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3133395d00133357340040022940c00cd5d0800898011aba2001322533573892012a4c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a39335d0013253357389201194c5b2e2f506c7574617263682f426f6f6c2e68733a3137305d0013375e6e9cc94cd5ce2481264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea800400cdd399299ab9c491264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040054cd5ce2492c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004c94cd5ce2492c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004d5d0801000899191919192999ab9a3370e90010010992999ab9a4a02a66ae7124012b4c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3237345d001323232323232533357346644a66ae712401194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cdc800100319b90006001153335734a6644a66ae71241194c5b2e2f506c7574617263682f426f6f6c2e68733a3133395d00133357340040022940cc94cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001333322222533573892012f4c5b6c69622f536d617274546f6b656e732f54797065732f50546f6b656e4469726563746f72792e68733a3230335d0013375e00266664444a66ae7124012f4c5b6c69622f536d617274546f6b656e732f54797065732f50546f6b656e4469726563746f72792e68733a3139385d001374e66ae80010cd5d000199aba000233574000297ae0004005003002375200c6ea4008d5d0a99ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010033574264a66ae712401194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440060162664a66ae712401194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba200133222533573892012f4c5b6c69622f536d617274546f6b656e732f54797065732f50546f6b656e4469726563746f72792e68733a3231355d001323375e00466664444a66ae7124012f4c5b6c69622f536d617274546f6b656e732f54797065732f50546f6b656e4469726563746f72792e68733a3139385d001374e66ae80010cd5d000199aba000233574000297ae000400332325333573466e1cdc69bae3253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3635365d00153335573e0022a66ae712410e4c69737420697320656d7074792e001613253335573e00226ae8400854cd5ce249244c69737420636f6e7461696e73206d6f7265207468616e206f6e6520656c656d656e742e0016357440026aae78009203815333573466e1c0052000135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100315333573466e1c0052002135742a66ae712401194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001003161635573a0026ea8d5d0a99ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100132325333573466e1cdc69bae325335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3635365d00153335573e0022a66ae712410e4c69737420697320656d7074792e001613253335573e00226ae8400854cd5ce249244c69737420636f6e7461696e73206d6f7265207468616e206f6e6520656c656d656e742e0016357440026aae78009203815333573466e1c005200013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440062a666ae68cdc3800a400426ae84c94cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440062c2c6aae74004dd51aba13253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013574400264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004dd60009ba900637520020162a666ae68cccc88894cd5ce24812b4c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3130375d001333325335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3438355d001332225335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3532345d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002244a0022a666ae68cdd79aab9d357420020082600a6ae840044c008d5d10008009299ab9c4901294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3438375d0013222300200337566aae780040040100048cc894cd5ce249294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3135305d0013375e6e98008dd30009991299ab9c4901294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3534335d001332253357389201294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3535335d0013322533573892011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266ec00080052f5bded8c00046ea000401000c00454cd5ce24815e5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3130383a352d31380016012533573892011c4c5b6c69622f54797065732f436f6e7374616e74732e68733a32305d001375200c90010088a4c2a66ae7124119496e636f7272656374206d696e7420666f7220496e73657274001615335738920121496e636f7272656374206e6f6465206f75747075747320666f7220496e736572740016153357389201255370656e74206e6f64652073686f756c6420636f76657220696e73657274696e67206b65790016375c6ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001003375c6ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001003357440026ae88004dd619299ab9c4901214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3635365d00153335573e0022a66ae712410e4c69737420697320656d7074792e001613253335573e00226ae8400854cd5ce249244c69737420636f6e7461696e73206d6f7265207468616e206f6e6520656c656d656e742e00163574400200e6eb800458d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100115333573464a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3931325d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3931335d0013375e02aa66ae7124012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004004dd61aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004d5d099299ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea800404854ccd5cd1aba300515333573464a66ae712412f4c5b6c69622f536d617274546f6b656e732f54797065732f50546f6b656e4469726563746f72792e68733a3138345d0013375e0026e9ccd5d026010140003357409801014000335740980105d8799f40ff00335740980105d8799f40ff004bd7019299ab9c4901214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3635365d00153335573e0022a66ae712410e4c69737420697320656d7074792e001613253335573e00226ae8400854cd5ce249244c69737420636f6e7461696e73206d6f7265207468616e206f6e6520656c656d656e742e0016357440020082a666ae68cccc88894cd5ce24812b4c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3130375d001333325335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3438355d001332225335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3532345d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002244a0022a666ae68cdd79aab9d357420020082600a6ae840044c008d5d10008009299ab9c4901294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3438375d0013222300200337566aae780040040100048cc894cd5ce249294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3135305d0013375e6e98008dd30009991299ab9c4901294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3534335d001332253357389201294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3535335d0013322533573892011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266ec00080052f5bded8c00046ea000401000c00454cd5ce24815e5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3130383a352d3138001600b4c1014000480080285261533573892117496e636f7272656374206d696e7420666f7220496e697400161533573892011e496e6974206f7574707574206f6e65206e6f646520616e6420656d707479001615335738920119496e6974206d757374206e6f74207370656e64204e6f64657300161533573892011a496e6974206d75737420636f6e73756d652054784f7574526566001635573c0046aae74004dd5299ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea800403ccc94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3330395d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae01332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae84004c008d5d10009299ab9c49012b4c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3133365d00132323235335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3831345d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e0022c2a666ae68cdd79aab9d3574200201a264644660020060046eb4d55cf19299ab9c4901214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3635365d00153335573e0022a66ae712410e4c69737420697320656d7074792e001613253335573e00226ae8400854cd5ce249244c69737420636f6e7461696e73206d6f7265207468616e206f6e6520656c656d656e742e0016357440026eacd55cf1aba100235573a64a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3635365d00153335573e0022a66ae712410e4c69737420697320656d7074792e001613253335573e00226ae8400854cd5ce249244c69737420636f6e7461696e73206d6f7265207468616e206f6e6520656c656d656e742e0016357440026eacd55cf1aba1001130023574400200244646464a666ae68cdc3a400800426464646464a666ae68cdc3a99ab9c491214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3637395d001333253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3235335d001323230022330020020012300223300200200122253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3235345d00153335573e0022004266006660080046ae84004d5d100091299ab9c491214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3638325d00133700004a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3638305d00133323230022330020020012300223300200200122253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3232365d00153335573e002200426600666e0000920023574400290001bab35573c0029000005a40082a666ae68cdc3804a40042a666ae68cdc81bae001375c6ae854cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100315333573466ebc004028401454cd5ce24914496e636f727265637420746f6b656e206e616d650016153357389201134e6f6465206973206e6f74206f72646572656400161533573892011f496e636f7272656374206e756d626572206f66206e6f646520746f6b656e7300161533573892010f546f6f206d616e7920617373657473001635742a66ae712401194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001003357440026ae88004dd6000a99ab9c4912c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011533573892015e5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3134303a352d3139001635573c0046aae74004dd51aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440086eacd5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013574400264a66ae71241264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004008cc94cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3330395d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae01332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae84004c008d5d10009299ab9c49012b4c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3132365d0013253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3330315d0013232325333573466e1d2004002153357389212c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001153357389201136e6f7420616e20696e6c696e6520646174756d001635573c0046aae74004dd5000a99ab9c4912c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004c94cd5ce2481264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea800400400854cd5ce2490f616c6c2073616d65206f726967696e001633253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3331365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae0132533357346008002264a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae880084c00cd5d10011aba1001253357389212b4c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3231345d0013004533573892012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00137566ae84d5d119299ab9c491264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004dd61aba153357389201194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010083332253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3435385d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae013253335734600a002264a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae880084c00cd5d100118019aba1001253357389212b4c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3231335d0013003533573892012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00137566ae84d5d119299ab9c491264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea800400494cd5ce24812b4c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3231335d001533573892012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004004dd61aba15335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001008253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437365d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437375d0013375e6aae74004010004c94cd5ce249264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3530365d0013325335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3338395d0013225335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3430315d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297adef6c6013233300535573c6ae840088cc894cd5ce24811c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266ec0d55ce9aba100300100210013002357440020024a66ae712401294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3338395d00133300237560024644460040066e98004489400494cd5ce249264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3530385d0013253335734a66ae712401294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3432305d00135746002244a00224460040066644a66ae71241294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3430315d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297adef6c6013233300535573c6ae840088cc894cd5ce24811c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266ec0d55ce9aba100300100210013002357440020024a66ae712401264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3531355d0015333573466ebc004dd424000244a00224460040060020026eacd5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010033232325333573466e1d20000021533573892012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011533573892015e5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f4c696e6b65644c6973742f436f6d6d6f6e2e68733a3230323a352d3239001635573c0046aae74004dd51aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357446ae88018c94cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004d5d10009aba2357440026ae88004d5d100099299ab9c4901264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040041", + "description": "Directory Node Minting Policy", + "type": "PlutusScriptV3" +} \ No newline at end of file diff --git a/compiled/directorySpending.json b/compiled/directorySpending.json new file mode 100644 index 0000000..ce82d61 --- /dev/null +++ b/compiled/directorySpending.json @@ -0,0 +1,5 @@ +{ + "cborHex": "5906e05906dd010000225335738921324c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f5370656e644469726563746f72792e68733a36385d00132323232325333573466e1d20040021533357346644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437365d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437375d0013375e6aae7400400c004d5d099299ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013758a66ae712412c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100137566ae84c94cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004d5d10020a4c2c2a66ae71241655061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f4c696e6b65644c6973742f5370656e644469726563746f72792e68733a37393a332d3535001635573c0046aae74004dd519299ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004c94cd5ce2481264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004c94cd5ce2492c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004cc94cd5ce2481214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3634375d0013232300223300200200123002233002002001225335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3634375d00153335573e0022c2a666ae68c00cd5d080089aba100113002357440024a66ae71241324c5b6c69622f536d617274546f6b656e732f4c696e6b65644c6973742f5370656e644469726563746f72792e68733a37345d001332253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437365d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437375d0013375e6aae7400400c004014c94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00137566ae84d5d119299ab9c491264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040054cd5ce2492c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004dd61aba153357389201194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013574464a66ae712401264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040041", + "description": "Directory Spending", + "type": "PlutusScriptV3" +} \ No newline at end of file diff --git a/compiled/freezeAndSeizeTransfer.json b/compiled/freezeAndSeizeTransfer.json new file mode 100644 index 0000000..2a38b3b --- /dev/null +++ b/compiled/freezeAndSeizeTransfer.json @@ -0,0 +1,5 @@ +{ + "cborHex": "5908f65908f3010000225335738921384c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f4578616d706c655472616e736665724c6f6769632e68733a3138325d00132323232323232533357346644a66ae712401194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cdc39aab9d37546ae84c94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013574400c9002199911299ab9c491384c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f4578616d706c655472616e736665724c6f6769632e68733a3133325d0013233323230022330020020012300223300200200122253357389201384c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f4578616d706c655472616e736665724c6f6769632e68733a3133345d00153335573e00229444c8c8c8c94ccd5cd19b87480100084c8c8c8c94ccd5cd1991299ab9c491194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cdc8001001a999299ab9c4901194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944cdc8001800899b8f00148900325335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437365d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437375d0013375e6aae74004068004dd59aba153357389201194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100813300b357440146ae8802458dd719299ab9c4901214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3635365d00153335573e0022a66ae712410e4c69737420697320656d7074792e001613253335573e00226ae8400854cd5ce249244c69737420636f6e7461696e73206d6f7265207468616e206f6e6520656c656d656e742e0016357440026ae8800cdd71aba1002375c6ae84018dd6299ab9c4912c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011533573892016c5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f436f6e7472616374732f4578616d706c655472616e736665724c6f6769632e68733a3134313a31352d3730001635573c0046aae74004dd51aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440026ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004c94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004c010dd69aba13253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004d5d080100200119919180111980100100091801119801001000911299ab9c491214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e21201400113300353357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a40142666464600446600400400246004466004004002444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40040040020046eb0d5d0a99ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100637586ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100433232300223300200200123002233002002001225335738921384c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f4578616d706c655472616e736665724c6f6769632e68733a3138385d00153335573e002200626644a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400040026ae84d55cf1baa35573a6ae84004c008d5d10009bab35742a66ae712401194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001002149858dd61aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357446ae88004c94cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004d5d10009aba20013574400264a66ae712401264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010023574400264a66ae71241264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040041", + "description": "Freeze and Seize Transfer", + "type": "PlutusScriptV3" +} \ No newline at end of file diff --git a/compiled/permissionedMinting.json b/compiled/permissionedMinting.json new file mode 100644 index 0000000..7971941 --- /dev/null +++ b/compiled/permissionedMinting.json @@ -0,0 +1,5 @@ +{ + "cborHex": "5902b15902ae010000225335738921314c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f746f636f6c506172616d732e68733a36305d001533357346a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3231365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054ccd5cd19baf3574200200829444c008d5d100099299ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00137586ae84c94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004c94cd5ce2481264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040054cd5ce2492c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040045261601", + "description": "Permissioned Minting", + "type": "PlutusScriptV3" +} \ No newline at end of file diff --git a/compiled/permissionedTransfer.json b/compiled/permissionedTransfer.json new file mode 100644 index 0000000..9f100cf --- /dev/null +++ b/compiled/permissionedTransfer.json @@ -0,0 +1,5 @@ +{ + "cborHex": "5902b75902b4010000225335738921374c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f4578616d706c655472616e736665724c6f6769632e68733a39375d001533357346a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3231365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054ccd5cd19baf3574200200829444c008d5d100099299ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00137586ae84c94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004c94cd5ce2481264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040054cd5ce2492c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040045261601", + "description": "Permissioned Transfer", + "type": "PlutusScriptV3" +} \ No newline at end of file diff --git a/compiled/programmableLogicBase.json b/compiled/programmableLogicBase.json new file mode 100644 index 0000000..f5747f1 --- /dev/null +++ b/compiled/programmableLogicBase.json @@ -0,0 +1,5 @@ +{ + "cborHex": "596d78596d75010000225335738921394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3335365d00132323232323232533573892012245787472616374696e672070726f746f636f6c20706172616d65746572205554784f0013232325333573466e1d20040021323253357389211a45787472616374696e6720696e766f6b656420736372697074730013232325333573466e1d20020021533573892109505365697a654163740013232323232325333573466e1d20040021323232323232533357346644a66ae71241194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cdc3a99ab9c4901224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313135325d00133323230022330020020012300223300200200122253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313135335d00153335573e00220042a666ae68cdd780999299ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004c94cd5ce2492c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004c94cd5ce2492c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004d5d080089980199b8000248008d5d10008998018011aba20014800003120023375ea66ae712412c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004040cdd79991299ab9c491214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e212014001133233232225335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400246444a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400200264a66ae71241224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc42401400226646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400246444a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a40040040024660040040020026ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a40040040026eb0d5d0a99ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001017375a6ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100b3374a90001991299ab9c49011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400040026ae854cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001003332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400040026e98cc894cd5ce249214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3739365d001332323002233002002001230022330020020012253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3739385d00153335573e002297adef6c6015333573466ebcd55ce9aba100100313574400226644a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400040026ae84004c008d5d10008011bab35742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100235742a66ae712401194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001006332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400040026ae84c94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440046644a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266e9520024bd7025eb80cc94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3231365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054ccd5cd19baf3574200200629444c008d5d10009aba135573c6ea8d5d099299ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100135744008664a66ae712401194c5b2e2f506c7574617263682f4c6973742e68733a3330395d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae01332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae84004c008d5d10009299ab9c4901394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3337395d001357426aae78dd51aab9d00137566ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001016149858d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010023574400264a66ae71241264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004c94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004cc894cd5ce249214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e212014001133233232225335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400246444a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400200264a66ae71241224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc42401400226646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400246444a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a40040040024660040040020026ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a40040040020126eb4d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100a357440026ae880054cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011533573892016c5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3432373a372d3539001635573c0046aae74004dd51aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440026ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004c94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004cc894cd5ce249214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e212014001133233232225335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400246444a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400200264a66ae71241224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc42401400226646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400246444a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a40040040024660040040020026ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a40040040020166eb4d5d099299ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440026ae88008dd61aba15335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100d1533573892011a505472616e736665724163742076616c756546726f6d43726564001325335738920136505472616e7366657241637420636865636b5472616e736665724c6f676963416e6447657450726f6772616d6d61626c6556616c756500132533573892011f505472616e736665724163742076616c6964617465436f6e646974696f6e73001533357346644a66ae712401194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cdc39aab9d37546ae84c94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013574402090021999991111299ab9c491394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3231375d0013233323230022330020020012300223300200200122253357389201394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3232305d00153335573e00229444c8c8c94ccd5cd19b87480000084c8c8c8c94ccd5cd19b87480100084c8c94ccd5cd1991299ab9c4901194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3231365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054ccd5cd19baf3574200200629444c008d5d10009aba135573c6ea8d5d099299ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013574400201e66ebcd5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100235573a6ae84028cc894cd5ce2481214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437365d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437375d0013375e6aae7400400c004048dd59aba15335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100613300c357440166ae8802858d5d1000a99ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011533573892016d5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3232393a32352d3737001635573c0046aae74004dd51aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440026ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004c94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004c01cdd6a99ab9c4912c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011323232325333573466e1d2004002132323232533357346644a66ae71241194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cdc8001001a999299ab9c4901194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944cdc8001800899b8f0014890033225335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437365d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437375d0013375e6aae7400400c004050dd59aba15335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100813300e3574401a6ae8803058dd71aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440066eb8d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001002375c6aae74d5d0804a99ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011533573892016d5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3234363a32352d3830001635573c0046aae74004dd51aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440026ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004c94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004c01cdd69aba153357389201194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100135573c0046aae74004dd51aba100200435744004644a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e212014001133233232225335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400246444a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400200264a66ae71241224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc42401400226646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400246444a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a40040040024660040040020026ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a40040040020086ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100700b3758a66ae7124012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100333253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3330395d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae01332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae84004c008d5d10009299ab9c4901394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3337395d001357426aae78dd51aab9d00137566ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100c001332253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3932325d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3239375d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294454cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3133395d00133357340040022940c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3932375d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3239375d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294454cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3133395d00133357340040022940c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3932335d001337126eb4d55cf0009991299ab9c491264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3634345d001333325335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3536365d001322225335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3537385d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002200a2a666ae68cdd79aab9d3574200200c260086aae78d5d0800898011aba20010010010024800094cd5ce249264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3634385d001333325335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3536365d001322225335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3537385d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002200a2a666ae68cdd79aab9d3574200200c260086aae78d5d0800898011aba20010010010024800094cd5ce249264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3634385d001375a0026eac004018d55ce8011aab9d00137566aae78004004c94cd5ce249394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3137315d0013253357389201394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3130335d00135744002666464600446600400400246004466004004002444a66ae712401394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3137325d00153335573e00220042660066464a666ae68cdd7a99ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040040304ccc8894cd5ce249264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3439315d001333253357389201294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3335365d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313137325d001533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226666464646004466004004002460044660040040024444a66ae712412a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335335d00153335573e0022a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400060042646464a666ae68cdd780100089991299ab9c49011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266ec0008dd3198059bab35573c00c6eacd55cf0019998040038029aba200415333573466e40dd70011bae00113253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000e00266601000e00a008264a66ae7124011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000800266601000e6ae880114cd5ce24811c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000c00a6aae74008d55ce8021aba10012533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335325d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226660066ae84008d5d10010009aba10023574400400244a66ae712401264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3439345d001333253357389201294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3335365d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313137325d001533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226666464646004466004004002460044660040040024444a66ae712412a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335335d00153335573e0022a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400060042646464a666ae68cdd780100089991299ab9c49011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266ec0008dd4198059bad35573c00c6eb4d55cf0019998040038029aba200415333573466e40dd70011bae00113253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000e00266601000e00a008264a66ae7124011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000800266601000e6ae880114cd5ce24811c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000c00a6aae74008d55ce8021aba10012533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335325d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226660066ae84008d5d10010009aba10023574400400200a00400200400244a66ae71241264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3334345d001337000040020086eacd5d099299ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013574400420086ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004d5d08009aba20014bd6f7b6300009bac35742a66ae712401194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100d001149858ccccc888894cd5ce249394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3237395d001323333232300223300200200123002233002002001222253357389201394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3238345d00153335573e00420022646464a666ae68cdc3a4000004264646464a666ae68cdc3a400800426464a666ae68cc894cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3231365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054ccd5cd19baf3574200200629444c008d5d10009aba135573c6ea8d5d099299ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013574400202066ebcd5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100235573a6ae8402ccc894cd5ce2481214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437365d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437375d0013375e6aae7400400c00404cdd59aba15335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001006133300d357440186ae8802ccc894cd5ce2491c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400040026ae8402c02858d5d10009bac533573892012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011533573892016d5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3239333a32352d3737001635573c0046aae74004dd51aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440026ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004c94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004c020dd6a99ab9c4912c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011323232325333573466e1d2004002132323232533357346644a66ae71241194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cdc8001001a999299ab9c4901194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944cdc8001800899b8f0014890033225335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437365d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437375d0013375e6aae7400400c004054dd59aba15335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001008133300f3574401c6ae88034cc894cd5ce2491c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400040026ae8403403058dd71aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440066eb8d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001002375c6aae74d5d08051bac533573892012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011533573892016d5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3331303a32352d3830001635573c0046aae74004dd51aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440026ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004c94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004c020dd69aba153357389201194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100135573c0046aae74004dd51aba10030043574400497adef6c6032253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e212014001133233232225335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400246444a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400200264a66ae71241224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc42401400226646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a400400400246600400400246444a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3537335d0015333573466e2120140011330033253357389201224c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a313038355d001357446ae88d5d11aba2357446ae88d5d11aba2357446ae88004008cdc0800a40282a666ae68cdc4240140022660066ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a40040040024660040040020026ae88d5d11aba2357446ae88008cdc0800a401426644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c005200013574200426646646444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a400446600400400246444a66ae712401214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3536355d0015333573466e1c00520001357420042660066ae88008cdc0800a40044660040040020026ae88008cdc0800a40040040020086ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100600a3758a66ae7124012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100233253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3330395d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae01332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae84004c008d5d10009299ab9c4901394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3337395d001357426aae78dd51aab9d00137566ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100b00133322253357389201394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3133365d00133323230022330020020012300223300200200122253357389201394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3133375d00153335573e00220042660066464a666ae68cdd7a99ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040040304c8c8c94ccd5cd19b87480000084c8c8c94ccd5cd19b8748008008584c8c8c94ccd5cd19b874800000854ccd5cd199299ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3231365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054ccd5cd19baf3574200200629444c008d5d1000a99ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100101113332225335738921264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3439315d001333253357389201294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3335365d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313137325d001533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226666464646004466004004002460044660040040024444a66ae712412a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335335d00153335573e0022a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400060042646464a666ae68cdd780100089991299ab9c49011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266ec0008dd3198059bab35573c00c6eacd55cf0019998040038029aba200415333573466e40dd70011bae00113253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000e00266601000e00a008264a66ae7124011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000800266601000e6ae880114cd5ce24811c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000c00a6aae74008d55ce8021aba10012533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335325d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226660066ae84008d5d10010009aba10023574400400244a66ae712401264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3439345d001333253357389201294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3335365d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313137325d001533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226666464646004466004004002460044660040040024444a66ae712412a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335335d00153335573e0022a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400060042646464a666ae68cdd780100089991299ab9c49011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266ec0008dd4198059bad35573c00c6eb4d55cf0019998040038029aba200415333573466e40dd70011bae00113253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000e00266601000e00a008264a66ae7124011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000800266601000e6ae880114cd5ce24811c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000c00a6aae74008d55ce8021aba10012533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335325d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226660066ae84008d5d10010009aba10023574400400200a00400200400244a66ae71241264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3334345d0013370000400201a6eacd5d099299ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440162c2a666ae68cc94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3231365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054ccd5cd19baf3574200200629444c008d5d1000a99ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100101013332225335738921264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3439315d001333253357389201294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3335365d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313137325d001533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226666464646004466004004002460044660040040024444a66ae712412a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335335d00153335573e0022a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400060042646464a666ae68cdd780100089991299ab9c49011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266ec0008dd3198059bab35573c00c6eacd55cf0019998040038029aba200415333573466e40dd70011bae00113253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000e00266601000e00a008264a66ae7124011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000800266601000e6ae880114cd5ce24811c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000c00a6aae74008d55ce8021aba10012533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335325d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226660066ae84008d5d10010009aba10023574400400244a66ae712401264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3439345d001333253357389201294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3335365d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313137325d001533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226666464646004466004004002460044660040040024444a66ae712412a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335335d00153335573e0022a66ae712411c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d0013357400060042646464a666ae68cdd780100089991299ab9c49011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400266ec0008dd4198059bad35573c00c6eb4d55cf0019998040038029aba200415333573466e40dd70011bae00113253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000e00266601000e00a008264a66ae7124011c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000800266601000e6ae880114cd5ce24811c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000c00a6aae74008d55ce8021aba10012533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313335325d00122533573892012a4c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a313332315d00153335573e004200226660066ae84008d5d10010009aba10023574400400200a00400200400244a66ae71241264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3334345d0013370000400201a6eacd5d099299ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440162c6aae78008d55ce8009baa533573892012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100135573c0046aae74004dd5299ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011635573c0046aae74004dd5299ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040044010d5d0a99ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004c94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004d5d08009aba20014bd6f7b6300009bac3574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357446ae88028cc94cd5ce2481194c5b2e2f506c7574617263682f4c6973742e68733a3330395d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae01332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae84004c008d5d10009299ab9c4901394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3337395d001357426aae78dd51aab9d00137566ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100a37586ae854cd5ce249194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100d35573c0046aae74004dd51aba15335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100b3574264a66ae712401194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440026eb14cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011533573892016c5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3337323a332d3535001635573c0046aae74004dd519299ab9c49012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004c94cd5ce2481264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004c94cd5ce2492c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004cc94cd5ce2481214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3634375d0013232300223300200200123002233002002001225335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3634375d00153335573e0022c2a666ae68c00cd5d080089aba100113002357440024a66ae71241394c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f6772616d6d61626c654c6f676963426173652e68733a3336365d001332253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437365d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3437375d0013375e6aae7400400c004028c94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00137566ae84d5d119299ab9c491264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040054cd5ce2492c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d001357426ae88c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004004dd61aba15335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001003325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234365d0013574464a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004004d5d10009aba20013574400264a66ae71241264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010023574400264a66ae71241264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040041", + "description": "Programmable Logic Global", + "type": "PlutusScriptV3" +} \ No newline at end of file diff --git a/compiled/programmableTokenMinting.json b/compiled/programmableTokenMinting.json new file mode 100644 index 0000000..f1162b6 --- /dev/null +++ b/compiled/programmableTokenMinting.json @@ -0,0 +1,5 @@ +{ + "cborHex": "591033591030010000222253357389212b4c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f49737375616e63652e68733a34335d00132323232323232325333573466e1d20000021323232323232325333573466e1cd5d0a99ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100e480004c8c8c94ccd5cd1991299ab9c4901194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cdc3999911299ab9c4901264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3634345d001333325335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3536365d001322225335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3537385d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002200a2a666ae68cdd79aab9d3574200200c260086aae78d5d0800898011aba20010010010024800094cd5ce249264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3634385d001333325335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3536365d001322225335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3537385d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002200a2a666ae68cdd79aab9d3574200200c260086aae78d5d0800898011aba20010010010024800094cd5ce249264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3634385d001375a0026eac00400cdd59aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013574400801400e00c66ebcc94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004d5d0a99ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010040163370e6eb400520023325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3231365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054ccd5cd19baf3574200200629444c008d5d100080a999299ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3330395d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae01332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae84004c008d5d10009299ab9c49012b4c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f49737375616e63652e68733a36345d00135573a0026eacd5d099299ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357446ae880385261635573c0046aae74004c94cd5ce2481214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3635365d00153335573e0022a66ae712410e4c69737420697320656d7074792e001613253335573e00226ae8400854cd5ce249244c69737420636f6e7461696e73206d6f7265207468616e206f6e6520656c656d656e742e0016357440026644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3737305d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e0022c2a666ae68cdd79aab9d3574200200826eacd55cf1aba1001130023574400200202200c2a666ae68cdc4240000062a666ae68cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cdc3999911299ab9c4901264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3634345d001333325335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3536365d001322225335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3537385d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002200a2a666ae68cdd79aab9d3574200200c260086aae78d5d0800898011aba20010010010024800094cd5ce249264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3634385d001333325335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3536365d001322225335738921294c5b7372632f506c7574617263682f4c65646765724170692f4173736f634d61702e68733a3537385d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002200a2a666ae68cdd79aab9d3574200200c260086aae78d5d0800898011aba20010010010024800094cd5ce249264c5b7372632f506c7574617263682f4c65646765724170692f56616c75652e68733a3634385d001375a0026eac00400cdd59aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010013574400200e00800666ebcc94cd5ce24812c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004d5d0a99ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010010133325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3231365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054ccd5cd19baf3574200200629444c008d5d1000809199299ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3330395d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae01332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae84004c008d5d10009299ab9c49012b4c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f49737375616e63652e68733a36345d00135573a0026eacd5d099299ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357446ae8802c52616153335734664a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3231365d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054ccd5cd19baf3574200200629444c008d5d1000809199299ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3330395d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002297ae01332253357389211c4c5b2e2f506c7574617263682f4275696c74696e2e68733a3231335d00133574000400260066ae84004c008d5d10009299ab9c49012b4c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f49737375616e63652e68733a36345d00135573a0026eacd5d099299ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357446ae8802c52616325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004d5d08009bac35742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100a375a6aae78008d55ce80099299ab9c4901214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3635365d00153335573e0022a66ae712410e4c69737420697320656d7074792e001613253335573e00226ae8400854cd5ce249244c69737420636f6e7461696e73206d6f7265207468616e206f6e6520656c656d656e742e0016357440026644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3737305d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e0022c2a666ae68cdd79aab9d3574200200826eacd55cf1aba100113002357440020020040026eacd5d0a99ab9c4901194c5b2e2f506c7574617263682f4c6973742e68733a3234345d00100553357389212c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d00135742a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010011533573892015e5061747465726e206d61746368206661696c75726520696e207175616c69666965642027646f2720626c6f636b206174206c69622f536d617274546f6b656e732f436f6e7472616374732f49737375616e63652e68733a34373a332d3237001635573c0046aae74004dd51aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357440086ae88d5d10009aba20013574464a66ae712401264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d0010023574400264a66ae71241264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040041", + "description": "Issuance", + "type": "PlutusScriptV3" +} \ No newline at end of file diff --git a/compiled/protocolParametersNFTMinting.json b/compiled/protocolParametersNFTMinting.json new file mode 100644 index 0000000..4676151 --- /dev/null +++ b/compiled/protocolParametersNFTMinting.json @@ -0,0 +1,5 @@ +{ + "cborHex": "5904c45904c1010000225335738921314c5b6c69622f536d617274546f6b656e732f436f6e7472616374732f50726f746f636f6c506172616d732e68733a33395d001323232323232323232533357346644a66ae712401194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cc894cd5ce249194c5b2e2f506c7574617263682f426f6f6c2e68733a3134335d0013335734004002940cdd780126010f4e50726f746f636f6c506172616d73003375e0029801010100325335738921214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3931325d0013325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3330335d0013232300223300200200123002233002002001225335738921194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e002294054cc94cd5ce2481194c5b2e2f506c7574617263682f426f6f6c2e68733a3134375d0013357340022944c00cd5d0800898011aba2001253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3931335d0013375e01aa66ae7124012c4c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2f4669656c642e68733a3237385d0013574264a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004004004dd61aba15335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001008149858d55cf0011aab9d0013253357389201214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3635365d00153335573e0022a66ae712410e4c69737420697320656d7074792e001613253335573e00226ae8400854cd5ce249244c69737420636f6e7461696e73206d6f7265207468616e206f6e6520656c656d656e742e0016357440026644a66ae71241214c5b6c69622f506c7574617263682f436f72652f5574696c732e68733a3737305d001332323002233002002001230022330020020012253357389201194c5b2e2f506c7574617263682f4c6973742e68733a3139375d00153335573e0022c2a666ae68cdd79aab9d3574200200826eacd55cf1aba100113002357440020026ae84008004dd59aba1325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921194c5b2e2f506c7574617263682f4c6973742e68733a3234365d00135744a66ae71241194c5b2e2f506c7574617263682f4c6973742e68733a3234365d001357446ae88004d5d10022999ab9a3370e6aae74009200010011635573c0026ea8d5d099299ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001357446ae88008c94cd5ce249264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea8004d5d0a99ab9c491194c5b2e2f506c7574617263682f4c6973742e68733a3234345d001001325335738921264c5b2e2f506c7574617263682f44617461526570722f496e7465726e616c2e68733a3431325d00135573c6ea80040041", + "description": "Protocol Parameters NFT", + "type": "PlutusScriptV3" +} \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..d4dd992 --- /dev/null +++ b/flake.lock @@ -0,0 +1,2374 @@ +{ + "nodes": { + "CHaP": { + "flake": false, + "locked": { + "lastModified": 1734128100, + "narHash": "sha256-LTML3sdQbUL+FeXoafPPUOScBmIdWkofNwa1Fjuz7PU=", + "owner": "input-output-hk", + "repo": "cardano-haskell-packages", + "rev": "8df3e3656dcaac2c6328ac199ad90500a6a359bf", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "repo", + "repo": "cardano-haskell-packages", + "type": "github" + } + }, + "CHaP_2": { + "flake": false, + "locked": { + "lastModified": 1731401651, + "narHash": "sha256-tXaUck9+0Ob4h6GBlbhYMI4ekW5e8biVJU5jPT/rjus=", + "owner": "IntersectMBO", + "repo": "cardano-haskell-packages", + "rev": "82b295d6147a566c28dbcf038c54040f06f7e6b4", + "type": "github" + }, + "original": { + "owner": "IntersectMBO", + "ref": "repo", + "repo": "cardano-haskell-packages", + "type": "github" + } + }, + "HTTP": { + "flake": false, + "locked": { + "lastModified": 1451647621, + "narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=", + "owner": "phadej", + "repo": "HTTP", + "rev": "9bc0996d412fef1787449d841277ef663ad9a915", + "type": "github" + }, + "original": { + "owner": "phadej", + "repo": "HTTP", + "type": "github" + } + }, + "HTTP_2": { + "flake": false, + "locked": { + "lastModified": 1451647621, + "narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=", + "owner": "phadej", + "repo": "HTTP", + "rev": "9bc0996d412fef1787449d841277ef663ad9a915", + "type": "github" + }, + "original": { + "owner": "phadej", + "repo": "HTTP", + "type": "github" + } + }, + "blst": { + "flake": false, + "locked": { + "lastModified": 1691598027, + "narHash": "sha256-oqljy+ZXJAXEB/fJtmB8rlAr4UXM+Z2OkDa20gpILNA=", + "owner": "supranational", + "repo": "blst", + "rev": "3dd0f804b1819e5d03fb22ca2e6fac105932043a", + "type": "github" + }, + "original": { + "owner": "supranational", + "ref": "v0.3.11", + "repo": "blst", + "type": "github" + } + }, + "blst_2": { + "flake": false, + "locked": { + "lastModified": 1691598027, + "narHash": "sha256-oqljy+ZXJAXEB/fJtmB8rlAr4UXM+Z2OkDa20gpILNA=", + "owner": "supranational", + "repo": "blst", + "rev": "3dd0f804b1819e5d03fb22ca2e6fac105932043a", + "type": "github" + }, + "original": { + "owner": "supranational", + "ref": "v0.3.11", + "repo": "blst", + "type": "github" + } + }, + "blst_3": { + "flake": false, + "locked": { + "lastModified": 1691598027, + "narHash": "sha256-oqljy+ZXJAXEB/fJtmB8rlAr4UXM+Z2OkDa20gpILNA=", + "owner": "supranational", + "repo": "blst", + "rev": "3dd0f804b1819e5d03fb22ca2e6fac105932043a", + "type": "github" + }, + "original": { + "owner": "supranational", + "ref": "v0.3.11", + "repo": "blst", + "type": "github" + } + }, + "cabal-32": { + "flake": false, + "locked": { + "lastModified": 1603716527, + "narHash": "sha256-X0TFfdD4KZpwl0Zr6x+PLxUt/VyKQfX7ylXHdmZIL+w=", + "owner": "haskell", + "repo": "cabal", + "rev": "48bf10787e27364730dd37a42b603cee8d6af7ee", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.2", + "repo": "cabal", + "type": "github" + } + }, + "cabal-32_2": { + "flake": false, + "locked": { + "lastModified": 1603716527, + "narHash": "sha256-X0TFfdD4KZpwl0Zr6x+PLxUt/VyKQfX7ylXHdmZIL+w=", + "owner": "haskell", + "repo": "cabal", + "rev": "48bf10787e27364730dd37a42b603cee8d6af7ee", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.2", + "repo": "cabal", + "type": "github" + } + }, + "cabal-34": { + "flake": false, + "locked": { + "lastModified": 1645834128, + "narHash": "sha256-wG3d+dOt14z8+ydz4SL7pwGfe7SiimxcD/LOuPCV6xM=", + "owner": "haskell", + "repo": "cabal", + "rev": "5ff598c67f53f7c4f48e31d722ba37172230c462", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.4", + "repo": "cabal", + "type": "github" + } + }, + "cabal-34_2": { + "flake": false, + "locked": { + "lastModified": 1645834128, + "narHash": "sha256-wG3d+dOt14z8+ydz4SL7pwGfe7SiimxcD/LOuPCV6xM=", + "owner": "haskell", + "repo": "cabal", + "rev": "5ff598c67f53f7c4f48e31d722ba37172230c462", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.4", + "repo": "cabal", + "type": "github" + } + }, + "cabal-36": { + "flake": false, + "locked": { + "lastModified": 1669081697, + "narHash": "sha256-I5or+V7LZvMxfbYgZATU4awzkicBwwok4mVoje+sGmU=", + "owner": "haskell", + "repo": "cabal", + "rev": "8fd619e33d34924a94e691c5fea2c42f0fc7f144", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.6", + "repo": "cabal", + "type": "github" + } + }, + "cabal-36_2": { + "flake": false, + "locked": { + "lastModified": 1669081697, + "narHash": "sha256-I5or+V7LZvMxfbYgZATU4awzkicBwwok4mVoje+sGmU=", + "owner": "haskell", + "repo": "cabal", + "rev": "8fd619e33d34924a94e691c5fea2c42f0fc7f144", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.6", + "repo": "cabal", + "type": "github" + } + }, + "cardano-shell": { + "flake": false, + "locked": { + "lastModified": 1608537748, + "narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=", + "owner": "input-output-hk", + "repo": "cardano-shell", + "rev": "9392c75087cb9a3d453998f4230930dea3a95725", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-shell", + "type": "github" + } + }, + "cardano-shell_2": { + "flake": false, + "locked": { + "lastModified": 1608537748, + "narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=", + "owner": "input-output-hk", + "repo": "cardano-shell", + "rev": "9392c75087cb9a3d453998f4230930dea3a95725", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-shell", + "type": "github" + } + }, + "commonmark-simple": { + "flake": false, + "locked": { + "lastModified": 1707333942, + "narHash": "sha256-o1am93UXviPVdwwPPL5DcD8M4gwFple8SKw/lVmixa8=", + "owner": "srid", + "repo": "commonmark-simple", + "rev": "0308362957d77eea462c2c99d110820fbf30b4b8", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "commonmark-simple", + "type": "github" + } + }, + "commonmark-wikilink": { + "flake": false, + "locked": { + "lastModified": 1711394028, + "narHash": "sha256-eu5gMmgRz6Y51TBCaB26uJKNN3z1LRfUcTV4+PMy5Gw=", + "owner": "srid", + "repo": "commonmark-wikilink", + "rev": "57dcf665082ffc1b6f35a427e203ed115821b15c", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "commonmark-wikilink", + "type": "github" + } + }, + "easy-purescript-nix": { + "inputs": { + "flake-utils": "flake-utils" + }, + "locked": { + "lastModified": 1710161569, + "narHash": "sha256-lcIRIOFCdIWEGyKyG/tB4KvxM9zoWuBRDxW+T+mvIb0=", + "owner": "justinwoo", + "repo": "easy-purescript-nix", + "rev": "117fd96acb69d7d1727df95b6fde9d8715e031fc", + "type": "github" + }, + "original": { + "owner": "justinwoo", + "repo": "easy-purescript-nix", + "type": "github" + } + }, + "ema": { + "flake": false, + "locked": { + "lastModified": 1724260267, + "narHash": "sha256-pxTlvpK0l7pek43FIz6KYAazK0BWbnuBJSFrcShVoWE=", + "owner": "srid", + "repo": "ema", + "rev": "16e2752267cd49027e281409daa25b6ecba68fd3", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "ema", + "type": "github" + } + }, + "emanote": { + "inputs": { + "commonmark-simple": "commonmark-simple", + "commonmark-wikilink": "commonmark-wikilink", + "ema": "ema", + "emanote-template": "emanote-template", + "flake-parts": "flake-parts", + "flake-root": "flake-root", + "haskell-flake": "haskell-flake", + "heist-extra": "heist-extra", + "nixos-unified": "nixos-unified", + "nixpkgs": "nixpkgs_4", + "treefmt-nix": "treefmt-nix", + "unionmount": "unionmount" + }, + "locked": { + "lastModified": 1731365623, + "narHash": "sha256-MdS/72MESb1Bp1i7vcGQ/WejBdvg1QL8F4j5fjMUHbE=", + "owner": "srid", + "repo": "emanote", + "rev": "d165ad189dbf71bd66b0c7f211c45c5431499540", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "emanote", + "type": "github" + } + }, + "emanote-template": { + "flake": false, + "locked": { + "lastModified": 1711847690, + "narHash": "sha256-A/5b7vB1+FI2qsuPJL/pZ9CkWozSCbOoaqqN4y+Pmxc=", + "owner": "srid", + "repo": "emanote-template", + "rev": "32330b5e3bdca89ca67f5c212be6db43dbb13cd8", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "emanote-template", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1672831974, + "narHash": "sha256-z9k3MfslLjWQfnjBtEtJZdq3H7kyi2kQtUThfTgdRk0=", + "owner": "input-output-hk", + "repo": "flake-compat", + "rev": "45f2638735f8cdc40fe302742b79f248d23eb368", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "hkm/gitlab-fix", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "locked": { + "lastModified": 1733328505, + "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_3": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_4": { + "flake": false, + "locked": { + "lastModified": 1672831974, + "narHash": "sha256-z9k3MfslLjWQfnjBtEtJZdq3H7kyi2kQtUThfTgdRk0=", + "owner": "input-output-hk", + "repo": "flake-compat", + "rev": "45f2638735f8cdc40fe302742b79f248d23eb368", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "hkm/gitlab-fix", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_5": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "plutarch", + "emanote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1727826117, + "narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1730504689, + "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "506278e768c2a08bec68eb62932193e341f55c90", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": [ + "plutarch", + "hercules-ci-effects", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", + "type": "github" + }, + "original": { + "id": "flake-parts", + "type": "indirect" + } + }, + "flake-root": { + "locked": { + "lastModified": 1692742795, + "narHash": "sha256-f+Y0YhVCIJ06LemO+3Xx00lIcqQxSKJHXT/yk1RTKxw=", + "owner": "srid", + "repo": "flake-root", + "rev": "d9a70d9c7a5fd7f3258ccf48da9335e9b47c3937", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "flake-root", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "ghc-8.6.5-iohk": { + "flake": false, + "locked": { + "lastModified": 1600920045, + "narHash": "sha256-DO6kxJz248djebZLpSzTGD6s8WRpNI9BTwUeOf5RwY8=", + "owner": "input-output-hk", + "repo": "ghc", + "rev": "95713a6ecce4551240da7c96b6176f980af75cae", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "release/8.6.5-iohk", + "repo": "ghc", + "type": "github" + } + }, + "ghc-8.6.5-iohk_2": { + "flake": false, + "locked": { + "lastModified": 1600920045, + "narHash": "sha256-DO6kxJz248djebZLpSzTGD6s8WRpNI9BTwUeOf5RwY8=", + "owner": "input-output-hk", + "repo": "ghc", + "rev": "95713a6ecce4551240da7c96b6176f980af75cae", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "release/8.6.5-iohk", + "repo": "ghc", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "iogx", + "pre-commit-hooks-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "gitignore_2": { + "inputs": { + "nixpkgs": [ + "plutarch", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "hackage": { + "flake": false, + "locked": { + "lastModified": 1734309106, + "narHash": "sha256-JcB9YbRWasj3d1wpz8vfyI8ai3Nvu69+IPPhUb9ejoA=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "d3ac85d228d4b58d8083d8c8af2ba12d3199c886", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "hackage_2": { + "flake": false, + "locked": { + "lastModified": 1731457652, + "narHash": "sha256-v9u++UVoVRP0NTFBjtW/c/xt8js/l46zYFuV3D6M8RQ=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "3de0e93a65428a0dbf185b66b680f432a9ba7669", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "haskell-flake": { + "locked": { + "lastModified": 1725314890, + "narHash": "sha256-jjVrhLOlPjQiZ/8pe+g6Xc5sa563WXnNZDwGXVl4PXQ=", + "owner": "srid", + "repo": "haskell-flake", + "rev": "ed94388c2e622f28cb45108a4e73c9d2b2a796da", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "haskell-flake", + "type": "github" + } + }, + "haskell-nix": { + "inputs": { + "HTTP": "HTTP", + "cabal-32": "cabal-32", + "cabal-34": "cabal-34", + "cabal-36": "cabal-36", + "cardano-shell": "cardano-shell", + "flake-compat": "flake-compat", + "ghc-8.6.5-iohk": "ghc-8.6.5-iohk", + "hackage": [ + "hackage" + ], + "hls-1.10": "hls-1.10", + "hls-2.0": "hls-2.0", + "hls-2.2": "hls-2.2", + "hls-2.3": "hls-2.3", + "hls-2.4": "hls-2.4", + "hls-2.5": "hls-2.5", + "hls-2.6": "hls-2.6", + "hls-2.7": "hls-2.7", + "hls-2.8": "hls-2.8", + "hls-2.9": "hls-2.9", + "hpc-coveralls": "hpc-coveralls", + "hydra": "hydra", + "iserv-proxy": "iserv-proxy", + "nixpkgs": [ + "haskell-nix", + "nixpkgs-unstable" + ], + "nixpkgs-2003": "nixpkgs-2003", + "nixpkgs-2105": "nixpkgs-2105", + "nixpkgs-2111": "nixpkgs-2111", + "nixpkgs-2205": "nixpkgs-2205", + "nixpkgs-2211": "nixpkgs-2211", + "nixpkgs-2305": "nixpkgs-2305", + "nixpkgs-2311": "nixpkgs-2311", + "nixpkgs-2405": "nixpkgs-2405", + "nixpkgs-unstable": "nixpkgs-unstable", + "old-ghc-nix": "old-ghc-nix", + "stackage": "stackage" + }, + "locked": { + "lastModified": 1734310321, + "narHash": "sha256-V6n3f2JiauvU+M483gRcEirsPsr2mmhUfDiMHIlWo5g=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "4bd079e21afcff79917e953d2f1b11d3bfec8603", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "haskell.nix", + "type": "github" + } + }, + "haskell-nix_2": { + "inputs": { + "HTTP": "HTTP_2", + "cabal-32": "cabal-32_2", + "cabal-34": "cabal-34_2", + "cabal-36": "cabal-36_2", + "cardano-shell": "cardano-shell_2", + "flake-compat": "flake-compat_4", + "ghc-8.6.5-iohk": "ghc-8.6.5-iohk_2", + "hackage": "hackage_2", + "hls-1.10": "hls-1.10_2", + "hls-2.0": "hls-2.0_2", + "hls-2.2": "hls-2.2_2", + "hls-2.3": "hls-2.3_2", + "hls-2.4": "hls-2.4_2", + "hls-2.5": "hls-2.5_2", + "hls-2.6": "hls-2.6_2", + "hls-2.7": "hls-2.7_2", + "hls-2.8": "hls-2.8_2", + "hls-2.9": "hls-2.9_2", + "hpc-coveralls": "hpc-coveralls_2", + "hydra": "hydra_2", + "iserv-proxy": "iserv-proxy_2", + "nixpkgs": [ + "plutarch", + "haskell-nix", + "nixpkgs-unstable" + ], + "nixpkgs-2003": "nixpkgs-2003_2", + "nixpkgs-2105": "nixpkgs-2105_2", + "nixpkgs-2111": "nixpkgs-2111_2", + "nixpkgs-2205": "nixpkgs-2205_2", + "nixpkgs-2211": "nixpkgs-2211_2", + "nixpkgs-2305": "nixpkgs-2305_2", + "nixpkgs-2311": "nixpkgs-2311_2", + "nixpkgs-2405": "nixpkgs-2405_2", + "nixpkgs-unstable": "nixpkgs-unstable_2", + "old-ghc-nix": "old-ghc-nix_2", + "stackage": "stackage_2" + }, + "locked": { + "lastModified": 1731459093, + "narHash": "sha256-jtkwdegm5jhft4k2JqqxsxVWxXc2Or+Sbk1ym5T+1h0=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "fc8633a447714e7720b7db2a88038e75fa350150", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "haskell.nix", + "type": "github" + } + }, + "heist-extra": { + "flake": false, + "locked": { + "lastModified": 1710541479, + "narHash": "sha256-9e4U78eutom6D3EJqsCdV8iQxNgYA/pi001r5CZdm0A=", + "owner": "srid", + "repo": "heist-extra", + "rev": "589b7636f620dcdfc0dc07dea720feed1ab3e0fa", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "heist-extra", + "type": "github" + } + }, + "hercules-ci-effects": { + "inputs": { + "flake-parts": "flake-parts_3", + "nixpkgs": "nixpkgs_6" + }, + "locked": { + "lastModified": 1730903510, + "narHash": "sha256-mnynlrPeiW0nUQ8KGZHb3WyxAxA3Ye/BH8gMjdoKP6E=", + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "rev": "b89ac4d66d618b915b1f0a408e2775fe3821d141", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "type": "github" + } + }, + "hls-1.10": { + "flake": false, + "locked": { + "lastModified": 1680000865, + "narHash": "sha256-rc7iiUAcrHxwRM/s0ErEsSPxOR3u8t7DvFeWlMycWgo=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b08691db779f7a35ff322b71e72a12f6e3376fd9", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "1.10.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-1.10_2": { + "flake": false, + "locked": { + "lastModified": 1680000865, + "narHash": "sha256-rc7iiUAcrHxwRM/s0ErEsSPxOR3u8t7DvFeWlMycWgo=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b08691db779f7a35ff322b71e72a12f6e3376fd9", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "1.10.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.0": { + "flake": false, + "locked": { + "lastModified": 1687698105, + "narHash": "sha256-OHXlgRzs/kuJH8q7Sxh507H+0Rb8b7VOiPAjcY9sM1k=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "783905f211ac63edf982dd1889c671653327e441", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.0.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.0_2": { + "flake": false, + "locked": { + "lastModified": 1687698105, + "narHash": "sha256-OHXlgRzs/kuJH8q7Sxh507H+0Rb8b7VOiPAjcY9sM1k=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "783905f211ac63edf982dd1889c671653327e441", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.0.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.2": { + "flake": false, + "locked": { + "lastModified": 1693064058, + "narHash": "sha256-8DGIyz5GjuCFmohY6Fa79hHA/p1iIqubfJUTGQElbNk=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b30f4b6cf5822f3112c35d14a0cba51f3fe23b85", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.2.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.2_2": { + "flake": false, + "locked": { + "lastModified": 1693064058, + "narHash": "sha256-8DGIyz5GjuCFmohY6Fa79hHA/p1iIqubfJUTGQElbNk=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b30f4b6cf5822f3112c35d14a0cba51f3fe23b85", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.2.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.3": { + "flake": false, + "locked": { + "lastModified": 1695910642, + "narHash": "sha256-tR58doOs3DncFehHwCLczJgntyG/zlsSd7DgDgMPOkI=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "458ccdb55c9ea22cd5d13ec3051aaefb295321be", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.3.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.3_2": { + "flake": false, + "locked": { + "lastModified": 1695910642, + "narHash": "sha256-tR58doOs3DncFehHwCLczJgntyG/zlsSd7DgDgMPOkI=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "458ccdb55c9ea22cd5d13ec3051aaefb295321be", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.3.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.4": { + "flake": false, + "locked": { + "lastModified": 1699862708, + "narHash": "sha256-YHXSkdz53zd0fYGIYOgLt6HrA0eaRJi9mXVqDgmvrjk=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "54507ef7e85fa8e9d0eb9a669832a3287ffccd57", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.4.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.4_2": { + "flake": false, + "locked": { + "lastModified": 1699862708, + "narHash": "sha256-YHXSkdz53zd0fYGIYOgLt6HrA0eaRJi9mXVqDgmvrjk=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "54507ef7e85fa8e9d0eb9a669832a3287ffccd57", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.4.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.5": { + "flake": false, + "locked": { + "lastModified": 1701080174, + "narHash": "sha256-fyiR9TaHGJIIR0UmcCb73Xv9TJq3ht2ioxQ2mT7kVdc=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "27f8c3d3892e38edaef5bea3870161815c4d014c", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.5.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.5_2": { + "flake": false, + "locked": { + "lastModified": 1701080174, + "narHash": "sha256-fyiR9TaHGJIIR0UmcCb73Xv9TJq3ht2ioxQ2mT7kVdc=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "27f8c3d3892e38edaef5bea3870161815c4d014c", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.5.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.6": { + "flake": false, + "locked": { + "lastModified": 1705325287, + "narHash": "sha256-+P87oLdlPyMw8Mgoul7HMWdEvWP/fNlo8jyNtwME8E8=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "6e0b342fa0327e628610f2711f8c3e4eaaa08b1e", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.6.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.6_2": { + "flake": false, + "locked": { + "lastModified": 1705325287, + "narHash": "sha256-+P87oLdlPyMw8Mgoul7HMWdEvWP/fNlo8jyNtwME8E8=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "6e0b342fa0327e628610f2711f8c3e4eaaa08b1e", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.6.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.7": { + "flake": false, + "locked": { + "lastModified": 1708965829, + "narHash": "sha256-LfJ+TBcBFq/XKoiNI7pc4VoHg4WmuzsFxYJ3Fu+Jf+M=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "50322b0a4aefb27adc5ec42f5055aaa8f8e38001", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.7.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.7_2": { + "flake": false, + "locked": { + "lastModified": 1708965829, + "narHash": "sha256-LfJ+TBcBFq/XKoiNI7pc4VoHg4WmuzsFxYJ3Fu+Jf+M=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "50322b0a4aefb27adc5ec42f5055aaa8f8e38001", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.7.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.8": { + "flake": false, + "locked": { + "lastModified": 1715153580, + "narHash": "sha256-Vi/iUt2pWyUJlo9VrYgTcbRviWE0cFO6rmGi9rmALw0=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "dd1be1beb16700de59e0d6801957290bcf956a0a", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.8.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.8_2": { + "flake": false, + "locked": { + "lastModified": 1715153580, + "narHash": "sha256-Vi/iUt2pWyUJlo9VrYgTcbRviWE0cFO6rmGi9rmALw0=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "dd1be1beb16700de59e0d6801957290bcf956a0a", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.8.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.9": { + "flake": false, + "locked": { + "lastModified": 1720003792, + "narHash": "sha256-qnDx8Pk0UxtoPr7BimEsAZh9g2WuTuMB/kGqnmdryKs=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "0c1817cb2babef0765e4e72dd297c013e8e3d12b", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.9.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.9_2": { + "flake": false, + "locked": { + "lastModified": 1720003792, + "narHash": "sha256-qnDx8Pk0UxtoPr7BimEsAZh9g2WuTuMB/kGqnmdryKs=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "0c1817cb2babef0765e4e72dd297c013e8e3d12b", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.9.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hpc-coveralls": { + "flake": false, + "locked": { + "lastModified": 1607498076, + "narHash": "sha256-8uqsEtivphgZWYeUo5RDUhp6bO9j2vaaProQxHBltQk=", + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "rev": "14df0f7d229f4cd2e79f8eabb1a740097fdfa430", + "type": "github" + }, + "original": { + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "type": "github" + } + }, + "hpc-coveralls_2": { + "flake": false, + "locked": { + "lastModified": 1607498076, + "narHash": "sha256-8uqsEtivphgZWYeUo5RDUhp6bO9j2vaaProQxHBltQk=", + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "rev": "14df0f7d229f4cd2e79f8eabb1a740097fdfa430", + "type": "github" + }, + "original": { + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "type": "github" + } + }, + "hydra": { + "inputs": { + "nix": "nix", + "nixpkgs": [ + "haskell-nix", + "hydra", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1671755331, + "narHash": "sha256-hXsgJj0Cy0ZiCiYdW2OdBz5WmFyOMKuw4zyxKpgUKm4=", + "owner": "NixOS", + "repo": "hydra", + "rev": "f48f00ee6d5727ae3e488cbf9ce157460853fea8", + "type": "github" + }, + "original": { + "id": "hydra", + "type": "indirect" + } + }, + "hydra_2": { + "inputs": { + "nix": "nix_2", + "nixpkgs": [ + "plutarch", + "haskell-nix", + "hydra", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1671755331, + "narHash": "sha256-hXsgJj0Cy0ZiCiYdW2OdBz5WmFyOMKuw4zyxKpgUKm4=", + "owner": "NixOS", + "repo": "hydra", + "rev": "f48f00ee6d5727ae3e488cbf9ce157460853fea8", + "type": "github" + }, + "original": { + "id": "hydra", + "type": "indirect" + } + }, + "iogx": { + "inputs": { + "CHaP": [ + "CHaP" + ], + "easy-purescript-nix": "easy-purescript-nix", + "flake-compat": "flake-compat_2", + "flake-utils": "flake-utils_2", + "hackage": [ + "hackage" + ], + "haskell-nix": [ + "haskell-nix" + ], + "iohk-nix": "iohk-nix", + "nix2container": "nix2container", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable", + "pre-commit-hooks-nix": "pre-commit-hooks-nix", + "sphinxcontrib-haddock": "sphinxcontrib-haddock" + }, + "locked": { + "lastModified": 1734348819, + "narHash": "sha256-/bArU2htalHKKfw/Sn2KzrXf51XWsLX1RLXnWLDoI+w=", + "owner": "input-output-hk", + "repo": "iogx", + "rev": "ebedc8a33b33c0807db1cdc67376ba0fc020d10d", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "iogx", + "type": "github" + } + }, + "iohk-nix": { + "inputs": { + "blst": "blst", + "nixpkgs": [ + "iogx", + "nixpkgs" + ], + "secp256k1": "secp256k1", + "sodium": "sodium" + }, + "locked": { + "lastModified": 1732287300, + "narHash": "sha256-lURsE6HdJX0alscWhbzCWyLRK8GpAgKuXeIgX31Kfqg=", + "owner": "input-output-hk", + "repo": "iohk-nix", + "rev": "262cb2aec2ddd914124bab90b06fe24a1a74d02c", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "iohk-nix", + "type": "github" + } + }, + "iohk-nix_2": { + "inputs": { + "blst": "blst_2", + "nixpkgs": [ + "haskell-nix", + "nixpkgs" + ], + "secp256k1": "secp256k1_2", + "sodium": "sodium_2" + }, + "locked": { + "lastModified": 1732287300, + "narHash": "sha256-lURsE6HdJX0alscWhbzCWyLRK8GpAgKuXeIgX31Kfqg=", + "owner": "input-output-hk", + "repo": "iohk-nix", + "rev": "262cb2aec2ddd914124bab90b06fe24a1a74d02c", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "iohk-nix", + "type": "github" + } + }, + "iohk-nix_3": { + "inputs": { + "blst": "blst_3", + "nixpkgs": [ + "plutarch", + "haskell-nix", + "nixpkgs" + ], + "secp256k1": "secp256k1_3", + "sodium": "sodium_3" + }, + "locked": { + "lastModified": 1730297014, + "narHash": "sha256-n3f1iAmltKnorHWx7FrdbGIF/FmEG8SsZshS16vnpz0=", + "owner": "input-output-hk", + "repo": "iohk-nix", + "rev": "d407eedd4995e88d08e83ef75844a8a9c2e29b36", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "iohk-nix", + "type": "github" + } + }, + "iserv-proxy": { + "flake": false, + "locked": { + "lastModified": 1717479972, + "narHash": "sha256-7vE3RQycHI1YT9LHJ1/fUaeln2vIpYm6Mmn8FTpYeVo=", + "owner": "stable-haskell", + "repo": "iserv-proxy", + "rev": "2ed34002247213fc435d0062350b91bab920626e", + "type": "github" + }, + "original": { + "owner": "stable-haskell", + "ref": "iserv-syms", + "repo": "iserv-proxy", + "type": "github" + } + }, + "iserv-proxy_2": { + "flake": false, + "locked": { + "lastModified": 1717479972, + "narHash": "sha256-7vE3RQycHI1YT9LHJ1/fUaeln2vIpYm6Mmn8FTpYeVo=", + "owner": "stable-haskell", + "repo": "iserv-proxy", + "rev": "2ed34002247213fc435d0062350b91bab920626e", + "type": "github" + }, + "original": { + "owner": "stable-haskell", + "ref": "iserv-syms", + "repo": "iserv-proxy", + "type": "github" + } + }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "lowdown-src_2": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": "nixpkgs", + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1661606874, + "narHash": "sha256-9+rpYzI+SmxJn+EbYxjGv68Ucp22bdFUSy/4LkHkkDQ=", + "owner": "NixOS", + "repo": "nix", + "rev": "11e45768b34fdafdcf019ddbd337afa16127ff0f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "2.11.0", + "repo": "nix", + "type": "github" + } + }, + "nix2container": { + "inputs": { + "flake-utils": "flake-utils_3", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1730479402, + "narHash": "sha256-79NLeNjpCa4mSasmFsE3QA6obURezF0TUO5Pm+1daog=", + "owner": "nlewo", + "repo": "nix2container", + "rev": "5fb215a1564baa74ce04ad7f903d94ad6617e17a", + "type": "github" + }, + "original": { + "owner": "nlewo", + "repo": "nix2container", + "type": "github" + } + }, + "nix_2": { + "inputs": { + "lowdown-src": "lowdown-src_2", + "nixpkgs": "nixpkgs_5", + "nixpkgs-regression": "nixpkgs-regression_2" + }, + "locked": { + "lastModified": 1661606874, + "narHash": "sha256-9+rpYzI+SmxJn+EbYxjGv68Ucp22bdFUSy/4LkHkkDQ=", + "owner": "NixOS", + "repo": "nix", + "rev": "11e45768b34fdafdcf019ddbd337afa16127ff0f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "2.11.0", + "repo": "nix", + "type": "github" + } + }, + "nixos-unified": { + "locked": { + "lastModified": 1729549045, + "narHash": "sha256-W0VyC1MueUy6zMzcKZ9Ofnz/03da+SPFCYdbQ3MugfM=", + "owner": "srid", + "repo": "nixos-unified", + "rev": "09752a3c33541b7342416fb968c299c03c3e7e39", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "nixos-unified", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1657693803, + "narHash": "sha256-G++2CJ9u0E7NNTAi9n5G8TdDmGJXcIjkJ3NF8cetQB8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "365e1b3a859281cf11b94f87231adeabbdd878a2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2003": { + "locked": { + "lastModified": 1620055814, + "narHash": "sha256-8LEHoYSJiL901bTMVatq+rf8y7QtWuZhwwpKE2fyaRY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1db42b7fe3878f3f5f7a4f2dc210772fd080e205", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-20.03-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2003_2": { + "locked": { + "lastModified": 1620055814, + "narHash": "sha256-8LEHoYSJiL901bTMVatq+rf8y7QtWuZhwwpKE2fyaRY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1db42b7fe3878f3f5f7a4f2dc210772fd080e205", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-20.03-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2105": { + "locked": { + "lastModified": 1659914493, + "narHash": "sha256-lkA5X3VNMKirvA+SUzvEhfA7XquWLci+CGi505YFAIs=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "022caabb5f2265ad4006c1fa5b1ebe69fb0c3faf", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2105_2": { + "locked": { + "lastModified": 1659914493, + "narHash": "sha256-lkA5X3VNMKirvA+SUzvEhfA7XquWLci+CGi505YFAIs=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "022caabb5f2265ad4006c1fa5b1ebe69fb0c3faf", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2111": { + "locked": { + "lastModified": 1659446231, + "narHash": "sha256-hekabNdTdgR/iLsgce5TGWmfIDZ86qjPhxDg/8TlzhE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eabc38219184cc3e04a974fe31857d8e0eac098d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2111_2": { + "locked": { + "lastModified": 1659446231, + "narHash": "sha256-hekabNdTdgR/iLsgce5TGWmfIDZ86qjPhxDg/8TlzhE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eabc38219184cc3e04a974fe31857d8e0eac098d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2205": { + "locked": { + "lastModified": 1685573264, + "narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "380be19fbd2d9079f677978361792cb25e8a3635", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-22.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2205_2": { + "locked": { + "lastModified": 1685573264, + "narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "380be19fbd2d9079f677978361792cb25e8a3635", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-22.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2211": { + "locked": { + "lastModified": 1688392541, + "narHash": "sha256-lHrKvEkCPTUO+7tPfjIcb7Trk6k31rz18vkyqmkeJfY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-22.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2211_2": { + "locked": { + "lastModified": 1688392541, + "narHash": "sha256-lHrKvEkCPTUO+7tPfjIcb7Trk6k31rz18vkyqmkeJfY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-22.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2305": { + "locked": { + "lastModified": 1705033721, + "narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-23.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2305_2": { + "locked": { + "lastModified": 1705033721, + "narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-23.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2311": { + "locked": { + "lastModified": 1719957072, + "narHash": "sha256-gvFhEf5nszouwLAkT9nWsDzocUTqLWHuL++dvNjMp9I=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7144d6241f02d171d25fba3edeaf15e0f2592105", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-23.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2311_2": { + "locked": { + "lastModified": 1719957072, + "narHash": "sha256-gvFhEf5nszouwLAkT9nWsDzocUTqLWHuL++dvNjMp9I=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7144d6241f02d171d25fba3edeaf15e0f2592105", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-23.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2405": { + "locked": { + "lastModified": 1729242558, + "narHash": "sha256-VgcLDu4igNT0eYua6OAl9pWCI0cYXhDbR+pWP44tte0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4a3f2d3195b60d07530574988df92e049372c10e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-24.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2405_2": { + "locked": { + "lastModified": 1729242558, + "narHash": "sha256-VgcLDu4igNT0eYua6OAl9pWCI0cYXhDbR+pWP44tte0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4a3f2d3195b60d07530574988df92e049372c10e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-24.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1730504152, + "narHash": "sha256-lXvH/vOfb4aGYyvFmZK/HlsNsr/0CVWlwYvo2rxJk3s=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-regression_2": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1690680713, + "narHash": "sha256-NXCWA8N+GfSQyoN7ZNiOgq/nDJKOp5/BHEpiZP8sUZw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b81af66deb21f73a70c67e5ea189568af53b1e8c", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b81af66deb21f73a70c67e5ea189568af53b1e8c", + "type": "github" + } + }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1730741070, + "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_3": { + "locked": { + "lastModified": 1730741070, + "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1729980323, + "narHash": "sha256-eWPRZAlhf446bKSmzw6x7RWEE4IuZgAp8NW3eXZwRAY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "86e78d3d2084ff87688da662cf78c2af085d8e73", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable_2": { + "locked": { + "lastModified": 1729980323, + "narHash": "sha256-eWPRZAlhf446bKSmzw6x7RWEE4IuZgAp8NW3eXZwRAY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "86e78d3d2084ff87688da662cf78c2af085d8e73", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1712920918, + "narHash": "sha256-1yxFvUcJfUphK9V91KufIQom7gCsztza0H4Rz2VCWUU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "92323443a56f4e9fc4e4b712e3119f66d0969297", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1730768919, + "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a04d33c0c3f1a59a2c1cb0c6e34cd24500e5a1dc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1712883908, + "narHash": "sha256-icE1IJE9fHcbDfJ0+qWoDdcBXUoZCcIJxME4lMHwvSM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "a0c9e3aee1000ac2bfb0e5b98c94c946a5d180a9", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1657693803, + "narHash": "sha256-G++2CJ9u0E7NNTAi9n5G8TdDmGJXcIjkJ3NF8cetQB8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "365e1b3a859281cf11b94f87231adeabbdd878a2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_6": { + "locked": { + "lastModified": 1713714899, + "narHash": "sha256-+z/XjO3QJs5rLE5UOf015gdVauVRQd2vZtsFkaXBq2Y=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6143fc5eeb9c4f00163267708e26191d1e918932", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_7": { + "locked": { + "lastModified": 1731531548, + "narHash": "sha256-sz8/v17enkYmfpgeeuyzniGJU0QQBfmAjlemAUYhfy8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "24f0d4acd634792badd6470134c387a3b039dace", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_8": { + "locked": { + "lastModified": 1730768919, + "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a04d33c0c3f1a59a2c1cb0c6e34cd24500e5a1dc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "old-ghc-nix": { + "flake": false, + "locked": { + "lastModified": 1631092763, + "narHash": "sha256-sIKgO+z7tj4lw3u6oBZxqIhDrzSkvpHtv0Kki+lh9Fg=", + "owner": "angerman", + "repo": "old-ghc-nix", + "rev": "af48a7a7353e418119b6dfe3cd1463a657f342b8", + "type": "github" + }, + "original": { + "owner": "angerman", + "ref": "master", + "repo": "old-ghc-nix", + "type": "github" + } + }, + "old-ghc-nix_2": { + "flake": false, + "locked": { + "lastModified": 1631092763, + "narHash": "sha256-sIKgO+z7tj4lw3u6oBZxqIhDrzSkvpHtv0Kki+lh9Fg=", + "owner": "angerman", + "repo": "old-ghc-nix", + "rev": "af48a7a7353e418119b6dfe3cd1463a657f342b8", + "type": "github" + }, + "original": { + "owner": "angerman", + "ref": "master", + "repo": "old-ghc-nix", + "type": "github" + } + }, + "plutarch": { + "inputs": { + "CHaP": "CHaP_2", + "emanote": "emanote", + "flake-parts": "flake-parts_2", + "haskell-nix": "haskell-nix_2", + "hercules-ci-effects": "hercules-ci-effects", + "iohk-nix": "iohk-nix_3", + "nixpkgs": "nixpkgs_7", + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1731559653, + "narHash": "sha256-mhuW2CHxnc6FDWuMcjW/51PKuPOdYc4yxz+W5RmlQew=", + "owner": "colll78", + "repo": "plutarch-plutus", + "rev": "b2379767c7f1c70acf28206bf922f128adc02f28", + "type": "github" + }, + "original": { + "owner": "colll78", + "repo": "plutarch-plutus", + "rev": "b2379767c7f1c70acf28206bf922f128adc02f28", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat_5", + "gitignore": "gitignore_2", + "nixpkgs": "nixpkgs_8", + "nixpkgs-stable": "nixpkgs-stable_3" + }, + "locked": { + "lastModified": 1731363552, + "narHash": "sha256-vFta1uHnD29VUY4HJOO/D6p6rxyObnf+InnSMT4jlMU=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "cd1af27aa85026ac759d5d3fccf650abe7e1bbf0", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "pre-commit-hooks-nix": { + "inputs": { + "flake-compat": "flake-compat_3", + "gitignore": "gitignore", + "nixpkgs": "nixpkgs_3", + "nixpkgs-stable": "nixpkgs-stable_2" + }, + "locked": { + "lastModified": 1734279981, + "narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "CHaP": "CHaP", + "hackage": "hackage", + "haskell-nix": "haskell-nix", + "iogx": "iogx", + "iohk-nix": "iohk-nix_2", + "nixpkgs": [ + "haskell-nix", + "nixpkgs" + ], + "plutarch": "plutarch" + } + }, + "secp256k1": { + "flake": false, + "locked": { + "lastModified": 1683999695, + "narHash": "sha256-9nJJVENMXjXEJZzw8DHzin1DkFkF8h9m/c6PuM7Uk4s=", + "owner": "bitcoin-core", + "repo": "secp256k1", + "rev": "acf5c55ae6a94e5ca847e07def40427547876101", + "type": "github" + }, + "original": { + "owner": "bitcoin-core", + "ref": "v0.3.2", + "repo": "secp256k1", + "type": "github" + } + }, + "secp256k1_2": { + "flake": false, + "locked": { + "lastModified": 1683999695, + "narHash": "sha256-9nJJVENMXjXEJZzw8DHzin1DkFkF8h9m/c6PuM7Uk4s=", + "owner": "bitcoin-core", + "repo": "secp256k1", + "rev": "acf5c55ae6a94e5ca847e07def40427547876101", + "type": "github" + }, + "original": { + "owner": "bitcoin-core", + "ref": "v0.3.2", + "repo": "secp256k1", + "type": "github" + } + }, + "secp256k1_3": { + "flake": false, + "locked": { + "lastModified": 1683999695, + "narHash": "sha256-9nJJVENMXjXEJZzw8DHzin1DkFkF8h9m/c6PuM7Uk4s=", + "owner": "bitcoin-core", + "repo": "secp256k1", + "rev": "acf5c55ae6a94e5ca847e07def40427547876101", + "type": "github" + }, + "original": { + "owner": "bitcoin-core", + "ref": "v0.3.2", + "repo": "secp256k1", + "type": "github" + } + }, + "sodium": { + "flake": false, + "locked": { + "lastModified": 1675156279, + "narHash": "sha256-0uRcN5gvMwO7MCXVYnoqG/OmeBFi8qRVnDWJLnBb9+Y=", + "owner": "input-output-hk", + "repo": "libsodium", + "rev": "dbb48cce5429cb6585c9034f002568964f1ce567", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "libsodium", + "rev": "dbb48cce5429cb6585c9034f002568964f1ce567", + "type": "github" + } + }, + "sodium_2": { + "flake": false, + "locked": { + "lastModified": 1675156279, + "narHash": "sha256-0uRcN5gvMwO7MCXVYnoqG/OmeBFi8qRVnDWJLnBb9+Y=", + "owner": "input-output-hk", + "repo": "libsodium", + "rev": "dbb48cce5429cb6585c9034f002568964f1ce567", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "libsodium", + "rev": "dbb48cce5429cb6585c9034f002568964f1ce567", + "type": "github" + } + }, + "sodium_3": { + "flake": false, + "locked": { + "lastModified": 1675156279, + "narHash": "sha256-0uRcN5gvMwO7MCXVYnoqG/OmeBFi8qRVnDWJLnBb9+Y=", + "owner": "input-output-hk", + "repo": "libsodium", + "rev": "dbb48cce5429cb6585c9034f002568964f1ce567", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "libsodium", + "rev": "dbb48cce5429cb6585c9034f002568964f1ce567", + "type": "github" + } + }, + "sphinxcontrib-haddock": { + "flake": false, + "locked": { + "lastModified": 1594136664, + "narHash": "sha256-O9YT3iCUBHP3CEF88VDLLCO2HSP3HqkNA2q2939RnVY=", + "owner": "michaelpj", + "repo": "sphinxcontrib-haddock", + "rev": "f3956b3256962b2d27d5a4e96edb7951acf5de34", + "type": "github" + }, + "original": { + "owner": "michaelpj", + "repo": "sphinxcontrib-haddock", + "type": "github" + } + }, + "stackage": { + "flake": false, + "locked": { + "lastModified": 1734307971, + "narHash": "sha256-K/cG068tTrjNSEXtRy41Tgl8FzGuh4GHE6Ab3Efw074=", + "owner": "input-output-hk", + "repo": "stackage.nix", + "rev": "0f1c2177c3be7c738d025677bc0c687ba9a2cb38", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "stackage.nix", + "type": "github" + } + }, + "stackage_2": { + "flake": false, + "locked": { + "lastModified": 1731456685, + "narHash": "sha256-R0XG54ymDUUaQ8TprY9UuBnJ0UabRFQkwCt838JA56M=", + "owner": "input-output-hk", + "repo": "stackage.nix", + "rev": "ad774845ced6cda5a29966f13703332636d6cea8", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "stackage.nix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "plutarch", + "emanote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1711963903, + "narHash": "sha256-N3QDhoaX+paWXHbEXZapqd1r95mdshxToGowtjtYkGI=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "49dc4a92b02b8e68798abd99184f228243b6e3ac", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "unionmount": { + "flake": false, + "locked": { + "lastModified": 1710078535, + "narHash": "sha256-gKBgBtuiRTD3/3EeY8aMgFzuaSEffJacBxsCB3ct1eg=", + "owner": "srid", + "repo": "unionmount", + "rev": "41ae982fa118770bf4d3a3f2d48ac1ffb61c9f09", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "unionmount", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..2b8fd75 --- /dev/null +++ b/flake.nix @@ -0,0 +1,54 @@ +{ + description = "Smart Tokens"; + + inputs = { + iogx = { + url = "github:input-output-hk/iogx"; + inputs.hackage.follows = "hackage"; + inputs.CHaP.follows = "CHaP"; + inputs.haskell-nix.follows = "haskell-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + nixpkgs.follows = "haskell-nix/nixpkgs"; + iohk-nix.url = "github:input-output-hk/iohk-nix"; + iohk-nix.inputs.nixpkgs.follows = "haskell-nix/nixpkgs"; + + hackage = { + url = "github:input-output-hk/hackage.nix"; + flake = false; + }; + + CHaP = { + url = "github:input-output-hk/cardano-haskell-packages?ref=repo"; + flake = false; + }; + + haskell-nix = { + url = "github:input-output-hk/haskell.nix"; + inputs.hackage.follows = "hackage"; + }; + + plutarch = { + url = "github:colll78/plutarch-plutus/b2379767c7f1c70acf28206bf922f128adc02f28"; + }; + }; + + outputs = inputs: inputs.iogx.lib.mkFlake { + inherit inputs; + repoRoot = ./.; + outputs = import ./nix/outputs.nix; + systems = [ "x86_64-linux" ]; # "x86_64-darwin" ]; + }; + + nixConfig = { + extra-substituters = [ + "https://cache.iog.io" + ]; + extra-trusted-public-keys = [ + "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=" + ]; + allow-import-from-derivation = true; + }; + +} diff --git a/hei.yaml b/hei.yaml new file mode 100644 index 0000000..b900bbc --- /dev/null +++ b/hei.yaml @@ -0,0 +1,12 @@ +cradle: + multi: + - path: "./dist-newstyle" + config: + cradle: + none: + - path: "" + config: + cradle: + cabal: + - path: "./" + component: "wst-poc:wst-poc" \ No newline at end of file diff --git a/nix/outputs.nix b/nix/outputs.nix new file mode 100644 index 0000000..0d779d2 --- /dev/null +++ b/nix/outputs.nix @@ -0,0 +1,9 @@ +{ repoRoot, inputs, pkgs, lib, system }: +let + project = repoRoot.nix.project; +in +[ + ( + project.flake + ) +] diff --git a/nix/project.nix b/nix/project.nix new file mode 100644 index 0000000..cebdf5e --- /dev/null +++ b/nix/project.nix @@ -0,0 +1,29 @@ +{ repoRoot, inputs, pkgs, lib, system }: + +let + sha256map = { + "https://github.com/colll78/plutarch-plutus"."b2379767c7f1c70acf28206bf922f128adc02f28" = "sha256-mhuW2CHxnc6FDWuMcjW/51PKuPOdYc4yxz+W5RmlQew="; + "https://github.com/input-output-hk/catalyst-onchain-libs"."650a3435f8efbd4bf36e58768fac266ba5beede4" = "sha256-NUh+l97+eO27Ppd8Bx0yMl0E5EV+p7+7GuFun1B8gRc="; + }; + + modules = [{ }]; + + cabalProject = pkgs.haskell-nix.cabalProject' { + inherit modules sha256map; + src = ../.; + name = "smart-tokens-plutarch"; + compiler-nix-name = "ghc966"; + index-state = "2024-10-16T00:00:00Z"; + inputMap = { + "https://chap.intersectmbo.org/" = inputs.CHaP; + }; + shell.withHoogle = false; + }; + + project = lib.iogx.mkHaskellProject { + inherit cabalProject; + shellArgs = repoRoot.nix.shell; + }; + +in +project diff --git a/nix/shell.nix b/nix/shell.nix new file mode 100644 index 0000000..badcff7 --- /dev/null +++ b/nix/shell.nix @@ -0,0 +1,27 @@ +{ repoRoot, inputs, pkgs, lib, system }: + +cabalProject: + +let + plutarch = inputs.plutarch.packages.plutarch; +in +{ + name = "smart-tokens-plutarch"; + packages = [ + pkgs.ghcid + pkgs.nixpkgs-fmt + ]; + + env = { }; + + + preCommit = { + # NOTE: when this attribute set changes, `.pre-commit-config.yaml` (which is a sym link to the nix store) changes. + # To maintain a the same hooks for both nix and non-nix environment you should update the `.pre-commit-config.yaml.nonix` + # (`cp .pre-commit-config.yaml .pre-commit-config.yaml.nonix`). + # This step is necessary because `.pre-commit-config.yaml` is ignored by git. + cabal-fmt.enable = true; + stylish-haskell.enable = true; + nixpkgs-fmt.enable = false; + }; +} diff --git a/src/exe/export-smart-tokens/Main.hs b/src/exe/export-smart-tokens/Main.hs new file mode 100644 index 0000000..7afb99b --- /dev/null +++ b/src/exe/export-smart-tokens/Main.hs @@ -0,0 +1,80 @@ +{-# LANGUAGE OverloadedStrings #-} +module Main (main) where + +import Cardano.Binary qualified as CBOR +import Data.Aeson (KeyValue ((.=)), object) +import Data.Aeson.Encode.Pretty (encodePretty) +import Data.Bifunctor ( + first, + ) +import Data.ByteString.Base16 qualified as Base16 +import Data.ByteString.Lazy qualified as LBS +import Data.Text ( + Text, + pack, + ) +import Data.Text.Encoding qualified as Text +import Plutarch ( + Config (..), + TracingMode (..), + LogLevel (..), + compile, + ) +import Plutarch.Evaluate ( + evalScript, + applyArguments + ) +import Plutarch.Prelude +import Plutarch.Script (Script, serialiseScript) +import PlutusLedgerApi.V2 ( + Data, + ExBudget, + ) +import SmartTokens.Contracts.ProgrammableLogicBase (mkProgrammableLogicBase, mkProgrammableLogicGlobal) +import SmartTokens.Contracts.Issuance (mkProgrammableLogicMinting) +import SmartTokens.Contracts.ProtocolParams (mkProtocolParametersMinting, alwaysFailScript, mkPermissionedMinting) +import SmartTokens.Contracts.ExampleTransferLogic (mkPermissionedTransfer, mkFreezeAndSeizeTransfer) +import SmartTokens.LinkedList.MintDirectory (mkDirectoryNodeMP) +import SmartTokens.LinkedList.SpendDirectory (pmkDirectorySpending) + +encodeSerialiseCBOR :: Script -> Text +encodeSerialiseCBOR = Text.decodeUtf8 . Base16.encode . CBOR.serialize' . serialiseScript + +evalT :: Config -> ClosedTerm a -> Either Text (Script, ExBudget, [Text]) +evalT cfg x = evalWithArgsT cfg x [] + +evalWithArgsT :: Config -> ClosedTerm a -> [Data] -> Either Text (Script, ExBudget, [Text]) +evalWithArgsT cfg x args = do + cmp <- compile cfg x + let (escr, budg, trc) = evalScript $ applyArguments cmp args + scr <- first (pack . show) escr + pure (scr, budg, trc) + +writePlutusScript :: Config -> String -> FilePath -> ClosedTerm a -> IO () +writePlutusScript cfg title filepath term = do + case evalT cfg term of + Left e -> print e + Right (script, _, _) -> do + let + scriptType = "PlutusScriptV3" :: String + plutusJson = object ["type" .= scriptType, "description" .= title, "cborHex" .= encodeSerialiseCBOR script] + content = encodePretty plutusJson + LBS.writeFile filepath content + +writePlutusScriptTraceBind :: String -> FilePath -> ClosedTerm a -> IO () +writePlutusScriptTraceBind title filepath term = + writePlutusScript (Tracing LogInfo DoTracingAndBinds) title filepath term + +main :: IO () +main = do + putStrLn "Writing Plutus Scripts to files" + writePlutusScriptTraceBind "Programmable Logic Base" "./compiled/programmableLogicBase.json" mkProgrammableLogicBase + writePlutusScriptTraceBind "Programmable Logic Global" "./compiled/programmableLogicBase.json" mkProgrammableLogicGlobal + writePlutusScriptTraceBind "Issuance" "./compiled/programmableTokenMinting.json" mkProgrammableLogicMinting + writePlutusScriptTraceBind "Protocol Parameters NFT" "./compiled/protocolParametersNFTMinting.json" mkProtocolParametersMinting + writePlutusScriptTraceBind "Always Fail" "./compiled/alwaysFail.json" alwaysFailScript + writePlutusScriptTraceBind "Permissioned Minting" "./compiled/permissionedMinting.json" mkPermissionedMinting + writePlutusScriptTraceBind "Permissioned Transfer" "./compiled/permissionedTransfer.json" mkPermissionedTransfer + writePlutusScriptTraceBind "Freeze and Seize Transfer" "./compiled/freezeAndSeizeTransfer.json" mkFreezeAndSeizeTransfer + writePlutusScriptTraceBind "Directory Node Minting Policy" "./compiled/directoryNodeMintingPolicy.json" mkDirectoryNodeMP + writePlutusScriptTraceBind "Directory Spending" "./compiled/directorySpending.json" pmkDirectorySpending \ No newline at end of file diff --git a/src/exe/Main.hs b/src/exe/wst-poc/Main.hs similarity index 100% rename from src/exe/Main.hs rename to src/exe/wst-poc/Main.hs diff --git a/src/lib/Profile.hs b/src/lib/Profile.hs new file mode 100644 index 0000000..1a77f58 --- /dev/null +++ b/src/lib/Profile.hs @@ -0,0 +1,32 @@ +{-# LANGUAGE ImpredicativeTypes #-} + +module Profile ( + getTracesExUnits, + getExUnits, + getShowTerm +) where + +import Plutarch.Internal +import Plutarch +import Plutarch.Evaluate +import Data.Either +import PlutusCore.Evaluation.Machine.ExBudget (ExBudget) +import Data.Text + +getTracesExUnits :: ClosedTerm a -> [Text] +getTracesExUnits term = + let (_, _, traces) = fromRight (error "") (evalTerm (Tracing LogInfo DoTracingAndBinds) term) + in traces + +getExUnits :: ClosedTerm a -> ExBudget +getExUnits term = + let (_, budget, _) = fromRight (error "") (evalTerm NoTracing term) + in budget + +getShowTerm :: ClosedTerm a -> String +getShowTerm term = + let (t, _, _) = fromRight (error "") (evalTerm NoTracing term) + in + case t of + Right t' -> printTerm (Tracing LogInfo DoTracingAndBinds) t' + Left err -> show err diff --git a/src/lib/SmartTokens/Contracts/ExampleTransferLogic.hs b/src/lib/SmartTokens/Contracts/ExampleTransferLogic.hs new file mode 100644 index 0000000..6ee098c --- /dev/null +++ b/src/lib/SmartTokens/Contracts/ExampleTransferLogic.hs @@ -0,0 +1,201 @@ +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Use newtype instead of data" #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE QualifiedDo #-} +module SmartTokens.Contracts.ExampleTransferLogic ( + mkPermissionedTransfer, + mkFreezeAndSeizeTransfer, +) where + +import Plutarch.LedgerApi.V3 + ( PPubKeyHash, + PCurrencySymbol, + POutputDatum(POutputDatum), + PScriptContext, + PTxInInfo ) +import Plutarch.Monadic qualified as P +import Plutarch.Prelude + ( Generic, + (#), + (#$), + perror, + phoistAcyclic, + plet, + pfix, + pto, + pmatch, + type (:-->), + ClosedTerm, + S, + Term, + plam, + DerivePlutusType(..), + PlutusType, + pif, + pfromData, + pfstBuiltin, + psndBuiltin, + pfield, + pletFields, + pconstant, + PBool, + PEq(..), + PPartialOrd((#<)), + PAsData, + PBuiltinList, + PIsData, + PByteString, + PDataRecord, + PLabeledType((:=)), + PlutusTypeData, + PInteger, + PListLike(pcons, ptail, pelimList, phead), + PUnit, (#||) ) +import Plutarch.Builtin ( pasByteStr, pasConstr, pforgetData ) +import Plutarch.Core.Utils + ( pisRewarding, + phasDataCS, + pelemAtFast, + ptxSignedByPkh, + pand'List, + pvalidateConditions ) +import Plutarch.Unsafe ( punsafeCoerce ) +import SmartTokens.Types.PTokenDirectory ( PBlacklistNode, pletFieldsBlacklistNode) + +data PBlacklistProof (s :: S) + = PNonmembershipProof + ( Term + s + ( PDataRecord + '[ "nodeIdx" ':= PInteger + ] + ) + ) + deriving stock (Generic) + deriving anyclass (PlutusType, PIsData, PEq) + +instance DerivePlutusType PBlacklistProof where + type DPTStrat _ = PlutusTypeData + +{-| + The 'mkPermissionedTransfer' is a transfer logic script that enforces that all transactions which spend the + associated programmable tokens must be signed by the specified permissioned credential. + + Parameters: + - 'permissionedCred': The public key hash of the credential that is permitted to sign the transaction. + - 'ctx': The transaction's script context. + + The script works as follows: + 1. Extracts the list of signatories from the transaction context. + 2. Validates that the transaction is signed by the specified permissioned credential. + 3. If the transaction is signed by the permissioned credential, the script succeeds. Otherwise, it fails. + + This ensures that only transactions signed by the specified permissioned credential can spend the associated programmable tokens. +-} +mkPermissionedTransfer :: ClosedTerm (PAsData PPubKeyHash :--> PScriptContext :--> PUnit) +mkPermissionedTransfer = plam $ \permissionedCred ctx -> + pvalidateConditions + [ ptxSignedByPkh # permissionedCred # (pfield @"signatories" # (pfield @"txInfo" # ctx)) + ] + +{-| + The 'pvalidateWitnesses' function validates that none of the transaction witnesses are in the blacklist. + + Parameters: + - 'blacklistNodeCS': The currency symbol that identifies authentic blacklist nodes. + - 'proofs': A list of blacklist proofs provided via the redeemer. + - 'refInputs': A list of reference inputs in the transaction. + - 'witnesses': A list of transaction witnesses. + + The function works as follows: + 1. Iterates over the list of witnesses and blacklist proofs. + 2. For each witness, it verifies the correctness of the corresponding proof. + 3. The proof must demonstrate that the associated witness is not in the blacklist. + 4. If all proofs are valid, the function returns 'True'. Otherwise, it returns 'False'. + + The function uses a recursive approach with 'pfix' and 'pelimList' to process the list of proofs and witnesses. + It performs the following checks for each proof: + - For 'PNonmembershipProof': + - Ensures that the two nodes are adjacent in the blacklist. + - Verifies that the witness key is not in the blacklist by checking that it is lexographically greater than the key of the + first node and lexographically less than the key of the second node (and thus if it was in the blacklist those two nodes + would not be adjacent). + - Confirms the legitimacy of both directory entries by checking the presence of the directory node currency symbol. + - For 'PNonmembershipProofTail': + - Ensures that the witness key is greater than the tail node key in the blacklist. + - Confirms the legitimacy of the directory entry by checking the presence of the directory node currency symbol. + + If any of the checks fail, the function throws an error. +-} +pvalidateWitnesses :: Term s (PAsData PCurrencySymbol :--> PBuiltinList (PAsData PBlacklistProof) :--> PBuiltinList (PAsData PTxInInfo) :--> PBuiltinList (PAsData PByteString) :--> PBool) +pvalidateWitnesses = phoistAcyclic $ plam $ \blacklistNodeCS proofs refInputs witnesses -> + plet (pelemAtFast @PBuiltinList # refInputs) $ \patRefUTxOIdx -> + (pfix #$ plam $ \self remainingProofs txWits -> + pelimList @PBuiltinList + (\wit remainWits -> + pmatch (pfromData $ phead # remainingProofs) $ \case + PNonmembershipProof nonExist -> P.do + notExistF <- pletFields @'["nodeIdx"] nonExist + prevNodeUTxOF <- pletFields @'["value", "datum"] $ pfield @"resolved" # (patRefUTxOIdx # pfromData notExistF.nodeIdx) + POutputDatum ((pfield @"outputDatum" #) -> prevNodeDat') <- pmatch prevNodeUTxOF.datum + prevNodeDatumF <- pletFieldsBlacklistNode $ punsafeCoerce @_ @_ @(PAsData PBlacklistNode) (pto prevNodeDat') + witnessKey <- plet $ pasByteStr # pforgetData wit + nodeKey <- plet $ pfromData prevNodeDatumF.key + nodeNext <- plet $ pfromData prevNodeDatumF.next -- pasByteStr # pforgetData (phead # (ptail # prevNodeDatumF)) + let checks = + pand'List + [ + -- the currency symbol is not in the blacklist + nodeKey #< witnessKey + , witnessKey #< nodeNext #|| nodeNext #== pconstant "" + -- both directory entries are legitimate, this is proven by the + -- presence of the directory node currency symbol. + , phasDataCS # blacklistNodeCS # pfromData prevNodeUTxOF.value + ] + pif checks + (self # (ptail # remainingProofs) # remainWits) + perror + ) + (pconstant True) + txWits + ) # proofs # witnesses + + +{-| + The 'mkFreezeAndSeizeTransfer' is a transfer logic script that allows the associated programmable token + to be frozen via a dynamic blacklist. + + Parameters: + - 'blacklistNodeCS': The currency symbol that identifies authentic blacklist nodes. + - 'ctx': The transaction's script context. + + The script works as follows: + 1. Constructs a list of transaction witnesses by iterating over the withdrawal list, extracting the script credentials and + prepending them to the transaction required_signers set (txInfoSignatories). + 2. Enforces that the script is being invoked as a rewarding script (withdraw-zero trick) + 3. Validates that none of the tx witnesses are in the blacklist. This is done by iterating over the witnesses + the blacklist proofs (provided via the redeemer) verifying the correctness of each proof + (i.e. that the proof really does prove that the associated witness is not in the blacklist). +-} +mkFreezeAndSeizeTransfer :: ClosedTerm (PAsData PCurrencySymbol :--> PScriptContext :--> PUnit) +mkFreezeAndSeizeTransfer = plam $ \blacklistNodeCS ctx -> P.do + ctxF <- pletFields @'["txInfo", "redeemer", "scriptInfo"] ctx + infoF <- pletFields @'["inputs", "referenceInputs", "outputs", "signatories", "wdrl"] ctxF.txInfo + let red = pfromData $ punsafeCoerce @_ @_ @(PAsData (PBuiltinList (PAsData PBlacklistProof))) (pto ctxF.redeemer) + pkWits <- plet $ punsafeCoerce @_ @_ @(PBuiltinList (PAsData PByteString)) (pfromData infoF.signatories) + let txWitnesses = pfix # + plam (\self wdrlList -> + pelimList @PBuiltinList + (\wdrlPair rest -> + let cred = pfstBuiltin # wdrlPair + script = punsafeCoerce @_ @_ @(PAsData PByteString) $ phead #$ psndBuiltin #$ pasConstr # pforgetData cred + in pcons # script # (self # rest) + ) + pkWits + wdrlList + ) # pto (pfromData infoF.wdrl) + pvalidateConditions + [ pisRewarding ctxF.scriptInfo + , pvalidateWitnesses # blacklistNodeCS # red # infoF.referenceInputs # txWitnesses + ] \ No newline at end of file diff --git a/src/lib/SmartTokens/Contracts/Issuance.hs b/src/lib/SmartTokens/Contracts/Issuance.hs new file mode 100644 index 0000000..ebe548b --- /dev/null +++ b/src/lib/SmartTokens/Contracts/Issuance.hs @@ -0,0 +1,102 @@ +{-# LANGUAGE QualifiedDo #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE OverloadedStrings #-} +module SmartTokens.Contracts.Issuance ( + mkProgrammableLogicMinting, +) where + +import Plutarch.LedgerApi.V3 (PCredential, PScriptContext, PScriptInfo(PMintingScript)) +import Plutarch.Monadic qualified as P +import Plutarch.Prelude +import Plutarch.Builtin (pfromDataImpl, pdataImpl) +import Plutarch.LedgerApi.Value (PCurrencySymbol, pvalueOf) +import Plutarch.Core.Utils (ptryLookupValue, pheadSingleton, pand'List, (#>), pvalidateConditions) +import Plutarch.Unsafe (punsafeCoerce) +import Plutarch.Internal.PlutusType (PlutusType(pcon', pmatch')) +--import SmartTokens.Types.PTokenDirectory (PDirectorySetNode) + +data PSmartTokenMintingAction (s :: S) = PRegisterPToken | PMintPToken + +{- | + PSmartTokenMintingAction is encoded as an Enum, using values of PInteger + internally. +-} +instance PlutusType PSmartTokenMintingAction where + type PInner PSmartTokenMintingAction = PInteger + + pcon' PRegisterPToken = 0 + pcon' PMintPToken = 1 + + -- redeemer data is untrusted and non-permanent so we can safely decide zero is + -- PRegisterPToken and anything else we consider PMintPToken. + pmatch' x f = + pif (x #== 0) (f PRegisterPToken) (f PMintPToken) + +instance PIsData PSmartTokenMintingAction where + pfromDataImpl d = + punsafeCoerce (pfromDataImpl @PInteger $ punsafeCoerce d) + + pdataImpl x = + pdataImpl $ pto x + +mkProgrammableLogicMinting :: ClosedTerm (PAsData PCredential :--> PAsData PCredential :--> PAsData PCurrencySymbol :--> PScriptContext :--> PUnit) +mkProgrammableLogicMinting = plam $ \programmableLogicBase mintingLogicCred nodeCS ctx -> P.do + ctxF <- pletFields @'["txInfo", "redeemer", "scriptInfo"] ctx + infoF <- pletFields @'["referenceInputs", "outputs", "mint", "wdrl"] ctxF.txInfo + let red = punsafeCoerce @_ @_ @PSmartTokenMintingAction (pto ctxF.redeemer) + PMintingScript scriptInfo <- pmatch ctxF.scriptInfo + ownCS <- plet $ pfield @"_0" # scriptInfo + mintedValue <- plet $ pfromData infoF.mint + + let ownTkPairs = ptryLookupValue # ownCS # mintedValue + -- For ease of implementation of the POC we only allow one programmable token per instance of this minting policy. + -- This can be easily changed later. + ownTkPair <- plet (pheadSingleton # ownTkPairs) + ownTokenName <- plet (pfstBuiltin # ownTkPair) + ownNumMinted <- plet (pfromData $ psndBuiltin # ownTkPair) + txOutputs <- plet $ pfromData infoF.outputs + -- For ease of implementation of the POC we enforce that the first output must contain the minted tokens. + -- This can be easily changed later. + mintingToOutputF <- pletFields @'["value", "address"] (phead # txOutputs) + + let invokedScripts = + pmap @PBuiltinList + # plam (pfstBuiltin #) + # pto (pfromData infoF.wdrl) + + pmatch red $ \case + -- PRegisterPToken is used to register a new programmable token in the directory + -- It creates a permanent association between the currency symbol with a transferLogicScript and issuerLogicScript. + -- All transfers of the token will be validated by either the transferLogicScript or the issuerLogicScript. + -- This redeemer can only be invoked once per instance of this minting policy since the directory contracts do not permit duplicate + -- entries. + PRegisterPToken -> P.do + let nodeTkPairs = ptryLookupValue # nodeCS # mintedValue + nodeTkPair <- plet (pheadSingleton # nodeTkPairs) + _insertedName <- plet $ pfstBuiltin # nodeTkPair + insertedAmount <- plet $ psndBuiltin # nodeTkPair + + let checks = + pand'List + [ pvalueOf # pfromData mintingToOutputF.value # pfromData ownCS # pfromData ownTokenName #== ownNumMinted + , pfield @"credential" # mintingToOutputF.address #== programmableLogicBase + -- The entry for this currency symbol is inserted into the programmable token directory + , pfromData insertedAmount #== pconstant 1 + , pelem # mintingLogicCred # invokedScripts + ] + pif checks + (pconstant ()) + perror + PMintPToken -> + pif (ownNumMinted #> 0) + ( + pvalidateConditions + [ pvalueOf # pfromData mintingToOutputF.value # pfromData ownCS # pfromData ownTokenName #== ownNumMinted + , pfield @"credential" # mintingToOutputF.address #== programmableLogicBase + , pelem # mintingLogicCred # invokedScripts + ] + ) + ( + -- This branch is for validating the burning of tokens + pvalidateConditions [pelem # mintingLogicCred # invokedScripts] + ) diff --git a/src/lib/SmartTokens/Contracts/ProgrammableLogicBase.hs b/src/lib/SmartTokens/Contracts/ProgrammableLogicBase.hs new file mode 100644 index 0000000..e6ac804 --- /dev/null +++ b/src/lib/SmartTokens/Contracts/ProgrammableLogicBase.hs @@ -0,0 +1,405 @@ +{-# OPTIONS_GHC -Wno-unused-do-bind #-} +{-# OPTIONS_GHC -Wno-partial-type-signatures #-} +{-# LANGUAGE ImpredicativeTypes #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE QualifiedDo #-} +module SmartTokens.Contracts.ProgrammableLogicBase ( + mkProgrammableLogicBase, + mkProgrammableLogicGlobal +) where + +import Plutarch.Builtin (pasByteStr, pasConstr, pforgetData) +import Plutarch.Core.Utils (pand'List, pcanFind, pcountInputsFromCred, + pelemAtFast, pfilterCSFromValue, phasDataCS, + pisRewarding, pmustFind, ptxSignedByPkh, + pvalidateConditions, pvalueContains) +import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=)) +import Plutarch.LedgerApi.V3 (AmountGuarantees (Positive), + KeyGuarantees (Sorted), PCredential (..), + PCurrencySymbol, PLovelace, PMap (..), + PMaybeData (PDJust, PDNothing), + POutputDatum (POutputDatum), PPubKeyHash, + PScriptContext, PStakingCredential (PStakingHash), + PTokenName, PTxInInfo, PTxOut (..), PValue (..), + pdnothing) +import Plutarch.Monadic qualified as P +import Plutarch.Prelude (ClosedTerm, DerivePlutusType (..), Generic, PAsData, + PBool, PBuiltinList, PBuiltinPair, PByteString, + PDataRecord, PEq (..), PInteger, PIsData, + PLabeledType ((:=)), + PListLike (pcons, pelimList, phead, ptail), + PPartialOrd ((#<)), PUnit, PlutusType, PlutusTypeData, + S, Term, pcon, pconstant, pdata, pelem, perror, pfield, + pfix, pfromData, pfstBuiltin, phoistAcyclic, pif, plam, + plet, pletFields, pmap, pmatch, psndBuiltin, pto, + ptraceInfo, type (:-->), (#$), (#), (#||)) +import Plutarch.Unsafe (punsafeCoerce) +import PlutusLedgerApi.V1.Value (Value) +import SmartTokens.Types.ProtocolParams (PProgrammableLogicGlobalParams) +import SmartTokens.Types.PTokenDirectory (PDirectorySetNode) + +-- | Strip Ada from a ledger value +-- Importantly this function assumes that the Value is provided by the ledger (i.e. via the ScriptContext) +-- and thus the invariant that Ada is the first entry in the Value is maintained +pstripAda :: + forall (v :: AmountGuarantees) (s :: S). + Term s (PValue 'Sorted v :--> PValue 'Sorted v) +pstripAda = phoistAcyclic $ + plam $ \value -> + let nonAdaValueMapInner = ptail # pto (pto value) + in pcon (PValue $ pcon $ PMap nonAdaValueMapInner) + +-- TODO: +-- The current implementation of the contracts in this module are not designed to be maximally efficient. +-- In the future, this should be optimized to use the redeemer indexing design pattern to identify and validate +-- the programmable inputs. + +data PTokenProof (s :: S) + = PTokenExists + ( Term s ( PDataRecord '[ "nodeIdx" ':= PInteger ] ) ) + | PTokenDoesNotExist + ( Term + s + ( PDataRecord + '[ "nodeIdx" ':= PInteger + ] + ) + ) + deriving stock (Generic) + deriving anyclass (PlutusType, PIsData, PEq) + +instance DerivePlutusType PTokenProof where + type DPTStrat _ = PlutusTypeData + +emptyValue :: Value +emptyValue = mempty + +pemptyLedgerValue :: ClosedTerm (PValue 'Sorted 'Positive) +pemptyLedgerValue = punsafeCoerce $ pconstant emptyValue + +pvalueFromCred :: Term s (PAsData PCredential :--> PBuiltinList (PAsData PPubKeyHash) :--> PBuiltinList (PAsData PByteString) :--> PBuiltinList (PAsData PTxInInfo) :--> PValue 'Sorted 'Positive) +pvalueFromCred = phoistAcyclic $ plam $ \cred sigs scripts inputs -> + (pfix #$ plam $ \self acc -> + pelimList + (\txIn xs -> + self + # pletFields @'["address", "value"] (pfield @"resolved" # txIn) (\txInF -> + plet txInF.address $ \addr -> + pif (pfield @"credential" # addr #== cred) + ( + pmatch (pfield @"stakingCredential" # addr) $ \case + PDJust ((pfield @"_0" #) -> stakingCred) -> + pmatch stakingCred $ \case + PStakingHash ((pfield @"_0" #) -> ownerCred) -> + pmatch ownerCred $ \case + PPubKeyCredential ((pfield @"_0" #) -> pkh) -> + pif (ptxSignedByPkh # pkh # sigs) + (acc <> pfromData txInF.value) + perror + PScriptCredential ((pfield @"_0" #) -> scriptHash_) -> + pif (pelem # punsafeCoerce scriptHash_ # scripts) + (acc <> pfromData txInF.value) + perror + _ -> perror + PDNothing _ -> perror + ) + acc + ) + # xs + ) + acc + ) + # pemptyLedgerValue + # inputs + +pvalueToCred :: Term s (PAsData PCredential :--> PBuiltinList (PAsData PTxOut) :--> PValue 'Sorted 'Positive) +pvalueToCred = phoistAcyclic $ plam $ \cred inputs -> + let value = (pfix #$ plam $ \self acc -> + pelimList + (\txOut xs -> + self + # pletFields @'["address", "value"] txOut (\txOutF -> + plet txOutF.address $ \addr -> + pif (pfield @"credential" # addr #== cred) + (acc <> pfromData txOutF.value) + acc + ) + # xs + ) + acc + ) + # pemptyLedgerValue + # inputs + in pstripAda # value + +-- | Programmable logic base +-- This validator forwards its validation logic to the programmable logic stake script +-- using the withdraw-zero design pattern. +mkProgrammableLogicBase :: ClosedTerm (PAsData PCredential :--> PScriptContext :--> PUnit) +mkProgrammableLogicBase = plam $ \stakeCred ctx -> + let wdrls :: Term _ (PBuiltinList (PBuiltinPair (PAsData PCredential) (PAsData PLovelace))) + wdrls = pto $ pfromData $ pfield @"wdrl" # (pfield @"txInfo" # ctx) + in + plet wdrls $ \withdrawals -> + let firstWithdrawal :: Term _ (PAsData PCredential) + firstWithdrawal = pfstBuiltin # (phead @PBuiltinList # withdrawals) + hasCred = + pif (firstWithdrawal #== stakeCred) + (pconstant True) + ( + pcanFind @PBuiltinList + # plam (\withdrawPair -> pfstBuiltin # withdrawPair #== stakeCred) + # (ptail # withdrawals) + ) + in pvalidateConditions [hasCred] + +-- | Traverse the currency symbols of the combined value of all programmable base inputs +-- (excluding the first currency symbol in `totalValue` which the ledger enforces must be Ada). +-- For each currency symbol, we check a proof that either: +-- 1. The currency symbol is in the directory and the associated transfer logic script is executed in the transaction. +-- 2. The currency symbol is not in the directory. +pcheckTransferLogic :: Term s (PAsData PCurrencySymbol :--> PBuiltinList (PAsData PTxInInfo) :--> PBuiltinList (PAsData PTokenProof) :--> PBuiltinList (PAsData PByteString) :--> PValue 'Sorted 'Positive :--> PBool) +pcheckTransferLogic = plam $ \directoryNodeCS refInputs proofList scripts totalValue -> + plet (pelemAtFast @PBuiltinList # refInputs) $ \patRefUTxOIdx -> + let mapInnerList = pto (pto totalValue) + go = pfix #$ plam $ \self proofs innerValue -> + pelimList + (\csPair csPairs -> + let cs :: Term _ (PAsData PByteString) + cs = punsafeCoerce $ pfstBuiltin # csPair + in + pmatch (pfromData $ phead # proofs) $ \case + PTokenExists ((pfield @"nodeIdx" #) -> nodeIdx) -> P.do + directoryNodeUTxOF <- pletFields @'["value", "datum"] $ pfield @"resolved" # (patRefUTxOIdx # pfromData nodeIdx) + POutputDatum ((pfield @"outputDatum" #) -> paramDat') <- pmatch directoryNodeUTxOF.datum + directoryNodeDatumF <- pletFields @'["key", "next", "transferLogicScript"] (punsafeCoerce @_ @_ @PDirectorySetNode (pto paramDat')) + let transferLogicScriptHash = punsafeCoerce @_ @_ @(PAsData PByteString) $ phead #$ psndBuiltin #$ pasConstr # pforgetData directoryNodeDatumF.transferLogicScript + -- validate that the directory entry for the currency symbol is referenced by the proof + -- and that the associated transfer logic script is executed in the transaction + let checks = + pand'List + [ pelem # transferLogicScriptHash # scripts + , punsafeCoerce directoryNodeDatumF.key #== cs + , phasDataCS # directoryNodeCS # pfromData directoryNodeUTxOF.value + ] + pif checks + (self # (ptail # proofs) # csPairs) + perror + PTokenDoesNotExist notExist -> P.do + notExistF <- pletFields @'["nodeIdx"] notExist + prevNodeUTxOF <- pletFields @'["value", "datum"] $ pfield @"resolved" # (patRefUTxOIdx # pfromData notExistF.nodeIdx) + POutputDatum ((pfield @"outputDatum" #) -> prevNodeDat') <- pmatch prevNodeUTxOF.datum + nodeDatumF <- pletFields @'["key", "next"] (punsafeCoerce @_ @_ @PDirectorySetNode (pto prevNodeDat')) + currCS <- plet $ pasByteStr # pforgetData (pfstBuiltin # csPair) + nodeKey <- plet $ pasByteStr # pforgetData nodeDatumF.key + nodeNext <- plet $ pasByteStr # pforgetData nodeDatumF.next + let checks = + pand'List + [ + -- the currency symbol is not in the directory + nodeKey #< currCS + , currCS #< nodeNext #|| nodeNext #== pconstant "" + -- both directory entries are legitimate, this is proven by the + -- presence of the directory node currency symbol. + , phasDataCS # directoryNodeCS # pfromData prevNodeUTxOF.value + ] + pif checks + (self # (ptail # proofs) # csPairs) + perror + ) + (pconstant True) + innerValue + -- drop the ada entry in the value before traversing the rest of the value entries + in go # proofList # (ptail # mapInnerList) + +-- | Traverse the currency symbols of the combined value of all programmable base inputs +-- (excluding the first currency symbol in `totalValue` which the ledger enforces must be Ada). +-- For each currency symbol, we check a proof that either: +-- 1. The currency symbol is in the directory (and thus is a programmable token) +-- - given that it is a programmable token, we check that associated transfer logic script is executed in the transaction +-- and add the value entry to the result. +-- 2. The currency symbol is not in the directory. +-- Return a Value containing only programmable tokens from `totalValue` by filtering out the non-programmable token entries. +pcheckTransferLogicAndGetProgrammableValue :: Term s (PAsData PCurrencySymbol :--> PBuiltinList (PAsData PTxInInfo) :--> PBuiltinList (PAsData PTokenProof) :--> PBuiltinList (PAsData PByteString) :--> PValue 'Sorted 'Positive :--> PValue 'Sorted 'Positive) +pcheckTransferLogicAndGetProgrammableValue = plam $ \directoryNodeCS refInputs proofList scripts totalValue -> + plet (pelemAtFast @PBuiltinList # refInputs) $ \patRefUTxOIdx -> + let mapInnerList :: Term _ (PBuiltinList (PBuiltinPair (PAsData PCurrencySymbol) (PAsData (PMap 'Sorted PTokenName PInteger)))) + mapInnerList = pto (pto totalValue) + -- go :: Term _ (PBuiltinList (PAsData PTokenProof) :--> PBuiltinList (PBuiltinPair (PAsData PCurrencySymbol) (PAsData (PMap 'Sorted PTokenName PInteger))) :--> PBuiltinList (PBuiltinPair (PAsData PCurrencySymbol) (PAsData (PMap 'Sorted PTokenName PInteger))) :--> PValue 'Sorted 'Positive) + go = pfix #$ plam $ \self proofs inputInnerValue actualProgrammableTokenValue -> + pelimList + (\csPair csPairs -> + let cs :: Term _ (PAsData PByteString) + cs = punsafeCoerce $ pfstBuiltin # csPair + in + pmatch (pfromData $ phead # proofs) $ \case + PTokenExists ((pfield @"nodeIdx" #) -> nodeIdx) -> P.do + directoryNodeUTxOF <- pletFields @'["value", "datum"] $ pfield @"resolved" # (patRefUTxOIdx # pfromData nodeIdx) + POutputDatum ((pfield @"outputDatum" #) -> paramDat') <- pmatch directoryNodeUTxOF.datum + directoryNodeDatumF <- pletFields @'["key", "next", "transferLogicScript"] (pfromData $ punsafeCoerce @_ @_ @(PAsData PDirectorySetNode) (pto paramDat')) + let transferLogicScriptHash = punsafeCoerce @_ @_ @(PAsData PByteString) $ phead #$ psndBuiltin #$ pasConstr # pforgetData directoryNodeDatumF.transferLogicScript + -- validate that the directory entry for the currency symbol is referenced by the proof + -- and that the associated transfer logic script is executed in the transaction + let checks = + pand'List + [ pelem # transferLogicScriptHash # scripts + , punsafeCoerce directoryNodeDatumF.key #== cs + , phasDataCS # directoryNodeCS # pfromData directoryNodeUTxOF.value + ] + pif checks + (self # (ptail # proofs) # csPairs # (pcons # csPair # actualProgrammableTokenValue)) + perror + PTokenDoesNotExist notExist -> P.do + notExistF <- pletFields @'["nodeIdx"] notExist + prevNodeUTxOF <- pletFields @'["value", "datum"] $ pfield @"resolved" # (patRefUTxOIdx # pfromData notExistF.nodeIdx) + POutputDatum ((pfield @"outputDatum" #) -> prevNodeDat') <- pmatch prevNodeUTxOF.datum + nodeDatumF <- pletFields @'["key", "next"] (pfromData $ punsafeCoerce @_ @_ @(PAsData PDirectorySetNode) (pto prevNodeDat')) + currCS <- plet $ pasByteStr # pforgetData (pfstBuiltin # csPair) + nodeKey <- plet $ pasByteStr # pforgetData nodeDatumF.key + nodeNext <- plet $ pasByteStr # pforgetData nodeDatumF.next + let checks = + pand'List + [ + -- the currency symbol is not in the directory + nodeKey #< currCS + , currCS #< nodeNext #|| nodeNext #== pconstant "" + -- both directory entries are legitimate, this is proven by the + -- presence of the directory node currency symbol. + , phasDataCS # directoryNodeCS # pfromData prevNodeUTxOF.value + ] + pif checks + (self # (ptail # proofs) # csPairs # (pcons @PBuiltinList # csPair # actualProgrammableTokenValue)) + perror + ) + (pcon $ PValue $ pcon $ PMap actualProgrammableTokenValue) + inputInnerValue + -- drop the ada entry in the value before traversing the rest of the value entries + in go # proofList # (ptail # mapInnerList) # pto (pto pemptyLedgerValue) + +-- type ProgrammableLogicGlobalRedeemer = PBuiltinList (PAsData PTokenProof) + +data ProgrammableLogicGlobalRedeemer (s :: S) + = PTransferAct + ( Term s ( PDataRecord '[ "proofs" ':= PBuiltinList (PAsData PTokenProof) ] ) ) + | PSeizeAct + ( Term + s + ( PDataRecord + '[ "seizeInputIdx" ':= PInteger + , "seizeOutputIdx" ':= PInteger + , "directoryNodeIdx" ':= PInteger + ] + ) + ) + deriving stock (Generic) + deriving anyclass (PlutusType, PIsData, PEq) + +instance DerivePlutusType ProgrammableLogicGlobalRedeemer where + type DPTStrat _ = PlutusTypeData + +mkProgrammableLogicGlobal :: ClosedTerm (PAsData PCurrencySymbol :--> PScriptContext :--> PUnit) +mkProgrammableLogicGlobal = plam $ \protocolParamsCS ctx -> P.do + ctxF <- pletFields @'["txInfo", "redeemer", "scriptInfo"] ctx + infoF <- pletFields @'["inputs", "referenceInputs", "outputs", "signatories", "wdrl"] ctxF.txInfo + let red = pfromData $ punsafeCoerce @_ @_ @(PAsData ProgrammableLogicGlobalRedeemer) (pto ctxF.redeemer) + referenceInputs <- plet $ pfromData infoF.referenceInputs + -- Extract protocol parameter UTxO + ptraceInfo "Extracting protocol parameter UTxO" + let paramUTxO = + pfield @"resolved" #$ + pmustFind @PBuiltinList + # plam (\txIn -> + let resolvedIn = pfield @"resolved" # txIn + in phasDataCS # protocolParamsCS # (pfield @"value" # resolvedIn) + ) + # referenceInputs + + POutputDatum ((pfield @"outputDatum" #) -> paramDat') <- pmatch $ pfield @"datum" # paramUTxO + protocolParamsF <- pletFields @'["directoryNodeCS", "progLogicCred"] (pfromData $ punsafeCoerce @_ @_ @(PAsData PProgrammableLogicGlobalParams) (pto paramDat')) + progLogicCred <- plet protocolParamsF.progLogicCred + + ptraceInfo "Extracting invoked scripts" + let invokedScripts = + pmap @PBuiltinList + # plam (\wdrlPair -> + let cred = pfstBuiltin # wdrlPair + in punsafeCoerce @_ @_ @(PAsData PByteString) $ phead #$ psndBuiltin #$ pasConstr # pforgetData cred + ) + # pto (pfromData infoF.wdrl) + + pmatch red $ \case + PTransferAct ((pfield @"proofs" #) -> proofs) -> P.do + ptraceInfo "PTransferAct valueFromCred" + totalProgTokenValue <- + plet $ pvalueFromCred + # progLogicCred + # infoF.signatories + # invokedScripts + # infoF.inputs + ptraceInfo "PTransferAct checkTransferLogicAndGetProgrammableValue" + totalProgTokenValue_ <- + plet $ pcheckTransferLogicAndGetProgrammableValue + # protocolParamsF.directoryNodeCS + # referenceInputs + # pfromData proofs + # invokedScripts + # totalProgTokenValue + ptraceInfo "PTransferAct validateConditions" + pvalidateConditions + [ pisRewarding ctxF.scriptInfo + , pcheckTransferLogic + # protocolParamsF.directoryNodeCS + # referenceInputs + # pfromData proofs + # invokedScripts + # totalProgTokenValue_ + -- For POC we enforce that all value spent from the programmable contracts must + -- return to the programmable contracts. We can easily extend this to allow + -- for non-programmable tokens to leave the programmable contract. + , pvalueContains # (pvalueToCred # progLogicCred # pfromData infoF.outputs) # totalProgTokenValue_ + ] + PSeizeAct seizeAct -> P.do + -- TODO: + -- Possibly enforce that the seized assets must be seized to the programmable logic contract + -- just under different ownership (staking credential changed) + ptraceInfo "PSeizeAct" + txInputs <- plet $ pfromData infoF.inputs + seizeActF <- pletFields @'["seizeInputIdx", "seizeOutputIdx", "directoryNodeIdx"] seizeAct + let seizeInput = pfield @"resolved" # (pelemAtFast @PBuiltinList # txInputs # seizeActF.seizeInputIdx) + seizeOutput = pelemAtFast @PBuiltinList # infoF.outputs # seizeActF.seizeOutputIdx + directoryNodeUTxO = pelemAtFast @PBuiltinList # referenceInputs # pfromData seizeActF.directoryNodeIdx + seizeDirectoryNode <- pletFields @'["value", "datum"] (pfield @"resolved" # directoryNodeUTxO) + POutputDatum ((pfield @"outputDatum" #) -> seizeDat') <- pmatch seizeDirectoryNode.datum + directoryNodeDatumF <- pletFields @'["key", "next", "transferLogicScript", "issuerLogicScript"] (punsafeCoerce @_ @_ @PDirectorySetNode (pto seizeDat')) + + seizeInputF <- pletFields @'["address", "value", "datum"] seizeInput + seizeInputAddress <- plet seizeInputF.address + + let expectedSeizeOutput = + pdata $ + mkRecordConstr + PTxOut + ( #address + .= seizeInputF.address + .& #value + .= pdata (pfilterCSFromValue # pfromData seizeInputF.value # directoryNodeDatumF.key) + .& #datum + .= seizeInputF.datum + .& #referenceScript + .= pdata pdnothing + ) + -- For ease of implementation of POC we only allow one UTxO to be seized per transaction. + -- This can be easily modified to support seizure of multiple UTxOs. + let issuerLogicScriptHash = punsafeCoerce @_ @_ @(PAsData PByteString) $ phead #$ psndBuiltin #$ pasConstr # pforgetData directoryNodeDatumF.issuerLogicScript + pvalidateConditions + [ pcountInputsFromCred # progLogicCred # txInputs #== pconstant 1 + , pfield @"credential" # seizeInputAddress #== progLogicCred + , seizeOutput #== expectedSeizeOutput + , pelem # issuerLogicScriptHash # invokedScripts + ] + + + diff --git a/src/lib/SmartTokens/Contracts/ProtocolParams.hs b/src/lib/SmartTokens/Contracts/ProtocolParams.hs new file mode 100644 index 0000000..8b25b91 --- /dev/null +++ b/src/lib/SmartTokens/Contracts/ProtocolParams.hs @@ -0,0 +1,69 @@ +{-# LANGUAGE QualifiedDo #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE OverloadedStrings #-} +module SmartTokens.Contracts.ProtocolParams ( + mkProtocolParametersMinting, + alwaysFailScript, + mkPermissionedMinting, +) where + +import Plutarch.LedgerApi.V3 ( PTxOutRef, PScriptContext, PPubKeyHash ) +import Plutarch.Monadic qualified as P +import Plutarch.Prelude + ( PAsData, + PData, + PEq((#==)), + type (:-->), + (#), + plet, + perror, + pconstantData, + ClosedTerm, + plam, + pfromData, + pfstBuiltin, + psndBuiltin, + pletFields, + PUnit, pfield ) +import Plutarch.Core.Utils + ( pheadSingleton, + ptryLookupValue, + phasUTxO, + pvalidateConditions, + pletFieldsMinting, ptxSignedByPkh ) +import SmartTokens.Types.Constants ( pprotocolParamsTokenData ) + +-- | Protocol Parameters minting policy +-- This validator allows minting of a single token with a single token name. +mkProtocolParametersMinting :: ClosedTerm (PAsData PTxOutRef :--> PScriptContext :--> PUnit) +mkProtocolParametersMinting = plam $ \oref ctx -> P.do + ctxF <- pletFields @'["txInfo", "scriptInfo"] ctx + infoF <- pletFields @'["inputs", "mint"] ctxF.txInfo + scriptInfoF <- pletFieldsMinting ctxF.scriptInfo + let ownCS = scriptInfoF._0 + mintedValue <- plet $ pfromData infoF.mint + let ownTkPairs = ptryLookupValue # ownCS # mintedValue + -- Enforce that only a single token name is minted for this policy + ownTkPair <- plet (pheadSingleton # ownTkPairs) + ownTokenName <- plet (pfstBuiltin # ownTkPair) + ownNumMinted <- plet (psndBuiltin # ownTkPair) + pvalidateConditions + [ ownTokenName #== pprotocolParamsTokenData + , ownNumMinted #== pconstantData 1 + , phasUTxO # oref # infoF.inputs + ] + +-- | Permissioned Minting Policy +-- This minting policy checks for a given permissioned credential in the signatories of the transaction. +-- It allows minting of any number of tokens with any token name so long as the credential authorizes the transaction. +mkPermissionedMinting :: ClosedTerm (PAsData PPubKeyHash :--> PScriptContext :--> PUnit) +mkPermissionedMinting = plam $ \permissionedCred ctx -> + pvalidateConditions + [ ptxSignedByPkh # permissionedCred # (pfield @"signatories" # (pfield @"txInfo" # ctx)) + ] + +-- | A nonced always fails script +-- The parameter is used to modify the script hash. +-- This is where the protocol parameters UTxO should reside. +alwaysFailScript :: ClosedTerm (PData :--> PScriptContext :--> PUnit) +alwaysFailScript = plam $ \_ _ctx -> perror \ No newline at end of file diff --git a/src/lib/SmartTokens/Core/Scripts.hs b/src/lib/SmartTokens/Core/Scripts.hs new file mode 100644 index 0000000..efc2b02 --- /dev/null +++ b/src/lib/SmartTokens/Core/Scripts.hs @@ -0,0 +1,42 @@ +module SmartTokens.Core.Scripts ( + tryCompile, + tryCompileTracingAndBinds, + tryCompileNoTracing, +) where + +import Plutarch +import Plutarch.ByteString (PByteString, plengthBS, psliceBS, pindexBS) +import Plutarch.Crypto (pkeccak_256, pblake2b_224) +import Plutarch.Integer (PInteger, pmod) +import Plutarch.Lift (pconstant) +import Plutarch.Bool (pif, (#==)) +import PlutusCore.Crypto.Hash qualified as Hash +import PlutusLedgerApi.Common (serialiseUPLC) +import Data.ByteString.Short (fromShort) +import Plutarch.Script (Script(unScript)) +import Data.ByteString (ByteString) +import Data.ByteString qualified as BS +import Data.Word (Word8) +import PlutusLedgerApi.V2 ( + Data, + ExBudget, + ) +import Data.Text +import Plutarch.Evaluate +import Data.Bifunctor ( Bifunctor(first) ) + +tryCompile :: Config -> ClosedTerm a -> Script +tryCompile cfg x = case compile cfg x of + Left e -> error $ "Compilation failed: " <> show e + Right s -> s + +tryCompileTracingAndBinds :: ClosedTerm a -> Script +tryCompileTracingAndBinds = tryCompile (Tracing LogInfo DoTracingAndBinds) + +tryCompileNoTracing :: ClosedTerm a -> Script +tryCompileNoTracing = tryCompile NoTracing + + + + + diff --git a/src/lib/SmartTokens/LinkedList/Common.hs b/src/lib/SmartTokens/LinkedList/Common.hs new file mode 100644 index 0000000..cff3181 --- /dev/null +++ b/src/lib/SmartTokens/LinkedList/Common.hs @@ -0,0 +1,318 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE QualifiedDo #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# OPTIONS_GHC -Wno-unused-do-bind #-} +{-# OPTIONS_GHC -Wno-partial-type-signatures #-} + +module SmartTokens.LinkedList.Common ( + PDirectoryCommon (..), + makeCommon, + pInit, + pInsert, + nodeInputUtxoDatumUnsafePair, + parseNodeOutputUtxoPair, +) where + +import Plutarch.LedgerApi.Value (pnormalize) +import Plutarch.LedgerApi.AssocMap qualified as AssocMap +import Plutarch.Monadic qualified as P +import Plutarch.Bool (pand') +import Plutarch.Prelude + ( Generic, + (#), + (#$), + phoistAcyclic, + plet, + pto, + pcon, + pmatch, + tcont, + type (:-->), + ClosedTerm, + PType, + S, + Term, + plam, + TermCont, + PByteString, + pconstant, + PEq((#==)), + PBool, + PPartialOrd((#<)), + PInteger, + (#&&), + pdata, + pfromData, + pfield, + pletFields, + pall, + pany, + pfilter, + pmap, + pguardC, + PAsData, + PBuiltinList, + PListLike(pnull, phead), + PMaybe(PJust), + PPair(..), + PUnit ) +import Plutarch.Unsafe (punsafeCoerce) +import Plutarch.Core.Utils ( + passert, + pcountOfUniqueTokens, + pfindCurrencySymbolsByTokenPrefix, + pheadSingleton, + phasDataCS, + psingletonOfCS, + ptryFromInlineDatum, + pmapFilter, + ) +import Types.Constants (pnodeKeyTN, poriginNodeTN, ptryParseNodeKey) +import SmartTokens.Types.PTokenDirectory + ( PDirectorySetNode, + pisInsertedOnNode, + pisInsertedNode, + pisEmptyNode ) +import Plutarch.LedgerApi.V3 + ( KeyGuarantees(Sorted), + AmountGuarantees(NonZero, Positive), + PCurrencySymbol, + PTokenName, + PValue, + POutputDatum(POutputDatum), + PTxOut, + PScriptContext, + PScriptInfo(PMintingScript), + PAddress ) +import Plutarch.Builtin (pforgetData, pasByteStr) + +paysToAddress :: Term s (PAddress :--> (PAsData PTxOut) :--> PBool) +paysToAddress = phoistAcyclic $ plam $ \adr txOut -> adr #== (pfield @"address" # txOut) + +{- | Ensures that the minted amount of the FinSet CS is exactly the specified + tokenName and amount +-} +correctNodeTokenMinted :: + ClosedTerm + ( PCurrencySymbol + :--> PTokenName + :--> PInteger + :--> PValue 'Sorted 'NonZero + :--> PBool + ) +correctNodeTokenMinted = phoistAcyclic $ + plam $ \nodeCS tokenName amount mint -> P.do + PJust nodeMint <- pmatch $ AssocMap.plookup # nodeCS # pto mint + let tokenMap = AssocMap.psingleton # tokenName # amount + tokenMap #== nodeMint + +-- Potentially use this in the future if we plan to manage additional +-- value in the directory nodes. +nodeInputUtxoDatumUnsafePair :: + ClosedTerm + ( PAsData PTxOut + :--> PPair (PValue 'Sorted 'Positive) (PAsData PDirectorySetNode) + ) +nodeInputUtxoDatumUnsafePair = phoistAcyclic $ + plam $ \out -> pletFields @'["value", "datum"] out $ \outF -> + plet (punsafeCoerce $ ptryFromInlineDatum # outF.datum) $ \nodeDat -> + pcon (PPair (pfromData outF.value) nodeDat) + +nodeInputUtxoDatumUnsafe + :: ClosedTerm (PAsData PTxOut :--> PAsData PDirectorySetNode) +nodeInputUtxoDatumUnsafe = phoistAcyclic $ plam $ \txOut -> + punsafeCoerce $ ptryFromInlineDatum # (pfield @"datum" # txOut) + +parseNodeOutputUtxo :: + ClosedTerm + ( PAsData PCurrencySymbol + :--> PAsData PTxOut + :--> PAsData PDirectorySetNode + ) +parseNodeOutputUtxo = phoistAcyclic $ + plam $ \nodeCS out -> P.do + txOut <- pletFields @'["address", "value", "datum"] out + value <- plet $ pfromData txOut.value + PPair nodeTokenName amount <- pmatch $ psingletonOfCS # nodeCS # value + POutputDatum od <- pmatch $ pfromData txOut.datum + datum <- plet $ punsafeCoerce (pfield @"outputDatum" # od) + datumF <- pletFields @'["key", "next", "transferLogicScript", "issuerLogicScript"] datum + + nodeKeyData <- plet (pforgetData datumF.key) + let nodeKey = pasByteStr # nodeKeyData + nodeNext = pasByteStr # pforgetData datumF.next + + -- The following are checked by `pisInsertedNode` + -- passert "transferLogicScript deserialization" $ pdeserializesToCredential # datumF.transferLogicScript + -- passert "issuerLogicScript deserialization" $ pdeserializesToCredential # datumF.issuerLogicScript + + -- Prevents TokenDust attack + passert "Too many assets" $ pcountOfUniqueTokens # value #== 2 + passert "Incorrect number of node tokens" $ amount #== 1 + passert "Node is not ordered" $ nodeKey #< nodeNext + passert "Incorrect token name" $ nodeKeyData #== pforgetData (pdata nodeTokenName) + datum + +-- Potentially use this in the future if we plan to manage additional +-- value in the directory nodes. +parseNodeOutputUtxoPair :: + ClosedTerm + ( PAsData PCurrencySymbol + :--> PTxOut + :--> PPair (PValue 'Sorted 'Positive) (PAsData PDirectorySetNode) + ) +parseNodeOutputUtxoPair = phoistAcyclic $ + plam $ \nodeCS out -> P.do + txOut <- pletFields @'["address", "value", "datum"] out + value <- plet $ pfromData txOut.value + PPair tn amount <- pmatch $ psingletonOfCS # nodeCS # value + POutputDatum od <- pmatch $ pfromData txOut.datum + datum <- plet $ punsafeCoerce (pfield @"outputDatum" # od) + let nodeKey = ptryParseNodeKey # tn + datumKey = punsafeCoerce $ pfield @"key" # datum + + -- Prevents TokenDust attack + passert "All FSN tokens from node policy" $ + pheadSingleton # (pfindCurrencySymbolsByTokenPrefix # value # pconstant "FSN") #== nodeCS + passert "Too many assets" $ pcountOfUniqueTokens # value #== 2 + passert "Incorrect number of nodeTokens" $ amount #== 1 + passert "Incorrect token name" $ nodeKey #== datumKey + pcon (PPair value datum) + +makeCommon :: + forall {r :: PType} {s :: S}. + Term s PScriptContext -> + TermCont @r + s + ( PDirectoryCommon s ) +makeCommon ctx' = do + ------------------------------ + -- Preparing info needed for validation: + ctx <- tcont $ pletFields @'["txInfo", "scriptInfo"] ctx' + info <- + tcont $ + pletFields + @'["inputs", "outputs", "mint", "referenceInputs", "signatories", "validRange"] + ctx.txInfo + + ownCS <- tcont . plet $ P.do + PMintingScript mintRecord <- pmatch ctx.scriptInfo + pfield @"_0" # mintRecord + + mint <- tcont . plet $ pnormalize #$ pfromData info.mint + -- asOuts <- tcont . plet $ pmap # plam (pfield @"resolved" #) + -- refInsAsOuts <- tcont . plet $ asOuts # pfromData info.referenceInputs + hasNodeTk <- tcont . plet $ phasDataCS # ownCS + -- insAsOuts <- tcont . plet $ pmap # plam (pfield @"resolved" #) # info.inputs + -- onlyAtNodeVal <- tcont . plet $ pfilter @PBuiltinList # plam (\txo -> (hasNodeTk # (pfield @"value" # txo))) + txInputs <- tcont . plet $ pfromData info.inputs + let txOutputs = punsafeCoerce @_ @_ @(PBuiltinList (PAsData PTxOut)) (pfromData info.outputs) + fromNodeValidator <- tcont . plet $ pmapFilter @PBuiltinList # plam (\txo -> hasNodeTk # (pfield @"value" # txo)) # plam (pfield @"resolved" #) # txInputs + toNodeValidator <- tcont . plet $ pfilter @PBuiltinList # plam (\txo -> hasNodeTk # (pfield @"value" # txo)) # txOutputs + ------------------------------ + + let firstNodeInput :: Term _ (PAsData PTxOut) = phead @PBuiltinList # fromNodeValidator + let atNodeValidator = + let isSameAddress = (paysToAddress # (pfield @"address" # firstNodeInput)) + in pall # isSameAddress # toNodeValidator + + pguardC "all same origin" atNodeValidator + + nodeInputs <- tcont . plet $ pmap # nodeInputUtxoDatumUnsafe # fromNodeValidator + + nodeOutputs <- + tcont . plet $ + pmap + # (parseNodeOutputUtxo # ownCS) + # toNodeValidator + + let common = + MkCommon + { ownCS = pfromData ownCS + , mint + , nodeInputs + , nodeOutputs + } + pure common + + +-- | Initialize the linked list +-- Validations: +-- - No node inputs should be spent +-- - There should be only a single node token minted (the origin node token) +-- - There should be exactly one node output, the key of which should be empty and the next key should be empty +pInit :: forall (s :: S). PDirectoryCommon s -> Term s PUnit +pInit common = P.do + -- Input Checks + passert "Init must not spend Nodes" $ pnull # common.nodeInputs + + -- Output Checks: + let nodeOutput = pheadSingleton # common.nodeOutputs + passert "Init output one node and empty" $ pisEmptyNode # nodeOutput + + -- Mint checks: + passert "Incorrect mint for Init" $ + correctNodeTokenMinted # common.ownCS # poriginNodeTN # 1 # common.mint + + pconstant () + +-- | Insert a new node into the linked list +-- Validations: +-- - There should be only one spent node (tx inputs contains only one node UTxO) +-- - The spent node indeed covers the key we want to insert +-- - The key of the spent node is lexographically less than pkToInsert and +-- the next key of the spent node is lexographically greater than pkToInsert. +-- - The node outputs should contain the inserted node +-- - There should be only a single node token minted (token name of which should match the key we are inserting) +pInsert :: + forall (s :: S). + PDirectoryCommon s -> + Term s (PAsData PByteString :--> PUnit) +pInsert common = plam $ \pkToInsert -> P.do + keyToInsert <- plet $ pfromData pkToInsert + + -- Input Checks: + -- There is only one spent node (tx inputs contains only one node UTxO) + let coveringDatum = pheadSingleton # common.nodeInputs + + -- Output Checks: + coveringDatumF <- pletFields @'["key", "next", "transferLogicScript", "issuerLogicScript"] coveringDatum + coveringDatumKey <- plet $ pasByteStr # pforgetData coveringDatumF.key + coveringDatumNext <- plet $ pasByteStr # pforgetData coveringDatumF.next + + -- The key of the spent node is lexographically less than pkToInsert and + -- the next key of the spent node is lexographically greater than pkToInsert. + -- Thus the coveringNode is the node upon which we are inserting. + passert "Spent node should cover inserting key" $ + pand' # (coveringDatumKey #< keyToInsert) # (keyToInsert #< coveringDatumNext) + + let isInsertedOnNode = pisInsertedOnNode # pdata keyToInsert # pdata coveringDatumKey # coveringDatumF.transferLogicScript # coveringDatumF.issuerLogicScript + isInsertedNode = pisInsertedNode # pdata keyToInsert # pdata coveringDatumNext + + passert "Incorrect node outputs for Insert" $ + pany + # isInsertedOnNode + # common.nodeOutputs + #&& pany # isInsertedNode # common.nodeOutputs + + -- Mint checks: + passert "Incorrect mint for Insert" $ + correctNodeTokenMinted # common.ownCS # (pnodeKeyTN # keyToInsert) # 1 # common.mint + + pconstant () + +-- Common information shared between all redeemers. +data PDirectoryCommon (s :: S) = MkCommon + { ownCS :: Term s PCurrencySymbol + -- ^ state token (own) CS + , mint :: Term s (PValue 'Sorted 'NonZero) + -- ^ value minted in current Tx + , nodeInputs :: Term s (PBuiltinList (PAsData PDirectorySetNode)) + -- ^ node inputs in the tx + , nodeOutputs :: Term s (PBuiltinList (PAsData PDirectorySetNode)) + -- ^ node outputs in the tx + } + deriving stock (Generic) diff --git a/src/lib/SmartTokens/LinkedList/MintDirectory.hs b/src/lib/SmartTokens/LinkedList/MintDirectory.hs new file mode 100644 index 0000000..7fae322 --- /dev/null +++ b/src/lib/SmartTokens/LinkedList/MintDirectory.hs @@ -0,0 +1,62 @@ +{-# OPTIONS_GHC -Wno-redundant-constraints #-} +{-# OPTIONS_GHC -Wno-unused-do-bind #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE QualifiedDo #-} + +module SmartTokens.LinkedList.MintDirectory ( + mkDirectoryNodeMP, +) where + +import Plutarch.LedgerApi.V3 (PScriptContext, PTxOutRef) +import Plutarch.Monadic qualified as P +import Plutarch.Unsafe (punsafeCoerce) +import SmartTokens.LinkedList.Common (makeCommon, pInit, pInsert) + +import Plutarch.Core.Utils (pand'List, passert, phasUTxO) +import Plutarch.Prelude (ClosedTerm, DerivePlutusType (..), Generic, PAsData, + PByteString, PDataRecord, PEq, PIsData, + PLabeledType ((:=)), PUnit, PlutusType, PlutusTypeData, + S, Term, TermCont (runTermCont), pconstant, perror, + pfield, pfromData, pif, plam, plet, pletFields, pmatch, + pto, type (:-->), (#)) + +-------------------------------- +-- FinSet Node Minting Policy: +-------------------------------- + +data PDirectoryNodeAction (s :: S) + = PInit (Term s (PDataRecord '[])) + | PInsert (Term s (PDataRecord '["keyToInsert" ':= PByteString])) + deriving stock (Generic) + deriving anyclass (PlutusType, PIsData, PEq) + +instance DerivePlutusType PDirectoryNodeAction where type DPTStrat _ = PlutusTypeData + +mkDirectoryNodeMP :: + ClosedTerm + ( PAsData PTxOutRef + :--> PScriptContext + :--> PUnit + ) +mkDirectoryNodeMP = plam $ \initUTxO ctx -> P.do + let red = punsafeCoerce @_ @_ @PDirectoryNodeAction (pto (pfield @"redeemer" # ctx)) + + common <- runTermCont $ makeCommon ctx + + pmatch red $ \case + PInit _ -> P.do + ctxF <- pletFields @'["txInfo"] ctx + infoF <- pletFields @'["inputs"] ctxF.txInfo + passert "Init must consume TxOutRef" $ + phasUTxO # initUTxO # pfromData infoF.inputs + pInit common + PInsert action -> P.do + act <- pletFields @'["keyToInsert"] action + pkToInsert <- plet act.keyToInsert + let mintsProgrammableToken = pconstant False + insertChecks = + pand'List + [ mintsProgrammableToken + ] + pif insertChecks (pInsert common # pkToInsert) perror diff --git a/src/lib/SmartTokens/LinkedList/SpendDirectory.hs b/src/lib/SmartTokens/LinkedList/SpendDirectory.hs new file mode 100644 index 0000000..8629c78 --- /dev/null +++ b/src/lib/SmartTokens/LinkedList/SpendDirectory.hs @@ -0,0 +1,81 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE QualifiedDo #-} + +module SmartTokens.LinkedList.SpendDirectory (pmkDirectorySpending, pmkDirectorySpendingYielding, pmkDirectoryGlobalLogic) where + +import Plutarch.LedgerApi.V3 + ( PCredential, + PCurrencySymbol, + POutputDatum(POutputDatum), + PScriptContext ) +import Plutarch.Monadic qualified as P +import Plutarch.Prelude + ( (#), + (#$), + perror, + pto, + pmatch, + type (:-->), + ClosedTerm, + plam, + pconstant, + pfromData, + pfield, + pletFields, + PAsData, + PBuiltinList, + PMaybe(PNothing, PJust), + PUnit ) +import Plutarch.Unsafe (punsafeCoerce) +import Plutarch.Core.Utils (pvalidateConditions, phasDataCS, pmustFind) +import Plutarch.LedgerApi.AssocMap qualified as AssocMap +import SmartTokens.Types.ProtocolParams (PProgrammableLogicGlobalParams) + +pmkDirectoryGlobalLogic :: ClosedTerm (PAsData PCurrencySymbol :--> PScriptContext :--> PUnit) +pmkDirectoryGlobalLogic = plam $ \protocolParamsCS ctx -> P.do + ctxF <- pletFields @'["txInfo", "scriptInfo"] ctx + infoF <- pletFields @'["referenceInputs", "mint"] ctxF.txInfo + let paramUTxO = + pfield @"resolved" #$ + pmustFind @PBuiltinList + # plam (\txIn -> + let resolvedIn = pfield @"resolved" # txIn + in phasDataCS # protocolParamsCS # (pfield @"value" # resolvedIn) + ) + # infoF.referenceInputs + POutputDatum ((pfield @"outputDatum" #) -> paramDat') <- pmatch $ pfield @"datum" # paramUTxO + protocolParamsF <- pletFields @'["directoryNodeCS"] (pfromData $ punsafeCoerce @_ @_ @(PAsData PProgrammableLogicGlobalParams) (pto paramDat')) + pvalidateConditions [phasDataCS # protocolParamsF.directoryNodeCS # pfromData infoF.mint] + +pmkDirectorySpendingYielding :: + ClosedTerm (PAsData PCredential :--> PScriptContext :--> PUnit) +pmkDirectorySpendingYielding = plam $ \globalCred ctx -> P.do + ctxF <- pletFields @'["txInfo"] ctx + let stakeCerts = pfield @"wdrl" # ctxF.txInfo + stakeScript = pfromData globalCred + pmatch (AssocMap.plookup # stakeScript # stakeCerts) $ \case + PJust _ -> (pconstant ()) + PNothing -> perror + +pmkDirectorySpending :: + ClosedTerm (PAsData PCurrencySymbol :--> PScriptContext :--> PUnit) +pmkDirectorySpending = plam $ \protocolParamsCS ctx -> P.do + ctxF <- pletFields @'["txInfo", "scriptInfo"] ctx + infoF <- pletFields @'["referenceInputs", "mint"] ctxF.txInfo + let paramUTxO = + pfield @"resolved" #$ + pmustFind @PBuiltinList + # plam (\txIn -> + let resolvedIn = pfield @"resolved" # txIn + in phasDataCS # protocolParamsCS # (pfield @"value" # resolvedIn) + ) + # infoF.referenceInputs + POutputDatum ((pfield @"outputDatum" #) -> paramDat') <- pmatch $ pfield @"datum" # paramUTxO + protocolParamsF <- pletFields @'["directoryNodeCS"] (pfromData $ punsafeCoerce @_ @_ @(PAsData PProgrammableLogicGlobalParams) (pto paramDat')) + pvalidateConditions [phasDataCS # protocolParamsF.directoryNodeCS # pfromData infoF.mint] \ No newline at end of file diff --git a/src/lib/SmartTokens/Types/Constants.hs b/src/lib/SmartTokens/Types/Constants.hs new file mode 100644 index 0000000..a61e88f --- /dev/null +++ b/src/lib/SmartTokens/Types/Constants.hs @@ -0,0 +1,22 @@ +{-# LANGUAGE OverloadedStrings #-} +module SmartTokens.Types.Constants( + protocolParamsToken, + pprotocolParamsToken, + pprotocolParamsTokenData +) where + +import Plutarch.LedgerApi.V1 (PTokenName (..)) +import Plutarch.Prelude + ( PAsData, pconstantData, ClosedTerm, pconstant ) +import PlutusLedgerApi.V1 (TokenName(..)) + +protocolParamsToken :: TokenName +protocolParamsToken = "ProtocolParams" + +pprotocolParamsToken :: ClosedTerm PTokenName +pprotocolParamsToken = pconstant protocolParamsToken + +pprotocolParamsTokenData :: ClosedTerm (PAsData PTokenName) +pprotocolParamsTokenData = pconstantData protocolParamsToken + + diff --git a/src/lib/SmartTokens/Types/PTokenDirectory.hs b/src/lib/SmartTokens/Types/PTokenDirectory.hs new file mode 100644 index 0000000..ad86028 --- /dev/null +++ b/src/lib/SmartTokens/Types/PTokenDirectory.hs @@ -0,0 +1,217 @@ +{-# OPTIONS_GHC -Wno-unused-do-bind #-} +{-# OPTIONS_GHC -Wno-partial-type-signatures #-} +{-# LANGUAGE ImpredicativeTypes #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE QualifiedDo #-} +{-# LANGUAGE UndecidableInstances #-} + +module SmartTokens.Types.PTokenDirectory ( + DirectorySetNode (..), + PDirectorySetNode (..), + PBlacklistNode (..), + isHeadNode, + isTailNode, + pemptyBSData, + pemptyCSData, + pmkDirectorySetNode, + pisInsertedOnNode, + pisInsertedNode, + pletFieldsBlacklistNode, + pisEmptyNode, +) where + +import Generics.SOP qualified as SOP +import Plutarch (Config (NoTracing)) +import Plutarch.Builtin (pasByteStr, pasConstr, pasList, pforgetData, plistData) +import Plutarch.Core.PlutusDataList (DerivePConstantViaDataList (..), + PlutusTypeDataList, ProductIsData (..)) +import Plutarch.Core.Utils (pcond, pheadSingleton, pmkBuiltinList) +import Plutarch.DataRepr (PDataFields) +import Plutarch.DataRepr.Internal.Field (HRec (..), Labeled (Labeled)) +import Plutarch.Evaluate (unsafeEvalTerm) +import Plutarch.Internal.PlutusType (pcon', pmatch') +import Plutarch.LedgerApi.V3 (PCredential, PCurrencySymbol) +import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted)) +import Plutarch.List +import Plutarch.Prelude +import Plutarch.Unsafe (punsafeCoerce) +import PlutusLedgerApi.V3 (Credential, CurrencySymbol) +import PlutusTx (Data (B, Constr)) +import PlutusTx qualified + +pdeserializeCredential :: Term s (PAsData PCredential) -> Term s (PAsData PCredential) +pdeserializeCredential term = + plet (pasConstr # pforgetData term) $ \constrPair -> + plet (pfstBuiltin # constrPair) $ \constrIdx -> + pif (plengthBS # (pasByteStr # (pheadSingleton # (psndBuiltin # constrPair))) #== 28) + ( + pcond + [ ( constrIdx #== 0 , term) + , ( constrIdx #== 1 , term) + ] + perror + ) + perror + +-- data BlackListNode = +-- BlackListNode { +-- key :: BuiltinByteString, +-- next :: BuiltinByteString +-- } + +newtype PBlacklistNode (s :: S) + = PBlacklistNode + ( Term + s + ( PDataRecord + '[ "key" ':= PByteString + , "next" ':= PByteString + ] + ) + ) + deriving stock (Generic) + +-- TODO: +-- The reason we have to manually implement this is because the PlutusTypeDataList DerivePlutusType strategy +-- breaks when we use PByteString fields probably due to the fact that the PLifted/PConstant instances use ByteString +-- instead of BuiltinByteString. We should fix the PlutusTypeDataList strategy to work with PByteString fields. +instance PlutusType PBlacklistNode where + type PInner PBlacklistNode = PDataRecord '[ "key" ':= PByteString, "next" ':= PByteString ] + pcon' (PBlacklistNode t1) = t1 + pmatch' xs f = + plet (pto xs) $ \innerFieldList -> + let key_ = phead # innerFieldList + in plet (ptail # innerFieldList) $ \remaining -> + let next_ = phead # remaining + in pif (pnull # (ptail # remaining)) (f (PBlacklistNode (pdcons # punsafeCoerce key_ #$ pdcons # punsafeCoerce next_ # pdnil))) perror + +type PBlacklistNodeHRec (s :: S) = + HRec + '[ '("key", Term s (PAsData PByteString)) + , '("next", Term s (PAsData PByteString)) + ] + +pletFieldsBlacklistNode :: forall {s :: S} {r :: PType}. Term s (PAsData PBlacklistNode) -> (PBlacklistNodeHRec s -> Term s r) -> Term s r +pletFieldsBlacklistNode term = runTermCont $ do + fields <- tcont $ plet $ pasList # (pforgetData term) + let key_ = punsafeCoerce @_ @_ @(PAsData PByteString) $ phead # fields + next_ = punsafeCoerce @_ @_ @(PAsData PByteString) $ pheadSingleton # (ptail # fields) + tcont $ \f -> f $ HCons (Labeled @"key" key_) (HCons (Labeled @"next" next_) HNil) + +-- instance DerivePlutusType PBlacklistNode where +-- type DPTStrat _ = PlutusTypeDataList + +data DirectorySetNode = DirectorySetNode + { key :: CurrencySymbol + , next :: CurrencySymbol + , transferLogicScript :: Credential + , issuerLogicScript :: Credential + } + deriving stock (Show, Eq, Generic) + deriving anyclass (SOP.Generic) + deriving + (PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData) via (ProductIsData DirectorySetNode) + +deriving via + ( DerivePConstantViaDataList + DirectorySetNode + PDirectorySetNode + ) + instance + (PConstantDecl DirectorySetNode) + +-- Optimization: +-- Use the following manual instances instead of the deriving via above if so that we can define key and next fields of type ByteString +-- We should discuss whether we want to prefer newtypes or primitive types for datum / redeemer fields going forward. +-- import Data.ByteString +-- import PlutusTx.Builtins qualified as Builtins +-- import PlutusTx.Builtins.Internal qualified as BI +-- import PlutusTx.Prelude (BuiltinByteString, fromBuiltin, toBuiltin) +-- instance PlutusTx.ToData DirectorySetNode where +-- toBuiltinData DirectorySetNode{key, next, transferLogicScript, issuerLogicScript} = +-- BI.mkList $ BI.mkCons (BI.mkB $ toBuiltin key) $ BI.mkCons (BI.mkB $ toBuiltin next) $ BI.mkCons (PlutusTx.toBuiltinData transferLogicScript) $ BI.mkCons (PlutusTx.toBuiltinData issuerLogicScript) $ BI.mkNilData BI.unitval + +-- instance PlutusTx.FromData DirectorySetNode where +-- fromBuiltinData builtinData = +-- let fields = BI.snd $ BI.unsafeDataAsConstr builtinData +-- key = BI.head fields +-- fields1 = BI.tail fields +-- next = BI.head fields1 +-- fields2 = BI.tail fields1 +-- transferLogicScript = PlutusTx.unsafeFromBuiltinData $ BI.head fields2 +-- fields3 = BI.tail fields2 +-- issuerLogicScript = PlutusTx.unsafeFromBuiltinData $ BI.head fields3 +-- in Just $ DirectorySetNode (fromBuiltin $ BI.unsafeDataAsB key) (fromBuiltin $ BI.unsafeDataAsB next) transferLogicScript issuerLogicScript + + +newtype PDirectorySetNode (s :: S) + = PDirectorySetNode + ( Term + s + ( PDataRecord + '[ "key" ':= PCurrencySymbol + , "next" ':= PCurrencySymbol + , "transferLogicScript" ':= PCredential + , "issuerLogicScript" ':= PCredential + ] + ) + ) + deriving stock (Generic) + deriving anyclass (PlutusType, PIsData, PEq, PShow, PDataFields) + +instance DerivePlutusType PDirectorySetNode where + type DPTStrat _ = PlutusTypeDataList + +instance PUnsafeLiftDecl PDirectorySetNode where + type PLifted PDirectorySetNode = DirectorySetNode + +isHeadNode :: ClosedTerm (PAsData PDirectorySetNode :--> PBool) +isHeadNode = plam $ \node -> + pfield @"key" # node #== pemptyCSData + +isTailNode :: ClosedTerm (PAsData PDirectorySetNode :--> PBool) +isTailNode = plam $ \node -> + pfield @"next" # node #== pemptyCSData + +pisEmptyNode :: ClosedTerm (PAsData PDirectorySetNode :--> PBool) +pisEmptyNode = plam $ \node -> + let nullTransferLogicCred = pconstant (Constr 0 [PlutusTx.B ""]) + nullIssuerLogicCred = pconstant (Constr 0 [PlutusTx.B ""]) + expectedEmptyNode = punsafeCoerce $ plistData # pmkBuiltinList [pforgetData pemptyBSData, pforgetData pemptyBSData, nullTransferLogicCred, nullIssuerLogicCred] + in node #== expectedEmptyNode + +pemptyBSData :: ClosedTerm (PAsData PByteString) +pemptyBSData = unsafeEvalTerm NoTracing (punsafeCoerce (pconstant $ PlutusTx.B "")) + +pemptyCSData :: ClosedTerm (PAsData PCurrencySymbol) +pemptyCSData = unsafeEvalTerm NoTracing (punsafeCoerce (pconstant $ PlutusTx.B "")) + +pmkDirectorySetNode :: ClosedTerm (PAsData PByteString :--> PAsData PByteString :--> PAsData PCredential :--> PAsData PCredential :--> PAsData PDirectorySetNode) +pmkDirectorySetNode = phoistAcyclic $ + plam $ \key_ next_ transferLogicCred issuerLogicCred -> + punsafeCoerce $ plistData # pmkBuiltinList [pforgetData key_, pforgetData next_, pforgetData transferLogicCred, pforgetData issuerLogicCred] + +pisInsertedOnNode :: ClosedTerm (PAsData PByteString :--> PAsData PByteString :--> PAsData PCredential :--> PAsData PCredential :--> PAsData PDirectorySetNode :--> PBool) +pisInsertedOnNode = phoistAcyclic $ + plam $ \insertedKey coveringKey transferLogicCred issuerLogicCred outputNode -> + let expectedDirectoryNode = pmkDirectorySetNode # coveringKey # insertedKey # transferLogicCred # issuerLogicCred + in outputNode #== expectedDirectoryNode + +-- pisInsertedNode :: ClosedTerm (PAsData PByteString :--> PAsData PByteString :--> PAsData PCredential :--> PAsData PCredential :--> PAsData PDirectorySetNode :--> PBool) +-- pisInsertedNode = phoistAcyclic $ +-- plam $ \insertedKey coveringNext transferLogicCred issuerLogicCred outputNode -> +-- let expectedDirectoryNode = pmkDirectorySetNode # insertedKey # coveringNext # transferLogicCred # issuerLogicCred +-- in outputNode #== expectedDirectoryNode + +pisInsertedNode :: ClosedTerm (PAsData PByteString :--> PAsData PByteString :--> PAsData PDirectorySetNode :--> PBool) +pisInsertedNode = phoistAcyclic $ + plam $ \insertedKey coveringNext outputNode -> + pletFields @'["transferLogicScript", "issuerLogicScript"] outputNode $ \outputNodeDatumF -> + let transferLogicCred_ = outputNodeDatumF.transferLogicScript + issuerLogicCred_ = outputNodeDatumF.issuerLogicScript + expectedDirectoryNode = + pmkDirectorySetNode # insertedKey # coveringNext # pdeserializeCredential transferLogicCred_ # pdeserializeCredential issuerLogicCred_ + in outputNode #== expectedDirectoryNode diff --git a/src/lib/SmartTokens/Types/ProtocolParams.hs b/src/lib/SmartTokens/Types/ProtocolParams.hs new file mode 100644 index 0000000..cddae7f --- /dev/null +++ b/src/lib/SmartTokens/Types/ProtocolParams.hs @@ -0,0 +1,51 @@ +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wno-deferred-type-errors #-} + +module SmartTokens.Types.ProtocolParams ( + ProgrammableLogicGlobalParams (..), + PProgrammableLogicGlobalParams (..), +) where + +import Plutarch.Core.PlutusDataList + ( DerivePConstantViaDataList(..), + PlutusTypeDataList, + ProductIsData(..) ) +import Generics.SOP qualified as SOP +import Plutarch.LedgerApi.V3 (PCurrencySymbol, PCredential) +import Plutarch.Prelude +import Plutarch.DataRepr (PDataFields) +import PlutusTx qualified +import PlutusLedgerApi.V3 (Credential, CurrencySymbol) +import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted)) + +-- TODO: +-- Figure out why deriving PlutusType breaks when I uncomment this +-- and disable no-deferred-type-errors +data ProgrammableLogicGlobalParams = ProgrammableLogicGlobalParams + { directoryNodeCS :: CurrencySymbol + , progLogicCred :: Credential + } + deriving stock (Show, Eq, Generic) + deriving anyclass (SOP.Generic) + deriving + (PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData) via (ProductIsData ProgrammableLogicGlobalParams) + deriving (PConstantDecl) via (DerivePConstantViaDataList ProgrammableLogicGlobalParams PProgrammableLogicGlobalParams) + +newtype PProgrammableLogicGlobalParams (s :: S) + = PProgrammableLogicGlobalParams + ( Term + s + ( PDataRecord + '[ "directoryNodeCS" ':= PCurrencySymbol + , "progLogicCred" ':= PCredential + ] + ) + ) + deriving stock (Generic) + deriving anyclass (PlutusType, PIsData, PEq, PShow, PDataFields) + +instance DerivePlutusType PProgrammableLogicGlobalParams where + type DPTStrat _ = PlutusTypeDataList + +instance PUnsafeLiftDecl PProgrammableLogicGlobalParams where + type PLifted PProgrammableLogicGlobalParams = ProgrammableLogicGlobalParams \ No newline at end of file diff --git a/src/lib/Types/Constants.hs b/src/lib/Types/Constants.hs new file mode 100644 index 0000000..96fdee7 --- /dev/null +++ b/src/lib/Types/Constants.hs @@ -0,0 +1,31 @@ +{-# LANGUAGE QualifiedDo #-} +{-# LANGUAGE OverloadedStrings #-} +{-# OPTIONS_GHC -Wno-unused-do-bind #-} + +module Types.Constants( + pnodeKeyTN, + poriginNodeTN, + ptryParseNodeKey +) where + +import Plutarch.LedgerApi.V1 (PTokenName (..)) +import Plutarch.Prelude +import Plutarch.Core.Utils (pnonew) +import PlutusLedgerApi.V1 (TokenName(..)) +import Plutarch.Builtin (PDataNewtype(..)) + + +pnodeKeyTN :: ClosedTerm (PByteString :--> PTokenName) +pnodeKeyTN = phoistAcyclic $ + plam $ + \nodeKey -> pcon $ PTokenName $ pcon $ PDataNewtype $ pdata nodeKey + +poriginNodeTN :: ClosedTerm PTokenName +poriginNodeTN = + let tn :: TokenName + tn = "" + in pconstant tn + +ptryParseNodeKey :: ClosedTerm (PTokenName :--> PByteString) +ptryParseNodeKey = phoistAcyclic $ + plam $ \(pnonew -> tn) -> tn \ No newline at end of file diff --git a/src/wst-poc.cabal b/src/wst-poc.cabal index c66e3c8..e9fbcac 100644 --- a/src/wst-poc.cabal +++ b/src/wst-poc.cabal @@ -1,19 +1,20 @@ -cabal-version: 3.4 -name: wst-poc -version: 0.3.0.0 -synopsis: On-chain code for regulated stablecoin proof-of-concept -license: Apache-2.0 -license-files: - LICENSE - -maintainer: j-mueller@users.noreply.github.com -author: Djed team @ IOG -homepage: https://github.com/input-output-hk/wst-poc -bug-reports: https://github.com/input-output-hk/wst-poc +cabal-version: 3.4 +name: wst-poc +version: 0.3.0.0 +synopsis: On-chain code for regulated stablecoin proof-of-concept +license: Apache-2.0 +license-files: LICENSE +maintainer: j-mueller@users.noreply.github.com +author: Djed team @ IOG +homepage: https://github.com/input-output-hk/wst-poc +bug-reports: https://github.com/input-output-hk/wst-poc description: Please see the README on GitHub at -build-type: Simple +-- A copyright notice. +-- copyright: +-- category: +extra-source-files: CHANGELOG.md common lang default-language: Haskell2010 @@ -21,25 +22,67 @@ common lang DeriveGeneric StandaloneDeriving DeriveLift FlexibleContexts GeneralizedNewtypeDeriving DeriveFunctor DeriveFoldable DeriveTraversable ImportQualifiedPost NumericUnderscores + LambdaCase DerivingStrategies KindSignatures TypeApplications + DataKinds TypeOperators GADTs ViewPatterns TypeFamilies + DeriveAnyClass DerivingVia RankNTypes ghc-options: -Wall -Wnoncanonical-monad-instances -Wunused-packages -Wincomplete-uni-patterns -Wincomplete-record-updates -Wredundant-constraints -Widentities library - import: lang + import: lang exposed-modules: + SmartTokens.Contracts.Issuance + SmartTokens.Contracts.ProgrammableLogicBase + SmartTokens.Contracts.ExampleTransferLogic + SmartTokens.Contracts.ProtocolParams + SmartTokens.Types.Constants + SmartTokens.Types.ProtocolParams + SmartTokens.Types.PTokenDirectory + SmartTokens.LinkedList.MintDirectory + SmartTokens.LinkedList.SpendDirectory + SmartTokens.LinkedList.Common + Types.Constants Wst.Cli Wst.Offchain Wst.Onchain Wst.Server - hs-source-dirs: lib + Profile + + -- Compile + build-depends: - base >= 4.14 && < 4.20 + , base + , plutarch-onchain-lib + , generics-sop + , plutarch + , plutarch-ledger-api + , plutus-core + , plutus-ledger-api + , plutus-tx + , text + hs-source-dirs: lib executable wst-poc import: lang main-is: Main.hs - hs-source-dirs: exe + hs-source-dirs: exe/wst-poc build-depends: base, - wst-poc \ No newline at end of file + wst-poc + +executable export-smart-tokens + import: lang + main-is: Main.hs + build-depends: + , wst-poc + , aeson-pretty + , base + , cardano-binary + , aeson + , base16-bytestring + , bytestring + , text + , plutarch + , plutus-ledger-api + hs-source-dirs: exe/export-smart-tokens