A Reality check of September 12th and beyond. How will the world of Cardano dApps look like?

Cardano has released a new feature that enables the smart contract service over the testnet. Smart contracts are the salient features of today's blockchains where business logics e.g. are allowed to develop into the blockchains. These business logics include financial applications like token swap, bidding etc. Cardano is known to be the most emerging blockchain technology because of its innovative transaction model called Extended Unspent Transaction Output (EUTXO).

Extended Unspent Transaction Output Model

Cardano uses the idea of the UTXO model in bitcoin and then extends it with a new innovation known as EUTXO. In the bitcoin UTXO model, transactions consist of two main parts: inputs and outputs. The transaction’s outputs are locked using the hash of the public key known as address. To spend coins, the spender uses the private key corresponding to that public key hash or address. In the creation of a transaction, the UTXO from the output of a previous transaction is used as an input and then the ownership of coins are transferred to the next spender in the form of a new UTXO as an output. Cardano adopts this model with an extra layer of validation and scripts.

In the UTXO model, transaction outputs are locked by some validation scripts instead of public key hash or address. The scripts contain some arbitrary logics and conditions that decide whether to unlock the UTXO or not. When a Cardano node receives a transaction, it executes scripts to validate that given UTXO fulfills the condition to be used as an input. Second feature of UTXO is that outputs can contain arbitrary data in addition to other values (ADA) and address. Together with all this provided information, scripts can generate the results clearly “yes” or “no” whether a transaction’ input is valid or not.

Moreover, Cardano’ ETUXO model also has some advantages over the accounts based models as used in Ethereum. The submitted transaction can become part of the ledger with a high success rate. This is because transactions are validated by the scripts and arbitrary data fields before the submission. Simply, the transaction can be checked by off-chain processing before being sent to the blockchain. However, transactions can be failed because of the appearance of the same transaction concurrently in the blockchain network. Due to this, Cardano’ UTXO has an edge over the Ethereum’s accounting model where a transaction can fail in the middle of execution of smart contract logic. Moreover, transaction execution cost/ fee can be determined off-chain in Cardano as compared to Ethereum.

Haskell Language

It is a functional language. Following is the basic syntax of the Haskell language.

ghci> let a = “C stands for Cardano”
ghci> print a
ghci> C stands for Cardano”

In the above described basic syntax, “a” is considered as the function. Functional language is different as compared to other languages where “a” will be considered as a variable. Cardano has been developed using Haskell. The codes written in Haskell are compiled by a compiler called Haskell Compilation System (GHC).

Programming languages for Smart Contracts

In Cardano, the following three languages are used to write smart contracts.

  1. Plutus

    1. Known as a purpose built language to provide full-stack programming support for writing smart contacts.

  2. Marlowe

    1. A domain-specific language (DSL) to develop and execute smart contracts

    2. It can be embedded in the javascript and haskell

  3. Glow

    1. Also a domain-specific language and its salient feature is to develop secure smart contracts based applications in an adversarial environment.

Plutus is a well known and most leading functional programming language to develop smart contracts for real world applications for the Cardano ecosystems. Therefore, Plutus will be discussed in the next sections.

Plutus Core

It is a scripting language that is used to write smart contracts known as Plutus contracts. Also, it is a large subset of Haskell libraries. Therefore, knowledge of Haskell language is required to learn and write Plutus core for applications. There is familiarity between the Plutus scripting language and the Haskell core language. Scripts written by Plutus core are compiled by the Plutus compiler.

Plutus Playground

It is a web based framework that provides User Interface (UI) to compile, evaluate and simulate the functionality of the smart contract. Also, while developing smart contracts, endpoints are defined by a schema. After compilation and evaluation, endpoints enabled the functionality in the form of buttons in the wallets. Moreover, Plutus playground is a standalone environment that works

Plutus Contract

Cardano smart contracts are developed using the Plutus core language. These smart contracts are known as Plutus smart contracts. There are two main parts of Plutus contracts “on-chain code” and “off-chain code”. Both these codes are written in Haskell language. Precisely, on-chain codes run on the blockchain and whereas off-chain codes run on user’ machine. Moreover, the on-chain code in Plutus contract is compiled by Plutus compiler and the off-chain code in the Plutus contract is compiled by the Haskell compiler.

