CIP Draft - Multi-Script Hashes

Multi-Script Hashes

Abstract

This is a (draft) CIP to introduce a simple way to statically identify a
collection of scripts that depend on each other, so that each script can
detect if a transaction tries to substitute an outside script address for an
expected one.

Motivation

Most non-trivial DApps will be distributed not only in the usual sense, but
will also have their on-chain logic spread across multiple validator
scripts. Some types of transactions will then be expected to consume and
create UTxOs belonging to different scripts.

To take an abstracted example, consider a DApp with only two validators
scripts, S₁ and S₂. There are transactions T₁ that deal only with the
first validator script, transactions T₂ that deal only with the second, and
transactions T₁₂ that involve both. A T₁₂ might for example simply move
some funds from the first script to the second. The question is, how can the
S₁ ensure that the recipient is in fact S₂?

The simplest solution is that we first compile S₂, then supply its
ValidatorHash or its Address as a parameter to S₁, which can trivially
compare it to the recipient’s address.

If, however, there is also a valid transaction T₂₁ that moves funds from
S₂ to S₁, we can’t apply the same solution: there is currently no way to
resolve a mutual dependency between scripts.

There are workarounds to guard against the substitution. We can mint a limited
amount of a token, for example, supply its CurrencySymbol as a parameter to
all scripts, and then ensure that every UTxO locked by any script in our DApp
carries one of these tokens as an identification badge. This however
introduces unnecessary complexity and increases all transaction costs. It
would be better to solve the root issue of mutual dependency.

Specification

The minimum required functionality can be provided with just two additional
functions in Plutus API, and a new field in TxInfo:

validatorHashes :: [Validator] -> [ValidatorHash]
allScripts :: [Validator] -> ScriptLookups Any
txInfoValidators :: TxInfo -> [ValidatorHash]

The new validatorHashes function is a generalization of the existing

validatorHash :: Validator -> ValidatorHash

The new function would hash the entire list of validators, together with
[1..n] for each result hash. The length of the result list would equal the
length of the argument, and the value of every single ValidatorHash result
list item would depend on every Validator item in the argument list. In
other words, a change to any single Validator would affect every
ValidatorHash.

The same explanation applies to the new allScripts function, which is a
generalization of the existing

otherScript :: Validator -> ScriptLookups Any

The [ValidatorHash] list calculated by allScripts would be made available
as the txInfoValidators accessor so each validator triggered by the
transation could check it against the addresses of transaction’s UTxOs.

Furthermore, if allScripts is invoked with argument vs, every TxOut
consumed by the transaction must satisfy all (`elem` validatorHashes vs) . toValidatorHash . txOutAddress. The transaction otherwise fails in phase 1
of validation.

Rationale

Assume the off-chain portion of our example DApp consistently specifies the
allScripts [S₁, S₂] lookup with every transaction and that both validators
use txInfoValidators to verify both the ownInput address and the
destinations of both T₁₂ and T₂₁. If an attacker attempts to submit a
transaction substituting a third address S₃, the validators would reject
it. Adding otherScript S₃ or allScripts [S₁, S₃] as a lookup would not
work: the former would not populate txInfoValidators and the latter would
provide the wrong address for S₁.

Backwards Compatibility

The addition of two new functions validatorHashes and allScripts would be
a backward-compatible extension of the API. The addition of txInfoValidators
is more problematic. Perhaps it can be done without a hard fork, but I’m not
sure.

Copyright

Apache-2.0

3 Likes

welcome @blamario to the Forum! If there isn’t a resounding response here remember there’s generally more response to technically oriented CIPs as submitted by PR on Github. So if some time goes by and you don’t hear anything here, please feel welcome to post your PR. :nerd_face:

When you do, please remember the CIP markdown text is copied & repurposed into other forms, and will flow better when the hard line breaks are removed :star_struck:

1 Like