Пример #1
0
        // Stratis kernel protocol
        // coinstake must meet hash target according to the protocol:
        // kernel (input 0) must meet the formula
        //     hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime) < bnTarget * nWeight
        // this ensures that the chance of getting a coinstake is proportional to the
        // amount of coins one owns.
        // The reason this hash is chosen is the following:
        //   nStakeModifier: scrambles computation to make it very difficult to precompute
        //                   future proof-of-stake
        //   txPrev.block.nTime: prevent nodes from guessing a good timestamp to
        //                       generate transaction for future advantage,
        //                       obsolete since v3
        //   txPrev.nTime: slightly scrambles computation
        //   txPrev.vout.hash: hash of txPrev, to reduce the chance of nodes
        //                     generating coinstake at the same time
        //   txPrev.vout.n: output number of txPrev, to reduce the chance of nodes
        //                  generating coinstake at the same time
        //   nTime: current timestamp
        //   block/tx hash should not be used here as they can be generated in vast
        //   quantities so as to generate blocks faster, degrading the system back into
        //   a proof-of-work situation.
        //
        private static bool CheckStakeKernelHashV2(ChainedBlock pindexPrev, uint nBits, uint nTimeBlockFrom,
                                                   Transaction txPrev, OutPoint prevout, uint nTimeTx, out uint256 hashProofOfStake, out uint256 targetProofOfStake, bool fPrintProofOfStake)
        {
            targetProofOfStake = null; hashProofOfStake = null;

            if (nTimeTx < txPrev.Time)        // Transaction timestamp violation
            {
                return(false);                //error("CheckStakeKernelHash() : nTime violation");
            }
            // Base target
            var bnTarget = new Target(nBits).ToBigInteger();

            // Weighted target
            var nValueIn = txPrev.Outputs[prevout.N].Value.Satoshi;
            var bnWeight = BigInteger.ValueOf(nValueIn);

            bnTarget = bnTarget.Multiply(bnWeight);

            // todo: investigate this issue, is the convertion to uint256 similar to the c++ implementation
            //targetProofOfStake = Target.ToUInt256(bnTarget);

            var     nStakeModifier       = pindexPrev.Header.PosParameters.StakeModifier;
            uint256 bnStakeModifierV2    = pindexPrev.Header.PosParameters.StakeModifierV2;
            int     nStakeModifierHeight = pindexPrev.Height;
            var     nStakeModifierTime   = pindexPrev.Header.Time;

            // Calculate hash
            using (var ms = new MemoryStream())
            {
                var serializer = new BitcoinStream(ms, true);
                if (IsProtocolV3((int)nTimeTx))
                {
                    serializer.ReadWrite(bnStakeModifierV2);
                }
                else
                {
                    serializer.ReadWrite(nStakeModifier);
                    serializer.ReadWrite(nTimeBlockFrom);
                }

                serializer.ReadWrite(txPrev.Time);
                serializer.ReadWrite(prevout.Hash);
                serializer.ReadWrite(prevout.N);
                serializer.ReadWrite(nTimeTx);

                hashProofOfStake = Hashes.Hash256(ms.ToArray());
            }

            if (fPrintProofOfStake)
            {
                //LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",
                //	nStakeModifier, nStakeModifierHeight,
                //	DateTimeStrFormat(nStakeModifierTime),

                //	DateTimeStrFormat(nTimeBlockFrom));

                //LogPrintf("CheckStakeKernelHash() : check modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
                //	nStakeModifier,
                //	nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx,
                //	hashProofOfStake.ToString());
            }

            // Now check if proof-of-stake hash meets target protocol
            var hashProofOfStakeTarget = new BigInteger(hashProofOfStake.ToBytes(false));

            if (hashProofOfStakeTarget.CompareTo(bnTarget) > 0)
            {
                return(false);
            }


            //  if (fDebug && !fPrintProofOfStake)
            //  {
            //		LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",
            //		nStakeModifier, nStakeModifierHeight,
            //		DateTimeStrFormat(nStakeModifierTime),

            //		DateTimeStrFormat(nTimeBlockFrom));

            //		LogPrintf("CheckStakeKernelHash() : pass modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
            //		nStakeModifier,
            //		nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx,
            //		hashProofOfStake.ToString());
            //  }

            return(true);
        }
