public void SetToMultiSig_ArgumentExceptionTest(Signature sig, IRedeemScript rdm, ITransaction tx, int index, string expErr) { var scr = new SignatureScript(); Exception ex = Assert.Throws <ArgumentException>(() => scr.SetToMultiSig(sig, rdm, tx, index)); Assert.Contains(expErr, ex.Message); }
public void SetToMultiSigTest(byte[] scrData, Signature sig, IRedeemScript rdm, ITransaction tx, int index, byte[] expected) { var scr = new SignatureScript(scrData); scr.SetToMultiSig(sig, rdm, tx, index); Assert.Equal(expected, scr.Data); }
/// <inheritdoc/> /// <exception cref="ArgumentException"/> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentOutOfRangeException"/> public void SetToMultiSig(Signature sig, IRedeemScript redeem, ITransaction tx, int inputIndex) { if (sig is null) { throw new ArgumentNullException(nameof(sig), "Signature can not be null."); } if (redeem is null) { throw new ArgumentNullException(nameof(redeem), "Redeem script can not be null."); } if (tx is null) { throw new ArgumentNullException(nameof(tx), "Transaction can not be null."); } if (inputIndex < 0 || inputIndex >= tx.TxInList.Length) { throw new ArgumentOutOfRangeException(nameof(inputIndex), "Invalid input index."); } if (redeem.Data.Length > Constants.MaxScriptItemLength) { throw new ArgumentOutOfRangeException(nameof(redeem), "Redeem script is bigger than allowed length."); } if (redeem.GetRedeemScriptType() != RedeemScriptType.MultiSig) { throw new ArgumentException("Invalid redeem script type."); } if (!redeem.TryEvaluate(out IOperation[] rdmOps, out _, out string error)) { throw new ArgumentException($"Can not evaluate redeem script: {error}"); } // OP_m | pub1 | pub2 | ... | pub(n) | OP_n | OP_CheckMultiSig if (!((PushDataOp)rdmOps[0]).TryGetNumber(out long m, out error)) { throw new ArgumentException($"Invalid m ({error})."); } if (m < 0) { throw new ArgumentOutOfRangeException(nameof(m), "M can not be negative."); } if (m == 0) { throw new ArgumentOutOfRangeException(nameof(m), "M value zero is not allowed to prevent funds being stolen."); } if (!((PushDataOp)rdmOps[^ 2]).TryGetNumber(out long n, out error))
public virtual void SetToP2SH_P2WSH(IRedeemScript redeem) => throw new NotImplementedException();
public virtual void SetToMultiSig(Signature sig, IRedeemScript redeem, ITransaction tx, int inputIndex) => throw new NotImplementedException();
public virtual void SetToCheckLocktimeVerify(Signature sig, IRedeemScript redeem) => throw new NotImplementedException();
public void GetRedeemScriptTypeTest(IRedeemScript scr, RedeemScriptType expected) { RedeemScriptType actual = scr.GetRedeemScriptType(); Assert.Equal(expected, actual); }
private bool VerifyP2wsh(ITransaction tx, int index, IRedeemScript redeem, ReadOnlySpan <byte> expectedHash, ulong amount, out string error) { ReadOnlySpan <byte> actualHash = sha256.ComputeHash(redeem.Data); if (!actualHash.SequenceEqual(expectedHash)) { error = "Invalid hash."; return(false); } if (!redeem.TryEvaluate(out IOperation[] redeemOps, out int redeemOpCount, out error)) { error = $"Script evaluation failed." + $"{Environment.NewLine}TxId: {tx.GetTransactionId()}" + $"{Environment.NewLine}More info: {error}"; return(false); } // Note that there is no *Constants.WitnessScaleFactor here anymore TotalSigOpCount += redeem.CountSigOps(redeemOps); var stack = new OpData() { Tx = tx, TxInIndex = index, ForceLowS = ForceLowS, StrictNumberEncoding = StrictNumberEncoding, IsBip65Enabled = consensus.IsBip65Enabled(BlockHeight), IsBip112Enabled = consensus.IsBip112Enabled(BlockHeight), IsStrictDerSig = consensus.IsStrictDerSig(BlockHeight), IsBip147Enabled = consensus.IsBip147Enabled(BlockHeight), }; for (int j = 0; j < tx.WitnessList[index].Items.Length - 1; j++) { if (!tx.WitnessList[index].Items[j].Run(stack, out error)) { error = $"Script evaluation failed." + $"{Environment.NewLine}TxId: {tx.GetTransactionId()}" + $"{Environment.NewLine}More info: {error}"; return(false); } } stack.AmountBeingSpent = amount; stack.IsSegWit = true; stack.OpCount = redeemOpCount; stack.ExecutingScript = redeemOps; foreach (var op in redeemOps) { if (!op.Run(stack, out error)) { error = $"Script evaluation failed." + $"{Environment.NewLine}TxId: {tx.GetTransactionId()}" + $"{Environment.NewLine}More info: {error}"; return(false); } } // Stack has to only have 1 item left if (stack.ItemCount == 1 && IsNotZero(stack.Pop())) { error = null; return(true); } else { error = stack.ItemCount != 1 ? "Stack has to have only 1 item after witness execution." : "Top stack item is not true"; return(false); } }