<p>Hopefully I'm following your question...</p>
<p>I'm not aware of any type checks performed at validation, <strike>but I'm also not aware of any situation that a validator/script would need to spend resources preventing this.</strike></p>
<p>In other words, scripts generally operate under the assumption that proper off-chain code is being used in tandem with the on-chain script. The off-chain code <em>does</em> have type checks.</p>
<p>There is always the threat that a malicious actor will go around the expected off-chain code to abuse the script. The onus is on a script developer to write a script that checks for correct values--I am having a hard time thinking of a situation that someone giving the wrong type and that value being misinterpreted as the correct value.</p>
<hr />
<p>You give the example of a &quot;malicious actor [blocking the] spending [of] a script utxo by adding an invalid pubkey hash.&quot; I don't understand how this case is different from the malicious actor sending a random, un-owned pubkey. In both cases it would prevent the spending of the UTxO.</p>
<h2>EDIT:</h2>
<p>It sounds like at least in the case of PubKeyHash, which by default has no checks on bytestring length, it is possible to submit and validate against invalid pubkeys. Unfortunately, you can't just rely on type check :(.</p>
<p>It is the script writer's responsibility to understand this limitation and include protection for counterparties. For example:</p>
<ul>
<li>Force a redeemer to use the pubkey that matches the signer of the tx in the context. That way the pubkey always a pre-verified valid pubkey OR</li>
<li>Include additional intermediary datums that can hold funds in escrow for a (potentially invalid) recipient pubkey OR</li>
<li>Check the length of the bytestring to ensure it could be a valid pubkey</li>
</ul>
<p>Generally, while writing Plutus scripts you try to avoid over-constraining the logic. Since the PubKeyHash type problem isn't obvious, the above solutions might come across as overconstrained or overcomplicated to those outside the know. Documentation is warranted. Hopefully we can get better types for these things in the future to push devs and readers into a pit of success.</p>

CC BY-SA 4.0
2021-12-01T09:28:37.793Z
Person A makes a borrowing request/offer and locks his collateral in a script utxo. Person B comes along and accepts this offer. He gives person A the loan, destroys the old script utxo and creates a new one with the collateral and new datum, where he also specifies his receiving address (pubkey hash) for the payoff amount. But if the pubkey hash is not valid the validator will always fail and the collateral is locked forever in the utxo.

