Skip to content

Generic evals implementation details (outdated)

dimxy edited this page Apr 7, 2022 · 1 revision

Generic Evals implementation details

Generic evals are a set of reusable eval conditions allowing to define spending rules inside eval params in the corresponding conditions. The idea of generic evals is to define new conditions inside cc transactions, without modifying the chain codebase.
Below there are generic eval descriptions.

Eval 'must_pay_CC'

Eval 'must_pay_CC' provides that the spending tx has a cc output satisfying this eval rules.
Params:

  • 'condition' (mandatory) - condition in json which must exist in one of the spending transaction's outputs. There is a special keyword 'self' meaning the condition in the current being spent output
  • 'validate' (optional) - a simple validation expression that defines some rules on the output. Expressions are defined on several preloaded variables:

    NEXT_TX - the spending tx. It has nested properties like 'vin' and 'vout' arrays which in turn have properties (like the codebase transaction object has)
    THIS_OUTPUT - the current output where this cryptocondition resides, it is a structure with 'nValue' and 'scriptPubKey' properties
    NEXT_OUTPUT - an output in the spending tx which is currently validated, it is also a structure with 'nValue' and 'scriptPubKey' properties
    It is possible to cross-refer preloaded variables of other subconditions in a 'validate' expression, by a path according to the json pointer standard (see the EvalAsk example)

Eval 'must_pay_p2pk'

Eval 'must_pay_p2pk' provides that the spending tx must have a normal P2PK output satisfying this eval rules.
Params:

  • 'pubkey' (mandatory) - pubkey which must be in the spending tx P2PK output
  • 'validate' (optional) - a simple validation expression that defines rules on the P2PK output. For example it allows to check the amount in the next output

Examples

Example of EvalAsk cc implemented with generic evalcodes
EvalAsk cc allows to lock tokens on a 2of2 condition, one of which is token and another one is itself 2of2 condition defining two generic eval subconditions to swap coins for tokens:

  • the first must_pay_CC condition provides that some token amount is spent (THIS_OUTPUT.nValue > NEXT_OUTPUT.nValue) and the spending tx has an output with the same EvalAsk cryptocondition (this is to recreate the partially spent ask)
  • the second must_pay_p2pk condition provides that my pubkey (a pk in vin[0]) must receive coins of multiply of the spent tokens by the token price (the price is set to 500000000 in the validation expression)
 {
   type: threshold,
   threshold: 2, 
   subfulfillments: [
     { type: eval, code: EvalTokens }, 
     { type: threshold, 
       threshold: 2,
       subfulfillments: [
         { type: eval, code: 'must_pay_CC', condition: 'self', 
           validate : 'THIS_OUTPUT.nValue > NEXT_OUTPUT.nValue' },
         { type: eval, code: 'must_pay_p2pk', 
           validate: 'THIS_OUTPUT.nValue == #/subfulfillments/2/subfulfillments/1/NEXT_OUTPUT.nValue * 500000000 && THIS_OUTPUT.scriptPubKey.pubkey == THIS_TX.vin[0].scriptPubKey.pubkey' }
       ] 
     }
   ]
 }

How to implement this

We need:

  • modify lib cryptoconditions:
    add two new evals 'must_pay_p2pk' and 'must_pay_CC' added as new condition types
    with params defined. Those params must be added to fingerprinting so the params cannot be changed from a tx to another tx
  • implement a simple expression language with several operations defined on the preloaded variables.
    The generic eval is validated as true if the expression in the 'validate' param evaluates as 'true'. If it evaluates as 'false' or encounters an error the generic condition is considered are false.
Clone this wiki locally