This is token distribution design pattern proof of concept named as Distro, where by interlinking spending
contract with minting
contract, we have achieved greater use case for smart contracts interaction inside transaction, mainly minting contract where minting contract can have access to Datum of input UTxO.
There are different approaches to make a concept called "Shared Validation" possible and shared validation means several contracts with their unique validation will create a set of validations and together will validate whole transaction. Here by using txInfoRedeemer
and "inline datum" we've achieve shared validation.
In the case of two smart contracts, spending contract name is Distro and the minting contract name is Regulator which both will validate minting of "HAPPY_TOKEN".
The scenarios of PoC is about two developers use these two contracts to mint their share of project tokenomic tokens in two different phases. So after deciding what their share are from the total amount of project tokenomic and when they are going to mint, they will put all those information into inline datum and attached it to the UTxO that is going to be send to Distro contract, so when the time of minting comes, Distro(spending
) will use input UTxO inline datum and redeemer of Regulator(minting
) contract to validate all the minting conditions and cases.
-
The Regulator smart contract aims to handle the following:
1.1. Minting genesis token, which will be sent to Distro contract with inline datum and specify how, when and who is able to mint "HAPPY_TOKEN".
- Genesis token roles is to proof authenticity of the UTXO that its inline datum is going to be used as reference for minting.
1.2. All the information that going to be inside inline datum will be contract parameter of Regulator contract as well, and inside contract, the validator will check all the fields of inline datum of output UTxO authenticity and integrity against those parameters.
1.3. Checks whether first or second developer has signed the transaction or not.
- Since there are different versions of same contract for educational purposes, in one version both Regulator and Distro are going to check developer address, but one at Regulator contract is enough in the scenario of this design pattern.
-
The Distro smart contract aims to handle the following:
2.1. By accessing to Regulator contract redeemer, handle different cases of developer claiming tokens on each phases.
2.3 By using information stored as inline datum of input UTxO that must holds genesis token, the contract will validate the minting process.
2.3 Update inline datum based on the action developer has taken.
- Checkout
plutus-apps
repo tov1.0.0
tag. - Run
cabal update
and thencabal repl
. - Call
writeScript
function to compile Distro contract. - load
Regulator.Compiler
then callwritScript
again to compile Regulator contract. - Take the script hash of Regulator contract from the output and substitute Happy token currency symbol variable value inside
Regulator.ToJSON
file. - load
Regulator.ToJSON
and callmain
function to create Datum and Redeemer files for Regulator. - load
Distro.ToJSON
and callmain
function to create Datum and Redeemer for Distro Contract.
In order to run the scenario:
-
Make all script inside
./utils/scripts
folder executable. -
Create
wallets
folder insideutils
folder and add or createprotocol.json
file inside of it.$ cd ./utils; mkdir wallets; cd ./wallets $ cardano-cli query protocol-parameters --testnet-magic 1 --out-file protocol.json
-
Create following wallets folders inside
wallets
folder and use the folder name as wallet name. RuncreateWallet.sh
script and then fund... .TestnetDelegation.add
address of wallets. 2.1collateral
which will be used for collateral inside transactions. 2.2contract_reference
which will be used for contract reference UTxO for both Distro and Regulator contracts. 2.3first_dev
which will be used as First developer wallet to mint Happy token. 2.4second_dev
which will be used as Second developer wallet to mint Happy token. 2.5debugger
which will be used for debugging purpose. -
Change values of variables inside both
Regulator.ToJSON
andDistro.ToJSON
based on the wallets info, time/date of minting and the amount each developer will mint. -
After contracts compilation, and creating Datum and redeemer check
env.conf
file insidescripts
folder, environment variable and set them based on your system and environment configuration. -
Run
createDistroContractRefUTxO.sh
to create Distro contract reference script UTxO. -
Wait for awhile and then run
createRegulatorContractRefUTxO.sh
to create Regulator reference script UTxO. -
Run
genesisMint.sh
to mint genesis token and sending it with the inline datum that is going to be used as reference for minting phases. -
Run
firstDevClaimAtPhaseOne.sh
at the time of phase one. -
Based on the time you have set for the scenario phase two, run
firstDevClaimAtPhaseTwo.sh
, The script can run without running the first phase script and it will mint total phases at once.
This PoC was done in both Typed and Untyped validation for demonstrating different cost and issues of executing this design pattern, but with correct optimization and compilation, this PoC is effective and possible to implement within a Dapp.
Beside the usage described already, an NFT project can use this PoC and design pattern to allow its users mint NFT safely and secure without the need for the project minting those by themselves and then sending them to users. The minting process would be an internal transfer, therefore fee and cost for minting will be reduced.
Gimbalabs, Ekival, James, Genty, Adrian