Beispiel #1
0
        public ScriptId ExtractScriptPubKeyParameters(Script scriptPubKey)
        {
            bool needMoreCheck;

            if (!FastCheckScriptPubKey(scriptPubKey, out needMoreCheck))
            {
                return(null);
            }
            return(new ScriptId(scriptPubKey.ToBytes(true).SafeSubarray(2, 20)));
        }
Beispiel #2
0
        public override bool CheckScriptPubKey(Script scriptPubKey)
        {
            if (scriptPubKey == null)
            {
                throw new ArgumentNullException(nameof(scriptPubKey));
            }
            var bytes = scriptPubKey.ToBytes(true);

            return(bytes.Length == 34 && bytes[0] == 0 && bytes[1] == 32);
        }
Beispiel #3
0
 public new WitScriptId ExtractScriptPubKeyParameters(Script scriptPubKey)
 {
     if (!CheckScriptPubKey(scriptPubKey))
     {
         return(null);
     }
     byte[] data = new byte[32];
     Array.Copy(scriptPubKey.ToBytes(true), 2, data, 0, 32);
     return(new WitScriptId(data));
 }
Beispiel #4
0
 protected override bool FastCheckScriptPubKey(Script scriptPubKey, out bool needMoreCheck)
 {
     byte[] bytes = scriptPubKey.ToBytes(true);
     needMoreCheck = false;
     return(bytes.Length == 25 &&
            bytes[0] == (byte)OpcodeType.OP_DUP &&
            bytes[1] == (byte)OpcodeType.OP_HASH160 &&
            bytes[2] == 0x14 &&
            bytes[24] == (byte)OpcodeType.OP_CHECKSIG);
 }
Beispiel #5
0
        /// <summary>
        /// Adds a scriptPubKey to the list of elements that will be used for building the filter.
        /// </summary>
        /// <param name="scriptPubkey">The scriptPubkey.</param>
        /// <returns>The updated filter builder instance.</returns>
        public GolombRiceFilterBuilder AddScriptPubkey(Script scriptPubkey)
        {
            if (scriptPubkey == null)
            {
                throw new ArgumentNullException(nameof(scriptPubkey));
            }

            _values.Add(scriptPubkey.ToBytes());
            return(this);
        }
Beispiel #6
0
        public static bool VerifyScriptConsensus(Script scriptPubKey, Transaction tx, uint nIn, Money amount, ScriptVerify flags, out BitcoinConsensusError err)
        {
            var scriptPubKeyBytes = scriptPubKey.ToBytes();
            var txToBytes         = tx.ToBytes();

            err = BitcoinConsensusError.ERR_OK;
            var valid = VerifyScriptConsensusWithAmount(scriptPubKeyBytes, (uint)scriptPubKeyBytes.Length, amount.Satoshi, txToBytes, (uint)txToBytes.Length, nIn, flags, ref err);

            return(valid == 1);
        }
Beispiel #7
0
        public static bool VerifyScriptConsensus(Script scriptPubKey, Transaction tx, uint nIn, ScriptVerify flags)
        {
            var scriptPubKeyBytes = scriptPubKey.ToBytes();
            var txToBytes         = tx.ToBytes();

            var err   = BitcoinConsensusError.ERR_OK;
            var valid = VerifyScriptConsensus(scriptPubKeyBytes, (uint)scriptPubKeyBytes.Length, txToBytes, (uint)txToBytes.Length, nIn, flags, ref err);

            return(valid == 1);
        }
