Withdrawing funds from a smart contract is quite similar to depositing funds. In this case however we are going to be using the function collectFromScript
. In regards to inputs, it takes:
You may have noticed that this takes less inputs than payToScript_
, and this is because it attempts to collect all ada from the smart contract. The first input is the ValidatorScript itself (not the address like in the last section) and a RedeemerScript. A RedeemerScript is very much so like a DataScript where it is any kind of data which is relevant to the smart contract at hand. Of course the type of data will have to be specified at some point, but it enables an infinite number of possibilities of types of input.
Now let’s write out the type signature of our withdrawal function.
1 | withdrawADA :: MockWallet () |
Simple enough, right? This isn’t anything we haven’t seen before. withdrawADA
is simply a function that causes some sort of Wallet action. Now for the definition.
1 | withdrawADA = collectFromScript myFirstValidator unitRedeemer |
As you can see the RedeemerScript is provided to our collectFromScript
call as unitRedeemer
. Just like unitData
is the default empty DataScript, unitRedeemer
is the default empty RedeemerScript. With this function our wallet will send the RedeemerScript to the smart contract and if it validates/doesn’t run into any errors, then our wallet will collect all of the ada from the smart contract. Since we have an empty ValidatorScript there is no logic that will be processed on the collectFromScript
call, and thus all withdrawals will be allowed (for the time being).
Finally we need to make the Plutus Playground aware once more of our new function.
1 | $(mkFunction 'withdrawADA) |
And we have now completed adding the ability to withdraw ada from the smart contract.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | module MyFirstPlutusSmartContract where import qualified Language.PlutusTx as PlutusTx import Ledger import Wallet import Playground.Contract myFirstValidator :: ValidatorScript myFirstValidator = ValidatorScript (fromCompiledCode $$(PlutusTx.compile [|| \(a :: ()) (b :: ()) (c :: ()) -> () ||])) smartContractAddress :: Address' smartContractAddress = scriptAddress myFirstValidator watchSmartContract :: MockWallet () watchSmartContract = startWatching smartContractAddress depositADA :: Value -> MockWallet () depositADA val = payToScript_ smartContractAddress val unitData withdrawADA :: MockWallet () withdrawADA = collectFromScript myFirstValidator unitRedeemer $(mkFunction 'watchSmartContract) $(mkFunction 'depositADA) $(mkFunction 'withdrawADA) |
Compile this code yourself in the Plutus Playground and try testing depositing and withdrawing ada. Remember, you need to call watchSmartContract
first in the Action Sequence for each wallet you wish to keep track of the state of the smart contract.
In our next section, we will cover how to create our very first DataScript.