Following are the important terms that are used in the development of smart contracts (Plutus contracts):

Script

An executable program used to interact with the Cardano ledger.

Script output

This is an UTXO locked by a script.

Validator script

To spend the output in EUTXO model, the validator script verified the conditions that are attached with the “script output”. It also determines the address of the output.

Datum

This is the data field given in the script output of the EUTXO model.

Redeemer

This is the valid argument for the validator script. To spend a script output, the redeemer arguments are defined in a new transaction.

Plutus Tx

A compiler that compiles the Haskell code into Plutus core.

Smart Contract Deployment

We have not found any reference documentation or tutorial that leads us to the deployment of smart contract on to the Cardano testnet. “The team is concentrating on building the command line interface (CLI) for writing the "Hello World" design of smart contracts” .

In Cardano release 1.29.0 they announced about smart contracts but yet no information how to write and deploy a on Cardano network. On twitter post they announced about new hardfork that on testnet smart contracts are officially available on 1st September 2021 and on mainnet smart contracts are officially available on 12 September 2021

Neither the announcement, or supported documentation mentioned of how to actually deploy the smart contract into the testnet. The only thing supplied was a chain extended screenshot:

If you look at media, and videos a lot of previews of the smart contracts are done on Plutus Playground, but there is no link between Plutus Playground and actual Cardano testnet or mainnet whatsoever. Cardano has been written in Haskell which is a functional programming language, however the issues come when you are on a look out for talent. Even Charles Hoskinson himself mentioned in the video, that no one wants to learn Haskell.

To finalize the thought, in the latest V1.29.0 release, CLI command that is required for smart contract deployment is not there. Which begs the question how are these contracts will get on the blockchain post September 12th?

Example smart contract

This is a sample "Hello world" smart contract written in Plutus Playground:

Once compiled, the contract output looks like this:

And the issue comes up, that due to lack of connection between Plutus Playground and the testnet, the transaction is not traceable on the testnet:

Another Puzzle Smart Contract preview

-- A game with two players. Player 1 thinks of a secret word
-- and uses its hash, and the game validator script, to lock
-- some funds (the prize) in a pay-to-script transaction output.
-- Player 2 guesses the word by attempting to spend the transaction
-- output. If the guess is correct, the validator script releases the funds.
-- If it isn't, the funds stay locked.
import           Control.Monad             (void)
import qualified Data.ByteString.Char8     as C
import           Language.Plutus.Contract
import qualified Language.PlutusTx         as PlutusTx
import           Language.PlutusTx.Prelude hiding (pure, (<$>))
import           Ledger                    (Address, Validator, ValidatorCtx, Value, scriptAddress)
import qualified Ledger.Constraints        as Constraints
import qualified Ledger.Typed.Scripts      as Scripts
import           Playground.Contract
import qualified Prelude

------------------------------------------------------------

newtype HashedString = HashedString ByteString deriving newtype PlutusTx.IsData

PlutusTx.makeLift ''HashedString

newtype ClearString = ClearString ByteString deriving newtype PlutusTx.IsData

PlutusTx.makeLift ''ClearString

type GameSchema =
    BlockchainActions
        .\/ Endpoint "lock" LockParams
        .\/ Endpoint "guess" GuessParams

data Game
instance Scripts.ScriptType Game where
    type instance RedeemerType Game = ClearString
    type instance DatumType Game = HashedString

gameInstance :: Scripts.ScriptInstance Game
gameInstance = Scripts.validator @Game
    $$(PlutusTx.compile [|| validateGuess ||])
    $$(PlutusTx.compile [|| wrap ||]) where
        wrap = Scripts.wrapValidator @HashedString @ClearString

-- create a data script for the guessing game by hashing the string
-- and lifting the hash to its on-chain representation
hashString :: String -> HashedString
hashString = HashedString . sha2_256 . C.pack