Beispiel #8
0
        public Script GenerateScriptSig(byte[][] pushes, Script redeemScript)
        {
            List <Op> ops = new List <Op>();

            foreach (var push in pushes)
            {
                ops.Add(Op.GetPushOp(push));
            }
            ops.Add(Op.GetPushOp(redeemScript.ToBytes(true)));
            return(new Script(ops));
        }
        protected override bool FastCheckScriptPubKey(Script scriptPubKey, out bool needMoreCheck)
        {
            var bytes = scriptPubKey.ToBytes(true);

            needMoreCheck = false;
            return
                (bytes.Length == 23 &&
                 bytes[0] == (byte)OpcodeType.OP_HASH160 &&
                 bytes[1] == 0x14 &&
                 bytes[22] == (byte)OpcodeType.OP_EQUAL);
        }
        public new WitKeyId ExtractScriptPubKeyParameters(Network network, Script scriptPubKey)
        {
            if (!CheckScriptPubKey(scriptPubKey))
            {
                return(null);
            }
            var data = new byte[20];

            Array.Copy(scriptPubKey.ToBytes(true), 2, data, 0, 20);
            return(new WitKeyId(data));
        }
		protected override bool CheckScriptPubKeyCore(Script scriptPubKey, Op[] scriptPubKeyOps)
		{
			var ops = scriptPubKeyOps;
			if(ops.Length < 1)
				return false;
			if(ops[0].Code != OpcodeType.OP_RETURN)
				return false;
			if(scriptPubKey.ToBytes(true).Length > MaxScriptSizeLimit)
				return false;
			return scriptPubKeyOps.Skip(1).All(o => o.PushData != null && !o.IsInvalid);
		}
Beispiel #12
0
        /// <summary>
        /// Adds a scriptPubKey to the list of elements that will be used for building the filter.
        /// </summary>
        /// <param name="scriptPubkey">The scriptPubkey.</param>
        /// <returns>The updated filter builder instance.</returns>
        public GolombRiceFilterBuilder AddScriptPubkey(Script scriptPubkey)
        {
            if (scriptPubkey == null)
            {
                throw new ArgumentNullException(nameof(scriptPubkey));
            }

            // Unsafe is OK because Script is readonly and we do not modify the arrays inside values
            _values.Add(scriptPubkey.ToBytes(true));
            return(this);
        }
 protected override bool FastCheckScriptSig(Script scriptSig, Script scriptPubKey, out bool needMoreCheck)
 {
     byte[] bytes = scriptSig.ToBytes(true);
     if (bytes.Length == 0 ||
         bytes[0] != (byte)OpcodeType.OP_0)
     {
         needMoreCheck = false;
         return(false);
     }
     needMoreCheck = true;
     return(true);
 }
Beispiel #14
0
        private static Script CombineSignatures(Script scriptPubKey, TransactionChecker checker, byte[][] sigs1, byte[][] sigs2, HashVersion hashVersion)
        {
            var template = StandardScripts.GetTemplateFromScriptPubKey(scriptPubKey);

            if (template is PayToWitPubKeyHashTemplate)
            {
                scriptPubKey = new KeyId(scriptPubKey.ToBytes(true).SafeSubarray(1, 20)).ScriptPubKey;
                template     = StandardScripts.GetTemplateFromScriptPubKey(scriptPubKey);
            }
            if (template == null || template is TxNullDataTemplate)
            {
                return(PushAll(Max(sigs1, sigs2)));
            }

            if (template is PayToPubkeyTemplate || template is PayToPubkeyHashTemplate)
            {
                if (sigs1.Length == 0 || sigs1[0].Length == 0)
                {
                    return(PushAll(sigs2));
                }
                else
                {
                    return(PushAll(sigs1));
                }
            }
            if (template is PayToScriptHashTemplate || template is PayToWitTemplate)
            {
                if (sigs1.Length == 0 || sigs1[sigs1.Length - 1].Length == 0)
                {
                    return(PushAll(sigs2));
                }

                if (sigs2.Length == 0 || sigs2[sigs2.Length - 1].Length == 0)
                {
                    return(PushAll(sigs1));
                }

                var redeemBytes = sigs1[sigs1.Length - 1];
                var redeem      = new Script(redeemBytes);
                sigs1 = sigs1.Take(sigs1.Length - 1).ToArray();
                sigs2 = sigs2.Take(sigs2.Length - 1).ToArray();
                Script result = CombineSignatures(redeem, checker, sigs1, sigs2, hashVersion);
                result += Op.GetPushOp(redeemBytes);
                return(result);
            }

            if (template is PayToMultiSigTemplate)
            {
                return(CombineMultisig(scriptPubKey, checker, sigs1, sigs2, hashVersion));
            }

            return(null);
        }
