Working with Predicates
This guide builds on the Creating a Fuel dApp guide. Once you've gotten the dApp there up and running, then you can continue here via clicking the Predicate Example link. We will modify the predicate we created in the previous guide. The final result will look like this:
You can also check it live, deployed to the Testnet:
Adding a Configurable pin
The current predicate functionality we have is a simple one that checks if the user has a pin. We will modify this predicate to accept a configurable pin. This will allow the user to set their own pin.
- Modifying the Predicate Contract
The first step is to modify the predicate contract to accept a configurable pin. We will use the configurable
keyword to create an updatable constant to store the pin. We will also modify the main function to check this constant instead of a hardcoded pin.
predicate;
configurable {
PIN: u64 = 1337,
}
fn main(pin: u64) -> bool {
return PIN == pin;
}
- Modifying the Frontend
We will now add new button to the frontend that will update the pin
in the predicate when clicked. To do this, we will modify the ./src/pages/predicate.tsx
file.
We will add a function called changePin
, which will use the current pin in state to update the pin in the predicate as well as transfer 1000 to the predicate.
const changePin = async () => {
if (!wallet) {
return toast.error("Wallet not loaded");
}
if (!predicate) {
return toast.error("Predicate not loaded");
}
if (walletBalance?.eq(0)) {
return toast.error(
<span>Your wallet does not have enough funds. Please top it up using the <Link href={FAUCET_LINK} target="_blank">faucet.</Link></span>
);
}
if (!pin) {
return toast.error("Please enter a pin");
}
const configurableConstants = { PIN: bn(pin) };
// instantiate predicate with configurable constants
const reInitializePredicate = new TestPredicate({
provider: wallet.provider,
data: [configurableConstants.PIN],
configurableConstants,
});
if (!reInitializePredicate) {
return toast.error("Failed to initialize predicate");
}
// transferring funds to the predicate
const tx = await wallet.transfer(reInitializePredicate.address, 1000, baseAssetId, {
gasLimit: 10_000,
});
const { isStatusSuccess } = await tx.wait();
if (!isStatusSuccess) {
toast.error("Failed to update pin in predicate");
return;
}
if (isStatusSuccess) {
toast.success("Predicate pin updated");
}
await refreshWalletBalance?.();
};
It would also be useful to change the placeholder text to say "Enter a new pin" instead of "Hint - the correct pin is 1337".
<Input
className="w-[300px] mt-8"
value={pin as string}
onChange={(e) => setPin(e.target.value)}
placeholder="Enter a new pin"
/>
Finally, we will add a button that calls the changePin
function when clicked.
<Button onClick={changePin}>Change Pin</Button>
Congratulations! That's all. You should now be able to see the modified predicate dApp running at http://localhost:3000
with our newly added change pin functionality.
You can find the complete source code of the dApp we built here.
Next Steps
Now that you have a predicate dApp running and have the
npm create fuels
workflow powering you, you can start building more complex dApps using the Fuel Stack. A good place to start for ideas and reference code is the Sway Applications Repo.If you have any questions or need help, feel free to reach out to us on the Official Fuel Forum.
If you want to learn more about the Fuel Stack, check out the Fuel Docs.