コード例 #1
0
 public TransactionSignature(ECDSASignature signature, SigHash sigHash)
 {
     if(sigHash == SigHash.Undefined)
         throw new ArgumentException("sigHash should not be Undefined");
     _SigHash = sigHash;
     _Signature = signature.MakeCanonical();
 }
コード例 #2
0
ファイル: Transaction.cs プロジェクト: n1rvana/NBitcoin
 public TransactionSignature SignInput(Key key, ICoin coin, SigHash sigHash = SigHash.All)
 {
     return(Inputs.AsIndexedInputs().ToArray()[GetIndex(coin)].Sign(key, coin, sigHash));
 }
コード例 #3
0
ファイル: Transaction.cs プロジェクト: n1rvana/NBitcoin
 public uint256 GetSignatureHash(ICoin coin, SigHash sigHash = SigHash.All)
 {
     return(Inputs.AsIndexedInputs().ToArray()[GetIndex(coin)].GetSignatureHash(coin, sigHash));
 }
コード例 #4
0
ファイル: TransactionBuilder.cs プロジェクト: crowar/NBitcoin
		public Transaction SignTransactionInPlace(Transaction transaction, SigHash sigHash)
		{
			TransactionSigningContext ctx = new TransactionSigningContext(this, transaction);
			ctx.SigHash = sigHash;
			foreach(var input in transaction.Inputs.AsIndexedInputs())
			{
				var coin = FindSignableCoin(input);
				if(coin != null)
				{
					Sign(ctx, coin, input);
				}
			}
			return transaction;
		}
コード例 #5
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		//https://en.bitcoin.it/wiki/OP_CHECKSIG
		public uint256 SignatureHash(Transaction txTo, int nIn, SigHash nHashType)
		{
			if(nIn >= txTo.Inputs.Count)
			{
				Utils.log("ERROR: SignatureHash() : nIn=" + nIn + " out of range\n");
				return uint256.One;
			}

			// Check for invalid use of SIGHASH_SINGLE
			if(nHashType == SigHash.Single)
			{
				if(nIn >= txTo.Outputs.Count)
				{
					Utils.log("ERROR: SignatureHash() : nOut=" + nIn + " out of range\n");
					return uint256.One;
				}
			}

			var scriptCopy = new Script(_Script);
			scriptCopy.FindAndDelete(OpcodeType.OP_CODESEPARATOR);

			var txCopy = new Transaction(txTo.ToBytes());

			//Set all TxIn script to empty string
			foreach(var txin in txCopy.Inputs)
			{
				txin.ScriptSig = new Script();
			}
			//Copy subscript into the txin script you are checking
			txCopy.Inputs[nIn].ScriptSig = scriptCopy;

			var hashType = nHashType & (SigHash)31;
			if(hashType == SigHash.None)
			{
				//The output of txCopy is set to a vector of zero size.
				txCopy.Outputs.Clear();

				//All other inputs aside from the current input in txCopy have their nSequence index set to zero
				foreach(var input in txCopy.Inputs.Where((x, i) => i != nIn))
					input.Sequence = 0;
			}
			else if(hashType == SigHash.Single)
			{
				//The output of txCopy is resized to the size of the current input index+1.
				txCopy.Outputs.RemoveRange(nIn + 1, txCopy.Outputs.Count - (nIn + 1));
				//All other txCopy outputs aside from the output that is the same as the current input index are set to a blank script and a value of (long) -1.
				for(var i = 0 ; i < txCopy.Outputs.Count ; i++)
				{
					if(i == nIn)
						continue;
					txCopy.Outputs[i] = new TxOut();
				}
				//All other txCopy inputs aside from the current input are set to have an nSequence index of zero.
				foreach(var input in txCopy.Inputs.Where((x, i) => i != nIn))
					input.Sequence = 0;
			}


			if((nHashType & SigHash.AnyoneCanPay) != 0)
			{
				//The txCopy input vector is resized to a length of one.
				var script = txCopy.Inputs[nIn];
				txCopy.Inputs.Clear();
				txCopy.Inputs.Add(script);
				//The subScript (lead in by its length as a var-integer encoded!) is set as the first and only member of this vector.
				txCopy.Inputs[0].ScriptSig = scriptCopy;
			}


			//Serialize TxCopy, append 4 byte hashtypecode
			var ms = new MemoryStream();
			var bitcoinStream = new BitcoinStream(ms, true);
			txCopy.ReadWrite(bitcoinStream);
			bitcoinStream.ReadWrite((uint)nHashType);

			var hashed = ms.ToArray();
			return Hashes.Hash256(hashed);
		}