Beispiel #15
0
        public WitProgramParameters?ExtractScriptPubKeyParameters2(Script scriptPubKey)
        {
            if (!CheckScriptPubKey(scriptPubKey))
            {
                return(null);
            }
            var bytes   = scriptPubKey.ToBytes(true);
            var program = new byte[bytes.Length - 2];

            Array.Copy(bytes, 2, program, 0, program.Length);
            return(new WitProgramParameters((OpcodeType)bytes[0], program));;
        }
 protected override bool FastCheckScriptPubKey(Script scriptPubKey, out bool needMoreCheck)
 {
     byte[] bytes = scriptPubKey.ToBytes(true);
     if (bytes.Length == 0 ||
         bytes[0] != (byte)OpcodeType.OP_RETURN ||
         bytes.Length > this.MaxScriptSizeLimit)
     {
         needMoreCheck = false;
         return(false);
     }
     needMoreCheck = true;
     return(true);
 }
		protected override bool FastCheckScriptPubKey(Script scriptPubKey, out bool needMoreCheck)
		{
			var bytes = scriptPubKey.ToBytes(true);
			if(bytes.Length == 0 ||
				bytes[0] != (byte)OpcodeType.OP_RETURN ||
				bytes.Length > MaxScriptSizeLimit)
			{
				needMoreCheck = false;
				return false;
			}
			needMoreCheck = true;
			return true;
		}
        /// <summary>
        /// Initializes an instance of the <see cref="ScriptPubKey"/> class.
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="network">The network where the transaction was conducted.</param>
        public ScriptPubKey(NBitcoin.Script script, Network network) : base(script)
        {
            this.Type = this.GetScriptType(script.FindTemplate(network));

            // To avoid modifying the very low-level GetDestination logic, check for a cold staking script first.
            // The decision to show the cold pubkey's address in the 'addresses' list is based on the following:
            // 1. It seems more intuitive from a user's perspective that their balance will appear against this address.
            // 2. A balance should never appear against a hot address from an exchange's perspective, as they have no guarantee they will be able to spend those funds.
            // It is also presumed that it is preferable to show an address rather than not, as a block explorer would then have to show only a relatively meaningless raw script as the output's destination.
            // Another considered alternative was to show both addresses, but with a modified version byte. The underlying pubkey hashes would be the same, but the resulting addresses would be visually distinct from regular P2PKH.
            // This may have caused user confusion, however, as the modified addresses would not look like those they used to configure the cold staking setup, making searching for them on a block explorer more difficult.
            if (script.IsScriptType(ScriptType.ColdStaking))
            {
                var coldPubKeyHash = new KeyId(script.ToBytes(true).SafeSubarray(28, 20));

                this.ReqSigs   = 1;
                this.Addresses = new List <string> {
                    coldPubKeyHash.GetAddress(network).ToString()
                };

                return;
            }

            var destinations = new List <TxDestination> {
                script.GetDestination(network)
            };

            if (destinations[0] == null)
            {
                destinations = script.GetDestinationPublicKeys(network).Select(p => p.Hash).ToList <TxDestination>();
            }

            // TODO: We do not want to put the cold staking addresses into the 'addresses' element due to the high potential for confusion. Maybe introduce an additional element?
            if (destinations.Count == 1)
            {
                this.ReqSigs   = 1;
                this.Addresses = new List <string> {
                    destinations[0].GetAddress(network).ToString()
                };
            }
            else if (destinations.Count > 1)
            {
                PayToMultiSigTemplateParameters multi = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(script) ??
                                                        PayToFederationTemplate.Instance.ExtractScriptPubKeyParameters(script, network);
                if (multi != null)
                {
                    this.ReqSigs   = multi.SignatureCount;
                    this.Addresses = multi.PubKeys.Select(m => m.GetAddress(network).ToString()).ToList();
                }
            }
        }
 public Vin(OutPoint prevOut, Sequence sequence, NBitcoin.Script scriptSig)
 {
     if (prevOut.Hash == uint256.Zero)
     {
         this.Coinbase = Encoders.Hex.EncodeData(scriptSig.ToBytes());
     }
     else
     {
         this.TxId      = prevOut.Hash.ToString();
         this.VOut      = prevOut.N;
         this.ScriptSig = new Script(scriptSig);
     }
     this.Sequence = (uint)sequence;
 }
