<p>Haskell allows you to loop (recursively). And since all off-chain codes (<code>mustPayTo...</code> included) are written in Haskell, it is be possible.</p>

CC BY-SA 4.0
2022-02-04T07:50:14.297Z
2022-02-04T07:50:14.297Z
Aoaddeola
<p>Do you mean something like this:</p>
<pre><code>v = lovelaceValueOf 2_000_000
txc = foldl
      (\acc i -&gt; acc &lt;&gt; (Constraints.mustPayToTheScript (YourDatum i) $ v))
      (TxConstraints [] [] [])
      [1..1000]
</code></pre>

CC BY-SA 4.0
2022-02-04T18:11:43.530Z
Yes. also would that be considered recursion?
Floof99
CC BY-SA 4.0
2022-02-04T18:15:30.233Z
No, it is not using a recursive function. It just uses a fold -a very useful pattern.
Jey
CC BY-SA 4.0
2022-02-04T18:55:12.710Z
ok I look into fold some more, thank you
Floof99
CC BY-SA 4.0
2022-02-04T19:59:06.437Z
So I tried out your method but it seems like the compliler dosent like the treatment of the TXContraints any ideas?
Floof99
CC BY-SA 4.0
2022-02-04T20:02:33.557Z
You probably need to correctly declare the types. If you add your code in the question I can edit my answer.
Jey
CC BY-SA 4.0
2022-02-04T20:13:46.297Z
Ok I added it there error is in the lock endpoint function
Floof99
CC BY-SA 4.0
2022-02-04T21:06:20.643Z
There was a missing parenthesis in my code. I added it. You put it on the wrong line. Also there are many things missing in your lock-function. Start by making your code work for one UTxO and then use foldl to do it for 1000.
Jey
CC BY-SA 4.0
2022-02-04T08:26:04.177Z
2022-02-04T20:52:40.243Z
2022-02-04T20:52:40.243Z
Jey
<p>I want to make a recursive loop on endpoint call so that it calls mustPayToTheScript 1000 times with a decreasing datum so that it amounts to 1000 utxos siting at the same script address is this possible with plutus considering that its built on a functional language?</p>
<pre><code>import           Control.Monad          hiding (fmap)
import           Data.Aeson             (ToJSON, FromJSON)
import           Data.Text              (Text)
import           Data.Void              (Void)
import           GHC.Generics           (Generic)
import           Plutus.Contract        
import           Plutus.Contract        as Contract
import           Ledger.Address         as Add
import           Plutus.Trace.Emulator  as Emulator
import qualified PlutusTx
import           PlutusTx.Prelude       hiding (Semigroup(..), unless)
import           Ledger                 hiding (mint, singleton)
import           Ledger.Constraints     as Constraints
import qualified Ledger.Typed.Scripts   as Scripts
import           Ledger.Value           as Value
import           Playground.Contract    (printJson, printSchemas, ensureKnownCurrencies, stage, ToSchema)
import           Playground.TH          (mkKnownCurrencies, mkSchemaDefinitions)
import           Playground.Types       (KnownCurrency (..))
import           Prelude                (IO, Show (..), String)
import           Text.Printf            (printf)
import           Wallet.Emulator.Wallet
import           PlutusTx.Prelude
import           Wallet.Effects         as Effects
import qualified PlutusTx.Builtins      as Builtins
import           Plutus.V1.Ledger.Ada as Ada
import           Ledger.Tx              (scriptTxOut, ChainIndexTxOut)
import           Plutus.ChainIndex.Tx 
import           Ledger.Blockchain 
import           Playground.Contract
import           Prelude              ((/), Float, toInteger, floor)
import           Cardano.Api hiding (Value, TxOut,Address)
import           Cardano.Api.Shelley hiding (Value, TxOut, Address)
import           Codec.Serialise hiding (encode)



minADA :: Value
minADA = Ada.lovelaceValueOf 2000000

price :: Value 
price = Ada.lovelaceValueOf 10000000

data ContractInfo = ContractInfo
    { policyID :: !CurrencySymbol
    , walletOwner :: !PubKeyHash
    , nameOfToken :: !TokenName
    } deriving (Generic, ToJSON, FromJSON)