Пример #2
0
        //https://en.bitcoin.it/wiki/OP_CHECKSIG
        public static uint256 SignatureHash(Script scriptCode, Transaction txTo, int nIn, SigHash nHashType, Money amount, HashVersion sigversion, PrecomputedTransactionData precomputedTransactionData)
        {
            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)
                {
                    hashPrevouts = precomputedTransactionData == null?
                                   GetHashPrevouts(txTo) : precomputedTransactionData.HashPrevouts;
                }

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

                if (((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
                {
                    hashOutputs = precomputedTransactionData == null?
                                  GetHashOutputs(txTo) : precomputedTransactionData.HashOutputs;
                }
                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));
        }
Пример #3
0
        internal byte[] ReadData(Stream stream)
        {
            uint len       = 0;
            var  bitStream = new BitcoinStream(stream, false);

            if (this.Code == 0)
            {
                return(new byte[0]);
            }

            if ((byte)OpcodeType.OP_1 <= (byte)this.Code && (byte)this.Code <= (byte)OpcodeType.OP_16)
            {
                return(new byte[] { (byte)(this.Code - OpcodeType.OP_1 + 1) });
            }

            if (this.Code == OpcodeType.OP_1NEGATE)
            {
                return(new byte[] { 0x81 });
            }

            try
            {
                if (0x01 <= (byte)this.Code && (byte)this.Code <= 0x4b)
                {
                    len = (uint)this.Code;
                }
                else if (this.Code == OpcodeType.OP_PUSHDATA1)
                {
                    len = bitStream.ReadWrite((byte)0);
                }
                else if (this.Code == OpcodeType.OP_PUSHDATA2)
                {
                    len = bitStream.ReadWrite((ushort)0);
                }
                else if (this.Code == OpcodeType.OP_PUSHDATA4)
                {
                    len = bitStream.ReadWrite((uint)0);
                }
                else
                {
                    this.IsInvalid = true;
                    return(new byte[0]);
                }


                byte[] data = null;

                if (len <= MAX_SCRIPT_ELEMENT_SIZE) //Most of the time
                {
                    data = new byte[len];
                    int readen = stream.Read(data, 0, data.Length);
                    if (readen != data.Length)
                    {
                        this.IsInvalid = true;
                        return(new byte[0]);
                    }
                }
                else //Mitigate against a big array allocation
                {
                    var bytes = new List <byte>();
                    for (int i = 0; i < len; i++)
                    {
                        int b = stream.ReadByte();
                        if (b < 0)
                        {
                            this.IsInvalid = true;
                            return(new byte[0]);
                        }
                        bytes.Add((byte)b);
                    }
                    data = bytes.ToArray();
                }
                return(data);
            }
            catch (EndOfStreamException)
            {
                this.IsInvalid = true;
                return(new byte[0]);
            }
        }
Пример #4
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(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));
        }
Пример #5
0
        public override void ReadWrite(BitcoinStream stream)
        {
            bool witSupported = (((uint)stream.TransactionOptions & (uint)TransactionOptions.Witness) != 0) &&
                                stream.ProtocolVersion >= ProtocolVersion.WITNESS_VERSION;

            byte flags = 0;

            if (!stream.Serializing)
            {
                stream.ReadWrite(ref this.nVersion);

                // POS time stamp
                stream.ReadWrite(ref this.nTime);

                /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
                stream.ReadWrite <TxInList, TxIn>(ref this.vin);

                bool hasNoDummy = (this.nVersion & NoDummyInput) != 0 && this.vin.Count == 0;
                if (witSupported && hasNoDummy)
                {
                    this.nVersion = this.nVersion & ~NoDummyInput;
                }

                if (this.vin.Count == 0 && witSupported && !hasNoDummy)
                {
                    /* We read a dummy or an empty vin. */
                    stream.ReadWrite(ref flags);
                    if (flags != 0)
                    {
                        /* Assume we read a dummy and a flag. */
                        stream.ReadWrite <TxInList, TxIn>(ref this.vin);
                        this.vin.Transaction = this;
                        stream.ReadWrite <TxOutList, TxOut>(ref this.vout);
                        this.vout.Transaction = this;
                    }
                    else
                    {
                        /* Assume read a transaction without output. */
                        this.vout             = new TxOutList();
                        this.vout.Transaction = this;
                    }
                }
                else
                {
                    /* We read a non-empty vin. Assume a normal vout follows. */
                    stream.ReadWrite <TxOutList, TxOut>(ref this.vout);
                    this.vout.Transaction = this;
                }
                if (((flags & 1) != 0) && witSupported)
                {
                    /* The witness flag is present, and we support witnesses. */
                    flags ^= 1;
                    var wit = new Witness(this.Inputs);
                    wit.ReadWrite(stream);
                }
                if (flags != 0)
                {
                    /* Unknown flag in the serialization */
                    throw new FormatException("Unknown transaction optional data");
                }
            }
            else
            {
                uint version = (witSupported && (this.vin.Count == 0 && this.vout.Count > 0)) ? this.nVersion | NoDummyInput : this.nVersion;
                stream.ReadWrite(ref version);

                // the POS time stamp
                stream.ReadWrite(ref this.nTime);

                if (witSupported)
                {
                    /* Check whether witnesses need to be serialized. */
                    if (this.HasWitness)
                    {
                        flags |= 1;
                    }
                }
                if (flags != 0)
                {
                    /* Use extended format in case witnesses are to be serialized. */
                    var vinDummy = new TxInList();
                    stream.ReadWrite <TxInList, TxIn>(ref vinDummy);
                    stream.ReadWrite(ref flags);
                }
                stream.ReadWrite <TxInList, TxIn>(ref this.vin);
                this.vin.Transaction = this;
                stream.ReadWrite <TxOutList, TxOut>(ref this.vout);
                this.vout.Transaction = this;
                if ((flags & 1) != 0)
                {
                    var wit = new Witness(this.Inputs);
                    wit.ReadWrite(stream);
                }
            }
            stream.ReadWriteStruct(ref this.nLockTime);
        }