Beispiel #20
0
        public Script ReadWrite(Script data)
        {
            if (this.Serializing)
            {
                var bytes = data == null?Script.Empty.ToBytes(true) : data.ToBytes(true);

                ReadWriteAsVarString(ref bytes);
                return(data);
            }

            var varString = new VarString();

            varString.ReadWrite(this);
            return(Script.FromBytesUnsafe(varString.GetString(true)));
        }
		public const int MAX_OP_RETURN_RELAY = 83; //! bytes (+1 for OP_RETURN, +2 for the pushdata opcodes)
		public Script GenerateScriptPubKey(params byte[][] data)
		{
			if(data == null)
				throw new ArgumentNullException("data");
			Op[] ops = new Op[data.Length + 1];
			ops[0] = OpcodeType.OP_RETURN;
			for(int i = 0; i <data.Length;i++)
			{
				ops[1 + i] = Op.GetPushOp(data[i]);
			}
			var script = new Script(ops);
			if(script.ToBytes(true).Length > MaxScriptSizeLimit)
				throw new ArgumentOutOfRangeException("data", "Data in OP_RETURN should have a maximum size of " + MaxScriptSizeLimit + " bytes");
			return script;
		}
Beispiel #22
0
        public PubKey?ExtractScriptPubKeyParameters(Script scriptPubKey)
        {
            bool needMoreCheck;

            if (!FastCheckScriptPubKey(scriptPubKey, out needMoreCheck))
            {
                return(null);
            }

            if (PubKey.TryCreatePubKey(scriptPubKey.ToBytes(true).SafeSubarray(1, scriptPubKey.Length - 2), out var pk))
            {
                return(pk);
            }
            return(null);
        }
Beispiel #23
0
        public WitScript GenerateWitScript(Op[] scriptSig, Script redeemScript)
        {
            if (redeemScript == null)
            {
                throw new ArgumentNullException("redeemScript");
            }
            if (scriptSig == null)
            {
                throw new ArgumentNullException("scriptSig");
            }

            var ops = scriptSig.Concat(new[] { Op.GetPushOp(redeemScript.ToBytes(true)) }).ToArray();

            return(new WitScript(ops));
        }
Beispiel #24
0
        public Script ReadWrite(Script data)
        {
            if (Serializing)
            {
                var bytes = data == null?Script.Empty.ToBytes(true) : data.ToBytes(true);

                ReadWriteAsVarString(ref bytes);
                return(data);
            }
            else
            {
                var varString = new VarString();
                varString.ReadWrite(this);
                return(new Script(varString.GetString()));
            }
        }