contractInfo = ContractInfo 
    { policyID = &quot;8b0dbdd6504ff8f129400ab3b21f12a52ffb09f0b3cff594cb5bb868&quot;
    , walletOwner = &quot;a2c20c77887ace1cd986193e4e75babd8993cfd56995cd5cfce609c2&quot;
    , nameOfToken = &quot;reward&quot;
    }

--purchase portion of the contract 
data LootBoxData
instance Scripts.ValidatorTypes LootBoxData where
    type instance RedeemerType LootBoxData = ()
    type instance DatumType LootBoxData = Integer

--Checks the validatorHash to make sure the LootBox has tokens to host the transaction
--If never changed by the end of the project use the builtins script validator
{-# INLINABLE mkValidator #-}
mkValidator :: Integer -&gt; () -&gt; ScriptContext -&gt; Bool
mkValidator _ _ ctx = True

lootBox :: Scripts.TypedValidator LootBoxData
lootBox = Scripts.mkTypedValidator @LootBoxData
    $$(PlutusTx.compile [|| mkValidator ||])
    $$(PlutusTx.compile [|| wrap ||]) where
        wrap = Scripts.wrapValidator @Integer

valHash :: Ledger.ValidatorHash
valHash = Scripts.validatorHash lootBox

validate :: Validator
validate = Scripts.validatorScript lootBox

valAddress :: Address
valAddress = Scripts.validatorAddress lootBox



--Start of minting portion of the smart contract

{-# INLINABLE mkPolicy #-}
mkPolicy :: PubKeyHash -&gt; () -&gt; ScriptContext -&gt; Bool
mkPolicy pkh () ctx = txSignedBy (scriptContextTxInfo ctx) pkh

policy :: PubKeyHash -&gt; Scripts.MintingPolicy
policy pkh = mkMintingPolicyScript $
    $$(PlutusTx.compile [|| Scripts.wrapMintingPolicy . mkPolicy||])
    `PlutusTx.applyCode`
    (PlutusTx.liftCode pkh)

--dont need
curSymbol :: PubKeyHash -&gt; CurrencySymbol
curSymbol = scriptCurrencySymbol . policy

data MintParams = MintParams
    { mpTokenName :: !TokenName
    , mpAmount    :: !Integer
    } deriving (Generic, ToJSON, FromJSON, ToSchema)

PlutusTx.makeLift ''MintParams


--Start of endpoints
type SignedSchema = 
    Endpoint &quot;mint&quot; MintParams
     .\/ Endpoint &quot;lock&quot; MintParams
     .\/ Endpoint &quot;purchase&quot; ()

mint :: AsContractError e =&gt; MintParams -&gt; Contract w s e ()
mint mp = do
    ppkh &lt;- Contract.ownPaymentPubKeyHash
    let pkh     = unPaymentPubKeyHash ppkh
        val     = Value.singleton (curSymbol pkh) (mpTokenName mp) (mpAmount mp)
        lookups = Constraints.mintingPolicy $ policy (pkh)
        tx      = Constraints.mustMintValue val
    ledgerTx &lt;- submitTxConstraintsWith @Void lookups tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
    logInfo @String $ printf &quot;forged %s&quot; (show val)

lock :: MintParams -&gt; Contract w SignedSchema Text ()
lock mp =  do
-- make a recusive function that allows for the creation of a 1000 utxos of diffrent datums from a wallet (cheap if implemented correctly) 
        
    let v   = Value.singleton (policyID contractInfo) (nameOfToken contractInfo) (mpAmount mp) &lt;&gt; minADA
        txc =   foldl
                (\acc i -&gt; acc &lt;&gt; (Constraints.mustPayToTheScript (i) $ v)
                (TxConstraints [] [] []))
                [1..1000]
                
    ledgerTx &lt;- submitTx txc
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx

purchase :: () -&gt; Contract w SignedSchema Text ()
purchase _ =  do
    utxos &lt;- fundsAtAddressGeq valAddress (Ada.lovelaceValueOf 1)

    let redeemer = () 
        ppkh     = walletOwner contractInfo
        tx       = mustPayToPubKey (Add.PaymentPubKeyHash ppkh) price &lt;&gt; collectFromScript utxos redeemer
        
    void (submitTxConstraintsSpending lootBox utxos tx)

endpoints :: Contract () SignedSchema Text ()
endpoints = awaitPromise (mint' `select` lock' `select` purchase') &gt;&gt; endpoints
  where
    mint' = endpoint @&quot;mint&quot; mint
    lock' = endpoint @&quot;lock&quot; lock
    purchase' = endpoint @&quot;purchase&quot; purchase

mkSchemaDefinitions ''SignedSchema

mkKnownCurrencies []
</code></pre>

<plutus>
recursive mustPayToTheScript loop?
# recursive mustPayToTheScript loop?

(Asked by: username_0 on 2022-02-04)

I want to make a recursive loop on endpoint call so that it calls mustPayToTheScript 1000 times with a decreasing datum so that it amounts to 1000 utxos siting at the same script address is this possible with plutus considering that its built on a functional language?
import           Control.Monad          hiding (fmap)
import           Data.Aeson             (ToJSON, FromJSON)
import           Data.Text              (Text)
import           Data.Void              (Void)
import           GHC.Generics           (Generic)
import           Plutus.Contract        
import           Plutus.Contract        as Contract
import           Ledger.Address         as Add
import           Plutus.Trace.Emulator  as Emulator
import qualified PlutusTx
import           PlutusTx.Prelude       hiding (Semigroup(..), unless)
import           Ledger                 hiding (mint, singleton)
import           Ledger.Constraints     as Constraints
import qualified Ledger.Typed.Scripts   as Scripts
import           Ledger.Value           as Value
import           Playground.Contract    (printJson, printSchemas, ensureKnownCurrencies, stage, ToSchema)
import           Playground.TH          (mkKnownCurrencies, mkSchemaDefinitions)
import           Playground.Types       (KnownCurrency (..))
import           Prelude                (IO, Show (..), String)
import           Text.Printf            (printf)
import           Wallet.Emulator.Wallet
import           PlutusTx.Prelude
import           Wallet.Effects         as Effects
import qualified PlutusTx.Builtins      as Builtins
import           Plutus.V1.Ledger.Ada as Ada
import           Ledger.Tx              (scriptTxOut, ChainIndexTxOut)
import           Plutus.ChainIndex.Tx 
import           Ledger.Blockchain 
import           Playground.Contract
import           Prelude              ((/), Float, toInteger, floor)
import           Cardano.Api hiding (Value, TxOut,Address)
import           Cardano.Api.Shelley hiding (Value, TxOut, Address)
import           Codec.Serialise hiding (encode)



minADA :: Value
minADA = Ada.lovelaceValueOf 2000000

price :: Value 
price = Ada.lovelaceValueOf 10000000

data ContractInfo = ContractInfo
    { policyID :: !CurrencySymbol
    , walletOwner :: !PubKeyHash
    , nameOfToken :: !TokenName
    } deriving (Generic, ToJSON, FromJSON)


contractInfo = ContractInfo 
    { policyID = "8b0dbdd6504ff8f129400ab3b21f12a52ffb09f0b3cff594cb5bb868"
    , walletOwner = "a2c20c77887ace1cd986193e4e75babd8993cfd56995cd5cfce609c2"
    , nameOfToken = "reward"
    }

--purchase portion of the contract 
data LootBoxData
instance Scripts.ValidatorTypes LootBoxData where
    type instance RedeemerType LootBoxData = ()
    type instance DatumType LootBoxData = Integer

--Checks the validatorHash to make sure the LootBox has tokens to host the transaction
--If never changed by the end of the project use the builtins script validator
{-# INLINABLE mkValidator #-}
mkValidator :: Integer -> () -> ScriptContext -> Bool
mkValidator _ _ ctx = True

lootBox :: Scripts.TypedValidator LootBoxData
lootBox = Scripts.mkTypedValidator @LootBoxData
    $$(PlutusTx.compile [|| mkValidator ||])
    $$(PlutusTx.compile [|| wrap ||]) where
        wrap = Scripts.wrapValidator @Integer

valHash :: Ledger.ValidatorHash
valHash = Scripts.validatorHash lootBox

validate :: Validator
validate = Scripts.validatorScript lootBox

valAddress :: Address
valAddress = Scripts.validatorAddress lootBox



--Start of minting portion of the smart contract

{-# INLINABLE mkPolicy #-}
mkPolicy :: PubKeyHash -> () -> ScriptContext -> Bool
mkPolicy pkh () ctx = txSignedBy (scriptContextTxInfo ctx) pkh

policy :: PubKeyHash -> Scripts.MintingPolicy
policy pkh = mkMintingPolicyScript $
    $$(PlutusTx.compile [|| Scripts.wrapMintingPolicy . mkPolicy||])
    `PlutusTx.applyCode`
    (PlutusTx.liftCode pkh)

--dont need
curSymbol :: PubKeyHash -> CurrencySymbol
curSymbol = scriptCurrencySymbol . policy

data MintParams = MintParams
    { mpTokenName :: !TokenName
    , mpAmount    :: !Integer
    } deriving (Generic, ToJSON, FromJSON, ToSchema)

PlutusTx.makeLift ''MintParams


--Start of endpoints
type SignedSchema = 
    Endpoint "mint" MintParams
     .\/ Endpoint "lock" MintParams
     .\/ Endpoint "purchase" ()

mint :: AsContractError e => MintParams -> Contract w s e ()
mint mp = do
    ppkh <- Contract.ownPaymentPubKeyHash
    let pkh     = unPaymentPubKeyHash ppkh
        val     = Value.singleton (curSymbol pkh) (mpTokenName mp) (mpAmount mp)
        lookups = Constraints.mintingPolicy $ policy (pkh)
        tx      = Constraints.mustMintValue val
    ledgerTx <- submitTxConstraintsWith @Void lookups tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
    logInfo @String $ printf "forged %s" (show val)

lock :: MintParams -> Contract w SignedSchema Text ()
lock mp =  do
-- make a recusive function that allows for the creation of a 1000 utxos of diffrent datums from a wallet (cheap if implemented correctly) 
        
    let v   = Value.singleton (policyID contractInfo) (nameOfToken contractInfo) (mpAmount mp) <> minADA
        txc =   foldl
                (\acc i -> acc <> (Constraints.mustPayToTheScript (i) $ v)
                (TxConstraints [] [] []))
                [1..1000]
                
    ledgerTx <- submitTx txc
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx

purchase :: () -> Contract w SignedSchema Text ()
purchase _ =  do
    utxos <- fundsAtAddressGeq valAddress (Ada.lovelaceValueOf 1)

    let redeemer = () 
        ppkh     = walletOwner contractInfo
        tx       = mustPayToPubKey (Add.PaymentPubKeyHash ppkh) price <> collectFromScript utxos redeemer
        
    void (submitTxConstraintsSpending lootBox utxos tx)

endpoints :: Contract () SignedSchema Text ()
endpoints = awaitPromise (mint' `select` lock' `select` purchase') >> endpoints
  where
    mint' = endpoint @"mint" mint
    lock' = endpoint @"lock" lock
    purchase' = endpoint @"purchase" purchase

mkSchemaDefinitions ''SignedSchema

mkKnownCurrencies []

**Tags:** plutus

---

## 2 answers

### Answer by username_2 on 2022-02-04. Score: 1 | Accepted answer

Do you mean something like this:
v = lovelaceValueOf 2_000_000
txc = foldl
      (\acc i -> acc <> (Constraints.mustPayToTheScript (YourDatum i) $ v))
      (TxConstraints [] [] [])
      [1..1000]

> **Comments:**
> **username_0**: Yes. also would that be considered recursion?  
> **username_2**: No, it is not using a recursive function. It just uses a fold -a very useful pattern.  
> **username_0**: ok I look into fold some more, thank you  
> **username_0**: So I tried out your method but it seems like the compliler dosent like the treatment of the TXContraints any ideas?  
> **username_2**: You probably need to correctly declare the types. If you add your code in the question I can edit my answer.  
> **username_0**: Ok I added it there error is in the lock endpoint function  
> **username_2**: There was a missing parenthesis in my code. I added it. You put it on the wrong line. Also there are many things missing in your lock-function. Start by making your code work for one UTxO and then use foldl to do it for 1000.  

---

### Answer by username_1 on 2022-02-04. Score: 0

Haskell allows you to loop (recursively). And since all off-chain codes (`mustPayTo...` included) are written in Haskell, it is be possible.


---

