Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Plutus and Extended UTxO

Plutus and Extended UTxO

VIDEO: https://www.youtube.com/watch?v=TFezjgwuw8Y

This presentation was part of PlutusFest 2018 and introduces the design and architecture of the Plutus Platform, a Haskell-based environment and toolchain for developing contracts for the Cardano blockchain. The key features are its use of a standard purely functional programming language (instead of inventing a new language, which appears to be the popular approach), being based on a ledger-architecture that resembles a functional data flow graph (UTxO ledger, rather than an account-based ledger), and its tight integration and co-development of on-chain code (executed by block producing nodes) and off-chain code (executed on client machines).

See https://testnet.iohkdev.io/plutus/ for an online environment to write and test Plutus code and https://github.com/input-output-hk/plutus/ for the code.

2296a6bdc7779fe4017a23d268c8a79d?s=128

Manuel Chakravarty

December 11, 2018
Tweet

Transcript

  1. PLUTUS Plutus and Extended UTxO Manuel M T Chakravarty, Language

    Architect @ IOHK
  2. PLUTUS What is Plutus?

  3. PLUTUS What is Plutus? Innovative development and execution platform for

    distributed contract applications on Cardano SL & CL.
  4. PLUTUS The Three Pillars of Plutus

  5. PLUTUS Safety & Security

  6. PLUTUS Safety & Security Superior Ledger

  7. PLUTUS Safety & Security Superior Ledger Full Stack

  8. PLUTUS Safety & Security Superior Ledger Full Stack

  9. PLUTUS

  10. functional programming PLUTUS λ

  11. functional programming with modern type systems PLUTUS λτ

  12. functional programming modern type systems PLUTUS

  13. functional programming modern type systems PLUTUS input output

  14. functional programming modern type systems PLUTUS input output pure function

    side effects
  15. functional programming modern type systems PLUTUS input output typed function

    safe usage :: ⍺ :: β
  16. PLUTUS input output typed function safe usage :: ⍺ ::

    β local reasoning
  17. PLUTUS input output typed function safe usage :: ⍺ ::

    β local reasoning type-directed design
  18. PLUTUS input output typed function safe usage :: ⍺ ::

    β local reasoning type-directed design advanced testing & verification
  19. PLUTUS local reasoning type-directed design advanced testing & verification }

  20. PLUTUS local reasoning type-directed design advanced testing & verification }

    understand code behaviour
  21. PLUTUS local reasoning type-directed design advanced testing & verification }

    understand code behaviour find exploits
  22. PLUTUS core Plutus Core

  23. PLUTUS core Plutus Core not a bytecode typed FP calculus

  24. PLUTUS core Plutus Core not a bytecode not a classic

    virtual machine typed FP calculus abstract machine interpreter
  25. PLUTUS core Plutus Core small, powerful & based on peer-reviewed

    science not a bytecode not a classic virtual machine typed FP calculus abstract machine interpreter
  26. PLUTUS core Plutus Core

  27. PLUTUS core Plutus Core Where is it used?

  28. PLUTUS Safety & Security Superior Ledger Full Stack

  29. PLUTUS Account-based Ledger UTxO-based Ledger

  30. PLUTUS Account-based Ledger UTxO-based Ledger functional imperative

  31. PLUTUS Account-based Ledger UTxO-based Ledger functional imperative mutable shared state

    dataflow
  32. PLUTUS Account-based Ledger UTxO-based Ledger functional imperative mutable shared state

    dataflow compositional entangled
  33. PLUTUS What about the expressiveness of smart contracts?

  34. PLUTUS What about the expressiveness of smart contracts? Bitcoin

  35. PLUTUS What about the expressiveness of smart contracts? Bitcoin Ethereum

  36. PLUTUS What about the expressiveness of smart contracts? Bitcoin Ethereum

    minimal
  37. PLUTUS What about the expressiveness of smart contracts? Bitcoin Ethereum

    minimal enough rope
  38. PLUTUS

  39. PLUTUS

  40. PLUTUS Input Output

  41. PLUTUS Input Output

  42. PLUTUS Input Output ν: Validator x: Value core

  43. PLUTUS Input Output ν: Validator x: Value ρ: Redeemer core

    core
  44. PLUTUS Input Output ν: Validator x: Value ρ: Redeemer ν(ρ)

    ≟ True core core
  45. PLUTUS Input Output ν: Validator x: Value ρ: Redeemer ν(ρ)

    ≟ True ν: Validator x: Value ρ: Redeemer core core core core
  46. PLUTUS Input Output ν: Validator x: Value ρ: Redeemer ν(ρ)

    ≟ True ν: Validator x: Value ρ: Redeemer δ: Data core core core core core
  47. PLUTUS Input Output ν: Validator x: Value ρ: Redeemer ν(ρ)

    ≟ True ν: Validator x: Value ρ: Redeemer δ: Data σ: State core core core core core
  48. PLUTUS Input Output ν: Validator x: Value ρ: Redeemer ν(ρ)

    ≟ True ν: Validator x: Value ρ: Redeemer ν(ρ, δ, σ, x) ≟ True δ: Data σ: State core core core core core
  49. PLUTUS ν: Validator x: Value ρ: Redeemer ν(ρ, δ, σ,

    x) ≟ True δ: Data σ: State Extended UTxO core core core
  50. PLUTUS ν: Validator x: Value ρ: Redeemer ν(ρ, δ, σ,

    x) ≟ True δ: Data σ: State Extended UTxO Preserves the superior structure of UTxO ledgers core core core
  51. PLUTUS ν: Validator x: Value ρ: Redeemer ν(ρ, δ, σ,

    x) ≟ True δ: Data σ: State Extended UTxO Preserves the superior structure of UTxO ledgers Greatly increases the expressive power of scripts core core core
  52. PLUTUS Extended UTxO Preserves the superior structure of UTxO ledgers

    Greatly increases the expressive power of scripts
  53. PLUTUS Extended UTxO Preserves the superior structure of UTxO ledgers

    Greatly increases the expressive power of scripts data flows with value
  54. PLUTUS Extended UTxO Preserves the superior structure of UTxO ledgers

    Greatly increases the expressive power of scripts data flows with value scripts have an identity
  55. PLUTUS Extended UTxO Preserves the superior structure of UTxO ledgers

    Greatly increases the expressive power of scripts data flows with value scripts have an identity invariants across transaction chains
  56. PLUTUS Safety & Security Superior Ledger Full Stack

  57. PLUTUS

  58. PLUTUS What does it take to write a smart contract

    application?
  59. PLUTUS Simple crowdfunding

  60. PLUTUS Simple crowdfunding 1. Payment into campaign until a payment

    deadline
  61. PLUTUS Simple crowdfunding 1. Payment into campaign until a payment

    deadline 2. If funding goal reached, campaign owner can collect funds
  62. PLUTUS Simple crowdfunding 1. Payment into campaign until a payment

    deadline 2. If funding goal reached, campaign owner can collect funds 3. If funding goal not reached, refunds can be obtained by contributors
  63. PLUTUS Simple crowdfunding 1. Payment into campaign until a payment

    deadline 2. If funding goal reached, campaign owner can collect funds 3. If funding goal not reached, refunds can be obtained by contributors 4. If campaign owner does not collect by collection deadline, contributors can also obtain refunds
  64. PLUTUS 1. Payment into campaign until a payment deadline 2.

    If funding goal reached, campaign owner can collect funds 3. If funding goal not reached, refunds can be obtained by contributors 4. If campaign owner does not collect by collection deadline, contributors can also obtain refunds
  65. PLUTUS 1. Payment into campaign until a payment deadline 2.

    If funding goal reached, campaign owner can collect funds 3. If funding goal not reached, refunds can be obtained by contributors 4. If campaign owner does not collect by collection deadline, contributors can also obtain refunds pragma solidity ^0.4.6; contract WinnerTakesAll { uint minimumEntryFee; uint public deadlineProjects; uint public deadlineCampaign; uint public winningFunds; address public winningAddress; struct Project { address addr; string name; string url; uint funds; bool initialized; } … Solidity (on-chain)
  66. PLUTUS pragma solidity ^0.4.6; contract WinnerTakesAll { uint minimumEntryFee; uint

    public deadlineProjects; uint public deadlineCampaign; uint public winningFunds; address public winningAddress; struct Project { address addr; string name; string url; uint funds; bool initialized; } … Solidity (on-chain) var Web3 = require('web3'); var web3 = new Web3(); web3.setProvider(new web3.providers.HttpProvider(”http:… var accounts = web3.eth.accounts; accounts.forEach(function(v) { $(”#supportFrom”).append(”<opt… $(”#projectAddr”).append(”<opt… }); var compiled = web3.eth.compile.so… var code = compiled.code; var abi = compiled.info.abiDefinit… var contract = web3.eth.contract(a… … JavaScript (off-chain) +
  67. PLUTUS pragma solidity ^0.4.6; contract WinnerTakesAll { uint minimumEntryFee; uint

    public deadlineProjects; uint public deadlineCampaign; uint public winningFunds; address public winningAddress; struct Project { address addr; string name; string url; uint funds; bool initialized; } … Solidity var Web3 = require('web3'); var web3 = new Web3(); web3.setProvider(new web3.providers.HttpProvider(”http:… var accounts = web3.eth.accounts; accounts.forEach(function(v) { $(”#supportFrom”).append(”<opt… $(”#projectAddr”).append(”<opt… }); var compiled = web3.eth.compile.so… var code = compiled.code; var abi = compiled.info.abiDefinit… var contract = web3.eth.contract(a… … JavaScript
  68. PLUTUS pragma solidity ^0.4.6; contract WinnerTakesAll { uint minimumEntryFee; uint

    public deadlineProjects; uint public deadlineCampaign; uint public winningFunds; address public winningAddress; struct Project { address addr; string name; string url; uint funds; bool initialized; } … Solidity var Web3 = require('web3'); var web3 = new Web3(); web3.setProvider(new web3.providers.HttpProvider(”http:… var accounts = web3.eth.accounts; accounts.forEach(function(v) { $(”#supportFrom”).append(”<opt… $(”#projectAddr”).append(”<opt… }); var compiled = web3.eth.compile.so… var code = compiled.code; var abi = compiled.info.abiDefinit… var contract = web3.eth.contract(a… … JavaScript off-chain (wallet) on-chain (transaction)
  69. PLUTUS pragma solidity ^0.4.6; contract WinnerTakesAll { uint minimumEntryFee; uint

    public deadlineProjects; uint public deadlineCampaign; uint public winningFunds; address public winningAddress; struct Project { address addr; string name; string url; uint funds; bool initialized; } … Solidity var Web3 = require('web3'); var web3 = new Web3(); web3.setProvider(new web3.providers.HttpProvider(”http:… var accounts = web3.eth.accounts; accounts.forEach(function(v) { $(”#supportFrom”).append(”<opt… $(”#projectAddr”).append(”<opt… }); var compiled = web3.eth.compile.so… var code = compiled.code; var abi = compiled.info.abiDefinit… var contract = web3.eth.contract(a… … JavaScript off-chain (wallet) on-chain (transaction) two-level (staged) programming model JavaScript Solidity
  70. PLUTUS Solidity JavaScript off-chain (wallet) on-chain (transaction) two-level (staged) programming

    model ad hoc
  71. PLUTUS Solidity JavaScript off-chain (wallet) on-chain (transaction) two-level (staged) programming

    model ad hoc inconvenient
  72. PLUTUS Solidity JavaScript off-chain (wallet) on-chain (transaction) two-level (staged) programming

    model ad hoc inconvenient complex
  73. PLUTUS Solidity JavaScript off-chain (wallet) on-chain (transaction) two-level (staged) programming

    model ad hoc inconvenient complex fragile
  74. PLUTUS off-chain (wallet) on-chain (transaction) two-level (staged) programming model

  75. PLUTUS Haskell off-chain (wallet) on-chain (transaction) two-level (staged) programming model

  76. PLUTUS Haskell (Plutus Tx) Haskell off-chain (wallet) on-chain (transaction) two-level

    (staged) programming model
  77. PLUTUS Haskell (Plutus Tx) Haskell off-chain (wallet) on-chain (transaction) two-level

    (staged) programming model meta programming
  78. PLUTUS Haskell (Plutus Tx) Haskell off-chain (wallet) on-chain (transaction) two-level

    (staged) programming model meta programming integrated
  79. PLUTUS Haskell (Plutus Tx) Haskell off-chain (wallet) on-chain (transaction) two-level

    (staged) programming model meta programming integrated compact
  80. PLUTUS Haskell (Plutus Tx) Haskell off-chain (wallet) on-chain (transaction) two-level

    (staged) programming model meta programming integrated compact robust
  81. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do Haskell
  82. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" Haskell
  83. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey Haskell
  84. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript Haskell
  85. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) Haskell
  86. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value Haskell
  87. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) Haskell
  88. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) register (refundTrigger campaign) (refundHandler (Ledger.hashTx tx) campaign) contributionScript :: Campaign -> ValidatorScript Haskell
  89. PLUTUS Haskell contributionScript :: Campaign -> ValidatorScript

  90. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = Haskell

  91. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Haskell
  92. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> Plutus Tx Haskell
  93. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx Plutus Tx Haskell
  94. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Plutus Tx Haskell
  95. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && Plutus Tx Haskell
  96. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && Plutus Tx Haskell
  97. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Plutus Tx Haskell
  98. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && Plutus Tx Haskell
  99. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && Plutus Tx Haskell
  100. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && Plutus Tx Haskell
  101. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner Plutus Tx Haskell
  102. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner in $$(P.errorIfNot) isValid ||]) Plutus Tx Haskell
  103. PLUTUS Safety & Security Superior Ledger Full Stack

  104. PLUTUS Safety & Security Superior Ledger Full Stack

  105. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) register (refundTrigger campaign) (refundHandler (Ledger.hashTx tx) campaign) contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner in $$(P.errorIfNot) isValid ||]) off-chain on-chain
  106. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) register (refundTrigger campaign) (refundHandler (Ledger.hashTx tx) campaign) contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner in $$(P.errorIfNot) isValid ||]) core off-chain on-chain
  107. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) register (refundTrigger campaign) (refundHandler (Ledger.hashTx tx) campaign) contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner in $$(P.errorIfNot) isValid ||]) core core off-chain on-chain
  108. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) register (refundTrigger campaign) (refundHandler (Ledger.hashTx tx) campaign) contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner in $$(P.errorIfNot) isValid ||]) core core off-chain on-chain
  109. PLUTUS This is Plutus! Safety & Security Superior Ledger Full

    Stack