Beispiel #25
0
        public Script ReadWrite(Script data)
        {
            if (Serializing)
            {
                var bytes = data == null?Script.Empty.ToBytes(true) : data.ToBytes(true);

                ReadWriteAsVarString(ref bytes);
                return(data);
            }
            else
            {
                byte[] bytes = null;
                VarString.StaticRead(this, ref bytes);
                return(Script.FromBytesUnsafe(bytes));
            }
        }
 public WitScript GenerateWitScript(Script scriptSig, Script redeemScript)
 {
     if (redeemScript == null)
     {
         throw new ArgumentNullException("redeemScript");
     }
     if (scriptSig == null)
     {
         throw new ArgumentNullException("scriptSig");
     }
     if (!scriptSig.IsPushOnly)
     {
         throw new ArgumentException("The script sig should be push only", "scriptSig");
     }
     scriptSig = scriptSig + Op.GetPushOp(redeemScript.ToBytes(true));
     return(new WitScript(scriptSig));
 }
        /// <summary>
        ///     Extract the public key or null from the script, perform quick check on pubkey
        /// </summary>
        /// <param name="scriptPubKey"></param>
        /// <returns>The public key</returns>
        public PubKey ExtractScriptPubKeyParameters(Script scriptPubKey)
        {
            bool needMoreCheck;

            if (!FastCheckScriptPubKey(scriptPubKey, out needMoreCheck))
            {
                return(null);
            }
            try
            {
                return(new PubKey(scriptPubKey.ToBytes(true).SafeSubarray(1, scriptPubKey.Length - 2), true));
            }
            catch (FormatException)
            {
                return(null);
            }
        }
Beispiel #28
0
        protected override bool CheckScriptPubKeyCore(Script scriptPubKey, Op[] scriptPubKeyOps)
        {
            var ops = scriptPubKeyOps;

            if (ops.Length < 1)
            {
                return(false);
            }
            if (ops[0].Code != OpcodeType.OP_RETURN)
            {
                return(false);
            }
            if (scriptPubKey.ToBytes(true).Length > MaxScriptSizeLimit)
            {
                return(false);
            }
            return(scriptPubKeyOps.Skip(1).All(o => o.PushData != null && !o.IsInvalid));
        }
Beispiel #29
0
        public override bool CheckScriptPubKey(Script scriptPubKey)
        {
            if (scriptPubKey == null)
            {
                throw new ArgumentNullException(nameof(scriptPubKey));
            }
            var bytes = scriptPubKey.ToBytes(true);

            if (bytes.Length < 4 || bytes.Length > 42)
            {
                return(false);
            }
            if (!ValidSegwitVersion(bytes[0]))
            {
                return(false);
            }
            return(bytes[1] + 2 == bytes.Length);
        }
        public override bool CheckScriptPubKey(Script scriptPubKey)
        {
            if (scriptPubKey == null)
            {
                throw new ArgumentNullException("scriptPubKey");
            }
            byte[] bytes = scriptPubKey.ToBytes(true);
            if (bytes.Length < 4 || bytes.Length > 34)
            {
                return(false);
            }
            byte version = bytes[0];

            if (!ValidSegwitVersion(version))
            {
                return(false);
            }
            return(bytes[1] + 2 == bytes.Length);
        }
Beispiel #31
0
        public const int MAX_OP_RETURN_RELAY = 83;         //! bytes (+1 for OP_RETURN, +2 for the pushdata opcodes)
        public Script GenerateScriptPubKey(params byte[][] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            Op[] ops = new Op[data.Length + 1];
            ops[0] = OpcodeType.OP_RETURN;
            for (int i = 0; i < data.Length; i++)
            {
                ops[1 + i] = Op.GetPushOp(data[i]);
            }
            var script = new Script(ops);

            if (script.ToBytes(true).Length > MaxScriptSizeLimit)
            {
                throw new ArgumentOutOfRangeException("data", "Data in OP_RETURN should have a maximum size of " + MaxScriptSizeLimit + " bytes");
            }
            return(script);
        }
Beispiel #32
0
        private AddressIndexData GetOrCreateAddressData(Script scriptPubKey)
        {
            byte[] scriptPubKeyBytes = scriptPubKey.ToBytes();

            AddressIndexData addrData = this.addressesIndex.AddressIndexDatas.SingleOrDefault(x => StructuralComparisons.StructuralEqualityComparer.Equals(scriptPubKeyBytes, x.ScriptPubKeyBytes));

            if (addrData == null)
            {
                addrData = new AddressIndexData()
                {
                    ScriptPubKeyBytes = scriptPubKeyBytes,
                    Changes           = new List <AddressBalanceChange>()
                };

                this.addressesIndex.AddressIndexDatas.Add(addrData);
                return(addrData);
            }

            return(addrData);
        }
