public static void Sign(this TxIn txin, Transaction tx, TxOut prevOut, PrivateKey key, HashType hashType = HashType.SIGHASH_ALL) { SHA256 sha256 = new SHA256Managed(); UInt32 txInIndex; for (txInIndex = 0; txInIndex < tx.inputs.Length; txInIndex++) { if (TxIn.ReferenceEquals(txin, tx.inputs[txInIndex])) break; } if (txInIndex == tx.inputs.Length) throw new ArgumentException("Input not part of transaction."); // Only know how to sign if output does not contain OP_CODESEPERATOR for now. Script subScript = new Script(prevOut.scriptPubKey); Transaction txCopy = tx.CopyForSigning(txInIndex, subScript, hashType); Byte[] txHash = txCopy.ToBytes().Concat(new Byte[] { (Byte)hashType, 0x00, 0x00, 0x00 }).ToArray(); txHash = sha256.ComputeHash(sha256.ComputeHash(txHash)); Byte[] sig = key.Sign(txHash); sig = sig.Concat(new Byte[] { (Byte)hashType }).ToArray(); Script s = new Script(); if (subScript.IsPayToAddress()) { s.elements.Add(new ScriptElement(sig)); s.elements.Add(new ScriptElement(key.pubKey.ToBytes())); } else if (subScript.IsPayToPublicKey()) { s.elements.Add(new ScriptElement(sig)); } else { throw new ArgumentException("Unrecognized TxOut Script"); } txin.scriptSig = s.ToBytes(); }
private Boolean CheckSig(Byte[] sig, PublicKey pubKey, UInt32 txInIndex, Script subScript, Transaction tx) { HashType hashType = (HashType)sig.Last(); sig = sig.Take(sig.Length - 1).ToArray(); Transaction txCopy = tx.CopyForSigning(txInIndex, subScript, hashType); Byte[] txHash = txCopy.ToBytes().Concat(new Byte[] { (Byte)hashType, 0x00, 0x00, 0x00 }).ToArray(); txHash = sha256.ComputeHash(sha256.ComputeHash(txHash)); return pubKey.VerifySignature(txHash, sig); }
public static void Sign(this TxIn txin, Transaction tx, TxOut prevOut, PrivateKey key, HashType hashType = HashType.SIGHASH_ALL, Script redeemScript = null) { SHA256 sha256 = new SHA256Managed(); UInt32 txInIndex; for (txInIndex = 0; txInIndex < tx.inputs.Length; txInIndex++) { if (TxIn.ReferenceEquals(txin, tx.inputs[txInIndex])) break; } if (txInIndex == tx.inputs.Length) throw new ArgumentException("Input not part of transaction."); // Only know how to sign if output does not contain OP_CODESEPERATOR for now Script subScript = new Script(prevOut.scriptPubKey); //// Still don't fully handle codeseperator, but we remove them all as in the spec. //// Might be all we need to do, scriptSig will never contain OP_CODESEPERATOR since we are creating it. ////subScript.elements.RemoveAll(x => x.opCode == OpCode.OP_CODESEPARATOR); // Actually, those would be nonstandard anyway Transaction txCopy = tx.CopyForSigning(txInIndex, subScript, hashType); Byte[] txHash = txCopy.ToBytes().Concat(new Byte[] { (Byte)hashType, 0x00, 0x00, 0x00 }).ToArray(); txHash = sha256.ComputeHash(sha256.ComputeHash(txHash)); Script s = new Script(); if (subScript.IsPayToScriptHash()) { if (redeemScript == null) throw new ArgumentNullException("P2SH transaction requires serialied script"); s.elements.Add(new ScriptElement(redeemScript.ToBytes())); subScript = redeemScript; } if (subScript.IsPayToPubKeyHash()) { Byte[] sig = key.Sign(txHash).Concat(new Byte[] { (Byte)hashType }).ToArray(); s.elements.Insert(0, new ScriptElement(sig)); s.elements.Insert(1, new ScriptElement(key.pubKey.ToBytes())); } else if (subScript.IsPayToPublicKey()) { Byte[] sig = key.Sign(txHash).Concat(new Byte[] { (Byte)hashType }).ToArray(); s.elements.Insert(0, new ScriptElement(sig)); } else if (subScript.IsPayToMultiSig()) { Script scriptSig = new Script(txin.scriptSig); if (scriptSig.elements.Count == 0) scriptSig.elements.Add(new ScriptElement(OpCode.OP_0)); Byte[] sig = key.Sign(txHash).Concat(new Byte[] { (Byte)hashType }).ToArray(); s.elements.Insert(0, new ScriptElement(sig)); } else { throw new ArgumentException("Unrecognized TxOut Script"); } txin.scriptSig = s.ToBytes(); }