CashScript / cashscript

⚖️ Easily write and interact with Bitcoin Cash smart contracts
https://cashscript.org
MIT License
115 stars 80 forks source link

mandatory-script-verify-flag-failed (Push value size limit exceeded) (code 16) #70

Closed nyusternie closed 4 years ago

nyusternie commented 4 years ago

I've been working with the hodl_vault.cash contract; but when trying to increase the length of the signed message from 8 bytes to 12 bytes, I keep coming across this error.

Here are the splits that I'm attempting to perform:

int oracleBlockHeight = int(oracleMsg.split(4)[0]);
int oraclePledgeAmt = int(oracleMsg.split(4)[1].split(4)[0]);
int oraclePayoutAmt = int(oracleMsg.split(8)[1]);

(I've refactored the above as many ways as I could, but NONE will remove the error)

I have a few questions about split, first and foremost, do the tuples have to be of equal byte length? if so, then obviously, this won't work .. also, is it possible to chain multiple splits (I believe I saw that somewhere in the docs) or should I perform separate actions?

thanks!

nyusternie commented 4 years ago

after some heavy refactoring, I'm able to answer these questions:

do the tuples have to be of equal byte length

no they don't, as int oraclePayoutAmt = int(oracleMsg.split(8)[1]); is now working from a 12 byte message.

is it possible to chain multiple splits

yes, as int oraclePledgeAmt = int(oracleMsg.split(4)[1].split(4)[0]); is now working as well


fwiw, I'd really still like to know what Push value size limit exceeded means .. the refactoring that was done has actually simplified the contract, so I'm very happy with the results .. However, I pretty sure the pre-refactored code was "valid", so I'm not sure what "fixed" the issue and I'd hate run into this error again in future contracts..

thanks again!

rkalis commented 4 years ago

So "push value size limit exceeded" means that the script tried to push a single script element over the limit of 520 bytes. This is likel either the script itself (for the sake of hashing the script for P2SH) or it is the preimage (which is the size of the script + ~150 extra bytes).

You can run cashc path/to/contract.cash -cs to quickly see the opcount and the byte size of your contract. Your opcount should always stay below 201, while the bytesize should stay below 520 (minus 150 if you're using covenants, and minus the size of any constructor parameters, since these get added to the script as well).

nyusternie commented 4 years ago

bytesize should stay below 520 (minus 150 if you're using covenants, and minus the size of any constructor parameters, since these get added to the script as well)

yeah, it was definitely the constructor parameters, since that was the refactoring that I did .. didn't realize that they were counted in the 520 .. thanks for clearing that up 👍