Beispiel #33
0
        public void Serialize(BitcoinStream stream)
        {
            if (redeem_script != null)
            {
                stream.ReadWriteAsVarInt(ref defaultKeyLen);
                stream.ReadWrite(PSBTConstants.PSBT_OUT_REDEEMSCRIPT);
                var value = redeem_script.ToBytes();
                stream.ReadWriteAsVarString(ref value);
            }

            if (witness_script != null)
            {
                stream.ReadWriteAsVarInt(ref defaultKeyLen);
                stream.ReadWrite(PSBTConstants.PSBT_OUT_WITNESSSCRIPT);
                var value = witness_script.ToBytes();
                stream.ReadWriteAsVarString(ref value);
            }

            foreach (var pathPair in hd_keypaths)
            {
                var key = new byte[] { PSBTConstants.PSBT_OUT_BIP32_DERIVATION }.Concat(pathPair.Key.ToBytes());
                stream.ReadWriteAsVarString(ref key);
                var path     = pathPair.Value.Item2.ToBytes();
                var pathInfo = pathPair.Value.Item1.ToBytes().Concat(path);
                stream.ReadWriteAsVarString(ref pathInfo);
            }

            foreach (var entry in unknown)
            {
                var k = entry.Key;
                var v = entry.Value;
                stream.ReadWriteAsVarString(ref k);
                stream.ReadWriteAsVarString(ref v);
            }

            var sep = PSBTConstants.PSBT_SEPARATOR;

            stream.ReadWrite(ref sep);
        }
		public new WitScriptId ExtractScriptPubKeyParameters(Script scriptPubKey)
		{
			if(!CheckScriptPubKey(scriptPubKey))
				return null;
			byte[] data = new byte[32];
			Array.Copy(scriptPubKey.ToBytes(true), 2, data, 0, 32);
			return new WitScriptId(data);
		}
		public override bool CheckScriptPubKey(Script scriptPubKey)
		{
			if(scriptPubKey == null)
				throw new ArgumentNullException("scriptPubKey");
			var bytes = scriptPubKey.ToBytes(true);
			return bytes.Length == 34 && bytes[0] == 0 && bytes[1] == 32;
		}
		public WitScript GenerateWitScript(Script scriptSig, Script redeemScript)
		{
			if(redeemScript == null)
				throw new ArgumentNullException("redeemScript");
			if(scriptSig == null)
				throw new ArgumentNullException("scriptSig");
			if(!scriptSig.IsPushOnly)
				throw new ArgumentException("The script sig should be push only", "scriptSig");
			scriptSig = scriptSig + Op.GetPushOp(redeemScript.ToBytes(true));
			return new WitScript(scriptSig);
		}
		public KeyId ExtractScriptPubKeyParameters(Script scriptPubKey)
		{
			bool needMoreCheck;
			if(!FastCheckScriptPubKey(scriptPubKey, out needMoreCheck))
				return null;
			return new KeyId(scriptPubKey.ToBytes(true).SafeSubarray(3, 20));
		}
		protected override bool FastCheckScriptPubKey(Script scriptPubKey, out bool needMoreCheck)
		{
			var bytes = scriptPubKey.ToBytes(true);
			needMoreCheck = false;
			return bytes.Length == 25 &&
				   bytes[0] == (byte)OpcodeType.OP_DUP &&
				   bytes[1] == (byte)OpcodeType.OP_HASH160 &&
				   bytes[2] == 0x14 &&
				   bytes[24] == (byte)OpcodeType.OP_CHECKSIG;
		}
		public PubKey ExtractScriptPubKeyParameters(Script script)
		{
			bool needMoreCheck;
			if(!FastCheckScriptPubKey(script, out needMoreCheck))
				return null;
			try
			{
				return new PubKey(script.ToBytes(true).SafeSubarray(1, script.Length - 2), true);
			}
			catch(FormatException)
			{
				return null;
			}
		}
		protected override bool FastCheckScriptPubKey(Script scriptPubKey, out bool needMoreCheck)
		{
			needMoreCheck = false;
			return
				 scriptPubKey.Length > 3 &&
				 PubKey.Check(scriptPubKey.ToBytes(true), 1, scriptPubKey.Length - 2, false) &&
				 scriptPubKey.ToBytes(true)[scriptPubKey.Length - 1] == 0xac;
		}
		public WitScript GenerateWitScript(Op[] scriptSig, Script redeemScript)
		{
			if(redeemScript == null)
				throw new ArgumentNullException("redeemScript");
			if(scriptSig == null)
				throw new ArgumentNullException("scriptSig");

			var ops = scriptSig.Concat(new[] { Op.GetPushOp(redeemScript.ToBytes(true)) }).ToArray();
			return new WitScript(ops);
		}
		protected override bool FastCheckScriptPubKey(Script scriptPubKey)
		{
			var bytes = scriptPubKey.ToBytes(true);
			return bytes.Length == 22 && bytes[0] == 0 && bytes[1] == 20;
		}
		public override bool CheckScriptPubKey(Script scriptPubKey)
		{
			if(scriptPubKey == null)
				throw new ArgumentNullException("scriptPubKey");
			var bytes = scriptPubKey.ToBytes(true);
			if(bytes.Length < 4 || bytes.Length > 34)
			{
				return false;
			}
			var version = bytes[0];
			if(!ValidSegwitVersion(version))
				return false;
			return bytes[1] + 2 == bytes.Length;
		}