Пример #6
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref prevout);
     stream.ReadWrite(ref scriptSig);
     stream.ReadWrite(ref nSequence);
 }
Пример #7
0
        //IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )

        public void ReadWrite(BitcoinStream stream)
        {
            stream.ReadWrite(ref hash);
            stream.ReadWrite(ref n);
        }
Пример #8
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref vHave);
 }
Пример #9
0
        public void Serialize(BitcoinStream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            // Write the utxo
            // If there is a non-witness utxo, then don't serialize the witness one.
            if (witness_utxo != null)
            {
                // key
                stream.ReadWriteAsVarInt(ref defaultKeyLen);
                var key = PSBTConstants.PSBT_IN_WITNESS_UTXO;
                stream.ReadWrite(ref key);

                // value
                var data = witness_utxo.ToBytes();
                stream.ReadWriteAsVarString(ref data);
            }

            if (non_witness_utxo != null)
            {
                // key
                stream.ReadWriteAsVarInt(ref defaultKeyLen);
                var key = PSBTConstants.PSBT_IN_NON_WITNESS_UTXO;
                stream.ReadWrite(ref key);
                // value
                byte[] data = non_witness_utxo.ToBytes();
                stream.ReadWriteAsVarString(ref data);
            }

            // Write the sighash type
            if (sighash_type > 0)
            {
                stream.ReadWriteAsVarInt(ref defaultKeyLen);
                var key = PSBTConstants.PSBT_IN_SIGHASH;
                stream.ReadWrite(ref key);
                var tmp = Utils.ToBytes((uint)sighash_type, true);
                stream.ReadWriteAsVarString(ref tmp);
            }

            // Write the redeem script
            if (redeem_script != null)
            {
                stream.ReadWriteAsVarInt(ref defaultKeyLen);
                var key = PSBTConstants.PSBT_IN_REDEEMSCRIPT;
                stream.ReadWrite(ref key);
                var value = redeem_script.ToBytes();
                stream.ReadWriteAsVarString(ref value);
            }

            // Write the witness script
            if (witness_script != null)
            {
                stream.ReadWriteAsVarInt(ref defaultKeyLen);
                var key = PSBTConstants.PSBT_IN_WITNESSSCRIPT;
                stream.ReadWrite(ref key);
                var value = witness_script.ToBytes();
                stream.ReadWriteAsVarString(ref value);
            }

            // Write any partial signatures
            foreach (var sig_pair in partial_sigs)
            {
                var key = new byte[] { PSBTConstants.PSBT_IN_PARTIAL_SIG }.Concat(sig_pair.Key.ToBytes());
                stream.ReadWriteAsVarString(ref key);
                var sig = sig_pair.Value.ToBytes();
                stream.ReadWriteAsVarString(ref sig);
            }

            // Write any hd keypaths
            foreach (var pathPair in hd_keypaths)
            {
                var key = new byte[] { PSBTConstants.PSBT_IN_BIP32_DERIVATION }.Concat(pathPair.Key.ToBytes());
                stream.ReadWriteAsVarString(ref key);
                var masterFingerPrint = pathPair.Value.MasterFingerprint;
                var path              = pathPair.Value.KeyPath.ToBytes();
                var pathInfo          = masterFingerPrint.ToBytes().Concat(path);
                stream.ReadWriteAsVarString(ref pathInfo);
            }

            // Write script sig
            if (final_script_sig != null)
            {
                stream.ReadWriteAsVarInt(ref defaultKeyLen);
                var key = PSBTConstants.PSBT_IN_SCRIPTSIG;
                stream.ReadWrite(ref key);
                byte[] value = final_script_sig.ToBytes();
                stream.ReadWriteAsVarString(ref value);
            }

            // write script witness
            if (final_script_witness != null)
            {
                stream.ReadWriteAsVarInt(ref defaultKeyLen);
                var key = PSBTConstants.PSBT_IN_SCRIPTWITNESS;
                stream.ReadWrite(ref key);
                var stack = final_script_witness.ToBytes();
                stream.ReadWriteAsVarString(ref stack);
            }

            // Write unknown things
            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);
        }
