Can a contract make a call to a predicate?

Can a contract make a call to a predicate ?

2 Likes

what do you mean that

I want to build an orderbook DEX, I was thinking about having users submit their orders through predicates and then use a smart contract to match those predicates and fulfill the order. Would something like that be possible ?

A prototype for what you’re describing can be found here. I recommend studying the readme to get a better idea of what predicates are and how they can be used.

A predicate cannot be called by a contract because it is evaluated as part of the input set validation, which occurs prior to script execution. For this reason, predicates are pure and cannot read or modify contract state.

1 Like

In my case I want to match 2 predicates, so the transaction is only valid if they both fulfill the request. I don’t want to call a contract from a predicate, I want to call a predicate from a contract. The contract would make a call to a predicate with the trade parameters if it evaluated to true it would then transfer the funds from the predicate to the contract, it would then call the second predicate if it also evaluated to true it would transfer the funds from the predicate to the contract. Finally the contract would transfer the funds to the respective addresses.

This isn’t quite how predicates work . They are evaluated prior to script execution. If they evaluate true, their coins are available as “free balance” for the script to use, with unused balances available to be returned as change.

As a reminder, all transactions are either contractCreate (deployments) or scripts. Under the hood, what the SDK presents as contract calls (and the concept of contract calls as you may be familiar with them from Ethereum) are actually wrapped in a script that makes the call.

The trick is that a predicate can inspect the transaction (including the input / output set, and the script). This gives you some flexibility: you can encode the spending conditions in the predicate directly, or you can encode them in the script, with the predicate simply enforcing the bytecode of the script.

2 Likes

Ok thank you that makes it a lot clearer. So in the predicate I can inspect the bytecode of the script that executes the transaction, is that right ?

That’s correct. The standard library has some functions to assist with this under std::tx. A useful pattern is to hardcode the expected hash of the script in the predicate, and then read and hash the script to check correctness.

All right, I think I’ve found it that’s a really awesome feature. Thank you for the help.

1 Like

Is there any example of how to spend a predicate inside a script ?

Any coins belonging to the predicate can be spent (transferred, forwarded with calls etc.) in the script.

The SDK currently supports simple spending of a predicate’s coins.

However, if you want to execute a custom script (one that you write yourself, that makes various calls, etc.) that spends the predicate’s coins, you’ll need proceed as you would for any other script, but add the predicate to the input set of the transaction manually. This isn’t very well documented currently but the method needed for this can be found here.

We’re working on a way to make this more intuitive in the SDK.

1 Like