コード例 #6
0
ファイル: Script.cs プロジェクト: knocte/NBitcoin
		//https://en.bitcoin.it/wiki/OP_CHECKSIG
		public static uint256 SignatureHash(Script scriptCode, Transaction txTo, int nIn, SigHash nHashType, Money amount = null, HashVersion sigversion = HashVersion.Original)
		{
			if(sigversion == HashVersion.Witness)
			{
				if(amount == null)
					throw new ArgumentException("The amount of the output being signed must be provided", "amount");
				uint256 hashPrevouts = uint256.Zero;
				uint256 hashSequence = uint256.Zero;
				uint256 hashOutputs = uint256.Zero;

				if((nHashType & SigHash.AnyoneCanPay) == 0)
				{
					BitcoinStream ss = CreateHashWriter(sigversion);
					foreach(var input in txTo.Inputs)
					{
						ss.ReadWrite(input.PrevOut);
					}
					hashPrevouts = GetHash(ss); // TODO: cache this value for all signatures in a transaction
				}

				if((nHashType & SigHash.AnyoneCanPay) == 0 && ((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
				{
					BitcoinStream ss = CreateHashWriter(sigversion);
					foreach(var input in txTo.Inputs)
					{
						ss.ReadWrite((uint)input.Sequence);
					}
					hashSequence = GetHash(ss); // TODO: cache this value for all signatures in a transaction
				}

				if(((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
				{
					BitcoinStream ss = CreateHashWriter(sigversion);
					foreach(var txout in txTo.Outputs)
					{
						ss.ReadWrite(txout);
					}
					hashOutputs = GetHash(ss); // TODO: cache this value for all signatures in a transaction
				}
				else if(((uint)nHashType & 0x1f) == (uint)SigHash.Single && nIn < txTo.Outputs.Count)
				{
					BitcoinStream ss = CreateHashWriter(sigversion);
					ss.ReadWrite(txTo.Outputs[nIn]);
					hashOutputs = GetHash(ss);
				}

				BitcoinStream sss = CreateHashWriter(sigversion);
				// Version
				sss.ReadWrite(txTo.Version);
				// Input prevouts/nSequence (none/all, depending on flags)
				sss.ReadWrite(hashPrevouts);
				sss.ReadWrite(hashSequence);
				// The input being signed (replacing the scriptSig with scriptCode + amount)
				// The prevout may already be contained in hashPrevout, and the nSequence
				// may already be contain in hashSequence.
				sss.ReadWrite(txTo.Inputs[nIn].PrevOut);
				sss.ReadWrite(scriptCode);
				sss.ReadWrite(amount.Satoshi);
				sss.ReadWrite((uint)txTo.Inputs[nIn].Sequence);
				// Outputs (none/one/all, depending on flags)
				sss.ReadWrite(hashOutputs);
				// Locktime
				sss.ReadWriteStruct(txTo.LockTime);
				// Sighash type
				sss.ReadWrite((uint)nHashType);

				return GetHash(sss);
			}




			if(nIn >= txTo.Inputs.Count)
			{
				Utils.log("ERROR: SignatureHash() : nIn=" + nIn + " out of range\n");
				return uint256.One;
			}

			// Check for invalid use of SIGHASH_SINGLE
			if(nHashType == SigHash.Single)
			{
				if(nIn >= txTo.Outputs.Count)
				{
					Utils.log("ERROR: SignatureHash() : nOut=" + nIn + " out of range\n");
					return uint256.One;
				}
			}

			var scriptCopy = new Script(scriptCode._Script);
			scriptCopy.FindAndDelete(OpcodeType.OP_CODESEPARATOR);

			var txCopy = new Transaction(txTo.ToBytes());

			//Set all TxIn script to empty string
			foreach(var txin in txCopy.Inputs)
			{
				txin.ScriptSig = new Script();
			}
			//Copy subscript into the txin script you are checking
			txCopy.Inputs[nIn].ScriptSig = scriptCopy;

			var hashType = nHashType & (SigHash)31;
			if(hashType == SigHash.None)
			{
				//The output of txCopy is set to a vector of zero size.
				txCopy.Outputs.Clear();

				//All other inputs aside from the current input in txCopy have their nSequence index set to zero
				foreach(var input in txCopy.Inputs.Where((x, i) => i != nIn))
					input.Sequence = 0;
			}
			else if(hashType == SigHash.Single)
			{
				//The output of txCopy is resized to the size of the current input index+1.
				txCopy.Outputs.RemoveRange(nIn + 1, txCopy.Outputs.Count - (nIn + 1));
				//All other txCopy outputs aside from the output that is the same as the current input index are set to a blank script and a value of (long) -1.
				for(var i = 0 ; i < txCopy.Outputs.Count ; i++)
				{
					if(i == nIn)
						continue;
					txCopy.Outputs[i] = new TxOut();
				}
				//All other txCopy inputs aside from the current input are set to have an nSequence index of zero.
				foreach(var input in txCopy.Inputs.Where((x, i) => i != nIn))
					input.Sequence = 0;
			}


			if((nHashType & SigHash.AnyoneCanPay) != 0)
			{
				//The txCopy input vector is resized to a length of one.
				var script = txCopy.Inputs[nIn];
				txCopy.Inputs.Clear();
				txCopy.Inputs.Add(script);
				//The subScript (lead in by its length as a var-integer encoded!) is set as the first and only member of this vector.
				txCopy.Inputs[0].ScriptSig = scriptCopy;
			}


			//Serialize TxCopy, append 4 byte hashtypecode
			var stream = CreateHashWriter(sigversion);
			txCopy.ReadWrite(stream);
			stream.ReadWrite((uint)nHashType);
			return GetHash(stream);
		}
コード例 #7
0
 public TransactionSignature(byte[] sig, SigHash sigHash)
 {
     _Signature = ECDSASignature.FromDER(sig).MakeCanonical();
     _SigHash = sigHash;
 }
コード例 #8
0
ファイル: Script.cs プロジェクト: n1rvana/NBitcoin
        public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, Money value, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
        {
            var eval = new ScriptEvaluationContext
            {
                SigHash      = sigHash,
                ScriptVerify = scriptVerify
            };
            var result = eval.VerifyScript(scriptSig, scriptPubKey, tx, i, value);

            error = eval.Error;
            return(result);
        }
コード例 #9
0
ファイル: Transaction.cs プロジェクト: alp-bitcoin/NBitcoin
        public TransactionSignature Sign(Key key, Script scriptPubKey, SigHash sigHash = SigHash.All)
        {
            var hash = GetSignatureHash(scriptPubKey, sigHash);

            return(key.Sign(hash, sigHash));
        }
コード例 #10
0
ファイル: Transaction.cs プロジェクト: Virus-X/CoinSharp
 public Sha256Hash HashTransactionForSignature(SigHash type, int inputIndex, byte[] connectedScript)
 {
     throw new NotImplementedException();
 }
コード例 #11
0
ファイル: Transaction.cs プロジェクト: knocte/BitcoinDotNet
		///**
		// * Once a transaction has some inputs and outputs added, the signatures in the inputs can be calculated. The
		// * signature is over the transaction itself, to prove the redeemer actually created that transaction,
		// * so we have to do this step last.<p>
		// * <p/>
		// * This method is similar to SignatureHash in script.cpp
		// *
		// * @param hashType This should always be set to SigHash.ALL currently. Other types are unused.
		// * @param wallet   A wallet is required to fetch the keys needed for signing.
		// */
		//public synchronized void signInputs(SigHash hashType, Wallet wallet) throws ScriptException {
		//	Preconditions.checkState(inputs.size() > 0);
		//	Preconditions.checkState(outputs.size() > 0);

		//	// I don't currently have an easy way to test other modes work, as the official client does not use them.
		//	Preconditions.checkArgument(hashType == SigHash.ALL, "Only SIGHASH_ALL is currently supported");

		//	// The transaction is signed with the input scripts empty except for the input we are signing. In the case
		//	// where addInput has been used to set up a new transaction, they are already all empty. The input being signed
		//	// has to have the connected OUTPUT program in it when the hash is calculated!
		//	//
		//	// Note that each input may be claiming an output sent to a different key. So we have to look at the outputs
		//	// to figure out which key to sign with.

		//	byte[][] signatures = new byte[inputs.size()][];
		//	ECKey[] signingKeys = new ECKey[inputs.size()];
		//	for (int i = 0; i < inputs.size(); i++) {
		//		TransactionInput input = inputs[i];
		//		if (input.getScriptBytes().length != 0)
		//			log.warn("Re-signing an already signed transaction! Be sure this is what you want.");
		//		// Find the signing key we'll need to use.
		//		ECKey key = input.getOutpoint().getConnectedKey(wallet);
		//		// This assert should never fire. If it does, it means the wallet is inconsistent.
		//		Preconditions.checkNotNull(key, "Transaction exists in wallet that we cannot redeem: %s",
		//								   input.getOutpoint().getHash());
		//		// Keep the key around for the script creation step below.
		//		signingKeys[i] = key;
		//		// The anyoneCanPay feature isn't used at the moment.
		//		boolean anyoneCanPay = false;
		//		byte[] connectedPubKeyScript = input.getOutpoint().getConnectedPubKeyScript();
		//		Sha256Hash hash = hashTransactionForSignature(i, connectedPubKeyScript, hashType, anyoneCanPay);

		//		// Now sign for the output so we can redeem it. We use the keypair to sign the hash,
		//		// and then put the resulting signature in the script along with the public key (below).
		//		try {
		//			// Usually 71-73 bytes.
		//			ByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(73);
		//			bos.write(key.sign(hash).encodeToDER());
		//			bos.write((hashType.ordinal() + 1) | (anyoneCanPay ? 0x80 : 0));
		//			signatures[i] = bos.toByteArray();
		//			bos.close();
		//		} catch (IOException e) {
		//			throw new RuntimeException(e);  // Cannot happen.
		//		}
		//	}

		//	// Now we have calculated each signature, go through and create the scripts. Reminder: the script consists:
		//	// 1) For pay-to-address outputs: a signature (over a hash of the simplified transaction) and the complete
		//	//    public key needed to sign for the connected output. The output script checks the provided pubkey hashes
		//	//    to the address and then checks the signature.
		//	// 2) For pay-to-key outputs: just a signature.
		//	for (int i = 0; i < inputs.size(); i++) {
		//		TransactionInput input = inputs[i];
		//		ECKey key = signingKeys[i];
		//		Script scriptPubKey = input.getOutpoint().getConnectedOutput().getScriptPubKey();
		//		if (scriptPubKey.isSentToAddress()) {
		//			input.setScriptBytes(Script.createInputScript(signatures[i], key.getPubKey()));
		//		} else if (scriptPubKey.isSentToRawPubKey()) {
		//			input.setScriptBytes(Script.createInputScript(signatures[i]));
		//		} else {
		//			// Should be unreachable - if we don't recognize the type of script we're trying to sign for, we should
		//			// have failed above when fetching the key to sign with.
		//			throw new RuntimeException("Do not understand script type: " + scriptPubKey);
		//		}
		//	}

		//	// Every input is now complete.
		//}

		/**
		 * Calculates a signature hash, that is, a hash of a simplified form of the transaction. How exactly the transaction
		 * is simplified is specified by the type and anyoneCanPay parameters.<p>
		 *
		 * You don't normally ever need to call this yourself. It will become more useful in future as the contracts
		 * features of Bitcoin are developed.
		 *
		 * @param inputIndex input the signature is being calculated for. Tx signatures are always relative to an input.
		 * @param connectedScript the bytes that should be in the given input during signing.
		 * @param type Should be SigHash.ALL
		 * @param anyoneCanPay should be false.
		 * @throws ScriptException if connectedScript is invalid
		 */
		public Sha256Hash hashTransactionForSignature(int inputIndex,byte[] connectedScript,SigHash type,bool anyoneCanPay)
		{
			return hashTransactionForSignature(inputIndex, connectedScript, (byte)((type.ordinal() + 1) | (anyoneCanPay ? 0x80 : 0x00)));
		}
コード例 #12
0
ファイル: Script.cs プロジェクト: nikropht/NBitcoin
 public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify = ScriptVerify.StrictEnc | ScriptVerify.P2SH, SigHash sigHash = SigHash.Undefined)
 {
     ScriptEvaluationContext eval = new ScriptEvaluationContext();
     eval.SigHash = sigHash;
     eval.ScriptVerify = scriptVerify;
     return eval.VerifyScript(scriptSig, scriptPubKey, tx, i);
 }
コード例 #13
0
ファイル: TransactionBuilder.cs プロジェクト: crowar/NBitcoin
		/// <summary>
		/// Build the transaction
		/// </summary>
		/// <param name="sign">True if signs all inputs with the available keys</param>
		/// <param name="sigHash">The type of signature</param>
		/// <returns>The transaction</returns>
		/// <exception cref="NBitcoin.NotEnoughFundsException">Not enough funds are available</exception>
		public Transaction BuildTransaction(bool sign, SigHash sigHash)
		{
			TransactionBuildingContext ctx = new TransactionBuildingContext(this);
			if(_CompletedTransaction != null)
				ctx.Transaction = _CompletedTransaction.Clone();
			if(_LockTime != null)
				ctx.Transaction.LockTime = _LockTime.Value;
			foreach(var group in _BuilderGroups)
			{
				ctx.Group = group;
				ctx.AdditionalBuilders.Clear();
				ctx.AdditionalFees = Money.Zero;

				ctx.ChangeType = ChangeType.Colored;
				foreach(var builder in group.IssuanceBuilders)
					builder(ctx);

				var buildersByAsset = group.BuildersByAsset.ToList();
				foreach(var builders in buildersByAsset)
				{
					var coins = group.Coins.Values.OfType<ColoredCoin>().Where(c => c.Amount.Id == builders.Key);

					ctx.Dust = new AssetMoney(builders.Key);
					ctx.CoverOnly = null;
					ctx.ChangeAmount = new AssetMoney(builders.Key);
					var btcSpent = BuildTransaction(ctx, group, builders.Value, coins, new AssetMoney(builders.Key))
						.OfType<IColoredCoin>().Select(c => c.Bearer.Amount).Sum();
					ctx.AdditionalFees -= btcSpent;
				}

				ctx.AdditionalBuilders.Add(_ => _.AdditionalFees);
				ctx.Dust = GetDust();
				ctx.ChangeAmount = Money.Zero;
				ctx.CoverOnly = group.CoverOnly;
				ctx.ChangeType = ChangeType.Uncolored;
				BuildTransaction(ctx, group, group.Builders, group.Coins.Values.OfType<Coin>(), Money.Zero);
			}
			ctx.Finish();

			if(sign)
			{
				SignTransactionInPlace(ctx.Transaction, sigHash);
			}
			return ctx.Transaction;
		}
コード例 #14
0
ファイル: TransactionBuilder.cs プロジェクト: crowar/NBitcoin
			public TransactionBuilderSigner(ICoin coin, SigHash sigHash, IndexedTxIn txIn)
			{
				this.coin = coin;
				this.sigHash = sigHash;
				this.txIn = txIn;
			}
コード例 #15
0
ファイル: Transaction.cs プロジェクト: n1rvana/NBitcoin
 public uint256 GetSignatureHash(ICoin coin, SigHash sigHash = SigHash.All)
 {
     return(Script.SignatureHash(coin.GetScriptCode(), Transaction, (int)Index, sigHash, coin.TxOut.Value, coin.GetHashVersion()));
 }
コード例 #16
0
ファイル: Script.cs プロジェクト: eccentricbiped/NBitcoin
        public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, Money value, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined)
        {
            ScriptError unused;
            var         scriptSig = tx.Inputs[i].ScriptSig;

            return(VerifyScript(scriptSig, scriptPubKey, tx, i, value, scriptVerify, sigHash, out unused));
        }
コード例 #17
0
ファイル: Transaction.cs プロジェクト: alp-bitcoin/NBitcoin
 public uint256 GetSignatureHash(Script scriptPubKey, int nIn, SigHash sigHash = SigHash.All)
 {
     return(Inputs.AsIndexedInputs().ToArray()[nIn].GetSignatureHash(scriptPubKey, sigHash));
 }
コード例 #18
0
ファイル: Transaction.cs プロジェクト: alp-bitcoin/NBitcoin
 public TransactionSignature SignInput(ISecret secret, Script scriptPubKey, int nIn, SigHash sigHash = SigHash.All)
 {
     return(SignInput(secret.PrivateKey, scriptPubKey, nIn, sigHash));
 }
コード例 #19
0
ファイル: Transaction.cs プロジェクト: alp-bitcoin/NBitcoin
 public TransactionSignature SignInput(Key key, Script scriptPubKey, int nIn, SigHash sigHash = SigHash.All)
 {
     return(Inputs.AsIndexedInputs().ToArray()[nIn].Sign(key, scriptPubKey, sigHash));
 }
コード例 #20
0
ファイル: Transaction.cs プロジェクト: aklein53/bitcoinsharp
 private byte[] HashTransactionForSignature(SigHash type, bool anyoneCanPay)
 {
     using (var bos = new MemoryStream())
     {
         BitcoinSerializeToStream(bos);
         // We also have to write a hash type.
         var hashType = (uint) type + 1;
         if (anyoneCanPay)
             hashType |= 0x80;
         Utils.Uint32ToByteStreamLe(hashType, bos);
         // Note that this is NOT reversed to ensure it will be signed correctly. If it were to be printed out
         // however then we would expect that it is IS reversed.
         return Utils.DoubleDigest(bos.ToArray());
     }
 }
コード例 #21
0
        /*
         *  if (nIn >= txTo.vin.size())
         *  {
         *      printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
         *      return 1;
         *  }
         *  CTransaction txTmp(txTo);
         *
         *  // In case concatenating two scripts ends up with two codeseparators,
         *  // or an extra one at the end, this prevents all those possible incompatibilities.
         *  scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR));
         *
         *  // Blank out other inputs' signatures
         *  for (unsigned int i = 0; i < txTmp.vin.size(); i++)
         *      txTmp.vin[i].scriptSig = CScript();
         *  txTmp.vin[nIn].scriptSig = scriptCode;
         *
         *  // Blank out some of the outputs
         *  if ((nHashType & 0x1f) == SIGHASH_NONE)
         *  {
         *      // Wildcard payee
         *      txTmp.vout.clear();
         *
         *      // Let the others update at will
         *      for (unsigned int i = 0; i < txTmp.vin.size(); i++)
         *          if (i != nIn)
         *              txTmp.vin[i].nSequence = 0;
         *  }
         *  else if ((nHashType & 0x1f) == SIGHASH_SINGLE)
         *  {
         *      // Only lock-in the txout payee at same index as txin
         *      unsigned int nOut = nIn;
         *      if (nOut >= txTmp.vout.size())
         *      {
         *          printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
         *          return 1;
         *      }
         *      txTmp.vout.resize(nOut+1);
         *      for (unsigned int i = 0; i < nOut; i++)
         *          txTmp.vout[i].SetNull();
         *
         *      // Let the others update at will
         *      for (unsigned int i = 0; i < txTmp.vin.size(); i++)
         *          if (i != nIn)
         *              txTmp.vin[i].nSequence = 0;
         *  }
         *
         *  // Blank out other inputs completely, not recommended for open transactions
         *  if (nHashType & SIGHASH_ANYONECANPAY)
         *  {
         *      txTmp.vin[0] = txTmp.vin[nIn];
         *      txTmp.vin.resize(1);
         *  }
         *
         *  // Serialize and hash
         *  CHashWriter ss(SER_GETHASH, 0);
         *  ss << txTmp << nHashType;
         *  return ss.GetHash();
         */
        public override uint256 GetSignatureHash(Script scriptCode, int nIn, SigHash nHashType, Money amount,
                                                 HashVersion sigversion, PrecomputedTransactionData precomputedTransactionData)
        {
            if (nIn >= Inputs.Count)
            {
                //Utils.log("ERROR: SignatureHash() : nIn=" + nIn + " out of range\n");
                return(uint256.One);
            }

            var scriptCopy = new Script(scriptCode.ToBytes());

            scriptCopy = scriptCopy.FindAndDelete(OpcodeType.OP_CODESEPARATOR);

            var hashType = nHashType & (SigHash)31;

            // Check for invalid use of SIGHASH_SINGLE
            //if (hashType == SigHash.Single)
            //{
            //    if (nIn >= Outputs.Count)
            //    {
            //        //Utils.log("ERROR: SignatureHash() : nOut=" + nIn + " out of range\n");
            //        return uint256.One;
            //    }
            //}

            var txCopy = (SolarCoinTransaction)GetConsensusFactory().CreateTransaction();

            txCopy.FromBytes(this.ToBytes());
            //Set all TxIn script to empty string
            foreach (var txin in txCopy.Inputs)
            {
                txin.ScriptSig = new Script();
            }

            //Copy subscript into the txin script you are checking
            txCopy.Inputs[nIn].ScriptSig = scriptCopy;

            if (hashType == SigHash.None)
            {
                //The output of txCopy is set to a vector of zero size.
                txCopy.Outputs.Clear();

                //All other inputs aside from the current input in txCopy have their nSequence index set to zero
                foreach (var input in txCopy.Inputs.Where((x, i) => i != nIn))
                {
                    input.Sequence = 0;
                }
            }
            else if (hashType == SigHash.Single)
            {
                if (nIn >= Outputs.Count)
                {
                    //Utils.log("ERROR: SignatureHash() : nOut=" + nIn + " out of range\n");
                    return(uint256.One);
                }
                //The output of txCopy is resized to the size of the current input index+1.
                txCopy.Outputs.RemoveRange(nIn + 1, txCopy.Outputs.Count - (nIn + 1));
                //All other txCopy outputs aside from the output that is the same as the current input index are set to a blank script and a value of (long) -1.
                for (var i = 0; i < nIn; i++)
                {
                    //if (i == nIn)
                    //    continue;
                    txCopy.Outputs[i] = new TxOut();
                }

                //All other txCopy inputs aside from the current input are set to have an nSequence index of zero.
                foreach (var input in txCopy.Inputs.Where((x, i) => i != nIn))
                {
                    input.Sequence = 0;
                }
            }

            if ((nHashType & SigHash.AnyoneCanPay) != 0)
            {
                //The txCopy input vector is resized to a length of one.
                var script = txCopy.Inputs[nIn];
                txCopy.Inputs.Clear();
                txCopy.Inputs.Add(script);
                //The subScript (lead in by its length as a var-integer encoded!) is set as the first and only member of this vector.
                //txCopy.Inputs[0].ScriptSig = scriptCopy;
            }

            var previousType = txCopy.NType;

            txCopy.NType = (uint)PrimaryActions.SER_GETHASH;
            //Serialize TxCopy, append 4 byte hashtypecode
            var stream = CreateHashWriter(sigversion);

            txCopy.ReadWrite(stream);
            stream.ReadWrite((uint)nHashType);
            var txHash = GetHash(stream);

            txCopy.NType = previousType;

            return(txHash);
        }
コード例 #22
0
        public TransactionSignature UntrustedHashSign(KeyPath keyPath, UserPin pin, LockTime lockTime, SigHash sigHashType)
        {
            using(Transport.Lock())
            {
                MemoryStream data = new MemoryStream();
                byte[] path = Serializer.Serialize(keyPath);
                BufferUtils.WriteBuffer(data, path);

                var pinBytes = pin == null ? new byte[0] : pin.ToBytes();
                data.WriteByte((byte)pinBytes.Length);
                BufferUtils.WriteBuffer(data, pinBytes);
                BufferUtils.WriteUint32BE(data, (uint)lockTime);
                data.WriteByte((byte)sigHashType);
                byte[] response = ExchangeApdu(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_HASH_SIGN, (byte)0x00, (byte)0x00, data.ToArray(), OK);
                response[0] = (byte)0x30;
                return new TransactionSignature(response);
            }
        }
コード例 #23
0
ファイル: Neblio.cs プロジェクト: nopara73/NBitcoin
            public override uint256 GetSignatureHash(Script scriptCode, int nIn, SigHash nHashType, TxOut spentOutput, HashVersion sigversion, PrecomputedTransactionData precomputedTransactionData)
            {
                if (sigversion == HashVersion.WitnessV0)
                {
                    if (spentOutput?.Value == null || spentOutput.Value == TxOut.NullMoney)
                    {
                        throw new ArgumentException("The output being signed with the amount must be provided", nameof(spentOutput));
                    }
                    uint256 hashPrevouts = uint256.Zero;
                    uint256 hashSequence = uint256.Zero;
                    uint256 hashOutputs  = uint256.Zero;

                    if ((nHashType & SigHash.AnyoneCanPay) == 0)
                    {
                        hashPrevouts = precomputedTransactionData == null?
                                       GetHashPrevouts() : precomputedTransactionData.HashPrevouts;
                    }

                    if ((nHashType & SigHash.AnyoneCanPay) == 0 && ((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
                    {
                        hashSequence = precomputedTransactionData == null?
                                       GetHashSequence() : precomputedTransactionData.HashSequence;
                    }

                    if (((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
                    {
                        hashOutputs = precomputedTransactionData == null?
                                      GetHashOutputs() : precomputedTransactionData.HashOutputs;
                    }
                    else if (((uint)nHashType & 0x1f) == (uint)SigHash.Single && nIn < this.Outputs.Count)
                    {
                        BitcoinStream ss = CreateHashWriter(sigversion);
                        ss.ReadWrite(this.Outputs[nIn]);
                        hashOutputs = GetHash(ss);
                    }

                    BitcoinStream sss = CreateHashWriter(sigversion);
                    // Version
                    sss.ReadWrite(this.Version);
                    sss.ReadWrite(this.Time);                     // Neblio Timestamp!!!
                    // Input prevouts/nSequence (none/all, depending on flags)
                    sss.ReadWrite(hashPrevouts);
                    sss.ReadWrite(hashSequence);
                    // The input being signed (replacing the scriptSig with scriptCode + amount)
                    // The prevout may already be contained in hashPrevout, and the nSequence
                    // may already be contain in hashSequence.
                    sss.ReadWrite(Inputs[nIn].PrevOut);
                    sss.ReadWrite(scriptCode);
                    sss.ReadWrite(spentOutput.Value.Satoshi);
                    sss.ReadWrite((uint)Inputs[nIn].Sequence);
                    // Outputs (none/one/all, depending on flags)
                    sss.ReadWrite(hashOutputs);
                    // Locktime
                    sss.ReadWriteStruct(LockTime);
                    // Sighash type
                    sss.ReadWrite((uint)nHashType);

                    return(GetHash(sss));
                }

                bool fAnyoneCanPay = (nHashType & SigHash.AnyoneCanPay) != 0;
                bool fHashSingle   = ((byte)nHashType & 0x1f) == (byte)SigHash.Single;
                bool fHashNone     = ((byte)nHashType & 0x1f) == (byte)SigHash.None;

                if (nIn >= Inputs.Count)
                {
                    return(uint256.One);
                }
                if (fHashSingle)
                {
                    if (nIn >= Outputs.Count)
                    {
                        return(uint256.One);
                    }
                }

                var stream = CreateHashWriter(sigversion);

                stream.ReadWrite(Version);
                stream.ReadWrite(this.Time);                 // Neblio Timestamp!!!
                uint nInputs = (uint)(fAnyoneCanPay ? 1 : Inputs.Count);

                stream.ReadWriteAsVarInt(ref nInputs);
                for (int nInput = 0; nInput < nInputs; nInput++)
                {
                    if (fAnyoneCanPay)
                    {
                        nInput = nIn;
                    }
                    stream.ReadWrite(Inputs[nInput].PrevOut);
                    if (nInput != nIn)
                    {
                        stream.ReadWrite(Script.Empty);
                    }
                    else
                    {
                        WriteScriptCode(stream, scriptCode);
                    }

                    if (nInput != nIn && (fHashSingle || fHashNone))
                    {
                        stream.ReadWrite((uint)0);
                    }
                    else
                    {
                        stream.ReadWrite((uint)Inputs[nInput].Sequence);
                    }
                }

                uint nOutputs = (uint)(fHashNone ? 0 : (fHashSingle ? nIn + 1 : Outputs.Count));

                stream.ReadWriteAsVarInt(ref nOutputs);
                for (int nOutput = 0; nOutput < nOutputs; nOutput++)
                {
                    if (fHashSingle && nOutput != nIn)
                    {
                        this.Outputs.CreateNewTxOut().ReadWrite(stream);
                    }
                    else
                    {
                        Outputs[nOutput].ReadWrite(stream);
                    }
                }

                stream.ReadWriteStruct(LockTime);
                stream.ReadWrite((uint)nHashType);
                return(GetHash(stream));
            }
コード例 #24
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
		{
			var scriptSig = tx.Inputs[i].ScriptSig;
			return VerifyScript(scriptSig, scriptPubKey, tx, i, scriptVerify, sigHash, out error);
		}
コード例 #25
0
        public static byte[] SignatureHash(Script script, Transaction txTo, int inIdx, SigHash hashtype)
        {
            Ensure.InRange(nameof(inIdx), inIdx, 0, txTo.Inputs.Count);

            var tx = txTo.Clone();

            foreach (var input in tx.Inputs)
            {
                input.ScriptSig = Empty;
            }

            tx.Inputs[inIdx].ScriptSig = FindAndDelete(script, new Op(Opcode.OP_CODESEPARATOR));

            switch (hashtype)
            {
            case SigHash.None:
                tx.Outputs.Clear();

                foreach (var input in tx.Inputs.Where((x, i) => i != inIdx))
                {
                    input.Sequence = 0;
                }
                break;

            case SigHash.Single:
                var outIdx = inIdx;

                if (outIdx >= tx.Outputs.Count)
                {
                    throw new IndexOutOfRangeException();
                }

                var output = tx.Outputs[outIdx];
                tx.Outputs.Clear();

                for (var i = 0; i < outIdx; i++)
                {
                    tx.Outputs.Add(new TxOut());
                }
                tx.Outputs.Add(output);

                foreach (var input in tx.Inputs.Where((x, i) => i != inIdx))
                {
                    input.Sequence = 0;
                }
                break;

            case SigHash.AnyoneCanPay:
                var theInput = tx.Inputs[inIdx];
                tx.Inputs = new List <TxIn> {
                    theInput
                };
                break;
            }

            var s = Packer.Pack("AI", tx.ToByteArray(), hashtype);

            return(Hashes.Hash256(s));
        }
コード例 #26
0
 public TransactionSignature(byte[] sig, SigHash sigHash)
 {
     _Signature = ECDSASignature.FromDER(sig).MakeCanonical();
     _SigHash   = sigHash;
 }
コード例 #27
0
ファイル: Key.cs プロジェクト: bug-air-drop/NBitcoin.Wicc
 public TransactionSignature Sign(uint256 hash, SigHash sigHash, bool useLowR = true)
 {
     return(new TransactionSignature(Sign(hash, useLowR), sigHash));
 }
コード例 #28
0
ファイル: Transaction.cs プロジェクト: n1rvana/NBitcoin
 public TransactionSignature SignInput(ISecret secret, ICoin coin, SigHash sigHash = SigHash.All)
 {
     return(SignInput(secret.PrivateKey, coin, sigHash));
 }
コード例 #29
0
 public TransactionSignature Sign(uint256 hash, SigHash sigHash)
 {
     return(new TransactionSignature(Sign(hash), sigHash));
 }
コード例 #30
0
ファイル: Transaction.cs プロジェクト: n1rvana/NBitcoin
        public TransactionSignature Sign(Key key, ICoin coin, SigHash sigHash)
        {
            var hash = GetSignatureHash(coin, sigHash);

            return(key.Sign(hash, sigHash));
        }
コード例 #31
0
        public static bool VerifyScript(Script scriptSig, Transaction tx, int i, TxOut spentOutput, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
        {
            if (spentOutput == null)
            {
                throw new ArgumentNullException(nameof(spentOutput));
            }
            var eval = new ScriptEvaluationContext
            {
                SigHash      = sigHash,
                ScriptVerify = scriptVerify
            };
            var result = eval.VerifyScript(scriptSig, tx, i, spentOutput);

            error = eval.Error;
            return(result);
        }
コード例 #32
0
ファイル: Script.cs プロジェクト: eccentricbiped/NBitcoin
        public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined)
        {
            ScriptError unused;

            return(VerifyScript(scriptSig, scriptPubKey, tx, i, null, scriptVerify, sigHash, out unused));
        }
コード例 #33
0
 public static uint256 SignatureHash(ICoin coin, Transaction txTo, SigHash nHashType = SigHash.All)
 {
     return(txTo.GetSignatureHash(coin, nHashType));
 }
コード例 #34
0
ファイル: Script.cs プロジェクト: n1rvana/NBitcoin
        public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, Money value, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
        {
            var scriptSig = tx.Inputs[i].ScriptSig;

            return(VerifyScript(scriptSig, scriptPubKey, tx, i, value, scriptVerify, sigHash, out error));
        }
コード例 #35
0
 public static uint256 SignatureHash(Script scriptCode, Transaction txTo, int nIn, SigHash nHashType, Money amount = null, HashVersion sigversion = HashVersion.Original)
 {
     return(txTo.GetSignatureHash(scriptCode, nIn, nHashType, amount, sigversion, null));
 }
コード例 #36
0
ファイル: Script.cs プロジェクト: n1rvana/NBitcoin
        //https://en.bitcoin.it/wiki/OP_CHECKSIG
        public static uint256 SignatureHash(Script scriptCode, Transaction txTo, int nIn, SigHash nHashType, Money amount = null, HashVersion sigversion = HashVersion.Original)
        {
            if (sigversion == HashVersion.Witness)
            {
                if (amount == null)
                {
                    throw new ArgumentException("The amount of the output being signed must be provided", "amount");
                }
                uint256 hashPrevouts = uint256.Zero;
                uint256 hashSequence = uint256.Zero;
                uint256 hashOutputs  = uint256.Zero;

                if ((nHashType & SigHash.AnyoneCanPay) == 0)
                {
                    BitcoinStream ss = CreateHashWriter(sigversion);
                    foreach (var input in txTo.Inputs)
                    {
                        ss.ReadWrite(input.PrevOut);
                    }
                    hashPrevouts = GetHash(ss);                     // TODO: cache this value for all signatures in a transaction
                }

                if ((nHashType & SigHash.AnyoneCanPay) == 0 && ((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
                {
                    BitcoinStream ss = CreateHashWriter(sigversion);
                    foreach (var input in txTo.Inputs)
                    {
                        ss.ReadWrite(input.Sequence);
                    }
                    hashSequence = GetHash(ss);                     // TODO: cache this value for all signatures in a transaction
                }

                if (((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
                {
                    BitcoinStream ss = CreateHashWriter(sigversion);
                    foreach (var txout in txTo.Outputs)
                    {
                        ss.ReadWrite(txout);
                    }
                    hashOutputs = GetHash(ss);                     // TODO: cache this value for all signatures in a transaction
                }
                else if (((uint)nHashType & 0x1f) == (uint)SigHash.Single && nIn < txTo.Outputs.Count)
                {
                    BitcoinStream ss = CreateHashWriter(sigversion);
                    ss.ReadWrite(txTo.Outputs[nIn]);
                    hashOutputs = GetHash(ss);
                }

                BitcoinStream sss = CreateHashWriter(sigversion);
                // Version
                sss.ReadWrite(txTo.Version);
                // Input prevouts/nSequence (none/all, depending on flags)
                sss.ReadWrite(hashPrevouts);
                sss.ReadWrite(hashSequence);
                // The input being signed (replacing the scriptSig with scriptCode + amount)
                // The prevout may already be contained in hashPrevout, and the nSequence
                // may already be contain in hashSequence.
                sss.ReadWrite(txTo.Inputs[nIn].PrevOut);
                sss.ReadWrite(scriptCode);
                sss.ReadWrite(amount.Satoshi);
                sss.ReadWrite(txTo.Inputs[nIn].Sequence);
                // Outputs (none/one/all, depending on flags)
                sss.ReadWrite(hashOutputs);
                // Locktime
                sss.ReadWriteStruct(txTo.LockTime);
                // Sighash type
                sss.ReadWrite((uint)nHashType);

                return(GetHash(sss));
            }



            if (nIn >= txTo.Inputs.Count)
            {
                Utils.log("ERROR: SignatureHash() : nIn=" + nIn + " out of range\n");
                return(uint256.One);
            }

            // Check for invalid use of SIGHASH_SINGLE
            if (nHashType == SigHash.Single)
            {
                if (nIn >= txTo.Outputs.Count)
                {
                    Utils.log("ERROR: SignatureHash() : nOut=" + nIn + " out of range\n");
                    return(uint256.One);
                }
            }

            var scriptCopy = new Script(scriptCode._Script);

            scriptCopy.FindAndDelete(OpcodeType.OP_CODESEPARATOR);

            var txCopy = new Transaction(txTo.ToBytes());

            //Set all TxIn script to empty string
            foreach (var txin in txCopy.Inputs)
            {
                txin.ScriptSig = new Script();
            }
            //Copy subscript into the txin script you are checking
            txCopy.Inputs[nIn].ScriptSig = scriptCopy;

            var hashType = nHashType & (SigHash)31;

            if (hashType == SigHash.None)
            {
                //The output of txCopy is set to a vector of zero size.
                txCopy.Outputs.Clear();

                //All other inputs aside from the current input in txCopy have their nSequence index set to zero
                foreach (var input in txCopy.Inputs.Where((x, i) => i != nIn))
                {
                    input.Sequence = 0;
                }
            }
            else if (hashType == SigHash.Single)
            {
                //The output of txCopy is resized to the size of the current input index+1.
                txCopy.Outputs.RemoveRange(nIn + 1, txCopy.Outputs.Count - (nIn + 1));
                //All other txCopy outputs aside from the output that is the same as the current input index are set to a blank script and a value of (long) -1.
                for (var i = 0; i < txCopy.Outputs.Count; i++)
                {
                    if (i == nIn)
                    {
                        continue;
                    }
                    txCopy.Outputs[i] = new TxOut();
                }
                //All other txCopy inputs aside from the current input are set to have an nSequence index of zero.
                foreach (var input in txCopy.Inputs.Where((x, i) => i != nIn))
                {
                    input.Sequence = 0;
                }
            }


            if ((nHashType & SigHash.AnyoneCanPay) != 0)
            {
                //The txCopy input vector is resized to a length of one.
                var script = txCopy.Inputs[nIn];
                txCopy.Inputs.Clear();
                txCopy.Inputs.Add(script);
                //The subScript (lead in by its length as a var-integer encoded!) is set as the first and only member of this vector.
                txCopy.Inputs[0].ScriptSig = scriptCopy;
            }


            //Serialize TxCopy, append 4 byte hashtypecode
            var stream = CreateHashWriter(sigversion);

            txCopy.ReadWrite(stream);
            stream.ReadWrite((uint)nHashType);
            return(GetHash(stream));
        }
コード例 #37
0
 public static uint256 SignatureHash(Script scriptCode, Transaction txTo, int nIn, SigHash nHashType, Money amount, HashVersion sigversion, PrecomputedTransactionData precomputedTransactionData)
 {
     return(txTo.GetSignatureHash(scriptCode, nIn, nHashType, amount, sigversion, precomputedTransactionData));
 }
コード例 #38
0
 public TransactionSignature(byte[] sigSigHash)
 {
     _Signature = ECDSASignature.FromDER(sigSigHash.Take(sigSigHash.Length - 1).ToArray()).MakeCanonical();
     _SigHash = (SigHash)sigSigHash[sigSigHash.Length - 1];
 }
コード例 #39
0
        public static bool VerifyScript(Transaction tx, int i, TxOut spentOutput, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined)
        {
            ScriptError unused;
            var         scriptSig = tx.Inputs[i].ScriptSig;

            return(VerifyScript(scriptSig, tx, i, spentOutput, scriptVerify, sigHash, out unused));
        }
コード例 #40
0
ファイル: Transaction.cs プロジェクト: aklein53/bitcoinsharp
        /// <summary>
        /// Once a transaction has some inputs and outputs added, the signatures in the inputs can be calculated. The
        /// signature is over the transaction itself, to prove the redeemer actually created that transaction,
        /// so we have to do this step last.
        /// </summary>
        /// <remarks>
        /// This method is similar to SignatureHash in script.cpp
        /// </remarks>
        /// <param name="hashType">This should always be set to SigHash.ALL currently. Other types are unused. </param>
        /// <param name="wallet">A wallet is required to fetch the keys needed for signing.</param>
        /// <exception cref="ScriptException"/>
        public void SignInputs(SigHash hashType, Wallet wallet)
        {
            Debug.Assert(_inputs.Count > 0);
            Debug.Assert(_outputs.Count > 0);

            // I don't currently have an easy way to test other modes work, as the official client does not use them.
            Debug.Assert(hashType == SigHash.All);

            // The transaction is signed with the input scripts empty except for the input we are signing. In the case
            // where addInput has been used to set up a new transaction, they are already all empty. The input being signed
            // has to have the connected OUTPUT program in it when the hash is calculated!
            //
            // Note that each input may be claiming an output sent to a different key. So we have to look at the outputs
            // to figure out which key to sign with.

            var signatures = new byte[_inputs.Count][];
            var signingKeys = new EcKey[_inputs.Count];
            for (var i = 0; i < _inputs.Count; i++)
            {
                var input = _inputs[i];
                Debug.Assert(input.ScriptBytes.Length == 0, "Attempting to sign a non-fresh transaction");
                // Set the input to the script of its output.
                input.ScriptBytes = input.Outpoint.ConnectedPubKeyScript;
                // Find the signing key we'll need to use.
                var connectedPubKeyHash = input.Outpoint.ConnectedPubKeyHash;
                var key = wallet.FindKeyFromPubHash(connectedPubKeyHash);
                // This assert should never fire. If it does, it means the wallet is inconsistent.
                Debug.Assert(key != null, "Transaction exists in wallet that we cannot redeem: " + Utils.BytesToHexString(connectedPubKeyHash));
                // Keep the key around for the script creation step below.
                signingKeys[i] = key;
                // The anyoneCanPay feature isn't used at the moment.
                const bool anyoneCanPay = false;
                var hash = HashTransactionForSignature(hashType, anyoneCanPay);
                // Set the script to empty again for the next input.
                input.ScriptBytes = TransactionInput.EmptyArray;

                // Now sign for the output so we can redeem it. We use the keypair to sign the hash,
                // and then put the resulting signature in the script along with the public key (below).
                using (var bos = new MemoryStream())
                {
                    bos.Write(key.Sign(hash));
                    bos.Write((byte) (((int) hashType + 1) | (anyoneCanPay ? 0x80 : 0)));
                    signatures[i] = bos.ToArray();
                }
            }

            // Now we have calculated each signature, go through and create the scripts. Reminder: the script consists of
            // a signature (over a hash of the transaction) and the complete public key needed to sign for the connected
            // output.
            for (var i = 0; i < _inputs.Count; i++)
            {
                var input = _inputs[i];
                Debug.Assert(input.ScriptBytes.Length == 0);
                var key = signingKeys[i];
                input.ScriptBytes = Script.CreateInputScript(signatures[i], key.PubKey);
            }

            // Every input is now complete.
        }
コード例 #41
0
        public static bool VerifyScript(Transaction tx, int i, TxOut spentOutput, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
        {
            var scriptSig = tx.Inputs[i].ScriptSig;

            return(VerifyScript(scriptSig, tx, i, spentOutput, scriptVerify, sigHash, out error));
        }
コード例 #42
0
ファイル: Script.cs プロジェクト: knocte/NBitcoin
		//https://en.bitcoin.it/wiki/OP_CHECKSIG
		public static uint256 SignatureHash(ICoin coin, Transaction txTo, SigHash nHashType = SigHash.All)
		{
			var input = txTo.Inputs.AsIndexedInputs().FirstOrDefault(i => i.PrevOut == coin.Outpoint);
			if(input == null)
				throw new ArgumentException("coin should be spent spent in txTo", "coin");
			return input.GetSignatureHash(coin, nHashType);
		}
コード例 #43
0
 private bool UsesForkId(SigHash nHashType)
 {
     return(((uint)nHashType & 0x40u) != 0);
 }
コード例 #44
0
ファイル: Script.cs プロジェクト: knocte/NBitcoin
		public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, Money value, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined)
		{
			ScriptError unused;
			return VerifyScript(scriptSig, scriptPubKey, tx, i, value, scriptVerify, sigHash, out unused);
		}
コード例 #45
0
        public override uint256 GetSignatureHash(Script scriptCode, int nIn, SigHash nHashType, Money amount, HashVersion sigversion, PrecomputedTransactionData precomputedTransactionData)
        {
            uint nForkHashType = (uint)nHashType;

            if (UsesForkId(nHashType))
            {
                nForkHashType |= ForkId << 8;
            }

            if ((SupportSegwit && sigversion == HashVersion.Witness) || UsesForkId(nHashType))
            {
                if (amount == null)
                {
                    throw new ArgumentException("The amount of the output being signed must be provided", "amount");
                }
                uint256 hashPrevouts = uint256.Zero;
                uint256 hashSequence = uint256.Zero;
                uint256 hashOutputs  = uint256.Zero;

                if ((nHashType & SigHash.AnyoneCanPay) == 0)
                {
                    hashPrevouts = precomputedTransactionData == null?
                                   GetHashPrevouts() : precomputedTransactionData.HashPrevouts;
                }

                if ((nHashType & SigHash.AnyoneCanPay) == 0 && ((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
                {
                    hashSequence = precomputedTransactionData == null?
                                   GetHashSequence() : precomputedTransactionData.HashSequence;
                }

                if (((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
                {
                    hashOutputs = precomputedTransactionData == null?
                                  GetHashOutputs() : precomputedTransactionData.HashOutputs;
                }
                else if (((uint)nHashType & 0x1f) == (uint)SigHash.Single && nIn < this.Outputs.Count)
                {
                    BitcoinStream ss = CreateHashWriter(sigversion);
                    ss.ReadWrite(this.Outputs[nIn]);
                    hashOutputs = GetHash(ss);
                }

                BitcoinStream sss = CreateHashWriter(sigversion);
                // Version
                sss.ReadWrite(this.Version);
                // Input prevouts/nSequence (none/all, depending on flags)
                sss.ReadWrite(hashPrevouts);
                sss.ReadWrite(hashSequence);
                // The input being signed (replacing the scriptSig with scriptCode + amount)
                // The prevout may already be contained in hashPrevout, and the nSequence
                // may already be contain in hashSequence.
                sss.ReadWrite(Inputs[nIn].PrevOut);
                sss.ReadWrite(scriptCode);
                sss.ReadWrite(amount.Satoshi);
                sss.ReadWrite((uint)Inputs[nIn].Sequence);
                // Outputs (none/one/all, depending on flags)
                sss.ReadWrite(hashOutputs);
                // Locktime
                sss.ReadWriteStruct(LockTime);
                // Sighash type
                sss.ReadWrite((uint)nForkHashType);

                return(GetHash(sss));
            }



            if (nIn >= Inputs.Count)
            {
                return(uint256.One);
            }

            var hashType = nHashType & (SigHash)31;

            // Check for invalid use of SIGHASH_SINGLE
            if (hashType == SigHash.Single)
            {
                if (nIn >= Outputs.Count)
                {
                    return(uint256.One);
                }
            }

            var scriptCopy = scriptCode.Clone();

            scriptCode = scriptCopy.FindAndDelete(OpcodeType.OP_CODESEPARATOR);

            var txCopy = GetConsensusFactory().CreateTransaction();

            txCopy.FromBytes(this.ToBytes());
            //Set all TxIn script to empty string
            foreach (var txin in txCopy.Inputs)
            {
                txin.ScriptSig = new Script();
            }
            //Copy subscript into the txin script you are checking
            txCopy.Inputs[nIn].ScriptSig = scriptCopy;

            if (hashType == SigHash.None)
            {
                //The output of txCopy is set to a vector of zero size.
                txCopy.Outputs.Clear();

                //All other inputs aside from the current input in txCopy have their nSequence index set to zero
                foreach (var input in txCopy.Inputs.Where((x, i) => i != nIn))
                {
                    input.Sequence = 0;
                }
            }
            else if (hashType == SigHash.Single)
            {
                //The output of txCopy is resized to the size of the current input index+1.
                txCopy.Outputs.RemoveRange(nIn + 1, txCopy.Outputs.Count - (nIn + 1));
                //All other txCopy outputs aside from the output that is the same as the current input index are set to a blank script and a value of (long) -1.
                for (var i = 0; i < txCopy.Outputs.Count; i++)
                {
                    if (i == nIn)
                    {
                        continue;
                    }
                    txCopy.Outputs[i] = new TxOut();
                }
                //All other txCopy inputs aside from the current input are set to have an nSequence index of zero.
                foreach (var input in txCopy.Inputs.Where((x, i) => i != nIn))
                {
                    input.Sequence = 0;
                }
            }


            if ((nHashType & SigHash.AnyoneCanPay) != 0)
            {
                //The txCopy input vector is resized to a length of one.
                var script = txCopy.Inputs[nIn];
                txCopy.Inputs.Clear();
                txCopy.Inputs.Add(script);
                //The subScript (lead in by its length as a var-integer encoded!) is set as the first and only member of this vector.
                txCopy.Inputs[0].ScriptSig = scriptCopy;
            }


            //Serialize TxCopy, append 4 byte hashtypecode
            var stream = CreateHashWriter(sigversion);

            txCopy.ReadWrite(stream);
            stream.ReadWrite((uint)nForkHashType);
            return(GetHash(stream));
        }
コード例 #46
0
ファイル: Key.cs プロジェクト: woutersmit/NBitcoin
		public TransactionSignature Sign(uint256 hash, SigHash sigHash)
		{
			return new TransactionSignature(Sign(hash), sigHash);
		}
コード例 #47
0
        //https://en.bitcoin.it/wiki/OP_CHECKSIG
        public uint256 SignatureHash(Transaction txTo, int nIn, SigHash nHashType)
        {
            if (nIn >= txTo.Inputs.Count)
            {
                Utils.log("ERROR: SignatureHash() : nIn=" + nIn + " out of range\n");
                return(1);
            }

            // Check for invalid use of SIGHASH_SINGLE
            if (nHashType == SigHash.Single)
            {
                if (nIn >= txTo.Outputs.Count)
                {
                    Utils.log("ERROR: SignatureHash() : nOut=" + nIn + " out of range\n");
                    return(1);
                }
            }

            var scriptCopy = new Script(_Script);

            scriptCopy.FindAndDelete(OpcodeType.OP_CODESEPARATOR);

            var txCopy = new Transaction(txTo.ToBytes());

            //Set all TxIn script to empty string
            foreach (var txin in txCopy.Inputs)
            {
                txin.ScriptSig = new Script();
            }
            //Copy subscript into the txin script you are checking
            txCopy.Inputs[nIn].ScriptSig = scriptCopy;

            if (((int)nHashType & 31) == (int)SigHash.None)
            {
                //The output of txCopy is set to a vector of zero size.
                txCopy.Outputs.Clear();
                //All other inputs aside from the current input in txCopy have their nSequence index set to zero
                for (int i = 0; i < txCopy.Inputs.Count; i++)
                {
                    if (i == nIn)
                    {
                        continue;
                    }
                    txCopy.Inputs[i].Sequence = 0;
                }
            }

            if (((int)nHashType & 31) == (int)SigHash.Single)
            {
                //The output of txCopy is resized to the size of the current input index+1.
                var remainingOut = txCopy.Outputs.Take(nIn + 1).ToArray();
                txCopy.Outputs.Clear();
                txCopy.Outputs.AddRange(remainingOut);
                //All other txCopy outputs aside from the output that is the same as the current input index are set to a blank script and a value of (long) -1.
                for (int i = 0; i < txCopy.Outputs.Count; i++)
                {
                    if (i == nIn)
                    {
                        continue;
                    }
                    txCopy.Outputs[i] = new TxOut();
                }
                for (int i = 0; i < txCopy.Inputs.Count; i++)
                {
                    //All other txCopy inputs aside from the current input are set to have an nSequence index of zero.
                    if (i == nIn)
                    {
                        continue;
                    }
                    txCopy.Inputs[i].Sequence = 0;
                }
            }

            if (((int)nHashType & (int)SigHash.AnyoneCanPay) != 0)
            {
                //The txCopy input vector is resized to a length of one.
                var script = txCopy.Inputs[nIn];
                txCopy.Inputs.Clear();
                txCopy.Inputs.Add(script);
                //The subScript (lead in by its length as a var-integer encoded!) is set as the first and only member of this vector.
                txCopy.Inputs[0].ScriptSig = scriptCopy;
            }


            //Serialize TxCopy, append 4 byte hashtypecode
            MemoryStream  ms            = new MemoryStream();
            BitcoinStream bitcoinStream = new BitcoinStream(ms, true);

            txCopy.ReadWrite(bitcoinStream);
            bitcoinStream.ReadWrite((uint)nHashType);

            var hashed = ms.ToArray();

            return(Hashes.Hash256(hashed));
        }
コード例 #48
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined)
		{
			ScriptError unused;
			var scriptSig = tx.Inputs[i].ScriptSig;
			return VerifyScript(scriptSig, scriptPubKey, tx, i, scriptVerify, sigHash, out unused);
		}
コード例 #49
0
        public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify = ScriptVerify.StrictEnc | ScriptVerify.P2SH, SigHash sigHash = SigHash.Undefined)
        {
            ScriptEvaluationContext eval = new ScriptEvaluationContext();

            eval.SigHash      = sigHash;
            eval.ScriptVerify = scriptVerify;
            return(eval.VerifyScript(scriptSig, scriptPubKey, tx, i));
        }
コード例 #50
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
		{
			var eval = new ScriptEvaluationContext
			{
				SigHash = sigHash,
				ScriptVerify = scriptVerify
			};
			var result = eval.VerifyScript(scriptSig, scriptPubKey, tx, i);
			error = eval.Error;
			return result;
		}
コード例 #51
0
ファイル: TransactionBuilder.cs プロジェクト: crowar/NBitcoin
		public Transaction SignTransaction(Transaction transaction, SigHash sigHash)
		{
			var tx = transaction.Clone();
			SignTransactionInPlace(tx, sigHash);
			return tx;
		}