<p>On casual search I think what you need is Ledger.TxConstraint:</p>
<p><a href="https://playground.plutus.iohkdev.io/doc/haddock/plutus-ledger-constraints/html/src/Ledger.Constraints.TxConstraints.html" rel="nofollow noreferrer">https://playground.plutus.iohkdev.io/doc/haddock/plutus-ledger-constraints/html/src/Ledger.Constraints.TxConstraints.html</a></p>

CC BY-SA 4.0
2022-01-24T09:28:20.757Z
2022-01-24T09:28:20.757Z
d_fajardo
<blockquote>
<p>on endpoint call sends 1 to the caller and then the rest back to the contract</p>
</blockquote>
<p>Remember, the on-chain portion of a contract doesn't do anything actively, it only validates transactions. So a more accurate way to phrase this would be, &quot;the script only validates transactions that spend 1 ADA and return the rest to the script.&quot;</p>
<p>I think everything you need to write a validator you could find in the <a href="https://github.com/input-output-hk/plutus-pioneer-program/blob/8cbc68d146c82cc95d9be44c30e049aba3774003/code/week01/src/Week01/EnglishAuction.hs#L103" rel="nofollow noreferrer">auction code</a>. Notice that it stores the current bid amount in the datum and that datum is attached to the actual UTxO with the value.</p>
<pre><code>    ownOutput   :: TxOut
    outputDatum :: AuctionDatum
    (ownOutput, outputDatum) = case getContinuingOutputs ctx of
        [o] -&gt; case txOutDatumHash o of
            Nothing   -&gt; traceError &quot;wrong output type&quot;
            Just h -&gt; case findDatum h info of
                Nothing        -&gt; traceError &quot;datum not found&quot;
                Just (Datum d) -&gt;  case PlutusTx.fromData d of
                    Just ad' -&gt; (o, ad')
                    Nothing  -&gt; traceError &quot;error decoding data&quot;
        _   -&gt; traceError &quot;expected exactly one continuing output&quot;

    correctBidOutputDatum :: Bid -&gt; Bool
    correctBidOutputDatum b = (adAuction outputDatum == auction)   &amp;&amp;
                              (adHighestBid outputDatum == Just b)

    correctBidOutputValue :: Integer -&gt; Bool
    correctBidOutputValue amount =
        txOutValue ownOutput == tokenValue Plutus.&lt;&gt; Ada.lovelaceValueOf amount
</code></pre>
<p>If instead of the <code>close</code> endpoint, you have a <code>take distributions</code> endpoint, you could just do a similar check that the datum was updated and the value wasn't decremented by more than 1.</p>
<p>At that point, it is up to the caller to build a transaction in their own benefit. Again, the off-chain code in the above auction example could be adapted to build a transaction to claim distributions.</p>

CC BY-SA 4.0
2022-01-25T02:07:36.650Z
Thanks ill try this method
Floof99
CC BY-SA 4.0
2022-02-01T19:14:51.047Z
Did you have any luck?
Mitchell Turner
CC BY-SA 4.0
2022-02-02T22:48:42.430Z
yes I think I understand it better now thank you
Floof99
CC BY-SA 4.0
2022-01-24T19:36:33.307Z
2022-01-24T19:36:33.307Z
Mitchell Turner
<p>I am trying to make a Plutus smart contract which takes tokens locked to the contract and then on endpoint call (purchase) sends 1 to the caller and then the rest back to the contract. I cant find a distribution model for this I would assume you would have to create a new utxo out of the existing utxo and reduce it down into a single token on the script but I am very lost with this process.</p>
<p>I need help figuring this out so that I can create this send 1 token out of many script. A specific answer is what I'm looking for.</p>
<p>This is the code relevant to the problem, but it currently does not work.</p>
<pre><code>purchaseUtxo :: ChainIndexTxOut
purchaseUtxo = case fromTxOut (scriptTxOut (Value.singleton (policyID contractInfo) (nameOfToken contractInfo) (1)) validate (Datum $ PlutusTx.toBuiltinData ()) )  of
    Nothing     -&gt;  error ()
    Just x      -&gt;  x

purchase ::  AsContractError e =&gt; PurchaseParams -&gt; Contract w s e ()
purchase p=  do
    utxos &lt;- fundsAtAddressGeq valAddress (Ada.lovelaceValueOf 1)
    let utxoMap = Map.singleton (TxOutRef (_citxTxId ChainIndexTx) 1) purchaseUtxo
        redeemer = ()
        pkh = ownPubKey
        tx       = Constraints.mustPayToTheScript () price &lt;&gt; collectFromScript utxoMap redeemer
        
    void (submitTxConstraintsSpending lootBox utxos tx)
</code></pre>
<p>And here is the error:</p>
<blockquote>
<p>Compilation Error, Line 148, Column 54 (jump)<br>
<br>
error:<br>
• Couldn't match expected type ‘ChainIndexTx’<br>
with actual type ‘TxId<br>
-&gt; Data.Set.Internal.Set TxIn<br>
-&gt; ChainIndexTxOutputs<br>
-&gt; SlotRange<br>
-&gt; Map DatumHash Datum<br>
-&gt; Map RedeemerHash Redeemer<br>
-&gt; Map ScriptHash Script<br>
-&gt; Maybe SomeCardanoApiTx<br>
-&gt; ChainIndexTx’<br>
• Probable cause: ‘ChainIndexTx’ is applied to too few arguments<br>
In the first argument of ‘_citxTxId’, namely ‘ChainIndexTx’<br>
In the first argument of ‘TxOutRef’, namely<br>
‘(_citxTxId ChainIndexTx)’<br>
In the first argument of ‘Map.singleton’, namely<br>
‘(TxOutRef (_citxTxId ChainIndexTx) 1)’<br>
| 148 |     let utxoMap = Map.singleton (TxOutRef (_citxTxId ChainIndexTx) 1) purchaseUtxo<br>
|                                                      ^^^^^^^^^^^^</p>
</blockquote>