Only solution I have in mind is adding a required signer and compare the pubkey hash with the signer, but wanted to know if there is a more elegant way.
Alessandro Konrad
CC BY-SA 4.0
2021-12-01T22:01:04.490Z
K. I gotcha. In that case Person B would need to be a deranged actor, but since the loan is overcollateralized it could be a disproportionate loss for Person A. Worth preventing actively.
Mitchell Turner
CC BY-SA 4.0
2021-12-01T22:05:43.623Z
I'll point out, however, that the redemption of a datum does have type checks. The script needs to be run by the validator. It might be possible for Person A to create a "request/offer" datum with invalid values (according to my current understanding), but it wouldn't be possible for Person B to redeem that datum with invalid values, since the script couldn't possibly run.
Mitchell Turner
CC BY-SA 4.0
2021-12-02T10:27:01.750Z
Interesting, I'll try that out on testnet, since in the plutus simulator it seems not to be the case. Thanks for the response!
Alessandro Konrad
CC BY-SA 4.0
2021-12-02T14:25:48.653Z
Just tried it on the testnet. The types are not checked even if you redeem a script utxo and create a new one :(.
I was able to set the PubKeyHash to the ByteString "30".
Alessandro Konrad
CC BY-SA 4.0
2021-12-02T16:49:09.073Z
However I realized any bytestring combination, which is 28 bytes long is a valid pubkey hash. That is of course easy to verify.
Alessandro Konrad
CC BY-SA 4.0
2021-12-02T18:03:49.960Z
Oops. Yeah. I guess if the type is a Bytestring under the hood, that's type it's checking.
Mitchell Turner
CC BY-SA 4.0
2021-12-03T09:03:40.697Z
I'm also failing to understand the wrongdoings of party B. According to your scenario he could only block himself from receiving the collateral. There must be the party A counterpart to closing the contract that should not be impacted by actions of party B.
Don't ask party B to provide the pkh, it is available for you from inside the script via `ScriptContext{scriptContextTxInfo}`
andycandy
CC BY-SA 4.0
2021-12-03T18:29:29.847Z
Yep. That is an easy solution and I can think of other ways too. I think I mispoke for this situation. Generally, there isn't a need to write scripts in a way to prevent an actor from shooting themselves in the foot--they should just be incentivized to use the (ostensibly) safe off-chain code which will prevent error. This types problem is an exception since it can hurt counterparties.
Mitchell Turner
CC BY-SA 4.0
2021-12-01T02:58:14.867Z
2021-12-03T19:19:26.637Z
2021-12-03T19:19:26.637Z
Mitchell Turner
<p>You should be extra careful with data that is being provided to smart contracts by the user. You might prevent user errors by using data from the Context that is already provided to you inside the Plutus script.</p>
<p>From the discussion around answers I'm getting a feeling that the malicious actor is only able to &quot;break&quot; the logic in such a way that is unfavourable for him only.</p>
<p><code>ScriptContext{scriptContextTxInfo{txInfoSignatories}}</code> gives you access to the public key hashes, in this case Person B public key hash when he consumes initial utxo and is creating a new one.</p>

CC BY-SA 4.0
2021-12-03T09:28:24.623Z
2021-12-03T14:52:43.907Z
2021-12-03T14:52:43.907Z
andycandy
<p>Most types in Plutus are simply wrappers around BuiltinByteString. For instance the bytes in PubKeyHash are not serialized/deserialized to an actual pubkey hash and checked for correctness. So basically any bytestring can be inserted here. A malicious actor could easily block spending a script utxo by adding an invalid pubkey hash.
Is there a way to enforce this/let the validator check the pubkey hash for correctness?</p>

CC BY-SA 4.0
2021-12-01T02:59:52.283Z
Can you give me an example of a case that you'd care that someone created a UTxO that was unspendable? Anyone can send tokens to unowned addresses whenever they want--essentially burning them.
Mitchell Turner
<plutus><datum>
How can I enforce a datum type to be correct?
# How can I enforce a datum type to be correct?

(Asked by: username_0 on 2021-11-30)

Most types in Plutus are simply wrappers around BuiltinByteString. For instance the bytes in PubKeyHash are not serialized/deserialized to an actual pubkey hash and checked for correctness. So basically any bytestring can be inserted here. A malicious actor could easily block spending a script utxo by adding an invalid pubkey hash.
Is there a way to enforce this/let the validator check the pubkey hash for correctness?

**Tags:** plutus, datum
> **Comments:**
> **username_1**: Can you give me an example of a case that you'd care that someone created a UTxO that was unspendable? Anyone can send tokens to unowned addresses whenever they want--essentially burning them.  

---

## 2 answers

### Answer by username_1 on 2021-12-01. Score: 7 | Accepted answer

Hopefully I'm following your question...

I'm not aware of any type checks performed at validation, but I'm also not aware of any situation that a validator/script would need to spend resources preventing this.

In other words, scripts generally operate under the assumption that proper off-chain code is being used in tandem with the on-chain script. The off-chain code *does* have type checks.

There is always the threat that a malicious actor will go around the expected off-chain code to abuse the script. The onus is on a script developer to write a script that checks for correct values--I am having a hard time thinking of a situation that someone giving the wrong type and that value being misinterpreted as the correct value.

---

You give the example of a "malicious actor [blocking the] spending [of] a script utxo by adding an invalid pubkey hash." I don't understand how this case is different from the malicious actor sending a random, un-owned pubkey. In both cases it would prevent the spending of the UTxO.

## EDIT:

It sounds like at least in the case of PubKeyHash, which by default has no checks on bytestring length, it is possible to submit and validate against invalid pubkeys. Unfortunately, you can't just rely on type check :(.

It is the script writer's responsibility to understand this limitation and include protection for counterparties. For example:

* Force a redeemer to use the pubkey that matches the signer of the tx in the context. That way the pubkey always a pre-verified valid pubkey OR
* Include additional intermediary datums that can hold funds in escrow for a (potentially invalid) recipient pubkey OR
* Check the length of the bytestring to ensure it could be a valid pubkey

Generally, while writing Plutus scripts you try to avoid over-constraining the logic. Since the PubKeyHash type problem isn't obvious, the above solutions might come across as overconstrained or overcomplicated to those outside the know. Documentation is warranted. Hopefully we can get better types for these things in the future to push devs and readers into a pit of success.

> **Comments:**
> **username_0**: Person A makes a borrowing request/offer and locks his collateral in a script utxo. Person B comes along and accepts this offer. He gives person A the loan, destroys the old script utxo and creates a new one with the collateral and new datum, where he also specifies his receiving address (pubkey hash) for the payoff amount. But if the pubkey hash is not valid the validator will always fail and the collateral is locked forever in the utxo.  Only solution I have in mind is adding a required signer and compare the pubkey hash with the signer, but wanted to know if there is a more elegant way.  
> **username_1**: K. I gotcha. In that case Person B would need to be a deranged actor, but since the loan is overcollateralized it could be a disproportionate loss for Person A. Worth preventing actively.  
> **username_1**: I'll point out, however, that the redemption of a datum does have type checks. The script needs to be run by the validator. It might be possible for Person A to create a "request/offer" datum with invalid values (according to my current understanding), but it wouldn't be possible for Person B to redeem that datum with invalid values, since the script couldn't possibly run.  
> **username_0**: Interesting, I'll try that out on testnet, since in the plutus simulator it seems not to be the case. Thanks for the response!  
> **username_0**: Just tried it on the testnet. The types are not checked even if you redeem a script utxo and create a new one :(. I was able to set the PubKeyHash to the ByteString "30".  
> **username_0**: However I realized any bytestring combination, which is 28 bytes long is a valid pubkey hash. That is of course easy to verify.  
> **username_1**: Oops. Yeah. I guess if the type is a Bytestring under the hood, that's type it's checking.  
> **username_2**: I'm also failing to understand the wrongdoings of party B. According to your scenario he could only block himself from receiving the collateral. There must be the party A counterpart to closing the contract that should not be impacted by actions of party B. Don't ask party B to provide the pkh, it is available for you from inside the script via `ScriptContext{scriptContextTxInfo}`  
> **username_1**: Yep. That is an easy solution and I can think of other ways too. I think I mispoke for this situation. Generally, there isn't a need to write scripts in a way to prevent an actor from shooting themselves in the foot--they should just be incentivized to use the (ostensibly) safe off-chain code which will prevent error. This types problem is an exception since it can hurt counterparties.  

---

### Answer by username_2 on 2021-12-03. Score: 2

You should be extra careful with data that is being provided to smart contracts by the user. You might prevent user errors by using data from the Context that is already provided to you inside the Plutus script.

From the discussion around answers I'm getting a feeling that the malicious actor is only able to "break" the logic in such a way that is unfavourable for him only.

`ScriptContext{scriptContextTxInfo{txInfoSignatories}}` gives you access to the public key hashes, in this case Person B public key hash when he consumes initial utxo and is creating a new one.


---