Beispiel #44
0
		private static Script CombineSignatures(Script scriptPubKey, TransactionChecker checker, byte[][] sigs1, byte[][] sigs2, HashVersion hashVersion)
		{
			var template = StandardScripts.GetTemplateFromScriptPubKey(scriptPubKey);

			if(template is PayToWitPubKeyHashTemplate)
			{
				scriptPubKey = new KeyId(scriptPubKey.ToBytes(true).SafeSubarray(1, 20)).ScriptPubKey;
				template = StandardScripts.GetTemplateFromScriptPubKey(scriptPubKey);
			}
			if(template == null || template is TxNullDataTemplate)
				return PushAll(Max(sigs1, sigs2));

			if(template is PayToPubkeyTemplate || template is PayToPubkeyHashTemplate)
				if(sigs1.Length == 0 || sigs1[0].Length == 0)
					return PushAll(sigs2);
				else
					return PushAll(sigs1);
			if(template is PayToScriptHashTemplate || template is PayToWitTemplate)
			{
				if(sigs1.Length == 0 || sigs1[sigs1.Length - 1].Length == 0)
					return PushAll(sigs2);

				if(sigs2.Length == 0 || sigs2[sigs2.Length - 1].Length == 0)
					return PushAll(sigs1);

				var redeemBytes = sigs1[sigs1.Length - 1];
				var redeem = new Script(redeemBytes);
				sigs1 = sigs1.Take(sigs1.Length - 1).ToArray();
				sigs2 = sigs2.Take(sigs2.Length - 1).ToArray();
				Script result = CombineSignatures(redeem, checker, sigs1, sigs2, hashVersion);
				result += Op.GetPushOp(redeemBytes);
				return result;
			}

			if(template is PayToMultiSigTemplate)
			{
				return CombineMultisig(scriptPubKey, checker, sigs1, sigs2, hashVersion);
			}

			return null;
		}
		public ScriptId ExtractScriptPubKeyParameters(Script scriptPubKey)
		{
			if(!FastCheckScriptPubKey(scriptPubKey))
				return null;
			return new ScriptId(scriptPubKey.ToBytes(true).SafeSubarray(2, 20));
		}
		protected override bool FastCheckScriptPubKey(Script scriptPubKey)
		{
			var version = scriptPubKey.ToBytes(true)[0];
			return ValidSegwitVersionCore(version);
		}
		private static BitArray CalculateChecksum(uint256 blockId, int txIndex, int txOutIndex, Script scriptPubKey, int bitCount)
		{
			//All in little endian
			var hashed =
				blockId
				.ToBytes(true)
				.Concat(Utils.ToBytes((uint)txIndex, true))
				.Concat(Utils.ToBytes((uint)txOutIndex, true))
				.Concat(scriptPubKey.ToBytes(true))
				.ToArray();
			var hash = Hashes.Hash256(hashed);
			var bytes = hash.ToBytes(true);
			BitArray result = new BitArray(bitCount);
			for(int i = 0 ; i < bitCount ; i++)
			{
				int byteIndex = i / 8;
				int bitIndex = i % 8;
				result.Set(i, ((bytes[byteIndex] >> bitIndex) & 1) == 1);
			}
			return result;
		}
		protected override bool FastCheckScriptPubKey(Script scriptPubKey)
		{
			var bytes = scriptPubKey.ToBytes(true);
			return bytes.Length >= 3 &&
				   bytes[0] == (byte)OpcodeType.OP_DUP &&
				   bytes[1] == (byte)OpcodeType.OP_HASH160 &&
				   bytes[2] == 0x14;
		}
		public override bool CheckScriptPubKey(Script scriptPubKey)
		{
			if(scriptPubKey == null)
				throw new ArgumentNullException("scriptPubKey");
			var bytes = scriptPubKey.ToBytes(true);
			if(bytes.Length < 2)
				return false;
			var version = bytes[0];
			if(!ValidSegwitVersion(version))
				return false;
			var pushSize = bytes[1];
			return 0x01 <= pushSize && pushSize <= 0x4b;
		}