<plutus><smart-contract><plutus-playground><token>
What documentation works with handling utxos at the Plutus Script?
# What documentation works with handling utxos at the Plutus Script?

(Asked by: username_0 on 2022-01-23)

I am trying to make a Plutus smart contract which takes tokens locked to the contract and then on endpoint call (purchase) sends 1 to the caller and then the rest back to the contract. I cant find a distribution model for this I would assume you would have to create a new utxo out of the existing utxo and reduce it down into a single token on the script but I am very lost with this process.
I need help figuring this out so that I can create this send 1 token out of many script. A specific answer is what I'm looking for.
This is the code relevant to the problem, but it currently does not work.
purchaseUtxo :: ChainIndexTxOut
purchaseUtxo = case fromTxOut (scriptTxOut (Value.singleton (policyID contractInfo) (nameOfToken contractInfo) (1)) validate (Datum $ PlutusTx.toBuiltinData ()) )  of
    Nothing     ->  error ()
    Just x      ->  x

purchase ::  AsContractError e => PurchaseParams -> Contract w s e ()
purchase p=  do
    utxos <- fundsAtAddressGeq valAddress (Ada.lovelaceValueOf 1)
    let utxoMap = Map.singleton (TxOutRef (_citxTxId ChainIndexTx) 1) purchaseUtxo
        redeemer = ()
        pkh = ownPubKey
        tx       = Constraints.mustPayToTheScript () price <> collectFromScript utxoMap redeemer
        
    void (submitTxConstraintsSpending lootBox utxos tx)

And here is the error:

Compilation Error, Line 148, Column 54 (jump)

error:
• Couldn't match expected type ‘ChainIndexTx’
with actual type ‘TxId
-> Data.Set.Internal.Set TxIn
-> ChainIndexTxOutputs
-> SlotRange
-> Map DatumHash Datum
-> Map RedeemerHash Redeemer
-> Map ScriptHash Script
-> Maybe SomeCardanoApiTx
-> ChainIndexTx’
• Probable cause: ‘ChainIndexTx’ is applied to too few arguments
In the first argument of ‘_citxTxId’, namely ‘ChainIndexTx’
In the first argument of ‘TxOutRef’, namely
‘(_citxTxId ChainIndexTx)’
In the first argument of ‘Map.singleton’, namely
‘(TxOutRef (_citxTxId ChainIndexTx) 1)’
| 148 |     let utxoMap = Map.singleton (TxOutRef (_citxTxId ChainIndexTx) 1) purchaseUtxo
|                                                      ^^^^^^^^^^^^

**Tags:** plutus, smart-contract, plutus-playground, token

---

## 2 answers

### Answer by username_2 on 2022-01-24. Score: 2 | Accepted answer

on endpoint call sends 1 to the caller and then the rest back to the contract

Remember, the on-chain portion of a contract doesn't do anything actively, it only validates transactions. So a more accurate way to phrase this would be, "the script only validates transactions that spend 1 ADA and return the rest to the script."
I think everything you need to write a validator you could find in the auction code. Notice that it stores the current bid amount in the datum and that datum is attached to the actual UTxO with the value.
    ownOutput   :: TxOut
    outputDatum :: AuctionDatum
    (ownOutput, outputDatum) = case getContinuingOutputs ctx of
        [o] -> case txOutDatumHash o of
            Nothing   -> traceError "wrong output type"
            Just h -> case findDatum h info of
                Nothing        -> traceError "datum not found"
                Just (Datum d) ->  case PlutusTx.fromData d of
                    Just ad' -> (o, ad')
                    Nothing  -> traceError "error decoding data"
        _   -> traceError "expected exactly one continuing output"

    correctBidOutputDatum :: Bid -> Bool
    correctBidOutputDatum b = (adAuction outputDatum == auction)   &&
                              (adHighestBid outputDatum == Just b)

    correctBidOutputValue :: Integer -> Bool
    correctBidOutputValue amount =
        txOutValue ownOutput == tokenValue Plutus.<> Ada.lovelaceValueOf amount

If instead of the close endpoint, you have a take distributions endpoint, you could just do a similar check that the datum was updated and the value wasn't decremented by more than 1.
At that point, it is up to the caller to build a transaction in their own benefit. Again, the off-chain code in the above auction example could be adapted to build a transaction to claim distributions.

> **Comments:**
> **username_0**: Thanks ill try this method  
> **username_2**: Did you have any luck?  
> **username_0**: yes I think I understand it better now thank you  

---

### Answer by username_1 on 2022-01-24. Score: 1

On casual search I think what you need is Ledger.TxConstraint:

<https://playground.plutus.iohkdev.io/doc/haddock/plutus-ledger-constraints/html/src/Ledger.Constraints.TxConstraints.html>


---