Пример #10
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref header);
     stream.ReadWrite(ref _PartialMerkleTree);
 }
Пример #11
0
        internal static byte[] ReadData(Op op, Stream stream, bool ignoreWrongPush = false)
        {
            var           opcode    = op.Code;
            uint          len       = 0;
            BitcoinStream bitStream = new BitcoinStream(stream, false);

            if (opcode == 0)
            {
                return(new byte[0]);
            }

            if ((byte)OpcodeType.OP_1 <= (byte)opcode && (byte)opcode <= (byte)OpcodeType.OP_16)
            {
                return(new byte[] { (byte)(opcode - OpcodeType.OP_1 + 1) });
            }

            if (opcode == OpcodeType.OP_1NEGATE)
            {
                return(new byte[] { 0x81 });
            }

            try
            {
                if (0x01 <= (byte)opcode && (byte)opcode <= 0x4b)
                {
                    len = (uint)opcode;
                }
                else if (opcode == OpcodeType.OP_PUSHDATA1)
                {
                    len = bitStream.ReadWrite((byte)0);
                }
                else if (opcode == OpcodeType.OP_PUSHDATA2)
                {
                    len = bitStream.ReadWrite((ushort)0);
                }
                else if (opcode == OpcodeType.OP_PUSHDATA4)
                {
                    len = bitStream.ReadWrite((uint)0);
                }
                else
                {
                    throw new FormatException("Invalid opcode for pushing data : " + opcode);
                }
            }
            catch (EndOfStreamException)
            {
                if (!ignoreWrongPush)
                {
                    throw new FormatException("Incomplete script");
                }
                op.IncompleteData = true;
                return(new byte[0]);
            }

            if (stream.CanSeek && stream.Length - stream.Position < len)
            {
                len = (uint)(stream.Length - stream.Position);
                if (!ignoreWrongPush)
                {
                    throw new FormatException("Not enough bytes pushed with " + opcode.ToString() + " expected " + len + " but got " + len);
                }
                op.IncompleteData = true;
            }
            byte[] data   = new byte[len];
            var    readen = stream.Read(data, 0, data.Length);

            if (readen != data.Length && !ignoreWrongPush)
            {
                throw new FormatException("Not enough bytes pushed with " + opcode.ToString() + " expected " + len + " but got " + readen);
            }
            else if (readen != data.Length)
            {
                op.IncompleteData = true;
                Array.Resize(ref data, readen);
            }
            return(data);
        }
Пример #12
0
 public virtual void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref this.header);
     stream.ReadWrite(ref this.transactions);
 }
Пример #13
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref vtxundo);
 }
Пример #14
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref vprevout);
 }
Пример #15
0
        // select a block from the candidate blocks in vSortedByTimestamp, excluding
        // already selected blocks in vSelectedBlocks, and with timestamp up to
        // nSelectionIntervalStop.
        private static bool SelectBlockFromCandidates(ChainedBlock chainIndex, SortedDictionary <uint, uint256> sortedByTimestamp,
                                                      Dictionary <uint256, ChainedBlock> mapSelectedBlocks,
                                                      long nSelectionIntervalStop, ulong nStakeModifierPrev, out ChainedBlock pindexSelected)
        {
            bool    fSelected = false;
            uint256 hashBest  = 0;

            pindexSelected = null;

            foreach (var item in sortedByTimestamp)
            {
                var pindex = chainIndex.FindAncestorOrSelf(item.Value);
                if (pindex == null)
                {
                    return(false);                    // error("SelectBlockFromCandidates: failed to find block index for candidate block %s", item.second.ToString());
                }
                if (fSelected && pindex.Header.Time > nSelectionIntervalStop)
                {
                    break;
                }

                if (mapSelectedBlocks.Keys.Any(key => key == pindex.HashBlock))
                {
                    continue;
                }

                // compute the selection hash by hashing its proof-hash and the
                // previous proof-of-stake modifier
                uint256 hashSelection;
                using (var ms = new MemoryStream())
                {
                    var serializer = new BitcoinStream(ms, true);
                    serializer.ReadWrite(pindex.Header.PosParameters.HashProof);
                    serializer.ReadWrite(nStakeModifierPrev);

                    hashSelection = Hashes.Hash256(ms.ToArray());
                }

                // the selection hash is divided by 2**32 so that proof-of-stake block
                // is always favored over proof-of-work block. this is to preserve
                // the energy efficiency property
                if (pindex.Header.PosParameters.IsProofOfStake())
                {
                    hashSelection >>= 32;
                }

                if (fSelected && hashSelection < hashBest)
                {
                    hashBest       = hashSelection;
                    pindexSelected = pindex;
                }
                else if (!fSelected)
                {
                    fSelected      = true;
                    hashBest       = hashSelection;
                    pindexSelected = pindex;
                }
            }

            //LogPrint("stakemodifier", "SelectBlockFromCandidates: selection hash=%s\n", hashBest.ToString());
            return(fSelected);
        }