-- create a redeemer script for the guessing game by lifting the
-- string to its on-chain representation
clearString :: String -> ClearString
clearString = ClearString . C.pack

-- | The validation function (Datum -> Redeemer -> ValidatorCtx -> Bool)
validateGuess :: HashedString -> ClearString -> ValidatorCtx -> Bool
validateGuess (HashedString actual) (ClearString guess') _ = actual == sha2_256 guess'

-- | The validator script of the game.
gameValidator :: Validator
gameValidator = Scripts.validatorScript gameInstance

-- | The address of the game (the hash of its validator script)
gameAddress :: Address
gameAddress = Ledger.scriptAddress gameValidator

-- | Parameters for the "lock" endpoint
data LockParams = LockParams
    { secretWord :: String
    , amount     :: Value
    }
    deriving stock (Prelude.Eq, Prelude.Show, Generic)
    deriving anyclass (FromJSON, ToJSON, IotsType, ToSchema, ToArgument)

--  | Parameters for the "guess" endpoint
newtype GuessParams = GuessParams
    { guessWord :: String
    }
    deriving stock (Prelude.Eq, Prelude.Show, Generic)
    deriving anyclass (FromJSON, ToJSON, IotsType, ToSchema, ToArgument)

-- | The "lock" contract endpoint. See note [Contract endpoints]
lock :: AsContractError e => Contract GameSchema e ()
lock = do
    LockParams secret amt <- endpoint @"lock" @LockParams
    let tx         = Constraints.mustPayToTheScript (hashString secret) amt
    void (submitTxConstraints gameInstance tx)

-- | The "guess" contract endpoint. See note [Contract endpoints]
guess :: AsContractError e => Contract GameSchema e ()
guess = do
    GuessParams theGuess <- endpoint @"guess" @GuessParams
    unspentOutputs <- utxoAt gameAddress
    let redeemer = clearString theGuess
        tx       = collectFromScript unspentOutputs redeemer
    void (submitTxConstraintsSpending gameInstance unspentOutputs tx)

game :: AsContractError e => Contract GameSchema e ()
game = lock `select` guess

{- Note [Contract endpoints]

A contract endpoint is a function that uses the wallet API to interact with the
blockchain. We can look at contract endpoints from two different points of view.

1. Contract users

Contract endpoints are the visible interface of the contract. They provide a
UI (HTML form) for entering the parameters of the actions we may take as part
of the contract.

2. Contract authors

As contract authors we define endpoints as functions that return a value of
type 'MockWallet ()'. This type indicates that the function uses the wallet API
to produce and spend transaction outputs on the blockchain.

Endpoints can have any number of parameters: 'lock' has two
parameters, 'guess' has one and 'startGame' has none. For each endpoint we
include a call to 'mkFunction' at the end of the contract definition. This
causes the Haskell compiler to generate a schema for the endpoint. The Plutus
Playground then uses this schema to present an HTML form to the user where the
parameters can be entered.

-}

endpoints :: AsContractError e => Contract GameSchema e ()
endpoints = game

mkSchemaDefinitions ''GameSchema

$(mkKnownCurrencies [])

The code above , there is a word guessing game in which one user enters a word and locks some ADA. So when some other user guesses the right word. Then the amount of ADA sent to the second user as reward, as we all know that Cardano is EUTXO based. That’s why, any transaction is submitted only if the transaction has accurate value otherwise the transaction fails before submission. This is the main difference between UTXO and EUTXO.

Once the simulation is completed:

Failed Transaction:

Successful Transaction:

Conclusion

Cardano is definitely making the right moves towards the right direction, but the reality has to be addressed and that's exactly what we've tried to do in this article. September 12th is a major milestone, but we still have a long way to go before we have live dApps on the blockchain. Especially that the Blockchain itself requires additional development to be able to implement the smart contracts onto the chain.

ADAX team will continue our journey and development, and in addition to our recent how-to guide, we'll be supporting the progress and development of the blockchain and the dApps.

If any questions should come - our development team is always ready to step in and support. Please reach out dev@adax.pro

Last updated