* Verify a witness program. This runs after regular script * execution if a witness program is present. It will convert * the witness to a stack and execute the program. * @param {Witness} witness * @param {Script} output * @param {VerifyFlags} flags * @param {TX} tx * @param {N
(witness, output, flags, tx, index, value)
| 3203 | */ |
| 3204 | |
| 3205 | static verifyProgram(witness, output, flags, tx, index, value) { |
| 3206 | const program = output.getProgram(); |
| 3207 | |
| 3208 | assert(program, 'verifyProgram called on non-witness-program.'); |
| 3209 | assert((flags & Script.flags.VERIFY_WITNESS) !== 0); |
| 3210 | |
| 3211 | const stack = witness.toStack(); |
| 3212 | let redeem; |
| 3213 | |
| 3214 | if (program.version === 0) { |
| 3215 | if (program.data.length === 32) { |
| 3216 | if (stack.length === 0) |
| 3217 | throw new ScriptError('WITNESS_PROGRAM_WITNESS_EMPTY'); |
| 3218 | |
| 3219 | const witnessScript = stack.pop(); |
| 3220 | |
| 3221 | if (!sha256.digest(witnessScript).equals(program.data)) |
| 3222 | throw new ScriptError('WITNESS_PROGRAM_MISMATCH'); |
| 3223 | |
| 3224 | redeem = Script.fromRaw(witnessScript); |
| 3225 | } else if (program.data.length === 20) { |
| 3226 | if (stack.length !== 2) |
| 3227 | throw new ScriptError('WITNESS_PROGRAM_MISMATCH'); |
| 3228 | |
| 3229 | redeem = Script.fromPubkeyhash(program.data); |
| 3230 | } else { |
| 3231 | // Failure on version=0 (bad program data length). |
| 3232 | throw new ScriptError('WITNESS_PROGRAM_WRONG_LENGTH'); |
| 3233 | } |
| 3234 | } else { |
| 3235 | // Anyone can spend (we can return true here |
| 3236 | // if we want to always relay these transactions). |
| 3237 | // Otherwise, if we want to act like an "old" |
| 3238 | // implementation and only accept them in blocks, |
| 3239 | // we can use the regular output script which will |
| 3240 | // succeed in a block, but fail in the mempool |
| 3241 | // due to VERIFY_CLEANSTACK. |
| 3242 | if (flags & Script.flags.VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) |
| 3243 | throw new ScriptError('DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM'); |
| 3244 | return; |
| 3245 | } |
| 3246 | |
| 3247 | // Witnesses still have push limits. |
| 3248 | for (let j = 0; j < stack.length; j++) { |
| 3249 | if (stack.get(j).length > consensus.MAX_SCRIPT_PUSH) |
| 3250 | throw new ScriptError('PUSH_SIZE'); |
| 3251 | } |
| 3252 | |
| 3253 | // Verify the redeem script. |
| 3254 | redeem.execute(stack, flags, tx, index, value, 1); |
| 3255 | |
| 3256 | // Verify the stack values. |
| 3257 | if (stack.length !== 1) |
| 3258 | throw new ScriptError('CLEANSTACK'); |
| 3259 | |
| 3260 | if (!stack.getBool(-1)) |
| 3261 | throw new ScriptError('EVAL_FALSE'); |
| 3262 | } |
no test coverage detected