<p>That is indeed possible. The following will compile a fib function to plutus and execute it given the default cost model.</p>
<pre class="lang-haskell prettyprint-override"><code>{-# LANGUAGE DataKinds             #-}
{-# LANGUAGE DeriveAnyClass        #-}
{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns        #-}
{-# LANGUAGE NoImplicitPrelude     #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE RankNTypes            #-}
{-# LANGUAGE RecordWildCards       #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeApplications      #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeOperators         #-}

module Onchain where

import           Cardano.Api                          (PlutusScriptV2,
                                                       writeFileTextEnvelope)
import           Cardano.Api.Shelley                  (PlutusScript (..))
import           Codec.Serialise
import qualified Data.ByteString.Lazy                 as LBS
import qualified Data.ByteString.Short                as SBS
import           Data.Functor                         (void)
import qualified Ledger.Typed.Scripts                 as Scripts
import           Plutus.V1.Ledger.Api                 as PlutusV1
import           Plutus.V1.Ledger.Value               as PlutusV1
import qualified Plutus.V2.Ledger.Api                 as PlutusV2
import qualified Plutus.V2.Ledger.Contexts            as PlutusV2
import qualified PlutusTx
import           PlutusTx.Prelude                     as P 
import           Prelude                              (IO, print, map) 

import           PlutusCore.Evaluation.Machine.ExBudgetingDefaults (defaultCostModelParams)

{-# INLINEABLE fib #-}
fib :: Integer -&gt; Integer
fib n = go n (0,1)
  where
    go x (a, b) | x==0      = a
                | otherwise = go (x-1) (b, a+b)

fibScript :: Script
fibScript = PlutusV2.fromCompiledCode ($$(PlutusTx.compile [|| fib ||]))

serialisedScript :: PlutusV2.SerializedScript
serialisedScript = SBS.toShort . LBS.toStrict $ serialise fibScript

getEvalCtx :: MonadError CostModelApplyError m =&gt; m EvaluationContext
getEvalCtx = case defaultCostModelParams of
              Nothing -&gt; Err.throwError CMInternalReadError
              Just n  -&gt; mkEvaluationContext n

runScript :: MonadError CostModelApplyError m =&gt; Integer -&gt; m (LogOutput, Either EvaluationError ExBudget)
runScript n = getEvalCtx &gt;&gt;= (\c -&gt; return (evaluateScriptCounting a b c serialisedScript [I n]))
              where
                a :: PlutusV1.ProtocolVersion
                a = ProtocolVersion 7 0
                b :: PlutusV1.VerboseMode
                b = Quiet
</code></pre>

CC BY-SA 4.0
2022-12-20T00:39:12.267Z
Thank you very much. Makes a lot of sense to me now. I think these evaluation functions should be documented somewhere.
MaiaVictor
CC BY-SA 4.0
2022-12-20T07:57:53.110Z
What I always do, git clone the latest release plutus app repo (not main), then enter a nix-shell and execute `build-and-serve-docs`. This will run a local haddock server with all functions, really handy if you are searching for something! It's an up-to-date version of https://playground.plutus.iohkdev.io/doc/haddock/
Fermat
CC BY-SA 4.0
2022-12-19T18:28:31.220Z
2022-12-19T18:28:31.220Z
Fermat
<p>What do you want to do with the output of your fib-function ? Also with &quot;offline&quot; you probably mean off-chain. If you want to compute the Fibonacci sequence off-chain you can use pure Haskell. There are many examples like this one:</p>
<pre><code>fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
</code></pre>
<p>This is just an inefficient naive way. Other solutions can be found here: <a href="https://wiki.haskell.org/The_Fibonacci_sequence" rel="nofollow noreferrer">https://wiki.haskell.org/The_Fibonacci_sequence</a></p>
<p>And then in your contract:</p>
<pre><code>fibonacci :: forall w s. FibParams -&gt; Contract w s Text ()
fibonacci param = do
    pkh &lt;- ownPaymentPubKeyHash
    ... --do stuff with f
    unbalTx &lt;- ...
    ledgerTx &lt;- submitUnbalancedTx $ Constraints.adjustUnbalancedTx unbalTx
    awaitTxConfirmed $ getCardanoTxId ledgerTx
    Contract.logInfo @String $ &quot;submitted tx&quot;
  where
    f = fib (param num)
</code></pre>
<p>For testing you need to look into <code>runEmulatorTraceIO</code>.</p>

CC BY-SA 4.0
2022-12-15T18:49:17.587Z
I want to run `fib` in the context of Cardano's VM (is there one?) in order to benchmark its performance. Cardano doesn't run Haskell directly on nodes, right? It compiles to Plutus, and then interprets. I want to go through it to benchmark the Plutus interpreter versus native GHC Fib.
MaiaVictor
CC BY-SA 4.0
2022-12-15T08:01:55.333Z
2022-12-15T08:17:25.720Z
2022-12-15T08:17:25.720Z
Jey
<p>On Ethereum, I'm able to run and test a Fibonacci function by writing a Solidity smart-contract with a <code>fib</code> method, compiling to the EVM, deploying and running offline by using any EVM implementation, such as Sputnick:</p>
<pre><code>function fib(uint n) public constant returns(uint result) {
  if (n &lt;= 1) {
    return 1;
  } else {
    return Fib.fib(n - 1) + Fib.fib(n - 2);
  }
}
</code></pre>
<p>On Cardano, I'm aware I can use Haskell to create contracts, which is then compiled to Plutus. But, despite having spent some time googling, I'm still not sure how to achieve that. How do I run and test a &quot;fib&quot; function offline on Cardano?</p>

<plutus><testnet><tools>
How to run a simple Fib function offline?
# How to run a simple Fib function offline?

(Asked by: username_0 on 2022-12-13)

On Ethereum, I'm able to run and test a Fibonacci function by writing a Solidity smart-contract with a fib method, compiling to the EVM, deploying and running offline by using any EVM implementation, such as Sputnick:
function fib(uint n) public constant returns(uint result) {
  if (n <= 1) {
    return 1;
  } else {
    return Fib.fib(n - 1) + Fib.fib(n - 2);
  }
}

On Cardano, I'm aware I can use Haskell to create contracts, which is then compiled to Plutus. But, despite having spent some time googling, I'm still not sure how to achieve that. How do I run and test a "fib" function offline on Cardano?

**Tags:** plutus, testnet, tools

---

## 2 answers

### Answer by username_1 on 2022-12-19. Score: 1 | Accepted answer

That is indeed possible. The following will compile a fib function to plutus and execute it given the default cost model.
{-# LANGUAGE DataKinds             #-}
{-# LANGUAGE DeriveAnyClass        #-}
{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns        #-}
{-# LANGUAGE NoImplicitPrelude     #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE RankNTypes            #-}
{-# LANGUAGE RecordWildCards       #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeApplications      #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeOperators         #-}

module Onchain where

import           Cardano.Api                          (PlutusScriptV2,
                                                       writeFileTextEnvelope)
import           Cardano.Api.Shelley                  (PlutusScript (..))
import           Codec.Serialise
import qualified Data.ByteString.Lazy                 as LBS
import qualified Data.ByteString.Short                as SBS
import           Data.Functor                         (void)
import qualified Ledger.Typed.Scripts                 as Scripts
import           Plutus.V1.Ledger.Api                 as PlutusV1
import           Plutus.V1.Ledger.Value               as PlutusV1
import qualified Plutus.V2.Ledger.Api                 as PlutusV2
import qualified Plutus.V2.Ledger.Contexts            as PlutusV2
import qualified PlutusTx
import           PlutusTx.Prelude                     as P 
import           Prelude                              (IO, print, map) 

import           PlutusCore.Evaluation.Machine.ExBudgetingDefaults (defaultCostModelParams)

{-# INLINEABLE fib #-}
fib :: Integer -> Integer
fib n = go n (0,1)
  where
    go x (a, b) | x==0      = a
                | otherwise = go (x-1) (b, a+b)

fibScript :: Script
fibScript = PlutusV2.fromCompiledCode ($$(PlutusTx.compile [|| fib ||]))

serialisedScript :: PlutusV2.SerializedScript
serialisedScript = SBS.toShort . LBS.toStrict $ serialise fibScript

getEvalCtx :: MonadError CostModelApplyError m => m EvaluationContext
getEvalCtx = case defaultCostModelParams of
              Nothing -> Err.throwError CMInternalReadError
              Just n  -> mkEvaluationContext n

runScript :: MonadError CostModelApplyError m => Integer -> m (LogOutput, Either EvaluationError ExBudget)
runScript n = getEvalCtx >>= (\c -> return (evaluateScriptCounting a b c serialisedScript [I n]))
              where
                a :: PlutusV1.ProtocolVersion
                a = ProtocolVersion 7 0
                b :: PlutusV1.VerboseMode
                b = Quiet

> **Comments:**
> **username_0**: Thank you very much. Makes a lot of sense to me now. I think these evaluation functions should be documented somewhere.  
> **username_1**: What I always do, git clone the latest release plutus app repo (not main), then enter a nix-shell and execute `build-and-serve-docs`. This will run a local haddock server with all functions, really handy if you are searching for something! It's an up-to-date version of https://playground.plutus.iohkdev.io/doc/haddock/  

---

### Answer by username_2 on 2022-12-15. Score: 1

What do you want to do with the output of your fib-function ? Also with "offline" you probably mean off-chain. If you want to compute the Fibonacci sequence off-chain you can use pure Haskell. There are many examples like this one:
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

This is just an inefficient naive way. Other solutions can be found here: https://wiki.haskell.org/The_Fibonacci_sequence
And then in your contract:
fibonacci :: forall w s. FibParams -> Contract w s Text ()
fibonacci param = do
    pkh <- ownPaymentPubKeyHash
    ... --do stuff with f
    unbalTx <- ...
    ledgerTx <- submitUnbalancedTx $ Constraints.adjustUnbalancedTx unbalTx
    awaitTxConfirmed $ getCardanoTxId ledgerTx
    Contract.logInfo @String $ "submitted tx"
  where
    f = fib (param num)

For testing you need to look into runEmulatorTraceIO.

> **Comments:**
> **username_0**: I want to run `fib` in the context of Cardano's VM (is there one?) in order to benchmark its performance. Cardano doesn't run Haskell directly on nodes, right? It compiles to Plutus, and then interprets. I want to go through it to benchmark the Plutus interpreter versus native GHC Fib.  

---

