diff --git a/.gitignore b/.gitignore index 541195f..a0e13f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ CIP XXX Marlowe Oracle Protocol.html +v0.1.0-alpha.html diff --git a/CIP XXX Marlowe Oracle Protocol/diagrams/dot-watcher.sh b/CIP XXX Marlowe Oracle Protocol/diagrams/dot-watcher.sh new file mode 100755 index 0000000..9def62e --- /dev/null +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/dot-watcher.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Regenerate all the graphs +fd -g '*.dot' |while read -r dotfile; do + echo "Generating $dotfile" + svgfile="${dotfile%.dot}.svg" + # Compile all .dot files to .svg + dot -n2 -Tsvg:cairo -o "$svgfile" "$dotfile" +done + +inotifywait -m -e modify --quiet --format '%w%f' --include '.*\.dot$' . | while read -r dotfile; do + echo "Detected change in $dotfile" + svgfile="${dotfile%.dot}.svg" + # Compile only the modified .dot to .svg + dot -n2 -Tsvg:cairo -o "$svgfile" "$dotfile" + echo "Generated $svgfile" + # Open (or bring to front) only that single SVG + firefox "$svgfile" & +done diff --git a/diagrams/marlowe-request-delay.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request-delay.dot similarity index 100% rename from diagrams/marlowe-request-delay.dot rename to CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request-delay.dot diff --git a/diagrams/marlowe-request-delay.svg b/CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request-delay.svg similarity index 100% rename from diagrams/marlowe-request-delay.svg rename to CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request-delay.svg diff --git a/diagrams/marlowe-request-thread-delay.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request-thread-delay.dot similarity index 100% rename from diagrams/marlowe-request-thread-delay.dot rename to CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request-thread-delay.dot diff --git a/diagrams/marlowe-request-thread-delay.svg b/CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request-thread-delay.svg similarity index 100% rename from diagrams/marlowe-request-thread-delay.svg rename to CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request-thread-delay.svg diff --git a/diagrams/marlowe-request.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request.dot similarity index 100% rename from diagrams/marlowe-request.dot rename to CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request.dot diff --git a/diagrams/marlowe-request.svg b/CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request.svg similarity index 100% rename from diagrams/marlowe-request.svg rename to CIP XXX Marlowe Oracle Protocol/diagrams/marlowe-request.svg diff --git a/diagrams/spawning-requests.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/spawning-requests.dot similarity index 96% rename from diagrams/spawning-requests.dot rename to CIP XXX Marlowe Oracle Protocol/diagrams/spawning-requests.dot index 219eb4b..69f87d3 100644 --- a/diagrams/spawning-requests.dot +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/spawning-requests.dot @@ -25,7 +25,7 @@ digraph Spawning_Oracle_Requests { Oracle PubKeyHash - + @@ -70,7 +70,7 @@ digraph Spawning_Oracle_Requests { Oracle PubKeyHash - + @@ -131,7 +131,7 @@ digraph Spawning_Oracle_Requests { Oracle PubKeyHash - + @@ -156,7 +156,7 @@ digraph Spawning_Oracle_Requests { oracle choice at
119a#0 - + @@ -184,7 +184,7 @@ digraph Spawning_Oracle_Requests { oracle choice at
119a#0 - + @@ -220,7 +220,7 @@ digraph Spawning_Oracle_Requests { // Oracle PubKeyHash // // - // + // // // // diff --git a/diagrams/utxo-data-publishing.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-data-publishing.dot similarity index 96% rename from diagrams/utxo-data-publishing.dot rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-data-publishing.dot index 9da709a..b8e4f6a 100644 --- a/diagrams/utxo-data-publishing.dot +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-data-publishing.dot @@ -46,7 +46,7 @@ digraph PlainOraclePublishing { oracle data at
reference input - + @@ -76,7 +76,7 @@ digraph PlainOraclePublishing { oracle data at
reference input - + diff --git a/diagrams/utxo-data-publishing.svg b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-data-publishing.svg similarity index 99% rename from diagrams/utxo-data-publishing.svg rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-data-publishing.svg index c4edd41..654bd7d 100644 --- a/diagrams/utxo-data-publishing.svg +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-data-publishing.svg @@ -410,7 +410,7 @@ - + @@ -505,7 +505,7 @@ - + diff --git a/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-execution-thread.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-execution-thread.dot new file mode 100644 index 0000000..6a2d6bf --- /dev/null +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-execution-thread.dot @@ -0,0 +1,233 @@ +digraph Script_Execution_Thread { + rankdir=TD; + graph [pad="0.02", nodesep="0.6", ranksep="0.5"]; + node [shape=rect, style="filled,rounded", fillcolor="#f9f9f9", fontname="Courier New", fontsize="10"]; + edge [arrowhead=none, headport="n", tailport="s", color="#aaa", fontname="Courier New", fontsize="10"]; + + // --- Diagram 1: First Step --- + subgraph cluster_D1 { + label = "Thread Initialization"; + style="dashed"; + node [shape=rect, style="filled,rounded", fillcolor="#f9f9f9", fontname="Courier New", fontsize="10"]; + edge [arrowhead=none, headport="n", tailport="s", color="#aaa", fontname="Courier New", fontsize="10"]; + + D1_InitFundingOutput [shape=point]; + + D1_InitFundingOutput -> D1_InitTx; + + D1_InitTx [label=< + + + + + + + +
Initial Thread Tx
Script UTxO is initialized
but the spending script is not executed
+ > color="#aaa" shape="plain"]; + + D1_InitialScriptOutput [label=< + + + + + + + + + + + + +
Initial Script Thread Output
addressScript X
datumInitial script state
+ > shape="plain" border="1" color="#000"] + + D1_InitChangeOutput [shape=point]; + D1_InitTx -> D1_InitChangeOutput; + D1_InitTx -> D1_InitialScriptOutput; + + } + + D1_InitialScriptOutput -> D2_ScriptThreadTx1; + + // --- Diagram 2: Thread Continues --- + subgraph cluster_D2 { + label = "Thread Execution"; + labelloc=top; + style="dashed"; + node [shape=rect, style="filled,rounded", fillcolor="#f9f9f9", fontname="Courier New", fontsize="10"]; + edge [arrowhead=none, headport="n", tailport="s", color="#aaa", fontname="Courier New", fontsize="10"]; + + D2_ScriptThreadTx1 [label=< + + + + + + + + + + +
First Script Thread Tx
+ + + + + + + + +
Script X is executed.
It checks for a single and correct thread output.
redeemerAction Y
+
+ > color="#aaa" shape="plain"]; + + D2_ScriptThreadTx1ExtraInput1 [shape=point]; + D2_ScriptThreadTx1ExtraInput1 -> D2_ScriptThreadTx1; + + D2_ScriptThreadTx1ExtraInput2 [shape=point]; + D2_ScriptThreadTx1ExtraInput2 -> D2_ScriptThreadTx1; + + D2_ScriptThreadTx1ExtraInput3 [shape=point]; + D2_ScriptThreadTx1ExtraInput3 -> D2_ScriptThreadTx1; + + D2_ScriptThreadTx1Output [label=< + + + + + + + + + + + + +
Script Thread Output 1
addressScript X
datumScript state after
Action Y
+ > shape="plain" border="1" color="#000"] + + D2_ScriptThreadTx1 -> D2_ScriptThreadTx1Output; + + D2_ScriptThreadTx1ExtraOutput [shape=point]; + D2_ScriptThreadTx1 -> D2_ScriptThreadTx1ExtraOutput; + + // --- New for D2 --- + D2_ScriptThreadTx2 [label=< + + + + + + + + + + +
Second Script Thread Tx
+ + + + + + + + +
Script X is executed.
It checks for a single and correct thread output.
redeemerAction Z
+
+ > color="#aaa" shape="plain"]; + + D2_ScriptThreadTx1Output -> D2_ScriptThreadTx2; + + D2_ScriptThreadTx2ExtraInput1 [shape=point]; + D2_ScriptThreadTx2ExtraInput1 -> D2_ScriptThreadTx2; + D2_ScriptThreadTx2ExtraInput2 [shape=point]; + D2_ScriptThreadTx2ExtraInput2 -> D2_ScriptThreadTx2; + + D2_ScriptThreadTx2Output [label=< + + + + + + + + + + + + +
Script Thread Output 2
addressScript X
datumScript state after
Action Z
+ > shape="plain" border="1" color="#000"] + + D2_ScriptThreadTx2 -> D2_ScriptThreadTx2Output; + + D2_ScriptThreadTx2ExtraOutput1 [shape=point]; + D2_ScriptThreadTx2 -> D2_ScriptThreadTx2ExtraOutput1; + + D2_ScriptThreadTx2ExtraOutput2 [shape=point]; + D2_ScriptThreadTx2 -> D2_ScriptThreadTx2ExtraOutput2; + + D2_ScriptThread [shape=circle, style="dashed,rounded", color="#aaa" fillcolor="white", fontname="Helvetica", margin="0", padding="0", + label=<Execution Thread Continues…

--█--█--█--█--█--█--█--

Script at every transition
verifies proper continuation output.>]; + D2_ScriptThreadTx2Output -> D2_ScriptThread; + + // --- End New for D2 --- + } + + D2_ScriptThread -> D3_ScriptThreadFinalStepTx; + + // --- Diagram 3: Full Thread --- + subgraph cluster_D3 { + label = "Final Step"; + labelloc=top; + style="dashed"; + node [shape=rect, style="filled,rounded", fillcolor="#f9f9f9", fontname="Courier New", fontsize="10"]; + edge [arrowhead=none, headport="n", tailport="s", color="#aaa", fontname="Courier New", fontsize="10"]; + + // --- New for D3 (Final Step) --- + // Note: The original comment "// Now let's describe the last action/transaction without script outputs" is implicitly covered by this section. + D3_ScriptThreadFinalStepTx [label=< + + + + + + + + + + +
Final Script Thread Tx
+ + + + + + + + +
Script X is executed.
It ensures that there areno corresponding thread outputs.
redeemerAction W
+
+ > color="#aaa" shape="plain"]; + + D3_ScriptThreadFinalStepTxExtraInput1 [shape=point]; + D3_ScriptThreadFinalStepTxExtraInput1 -> D3_ScriptThreadFinalStepTx; + + D3_ScriptThreadFinalStepTxExtraInput2 [shape=point]; + D3_ScriptThreadFinalStepTxExtraInput2 -> D3_ScriptThreadFinalStepTx; + + D3_ScriptThreadFinalStepTxOutput1 [shape=point]; + D3_ScriptThreadFinalStepTx -> D3_ScriptThreadFinalStepTxOutput1 [label=<Non Script X output>]; + + D3_ScriptThreadFinalStepTxOutput2 [shape=point]; + D3_ScriptThreadFinalStepTx -> D3_ScriptThreadFinalStepTxOutput2 [label=<Non Script X output>]; + + D3_ScriptThreadFinalStepTxOutput3 [shape=point]; + D3_ScriptThreadFinalStepTx -> D3_ScriptThreadFinalStepTxOutput3 [label=<Non Script X output>]; + // --- End New for D3 --- + } +// D1_InitialScriptOutput -> D2_ScriptThreadTx1; +// D2_ScriptThread -> D3_ScriptThreadFinalStepTx; + // { rank= same; D1_InitialScriptOutput; D2_ScriptThreadTx1; D3_ScriptThreadFinalStepTx } +} diff --git a/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-execution-thread.svg b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-execution-thread.svg new file mode 100644 index 0000000..20ec60a --- /dev/null +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-execution-thread.svg @@ -0,0 +1,1408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/diagrams/utxo-marlowe-choice-fake.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-fake.dot similarity index 97% rename from diagrams/utxo-marlowe-choice-fake.dot rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-fake.dot index 8cc4860..34a509a 100644 --- a/diagrams/utxo-marlowe-choice-fake.dot +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-fake.dot @@ -19,7 +19,7 @@ digraph Marlowe_Choice_Fake { Eve PubKeyHash - + @@ -85,7 +85,7 @@ digraph Marlowe_Choice_Fake { // Eve PubKeyHash // // -// +// // // // diff --git a/diagrams/utxo-marlowe-choice-fake.svg b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-fake.svg similarity index 99% rename from diagrams/utxo-marlowe-choice-fake.svg rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-fake.svg index 46f015b..ec4db76 100644 --- a/diagrams/utxo-marlowe-choice-fake.svg +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-fake.svg @@ -278,7 +278,7 @@ - + diff --git a/diagrams/utxo-marlowe-choice-verification.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-verification.dot similarity index 98% rename from diagrams/utxo-marlowe-choice-verification.dot rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-verification.dot index 9d4654f..6f124ea 100644 --- a/diagrams/utxo-marlowe-choice-verification.dot +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-verification.dot @@ -21,7 +21,7 @@ digraph Marlowe_Choice_Authenticity { Oracle PubKeyHash - + diff --git a/diagrams/utxo-marlowe-choice-verification.svg b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-verification.svg similarity index 99% rename from diagrams/utxo-marlowe-choice-verification.svg rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-verification.svg index 8178562..c6e04a0 100644 --- a/diagrams/utxo-marlowe-choice-verification.svg +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-choice-verification.svg @@ -396,7 +396,7 @@ - + diff --git a/diagrams/utxo-marlowe-data-publishing.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-data-publishing.dot similarity index 97% rename from diagrams/utxo-marlowe-data-publishing.dot rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-data-publishing.dot index 75f8dff..823cea9 100644 --- a/diagrams/utxo-marlowe-data-publishing.dot +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-data-publishing.dot @@ -42,7 +42,7 @@ digraph Oracle_Choice_Referencing { Oracle PubKeyHash - + @@ -118,7 +118,7 @@ digraph Oracle_Choice_Referencing { oracle choice
at 119a#2 - + @@ -148,7 +148,7 @@ digraph Oracle_Choice_Referencing { oracle choice
at 119a#2 - + diff --git a/diagrams/utxo-marlowe-data-publishing.svg b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-data-publishing.svg similarity index 99% rename from diagrams/utxo-marlowe-data-publishing.svg rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-data-publishing.svg index 0b54a8c..9a51b74 100644 --- a/diagrams/utxo-marlowe-data-publishing.svg +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-data-publishing.svg @@ -417,7 +417,7 @@
- + @@ -699,7 +699,7 @@ - + @@ -765,7 +765,7 @@ - + diff --git a/diagrams/utxo-marlowe-thread-token.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-thread-token.dot similarity index 98% rename from diagrams/utxo-marlowe-thread-token.dot rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-thread-token.dot index 288b8e6..0947204 100644 --- a/diagrams/utxo-marlowe-thread-token.dot +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-thread-token.dot @@ -35,7 +35,7 @@ digraph Marlowe_Proof_Of_Execution { - + @@ -185,7 +185,7 @@ digraph Marlowe_Proof_Of_Execution { CLOSE - + diff --git a/diagrams/utxo-marlowe-thread-token.svg b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-thread-token.svg similarity index 99% rename from diagrams/utxo-marlowe-thread-token.svg rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-thread-token.svg index cf8018a..6b01f56 100644 --- a/diagrams/utxo-marlowe-thread-token.svg +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-marlowe-thread-token.svg @@ -414,7 +414,7 @@ - + @@ -924,7 +924,7 @@ - + diff --git a/diagrams/utxo-thread-token.dot b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-thread-token.dot similarity index 98% rename from diagrams/utxo-thread-token.dot rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-thread-token.dot index 2ecc004..a009bc7 100644 --- a/diagrams/utxo-thread-token.dot +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-thread-token.dot @@ -35,7 +35,7 @@ digraph Thread_Token { - + @@ -151,7 +151,7 @@ digraph Thread_Token { - + diff --git a/diagrams/utxo-thread-token.svg b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-thread-token.svg similarity index 99% rename from diagrams/utxo-thread-token.svg rename to CIP XXX Marlowe Oracle Protocol/diagrams/utxo-thread-token.svg index 411cddd..8db6c85 100644 --- a/diagrams/utxo-thread-token.svg +++ b/CIP XXX Marlowe Oracle Protocol/diagrams/utxo-thread-token.svg @@ -454,7 +454,7 @@ - + @@ -920,7 +920,7 @@ - + diff --git a/CIP XXX Marlowe Oracle Protocol/github-markdown.css b/CIP XXX Marlowe Oracle Protocol/github-markdown.css new file mode 100644 index 0000000..6c7e645 --- /dev/null +++ b/CIP XXX Marlowe Oracle Protocol/github-markdown.css @@ -0,0 +1,958 @@ +:root { + --container-size: 640px; /* default on really small devices */ +} + +@media (min-width: 600px) { + :root { --container-size: 900px; } +} + +@media (min-width: 900px) { + :root { --container-size: 1280px; } +} + +body { + width: 100%; + max-width: var(--container-size); + margin: 0 auto; + padding: 0 1rem; +} + + +@font-face { + font-family: octicons-link; + src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff'); +} + +.octicon { + display: inline-block; + fill: currentColor; + vertical-align: text-bottom; +} + +.anchor { + float: left; + line-height: 1; + margin-left: -20px; + padding-right: 4px; +} + +.anchor:focus { + outline: none; +} + +h1 .octicon-link, +h2 .octicon-link, +h3 .octicon-link, +h4 .octicon-link, +h5 .octicon-link, +h6 .octicon-link { + color: #1b1f23; + vertical-align: middle; + visibility: hidden; +} + +h1:hover .anchor, +h2:hover .anchor, +h3:hover .anchor, +h4:hover .anchor, +h5:hover .anchor, +h6:hover .anchor { + text-decoration: none; +} + +h1:hover .anchor .octicon-link, +h2:hover .anchor .octicon-link, +h3:hover .anchor .octicon-link, +h4:hover .anchor .octicon-link, +h5:hover .anchor .octicon-link, +h6:hover .anchor .octicon-link { + visibility: visible; +} + +body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + color: #24292e; + line-height: 1.5; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; + font-size: 16px; + line-height: 1.5; + word-wrap: break-word; +} + +.pl-c { + color: #6a737d; +} + +.pl-c1, +.pl-s .pl-v { + color: #005cc5; +} + +.pl-e, +.pl-en { + color: #6f42c1; +} + +.pl-s .pl-s1, +.pl-smi { + color: #24292e; +} + +.pl-ent { + color: #22863a; +} + +.pl-k { + color: #d73a49; +} + +.pl-pds, +.pl-s, +.pl-s .pl-pse .pl-s1, +.pl-sr, +.pl-sr .pl-cce, +.pl-sr .pl-sra, +.pl-sr .pl-sre { + color: #032f62; +} + +.pl-smw, +.pl-v { + color: #e36209; +} + +.pl-bu { + color: #b31d28; +} + +.pl-ii { + background-color: #b31d28; + color: #fafbfc; +} + +.pl-c2 { + background-color: #d73a49; + color: #fafbfc; +} + +.pl-c2:before { + content: "^M"; +} + +.pl-sr .pl-cce { + color: #22863a; + font-weight: 700; +} + +.pl-ml { + color: #735c0f; +} + +.pl-mh, +.pl-mh .pl-en, +.pl-ms { + color: #005cc5; + font-weight: 700; +} + +.pl-mi { + color: #24292e; + font-style: italic; +} + +.pl-mb { + color: #24292e; + font-weight: 700; +} + +.pl-md { + background-color: #ffeef0; + color: #b31d28; +} + +.pl-mi1 { + background-color: #f0fff4; + color: #22863a; +} + +.pl-mc { + background-color: #ffebda; + color: #e36209; +} + +.pl-mi2 { + background-color: #005cc5; + color: #f6f8fa; +} + +.pl-mdr { + color: #6f42c1; + font-weight: 700; +} + +.pl-ba { + color: #586069; +} + +.pl-sg { + color: #959da5; +} + +.pl-corl { + color: #032f62; + text-decoration: underline; +} + +details { + display: block; +} + +summary { + display: list-item; +} + +a { + background-color: transparent; +} + +a:active, +a:hover { + outline-width: 0; +} + +strong { + font-weight: inherit; + font-weight: bolder; +} + +h1 { + font-size: 2em; + margin: .67em 0; +} + +img { + border-style: none; +} + +code, +kbd, +pre { + font-family: monospace,monospace; + font-size: 1em; +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} + +input { + font: inherit; + margin: 0; +} + +input { + overflow: visible; +} + +[type=checkbox] { + box-sizing: border-box; + padding: 0; +} + +* { + box-sizing: border-box; +} + +input { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +a { + color: #0366d6; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +strong { + font-weight: 600; +} + +hr { + background: transparent; + border: 0; + border-bottom: 1px solid #dfe2e5; + height: 0; + margin: 15px 0; + overflow: hidden; +} + +hr:before { + content: ""; + display: table; +} + +hr:after { + clear: both; + content: ""; + display: table; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} + +details summary { + cursor: pointer; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin-bottom: 0; + margin-top: 0; +} + +h1 { + font-size: 32px; +} + +h1, +h2 { + font-weight: 600; +} + +h2 { + font-size: 24px; +} + +h3 { + font-size: 20px; +} + +h3, +h4 { + font-weight: 600; +} + +h4 { + font-size: 16px; +} + +h5 { + font-size: 14px; +} + +h5, +h6 { + font-weight: 600; +} + +h6 { + font-size: 12px; +} + +p { + margin-bottom: 10px; + margin-top: 0; +} + +blockquote { + margin: 0; +} + +ol, +ul { + margin-bottom: 0; + margin-top: 0; + padding-left: 0; +} + +ol ol, +ul ol { + list-style-type: lower-roman; +} + +ol ol ol, +ol ul ol, +ul ol ol, +ul ul ol { + list-style-type: lower-alpha; +} + +dd { + margin-left: 0; +} + +code, +pre { + font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace; + font-size: 12px; +} + +pre { + margin-bottom: 0; + margin-top: 0; +} + +input::-webkit-inner-spin-button, +input::-webkit-outer-spin-button { + -webkit-appearance: none; + appearance: none; + margin: 0; +} + +.border { + border: 1px solid #e1e4e8!important; +} + +.border-0 { + border: 0!important; +} + +.border-bottom { + border-bottom: 1px solid #e1e4e8!important; +} + +.rounded-1 { + border-radius: 3px!important; +} + +.bg-white { + background-color: #fff!important; +} + +.bg-gray-light { + background-color: #fafbfc!important; +} + +.text-gray-light { + color: #6a737d!important; +} + +.mb-0 { + margin-bottom: 0!important; +} + +.my-2 { + margin-bottom: 8px!important; + margin-top: 8px!important; +} + +.pl-0 { + padding-left: 0!important; +} + +.py-0 { + padding-bottom: 0!important; + padding-top: 0!important; +} + +.pl-1 { + padding-left: 4px!important; +} + +.pl-2 { + padding-left: 8px!important; +} + +.py-2 { + padding-bottom: 8px!important; + padding-top: 8px!important; +} + +.pl-3, +.px-3 { + padding-left: 16px!important; +} + +.px-3 { + padding-right: 16px!important; +} + +.pl-4 { + padding-left: 24px!important; +} + +.pl-5 { + padding-left: 32px!important; +} + +.pl-6 { + padding-left: 40px!important; +} + +.f6 { + font-size: 12px!important; +} + +.lh-condensed { + line-height: 1.25!important; +} + +.text-bold { + font-weight: 600!important; +} + +a:not([href]) { + color: inherit; + text-decoration: none; +} + +blockquote, +dl, +ol, +p, +pre, +table, +ul { + margin-bottom: 16px; + margin-top: 0; +} + +hr { + background-color: #e1e4e8; + border: 0; + height: .25em; + margin: 24px 0; + padding: 0; +} + +blockquote { + border-left: .25em solid #dfe2e5; + color: #6a737d; + padding: 0 1em; +} + +blockquote>:first-child { + margin-top: 0; +} + +blockquote>:last-child { + margin-bottom: 0; +} + +kbd { + background-color: #fafbfc; + border: 1px solid #c6cbd1; + border-bottom-color: #959da5; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #959da5; + color: #444d56; + display: inline-block; + font-size: 11px; + line-height: 10px; + padding: 3px 5px; + vertical-align: middle; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 600; + line-height: 1.25; + margin-bottom: 16px; + margin-top: 24px; +} + +h1 { + font-size: 2em; +} + +h1, +h2 { + border-bottom: 1px solid #eaecef; + padding-bottom: .3em; +} + +h2 { + font-size: 1.5em; +} + +h3 { + font-size: 1.25em; +} + +h4 { + font-size: 1em; +} + +h5 { + font-size: .875em; +} + +h6 { + color: #6a737d; + font-size: .85em; +} + +ol, +ul { + padding-left: 2em; +} + +ol ol, +ol ul, +ul ol, +ul ul { + margin-bottom: 0; + margin-top: 0; +} + +li { + word-wrap: break-all; +} + +li>p { + margin-top: 16px; +} + +li+li { + margin-top: .25em; +} + +dl { + padding: 0; +} + +dl dt { + font-size: 1em; + font-style: italic; + font-weight: 600; + margin-top: 16px; + padding: 0; +} + +dl dd { + margin-bottom: 16px; + padding: 0 16px; +} + +table { + display: block; + overflow: auto; + width: 100%; +} + +table th { + font-weight: 600; +} + +table td, +table th { + border: 1px solid #dfe2e5; + padding: 6px 13px; +} + +table tr { + background-color: #fff; + border-top: 1px solid #c6cbd1; +} + +table tr:nth-child(2n) { + background-color: #f6f8fa; +} + +img { + background-color: #fff; + box-sizing: content-box; + max-width: 100%; +} + +img[align=right] { + padding-left: 20px; +} + +img[align=left] { + padding-right: 20px; +} + +code { + background-color: rgba(27,31,35,.05); + border-radius: 3px; + font-size: 85%; + margin: 0; + padding: .2em .4em; +} + +pre { + word-wrap: normal; +} + +pre>code { + background: transparent; + border: 0; + font-size: 100%; + margin: 0; + padding: 0; + white-space: pre; + word-break: normal; +} + +.highlight { + margin-bottom: 16px; +} + +.highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.highlight pre, +pre { + background-color: #f6f8fa; + border-radius: 3px; + font-size: 85%; + line-height: 1.45; + overflow: auto; + padding: 16px; +} + +pre code { + background-color: transparent; + border: 0; + display: inline; + line-height: inherit; + margin: 0; + max-width: auto; + overflow: visible; + padding: 0; + word-wrap: normal; +} + +.commit-tease-sha { + color: #444d56; + display: inline-block; + font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace; + font-size: 90%; +} + +.blob-wrapper { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + overflow-x: auto; + overflow-y: hidden; +} + +.blob-wrapper-embedded { + max-height: 240px; + overflow-y: auto; +} + +.blob-num { + -moz-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; + color: rgba(27,31,35,.3); + cursor: pointer; + font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace; + font-size: 12px; + line-height: 20px; + min-width: 50px; + padding-left: 10px; + padding-right: 10px; + text-align: right; + user-select: none; + vertical-align: top; + white-space: nowrap; + width: 1%; +} + +.blob-num:hover { + color: rgba(27,31,35,.6); +} + +.blob-num:before { + content: attr(data-line-number); +} + +.blob-code { + line-height: 20px; + padding-left: 10px; + padding-right: 10px; + position: relative; + vertical-align: top; +} + +.blob-code-inner { + color: #24292e; + font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace; + font-size: 12px; + overflow: visible; + white-space: pre; + word-wrap: normal; +} + +.pl-token.active, +.pl-token:hover { + background: #ffea7f; + cursor: pointer; +} + +kbd { + background-color: #fafbfc; + border: 1px solid #d1d5da; + border-bottom-color: #c6cbd1; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #c6cbd1; + color: #444d56; + display: inline-block; + font: 11px SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace; + line-height: 10px; + padding: 3px 5px; + vertical-align: middle; +} + +:checked+.radio-label { + border-color: #0366d6; + position: relative; + z-index: 1; +} + +.tab-size[data-tab-size="1"] { + -moz-tab-size: 1; + tab-size: 1; +} + +.tab-size[data-tab-size="2"] { + -moz-tab-size: 2; + tab-size: 2; +} + +.tab-size[data-tab-size="3"] { + -moz-tab-size: 3; + tab-size: 3; +} + +.tab-size[data-tab-size="4"] { + -moz-tab-size: 4; + tab-size: 4; +} + +.tab-size[data-tab-size="5"] { + -moz-tab-size: 5; + tab-size: 5; +} + +.tab-size[data-tab-size="6"] { + -moz-tab-size: 6; + tab-size: 6; +} + +.tab-size[data-tab-size="7"] { + -moz-tab-size: 7; + tab-size: 7; +} + +.tab-size[data-tab-size="8"] { + -moz-tab-size: 8; + tab-size: 8; +} + +.tab-size[data-tab-size="9"] { + -moz-tab-size: 9; + tab-size: 9; +} + +.tab-size[data-tab-size="10"] { + -moz-tab-size: 10; + tab-size: 10; +} + +.tab-size[data-tab-size="11"] { + -moz-tab-size: 11; + tab-size: 11; +} + +.tab-size[data-tab-size="12"] { + -moz-tab-size: 12; + tab-size: 12; +} + +.task-list-item { + list-style-type: none; +} + +.task-list-item+.task-list-item { + margin-top: 3px; +} + +.task-list-item input { + margin: 0 .2em .25em -1.6em; + vertical-align: middle; +} + +hr { + border-bottom-color: #eee; +} + +.pl-0 { + padding-left: 0!important; +} + +.pl-1 { + padding-left: 4px!important; +} + +.pl-2 { + padding-left: 8px!important; +} + +.pl-3 { + padding-left: 16px!important; +} + +.pl-4 { + padding-left: 24px!important; +} + +.pl-5 { + padding-left: 32px!important; +} + +.pl-6 { + padding-left: 40px!important; +} + +.pl-7 { + padding-left: 48px!important; +} + +.pl-8 { + padding-left: 64px!important; +} + +.pl-9 { + padding-left: 80px!important; +} + +.pl-10 { + padding-left: 96px!important; +} + +.pl-11 { + padding-left: 112px!important; +} + +.pl-12 { + padding-left: 128px!important; +} diff --git a/markdown-watcher.sh b/CIP XXX Marlowe Oracle Protocol/markdown-watcher.sh similarity index 100% rename from markdown-watcher.sh rename to CIP XXX Marlowe Oracle Protocol/markdown-watcher.sh diff --git a/CIP XXX Marlowe Oracle Protocol/v0.1.0-alpha.md b/CIP XXX Marlowe Oracle Protocol/v0.1.0-alpha.md new file mode 100644 index 0000000..98c84b8 --- /dev/null +++ b/CIP XXX Marlowe Oracle Protocol/v0.1.0-alpha.md @@ -0,0 +1,268 @@ +--- +CIP: XXX +Title: Marlowe Oracle Protocol +Status: Proposed +Category: ??? +Authors: + \- Tomasz Rybarczyk \ + \- Simon Thompson \ + \- Nicolas Henin \ +Implementors: N/A +Discussions: ??? +Created: 2025-04-03 +License: CC-BY-4.0 +--- + +## Abstract + +Smart contracts running on Cardano require access to external data of various kinds from Oracle providers: exchange rates between crypto- and fiat currencies; “real world” data, such as weather information; information of significance for betting and gaming apps, including details of play from sporting events; and, not least, reliable and secure sources of randomness. Current Cardano Oracles primarily push a fixed repertoire of data on-chain, critically limiting their ability to provide the range and depth of data outlined above. + +This CIP describes a more flexible, transparent and composable oracle solution for Cardano, based on the Marlowe smart contract language, using the `Choice` construct in Marlowe to deliver the oracle value within a running smart contract, as well as making that value available to other Cardano other smart contacts, whether written in Marlowe, Aiken, Plutus or other languages. + +## Motivation: why is this CIP necessary? + +External data is used within the vast majority of smart contracts running on blockchain, and provision of this data by oracle providers is essential to these contracts running effectively and securely. The “push” model of data provides an ~80:20 solution: 80% of needs are satisfied by a limited set of data feeds, particularly those based on DeFi information of various kinds; it is, however, unable to service the “long tail” of potential demands for data of a more specialized kind, and to do this in practice a “pull” model of data provision is required. + +The mechanism outlined delivers data through the `Choice` construct in the Marlowe smart contract language. Executing an instance of this construct in a running contract delivers an external integer value that can be directly accessed within the contact, and also be made available for use by other smart contracts on Cardano. + +For this approach to work in practice, this CIP needs to address the following high-level questions: + +* How to identify what data is requested, and from which source, including an access mechanism for the source. +* How results of oracle requests are rendered for use within Marlowe. +* How results are made available on-chain to other Cardano smart contracts, including information about the data source, format and rendering. +* How the results of particular instances of data requests are identified, both within and outside running Marlowe contracts. +* The security model assumed by the oracle protocol. + +These high-level questions are answered in the next section, together with a discussion of implementation-related issues such as timeouts and error handling, and potential extensions of the protocol, such as access mechanisms. + +## Specification + +This section described the Marlowe Oracle Protocol in detail. Assumptions made in the description are listed here, before the specification itself. + +### Assumptions + +* No distinction is made between the data source and the oracle provider. In future versions of this protocol, this distinction may be possible. +* IPFS is used as a standard for content-addressable off-chain data here; other equivalent mechanisms may be used. +* We take a pragmatic approach to trust, assuming that users of the system are able to identify trustworthy oracles for themselves. + +The Marlowe Oracle protocol is based on using the choice mechanism in Marlowe, by which choices “external” to a contract are made available to the contract. The Marlowe construct that handles external actions is `When`, which selects between a number of `Case`s. Each `Case` is triggered by an `Action`: in this case the `Choice` action. On that action happening, the continuation contract is initiated; if no action is made before the timeout, the fallback contract is initiated: we assume that in this case it is `Close`, which closes contract operation, refunding any funds in the contract to the participants. The relevant Marlowe syntax constructs are (eliding irrelevant constructors): + +`data Contract = … | When [Case] Timeout Contract | …` +`data Case = Case Action Contract` +`data Action = … | Choice ChoiceId [Bound] | …` + +Choices are identified by a `ChoiceId`, which combines a `ChoiceName` – a `ByteString` – with a `Party` to the contract. On forming the action, a set of `Bound`s are given that constrain the `Integer` value to be chosen. + +`data ChoiceId = ChoiceId ChoiceName Party` +`type ChoiceName = ByteString` +`data Bound = Bound Integer Integer` + +The `ChoiceId` construct is used to describe an oracle value: + +* The `Party` is `PubKey pkh`, where `pkh` is the hash of a public key for the oracle that is the source of the data. +* The `ChoiceName` ByteString is used to identify the data requested, and the specific request itself. We discuss this in detail now. + +The `ChoiceName` byte string is used to describe a collection of data: + +| layout | data\_source | API | data\_query | query\_result | resolution | … | +| :---: | :---: | :---: | :---: | :---: | :---: | :---: | + +* The first 32 bytes describe the **layout** of the remainder of the byte string, namely its length, and the names and lengths of the remaining fields. +* Any fields may be present, but the fields **data\_source**, **API**, **data\_query**, **query\_result** and **resolution** must be included. + +A running example, based on oracle data from Wolfram Blockchain Labs, as documented [here](https://docs-ccdb.waexservices.com/), is used to illustrate the remainder of the description. + +The **data_source** should be the root URL for the oracle service whose public key is in the `Party` component of the `ChoiceId` of which this `ChoiceName` is the other component. + +In the running example of services provided by Wolfram Blockchain Labs this field would be https://access.ccdb.waexservices.com. + +The **API** should point to a description of the API for the data provider. This can take a number of forms, including. + +* The root URL for the web page which can reliably and safely translate a given \`data\_query\` (which could be a hash or machine readable version of the query) to a human readable form. +* The root URL for the API documentation for the interface for the data provider. In the running example this would be https://docs-ccdb.waexservices.com. +* In the case that there is no published interface, an anchor that points to a file in IPFS containing a sufficient description to understand the particular data\_query, query\_result and resolution for this particular choice. + +The **data\_query** should contain a query to the data\_source that conforms to the API. + +* In the case of the running example this will be a URL making a GET request to the endpoint for the service, defined according to the standard in the API. +* Instead of a query, the field may contain the anchor for an IPFS file containing the query. +* The query encoding can be also encoded using a custom format not suitable for human consumption which should be resolved and explained by the API. + +The **result** should contain an anchor for an IPFS file that contains the result of the query, and a description of how an Integer is extracted from the result, which is called the *resolution* of the query. + +* In the case of the running example, results are returned in JSON format, and the resolution will typically involve: + * Selecting a field or fields + * Converting those fields to numbers + * Aggregating those numbers into a single Integer. + +The **resolution** should contain an Integer, constructed according to the description in the **result**. + +### Data Availability + +We will first present a minimal Marlowe contract request structure first. Then we will try to iterate to make it safely useful in the context of cross-script data sharing. We will then move to the security aspect of the data sharing. At the end we present the specifics of the datum and the contract state encoding which should be used by the external on-chain data consumers. +Some elements of this scheme require slight extensions to the current Marlowe validator (but not the Language) and its tooling. We will indicate those elements in the spec. + +When we consider an on-chain data consumer - any smart contract - we should emphasis one critical aspect of information sharing on Cardano. Validators can only access a subset of the UTxO set during validation. This subset should be provided to the transaction as regular inputs or reference inputs - we will preset more details below in the [Execution Thread](#execution-thread) section. Smart contracts can not inspect any historical already consumed outputs or transactions. In order to provide some historical data to the smart contracts these data or some verifiable proofs of that history have to be present somewhere in the UTxO set and included in a transaction which requires it for validation. Usually those kind of informations are encoded through some specific tokens or datums. + +#### Marlowe Oracle Request + +##### Minimal Marlowe Request + +As already discussed a minimal protocol request consists of two constructs a `Choice` and a `Payout`. This structure provides oracle harvester ability to easily detect requests on the chain together with a guarantee of the reward payment. + + Minimal Marlowe Request + +Marlowe validator enforces a "removal" of the contract thread UTxO together with the state and choices from the UTxO set when a contract reaches its execution end. What we really mean by "removal" here is not any historical data deletion because block chain is immutable ledgers by nature but rather a removal of the UTxO from the set of unspend inputs and not outputting a corresponding "continuation" output which would preserve the Marlowe contract state. + +From that perspective the n its own this contract structure is not a reliable from the other on-chain data consumers point of view. + + +For example if we consider the minimal contract from the first section's diagram above the data point will disappear from the accessible UTxO set together with transaction in which it is provided. We just reach the `Close` step together with the `Choice` and `Pay` in the same on-chain transaction - `Pay` and `Close` are evaluated "eagerly" after the `Choice` suspension point (they are not suspension points on themselves). + +##### Marlowe Oracle Request with Enforced Delay + +Marlowe provides ways to enforce a delay of the contract execution in a predictable way. The ability to suspend contract can be used to provide guarantees for the consumers that the contract state will be present on the chain for a certain amount of time. + + Marlowe Request With Delay + +We propose to use this extra separate step as a basis of a reliable data sharing protocol. This step can follow a `Choice` and `Pay` steps directly or be used as some future step in the contract following them. What is important is that the delay is unconditionally present on all the following execution paths. An important detail is that all possible timeouts present int the contract are adjusted accordingly. The one which relates to the oracle `Choice` step should be appropriately distanced from the final delay so the overall interval during which the data are available on the chain is fully specified. Additionally all the timeouts in the following contract which precede the delay step should be larger then the its expected deadline. + + Marlowe Contract With a Delay Before Close + +#### UTxO Level Publishing + +##### Reference Inputs And Oracle Data Sharing + +Cardano provides a way to "use" UTxO in a transaction without consuming it. It is enough to add such a UTxO to the reference input set of a transaction. Through this mechanism cross smart contract communication and data sharing is possible. It does not involve direct interaction with the smart contract which possibly sits at the referenced UTxO level (the UTxO can be also a regular address based one) - this script is not executed when an input is referenced. On the other hand validators involved in the transaction which references a particular input can inspect it - read its datum, value or check the output address without consuming the other contract input. + +This mechanism is used by existing oracle provides on Cardano and enables access to a published data point. Data points are usually approved using an oracle signature under a data point structure and this tuple is included in a UTxO. + +> **FIXME**: check/consult this point with the Cardno oracles protocols. + + Data Publishing Using Reference Inputs + +As discussed previously data point is visible on chain as long as the UTxO is not consumed. There seem to be no standard cross oracle standard regarding those aspects of the protocols. Signed data points provide a bit more flexibility as they separate publisher from the data provider and possibly can be republish by anybody on the chain. +Of course the described publishing strategy on its own does not directly provide a way to enforce payment in exchange for the access to the information. In many cases publishing is driven by an up front payment through off-chain channels and is specific to the oracle provider. Some oracles also publish some data for free rather regularly. + +##### Marlowe Based Data Publishing + +Let's look at the UTxO level overview of the Marlowe data publishing process. Marlowe extends the above flow with a preliminary data point request and subsequent reward payout for the oracle. It can optionally include enforced delay on the contract level to also become a data feed for some other consumers. + +Data Publishing Using Reference Inputs + +At the end the data are provided to the consumers through the datum in similar fashion to the publishing feeds but they won't include any extra signature so authenticity of the data has to be proven using some other means which we discuss below. + +##### Authenticity Of The Data + +###### Forging Marlowe Choice + +On the UTxO level Marlowe validator ensures that the transaction which delivers the choice value was signed by a key corresponding to the party from the contract. After that step every Marlowe thread UTxO protects and keeps that choice together with the party information and value in a map in the datum. + + On-Chain Marlowe Choice Verification + +Even though Marlowe validator manages that information carefully so it is copied from the inputs to the transaction outputs we can not really be sure that the original information was actually verified in the first place. On the Cardano blockchain it is possible to create an arbitrary output. Malicious actor Eve could easily fake previously presented output just by publishing a transaction with precisely crafted output: + + Eve Is Publishing Fake Marlowe Choice + +The above scheme is possible because the transaction which Eve constructed does not involve Marlowe validator execution at all! Additionally the choice itself which is stored in the datum is not paired with the data provider signature so she can actually create an arbitrary data point and pair it with arbitrary `Party` (represented by public key hash in our case). + +###### Execution Thread + +Marlowe uses rather basic and standard pattern for sequential execution of smart contract on the EUTxO (Extened UTxO) based block chain. In this approach smart contract can be modelled by a state machine which resides on a UTxO. Machine transitions happen when the output is consumed. State itself is kept on the UTxO level in the dataum and asset level and the action input(s) to the machine is provided through the redeemer. Below diagram presents this concept in more details: + + Minimal Marlowe Request + +When spending validator is executed it checks if a given action(s) is executed correctly by inspecting the transaction and checking if it fulfils a particular transition conditions (signature checking for a given step, token presence etc.). Crucially in this context it verifies that the continuing output is present and it contains the same script address, expected value and datum with state of the machine representing result of a given action(s). + + +###### Thread Token + +In order to fix the above problem we could significantly change the validator and require an extra signature to be provided and stored together with the data point. + +> **FIXME** - should this optional comment: +> +> There is a MIP which proposes introduction of "Signed Choices" but even with this extension we don't plan to store the actual signatures in the Marlowe state. The authenticity of the value will be again implied by the execution itself. + +Another option is to introduce a data verification step execution proof. If we could prove that the choice which is stored in the contract state was actually verified by Marlowe validator in some previous transaction then any consumer could trust the data without checking the transaction history which is impossible to perform on-chain. In order to do so we can use the concept of a `thread token` coupled together with preconditions checking. + +Cardano ledger guarantees that tokens of a specific asset class can be minted only by a script which hashes to that asset class value. In other words token existence is a proof that a specific script was successfully executed in some past transaction. Thanks to [CIP-0069](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0069) we can use a single script to validate minting and spending which is really convenient - we can have a single script and token identifier which when present together on a UTxO can indicate a valid thread of execution. The essence of the thread token pattern flow is captured in the diagram below: + + Thread Token Lifecycle + +The final scheme consists of three properties of the script which implements it: + +* The script should allow minting a single unique token only if it is outputted to a UTxO where spending validator has the same hash as its own. + +* The script when validating spending should check if the token of its own currency is passed to the output which contains the same spending validator. + +* Additionally the script should allow burning on both spending and minting levels when there is no continuing execution thread output. + + +##### Thread Token as a Proof Of Marlowe Execution + +The pattern described above when introduced to the current Marlowe validator together with an additional precondition checking could be a basis for a reliable data authenticity verification scheme. The precondition which should be check during the initial minting in this case is that the initial choice map in the Marlowe state is empty. Given this initial check we can imply that: + +* Marlowe token is only present at a UTxO if the initial precondition was checked because Marlowe never leaks the thread token, burns it at the end and performs the actual check during minting. + +* Given some choice in the Marlowe state at the Marlowe UTxO which contains the thread token we can be sure that the choice verification step was executed because the initial state was checked and was empty. + + Thread Token Lifecycle + +> **TODO**: Clean up transaction headers and `Close` redeemer - could be be `INotify` assuming the last step is just a delay. + +Please note that we can ignore the exact thread identifier - it can be useful in some context but the scheme allows us to trust choices stored in the Marlowe state relying on a single Marlowe validator hash which should be reflected on the spending validator level and the thread token as well. +Additionally this trust scheme is Marlowe contract agnostic really. It can be used outside of the Marlowe Oracle Protocol context! + +##### Marlowe Datum Encoding + +> **TODO** + +## Rationale: how does this CIP achieve its goals? +>> CIP section spec: +> The rationale fleshes out the specification by describing what motivated the design and what led to particular design decisions. It should describe alternate designs considered and related work. The rationale should provide evidence of consensus within the community and discuss significant objections or concerns raised during the discussion. +> It must also explain how the proposal affects the backward compatibility of existing solutions when applicable. If the proposal responds to a CPS, the 'Rationale' section should explain how it addresses the CPS and answer any questions that the CPS poses for potential solutions. + +> **TODO** + +## Path to Active + +>> CIP section spec: +> Organised in two sub-sections (see Path to Active for detail): +> +> * Acceptance Criteria +> Describes what are the acceptance criteria whereby a proposal becomes 'Active'. +> * Implementation Plan +> Either a plan to meet those criteria or N/A if not applicable. + +> **TODO** + +## Appendix + +### Cross-Marlowe Choice Sharing + +In the current version of the Marlowe validator it is impossible to use choice value from the other instance of Marlowe. We could imagine that on the validator level choice value is read from another Marlowe contract UTxOs as described above but in such a case the choice name which is used to identify that choice should uniquely identify the query in a cross-contract fashion. This is exactly the nature of oracle choices described in this document. +It seems that in order to properly implement such a feature we should introduce to the language itself a notion of a `ChoiceId` which is "globally" unique. To do so we probably have to introduce `ChoiceName` to the language: + +```haskell +data ChoiceName = LocalChoiceName String | GloballyUniqueChoiceName String +data ChoiceId = ChoiceId ChoiceName Party +``` + + +## Optional Sections + +>> CIP section spec: +> May appear in any order, or with custom titles, at author and editor discretion: +> +> * Versioning: if Versioning is not addressed in Specification +> * References +> * Acknowledgements + +> **TODO** + +## Copyright + +The CIP must be explicitly licensed under acceptable copyright terms (see below). + +> **TODO** + diff --git a/README.md b/README.md index 11a4a8f..89cba60 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,25 @@ In this repo we track the development and discussion around the oracle protocol: + +* The CIP document versions which are the side effects of this effort can be found in the [./CIP XXX Marlowe Oracle Protocol](./CIP%20XXX%20Marlowe%20Oracle%20Protocol) directory. + +## Development Flow +======= + +### Working on The CIP document + +* The editing process of the latest CIP document version should happen on the `develop` branch. + +* In order to have a live preview which approximates the github rendering of the markdown please enter CIP directory and run the following command in a separate shell: + ```bash + $ cd ./CIP\ XXX\ Marlowe\ Oracle\ Protocol + $ ./markdown-watcher.sh + ``` * Some files and simple scripts are present here to ease the development process: - * [markdown-watcher.sh](./markdown-watcher.sh) and [diagrams/dot-watcher.sh](./diagrams/dot-watcher.sh) are simple scripts to watch for changes in the markdown and dot files and generate the corresponding diagrams and open up a browser and pdfs. - * [github-markdown.css](./github-markdown.css) is a CSS file to be used with the markdown-watcher.sh script to generate an html file which approximates the github markdown style. Please note that it is not a 100% exact rendering.