Пример #16
0
 public void ReadWrite(BitcoinStream s)
 {
     s.ReadWrite(ref this.federationId);
 }
Пример #17
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref header);
     stream.ReadWrite(ref vtx);
 }
Пример #18
0
        public void ReadWrite(BitcoinStream stream)
        {
            if (stream.Serializing)
            {
                uint nMaskSize = 0, nMaskCode = 0;
                CalcMaskSize(ref nMaskSize, ref nMaskCode);
                bool fFirst  = vout.Count > 0 && !vout[0].IsNull;
                bool fSecond = vout.Count > 1 && !vout[1].IsNull;
                uint nCode   = unchecked ((uint)(8 * (nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0)));
                // version
                stream.ReadWriteAsVarInt(ref nVersion);
                // size of header code
                stream.ReadWriteAsVarInt(ref nCode);
                // spentness bitmask
                for (uint b = 0; b < nMaskSize; b++)
                {
                    byte chAvail = 0;
                    for (uint i = 0; i < 8 && 2 + b * 8 + i < vout.Count; i++)
                    {
                        if (!vout[2 + (int)b * 8 + (int)i].IsNull)
                        {
                            chAvail |= (byte)(1 << (int)i);
                        }
                    }
                    stream.ReadWrite(ref chAvail);
                }

                // txouts themself
                for (uint i = 0; i < vout.Count; i++)
                {
                    if (!vout[(int)i].IsNull)
                    {
                        var compressedTx = new TxOutCompressor(vout[(int)i]);
                        stream.ReadWrite(ref compressedTx);
                    }
                }
                // coinbase height
                stream.ReadWriteAsVarInt(ref nHeight);
            }
            else
            {
                uint nCode = 0;
                // version
                stream.ReadWriteAsVarInt(ref nVersion);
                //// header code
                stream.ReadWriteAsVarInt(ref nCode);
                fCoinBase = (nCode & 1) != 0;
                List <bool> vAvail = new List <bool>()
                {
                    false, false
                };
                vAvail[0] = (nCode & 2) != 0;
                vAvail[1] = (nCode & 4) != 0;
                uint nMaskCode = unchecked ((uint)((nCode / 8) + ((nCode & 6) != 0 ? 0 : 1)));
                //// spentness bitmask
                while (nMaskCode > 0)
                {
                    byte chAvail = 0;
                    stream.ReadWrite(ref chAvail);
                    for (uint p = 0; p < 8; p++)
                    {
                        bool f = (chAvail & (1 << (int)p)) != 0;
                        vAvail.Add(f);
                    }
                    if (chAvail != 0)
                    {
                        nMaskCode--;
                    }
                }
                // txouts themself
                vout = Enumerable.Range(0, vAvail.Count).Select(_ => new TxOut()).ToList();
                for (uint i = 0; i < vAvail.Count; i++)
                {
                    if (vAvail[(int)i])
                    {
                        TxOutCompressor compressed = new TxOutCompressor();
                        stream.ReadWrite(ref compressed);
                        vout[(int)i] = compressed.TxOut;
                    }
                }
                //// coinbase height
                stream.ReadWriteAsVarInt(ref nHeight);
                Cleanup();
                UpdateValue();
            }
        }
Пример #19
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref value);
     stream.ReadWrite(ref publicKey);
     _MoneyValue = null;             //Might been updated
 }
Пример #20
0
 /// <inheritdoc />
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref _headers);
     stream.ReadWrite(ref _graph);
 }
Пример #21
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref _value);
 }
Пример #22
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref this.blocks);
 }