Beispiel #50
0
		public static bool VerifyScriptConsensus(Script scriptPubKey, Transaction tx, uint nIn, ScriptVerify flags)
		{
			var scriptPubKeyBytes = scriptPubKey.ToBytes();
			var txToBytes = tx.ToBytes();

			var err = BitcoinConsensusError.ERR_OK;
			var valid = VerifyScriptConsensus(scriptPubKeyBytes, (uint)scriptPubKeyBytes.Length, txToBytes, (uint)txToBytes.Length, nIn, flags, ref err);
			return valid == 1;
		}
		public Script GenerateScriptSig(byte[][] pushes, Script redeemScript)
		{
			List<Op> ops = new List<Op>();
			foreach(var push in pushes)
				ops.Add(Op.GetPushOp(push));
			ops.Add(Op.GetPushOp(redeemScript.ToBytes(true)));
			return new Script(ops);
		}
		public override bool CheckScriptPubKey(Script scriptPubKey)
		{
			if(scriptPubKey == null)
				throw new ArgumentNullException("scriptPubKey");
			var bytes = scriptPubKey.ToBytes(true);
			if(bytes.Length < 2)
				return false;
			var version = bytes[0];
			if(!ValidSegwitVersion(version))
				return false;
			var pushSize = bytes[1];
			if(pushSize < 0x02)
				return false;
			if(pushSize <= 0x4b)
				return (1 + 1 + pushSize) == bytes.Length;
			var ops = scriptPubKey.ToOps().ToArray();
			if(ops.Length != 2)
				return false;
			return ops.All(o => o.PushData != null);
		}
		protected override bool FastCheckScriptPubKey(Script scriptPubKey)
		{
			var bytes = scriptPubKey.ToBytes(true);
			return bytes.Length >= 1 && bytes[0] == (byte)OpcodeType.OP_RETURN;
		}