public static int GetSerializedSize(this IBitcoinSerializable serializable, ConsensusFactory consensusFactory, uint version, SerializationType serializationType)
        {
            var bitcoinStream = new BitcoinStream(Stream.Null, true, consensusFactory, version)
            {
                Type = serializationType
            };

            bitcoinStream.ReadWrite(serializable);
            return((int)bitcoinStream.Counter.WrittenBytes);
        }
Exemple #2
0
        public BitcoinStream(Stream inner, bool serializing, ConsensusFactory consensus, uint overrideProtocolVersion)
        {
            this.ConsensusFactory   = consensus;
            this.ProtocolVersion    = overrideProtocolVersion;
            this.TransactionOptions = TransactionOptions.All;
            this.Serializing        = serializing;

            this.isNetworkStream = inner is NetworkStream;
            this.Inner           = inner;
            this.MaxArraySize    = 1024 * 1024;
        }
Exemple #3
0
 public void Load(Stream stream, ConsensusFactory consensusFactory, ChainSerializationFormat format)
 {
     if (consensusFactory == null)
     {
         throw new ArgumentNullException(nameof(consensusFactory));
     }
     Load(new BitcoinStream(stream, false)
     {
         ConsensusFactory = consensusFactory
     }, format);
 }
        public bool StoreHeader(BlockHeader blockHeader)
        {
            ConsensusFactory consensusFactory = this.network.Consensus.ConsensusFactory;

            lock (this.locker)
            {
                this.leveldb.Put(blockHeader.GetHash().ToBytes(), blockHeader.ToBytes(consensusFactory));
            }

            return(true);
        }
Exemple #5
0
        public bool PutHeader(BlockHeader blockHeader)
        {
            ConsensusFactory consensusFactory = this.network.Consensus.ConsensusFactory;

            lock (this.locker)
            {
                this.leveldb.Put(DBH.Key(HeaderTableName, blockHeader.GetHash().ToReadOnlySpan()), blockHeader.ToBytes(consensusFactory));
            }

            return(true);
        }
        public static T Clone <T>(this T serializable, ConsensusFactory consensusFactory) where T : IBitcoinSerializable, new()
        {
            T instance = consensusFactory.TryCreateNew <T>();

            if (instance == null)
            {
                instance = new T();
            }

            instance.FromBytes(serializable.ToBytes(consensusFactory), consensusFactory);
            return(instance);
        }
Exemple #7
0
        public IDisposable ConsensusFactoryScope(ConsensusFactory consensusFactory)
        {
            var old = ConsensusFactory;

            return(new Scope(() =>
            {
                ConsensusFactory = consensusFactory;
            }, () =>
            {
                ConsensusFactory = old;
            }));
        }
 public static byte[] ToBytes(this IBitcoinSerializable serializable, ConsensusFactory consensusFactory, ProtocolVersion version = ProtocolVersion.PROTOCOL_VERSION)
 {
     using (var ms = new MemoryStream())
     {
         var bms = new BitcoinStream(ms, true)
         {
             ProtocolVersion  = version,
             ConsensusFactory = consensusFactory ?? Network.Main.Consensus.ConsensusFactory
         };
         serializable.ReadWrite(bms);
         return(ToArrayEfficient(ms));
     }
 }
        public static PSBT Load(byte[] rawBytes, ConsensusFactory consensusFactory)
        {
            if (rawBytes == null)
            {
                throw new ArgumentNullException(nameof(rawBytes));
            }
            var stream = new BitcoinStream(rawBytes);

            stream.ConsensusFactory = consensusFactory;
            var ret = new PSBT(stream, null);

            return(ret);
        }
Exemple #10
0
        public static void ReadWrite(this IBitcoinSerializable serializable, Stream stream, bool serializing,
                                     ConsensusFactory consensusFactory, ProtocolVersion protocolVersion = ProtocolVersion.PROTOCOL_VERSION)
        {
            if (consensusFactory == null)
            {
                throw new ArgumentException("{0} cannot be null", nameof(consensusFactory));
            }

            serializable.ReadWrite(new BitcoinStream(stream, serializing)
            {
                ProtocolVersion  = protocolVersion,
                ConsensusFactory = consensusFactory
            });
        }
Exemple #11
0
        public static Block Load(byte[] hex, ConsensusFactory consensusFactory)
        {
            if (hex == null)
            {
                throw new ArgumentNullException(nameof(hex));
            }
            if (consensusFactory == null)
            {
                throw new ArgumentNullException(nameof(consensusFactory));
            }
            var block = consensusFactory.CreateBlock();

            block.ReadWrite(hex, consensusFactory);
            return(block);
        }
Exemple #12
0
        public static Block Parse(string hex, ConsensusFactory consensusFactory)
        {
            if (hex == null)
            {
                throw new ArgumentNullException(nameof(hex));
            }
            if (consensusFactory == null)
            {
                throw new ArgumentNullException(nameof(consensusFactory));
            }
            var block = consensusFactory.CreateBlock();

            block.ReadWrite(Encoders.Hex.DecodeData(hex), consensusFactory);
            return(block);
        }
Exemple #13
0
        public static Block CreateBlock(BlockHeader header, ConsensusFactory consensusFactory)
        {
            var           ms = new MemoryStream(100);
            BitcoinStream bs = new BitcoinStream(ms, true);

            bs.ConsensusFactory = consensusFactory;
            bs.ReadWrite(header);

            var block = consensusFactory.CreateBlock();

            ms.Position = 0;
            bs          = new BitcoinStream(ms, false);
            block.Header.ReadWrite(bs);
            return(block);
        }
        public static string ToHex(this IBitcoinSerializable serializable, ConsensusFactory consensusFactory, SerializationType serializationType = SerializationType.Disk)
        {
            using (var memoryStream = new MemoryStream())
            {
                var bitcoinStream = new BitcoinStream(memoryStream, true, consensusFactory)
                {
                    Type = serializationType,
                };

                bitcoinStream.ReadWrite(serializable);
                memoryStream.Seek(0, SeekOrigin.Begin);
                byte[] bytes = memoryStream.ReadBytes((int)memoryStream.Length);

                return(DataEncoders.Encoders.Hex.EncodeData(bytes));
            }
        }
        public static byte[] ToBytes(this IBitcoinSerializable serializable, ConsensusFactory consensusFactory)
        {
            if (consensusFactory == null)
            {
                throw new ArgumentException("{0} cannot be null", nameof(consensusFactory));
            }

            using (var ms = new MemoryStream())
            {
                var bms = new BitcoinStream(ms, true, consensusFactory);

                serializable.ReadWrite(bms);

                return(ToArrayEfficient(ms));
            }
        }
Exemple #16
0
        public BlockHeader(string hex, ConsensusFactory consensusFactory)
        {
            if (hex == null)
            {
                throw new ArgumentNullException(nameof(hex));
            }
            if (consensusFactory == null)
            {
                throw new ArgumentNullException(nameof(consensusFactory));
            }
            BitcoinStream bs = new BitcoinStream(Encoders.Hex.DecodeData(hex))
            {
                ConsensusFactory = consensusFactory
            };

            this.ReadWrite(bs);
        }
Exemple #17
0
        public BlockHeader(byte[] data, ConsensusFactory consensusFactory)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if (consensusFactory == null)
            {
                throw new ArgumentNullException(nameof(consensusFactory));
            }
            BitcoinStream bs = new BitcoinStream(data)
            {
                ConsensusFactory = consensusFactory
            };

            this.ReadWrite(bs);
        }
Exemple #18
0
        public static void FromBytes(this IBitcoinSerializable serializable, byte[] bytes,
                                     ConsensusFactory consensusFactory, ProtocolVersion version = ProtocolVersion.PROTOCOL_VERSION)
        {
            if (consensusFactory == null)
            {
                throw new ArgumentException("{0} cannot be null", nameof(consensusFactory));
            }

            using (var ms = new MemoryStream(bytes))
            {
                var bitcoinStream = new BitcoinStream(ms, false)
                {
                    ProtocolVersion  = version,
                    ConsensusFactory = consensusFactory
                };

                serializable.ReadWrite(bitcoinStream);
            }
        }
Exemple #19
0
        public static byte[] ToBytes(this IBitcoinSerializable serializable, ConsensusFactory consensusFactory, ProtocolVersion version = ProtocolVersion.PROTOCOL_VERSION)
        {
            if (consensusFactory == null)
            {
                throw new ArgumentException("{0} cannot be null", nameof(consensusFactory));
            }

            using (var ms = new MemoryStream())
            {
                var bms = new BitcoinStream(ms, true)
                {
                    ProtocolVersion  = version,
                    ConsensusFactory = consensusFactory
                };

                serializable.ReadWrite(bms);

                return(ToArrayEfficient(ms));
            }
        }
Exemple #20
0
        /// <summary>
        /// Create a block with the specified option only. (useful for stripping data from a block).
        /// </summary>
        /// <param name="consensusFactory">The network consensus factory.</param>
        /// <param name="options">Options to keep.</param>
        /// <returns>A new block with only the options wanted.</returns>
        public Block WithOptions(ConsensusFactory consensusFactory, TransactionOptions options)
        {
            if (this.Transactions.Count == 0)
            {
                return(this);
            }

            if ((options == TransactionOptions.Witness) && this.Transactions[0].HasWitness)
            {
                return(this);
            }

            if ((options == TransactionOptions.None) && !this.Transactions[0].HasWitness)
            {
                return(this);
            }

            Block instance = consensusFactory.CreateBlock();

            using (var ms = new MemoryStream())
            {
                var bms = new BitcoinStream(ms, true)
                {
                    TransactionOptions = options,
                    ConsensusFactory   = consensusFactory
                };

                this.ReadWrite(bms);
                ms.Position = 0;
                bms         = new BitcoinStream(ms, false)
                {
                    TransactionOptions = options,
                    ConsensusFactory   = consensusFactory
                };

                instance.ReadWrite(bms);
            }
            return(instance);
        }
        public static PSBT Parse(string hexOrBase64, ConsensusFactory consensusFactory)
        {
            if (hexOrBase64 == null)
            {
                throw new ArgumentNullException(nameof(hexOrBase64));
            }
            if (consensusFactory == null)
            {
                throw new ArgumentNullException(nameof(consensusFactory));
            }
            byte[] raw;
            if (HexEncoder.IsWellFormed(hexOrBase64))
            {
                raw = Encoders.Hex.DecodeData(hexOrBase64);
            }
            else
            {
                raw = Encoders.Base64.DecodeData(hexOrBase64);
            }

            return(Load(raw, consensusFactory));
        }
 public Consensus(
     ConsensusFactory consensusFactory,
     ConsensusOptions consensusOptions,
     int coinType,
     uint256 hashGenesisBlock,
     int subsidyHalvingInterval,
     int majorityEnforceBlockUpgrade,
     int majorityRejectBlockOutdated,
     int majorityWindow,
     BuriedDeploymentsArray buriedDeployments,
     BIP9DeploymentsArray bip9Deployments,
     uint256 bip34Hash,
     int ruleChangeActivationThreshold,
     int minerConfirmationWindow,
     uint maxReorgLength,
     uint256 defaultAssumeValid,
     long maxMoney,
     long coinbaseMaturity,
     long premineHeight,
     Money premineReward,
     Money proofOfWorkReward,
     TimeSpan powTargetTimespan,
     TimeSpan powTargetSpacing,
     bool powAllowMinDifficultyBlocks,
     bool powNoRetargeting,
     Target powLimit,
     uint256 minimumChainWork,
     bool isProofOfStake,
     int lastPowBlock,
     BigInteger proofOfStakeLimit,
     BigInteger proofOfStakeLimitV2,
     Money proofOfStakeReward
     )
 {
     this.Rules                         = new List <IConsensusRule>();
     this.CoinbaseMaturity              = coinbaseMaturity;
     this.PremineReward                 = premineReward;
     this.PremineHeight                 = premineHeight;
     this.ProofOfWorkReward             = proofOfWorkReward;
     this.ProofOfStakeReward            = proofOfStakeReward;
     this.MaxReorgLength                = maxReorgLength;
     this.MaxMoney                      = maxMoney;
     this.Options                       = consensusOptions;
     this.BuriedDeployments             = buriedDeployments;
     this.BIP9Deployments               = bip9Deployments;
     this.SubsidyHalvingInterval        = subsidyHalvingInterval;
     this.MajorityEnforceBlockUpgrade   = majorityEnforceBlockUpgrade;
     this.MajorityRejectBlockOutdated   = majorityRejectBlockOutdated;
     this.MajorityWindow                = majorityWindow;
     this.BIP34Hash                     = bip34Hash;
     this.PowLimit                      = powLimit;
     this.PowTargetTimespan             = powTargetTimespan;
     this.PowTargetSpacing              = powTargetSpacing;
     this.PowAllowMinDifficultyBlocks   = powAllowMinDifficultyBlocks;
     this.PowNoRetargeting              = powNoRetargeting;
     this.HashGenesisBlock              = hashGenesisBlock;
     this.MinimumChainWork              = minimumChainWork;
     this.MinerConfirmationWindow       = minerConfirmationWindow;
     this.RuleChangeActivationThreshold = ruleChangeActivationThreshold;
     this.CoinType                      = coinType;
     this.ProofOfStakeLimit             = proofOfStakeLimit;
     this.ProofOfStakeLimitV2           = proofOfStakeLimitV2;
     this.LastPOWBlock                  = lastPowBlock;
     this.IsProofOfStake                = isProofOfStake;
     this.DefaultAssumeValid            = defaultAssumeValid;
     this.ConsensusFactory              = consensusFactory;
 }
Exemple #23
0
 public static void ReadWrite(this IBitcoinSerializable serializable, byte[] bytes, ConsensusFactory consensusFactory, uint?version = null)
 {
     ReadWrite(serializable, new MemoryStream(bytes), false, consensusFactory, version);
 }
Exemple #24
0
        public static void ReadWrite(this IBitcoinSerializable serializable, Stream stream, bool serializing, ConsensusFactory consensusFactory, uint?version = null)
        {
            BitcoinStream s = new BitcoinStream(stream, serializing)
            {
                ProtocolVersion = version
            };

            if (consensusFactory != null)
            {
                s.ConsensusFactory = consensusFactory;
            }
            serializable.ReadWrite(s);
        }
Exemple #25
0
 public Block CreateNextBlockWithCoinbase(PubKey pubkey, Money value, ConsensusFactory consensusFactory)
 {
     return(CreateNextBlockWithCoinbase(pubkey, value, DateTimeOffset.UtcNow, consensusFactory));
 }
Exemple #26
0
        public Block CreateNextBlockWithCoinbase(PubKey pubkey, Money value, DateTimeOffset now, ConsensusFactory consensusFactory)
        {
            Block block = consensusFactory.CreateBlock();

            block.Header.Nonce         = RandomUtils.GetUInt32();
            block.Header.HashPrevBlock = this.GetHash();
            block.Header.BlockTime     = now;
            var tx = block.AddTransaction(consensusFactory.CreateTransaction());

            tx.Inputs.Add(scriptSig: new Script(Op.GetPushOp(RandomUtils.GetBytes(30))));
            tx.Outputs.Add(new TxOut()
            {
                Value        = value,
                ScriptPubKey = PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(pubkey)
            });
            return(block);
        }
Exemple #27
0
 public BitcoinStream(Stream inner, bool serializing, ConsensusFactory consensus)
     : this(inner, serializing, consensus, consensus.Protocol.ProtocolVersion)
 {
 }
Exemple #28
0
 public static Block CreateBlock(ConsensusFactory consensusFactory)
 {
     return(consensusFactory.CreateBlock());
 }
        /// <summary>
        /// Mines a new genesis block, to use with a new network.
        /// Typically, 3 such genesis blocks need to be created when bootstrapping a new coin: for Main, Test and Reg networks.
        /// </summary>
        /// <param name="consensusFactory">
        /// The consensus factory used to create transactions and blocks.
        /// Use <see cref="PosConsensusFactory"/> for proof-of-stake based networks.
        /// </param>
        /// <param name="coinbaseText">
        /// Traditionally a news headline from the day of the launch, but could be any string or link.
        /// This will be inserted in the input coinbase transaction script.
        /// It should be shorter than 92 characters.
        /// </param>
        /// <param name="target">
        /// The difficulty target under which the hash of the block need to be.
        /// Some more details: As an example, the target for the Stratis Main network is 00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
        /// To make it harder to mine the genesis block, have more zeros at the beginning (keeping the length the same). This will make the target smaller, so finding a number under it will be more difficult.
        /// To make it easier to mine the genesis block ,do the opposite. Example of an easy one: 00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
        /// Make the Test and Reg targets ones easier to find than the Main one so that you don't wait too long to mine the genesis block.
        /// </param>
        /// <param name="genesisReward">
        /// Specify how many coins to put in the genesis transaction's output. These coins are unspendable.
        /// </param>
        /// <param name="version">
        /// The version of the transaction and the block header set in the genesis block.
        /// </param>
        /// <example>
        /// The following example shows the creation of a genesis block.
        /// <code>
        /// Block genesis = MineGenesisBlock(new PosConsensusFactory(), "Some topical headline.", new Target(new uint256("000fffff00000000000000000000000000000000000000000000000000000000")), Money.Coins(50m));
        /// BlockHeader header = genesis.Header;
        /// Console.WriteLine("Make a note of the following values:");
        /// Console.WriteLine("bits: " + header.Bits);
        /// Console.WriteLine("nonce: " + header.Nonce);
        /// Console.WriteLine("time: " + header.Time);
        /// Console.WriteLine("version: " + header.Version);
        /// Console.WriteLine("hash: " + header.GetHash());
        /// Console.WriteLine("merkleroot: " + header.HashMerkleRoot);
        /// </code>
        /// </example>
        /// <returns>A genesis block.</returns>
        public static Block MineGenesisBlock(ConsensusFactory consensusFactory, string coinbaseText, Target target, Money genesisReward, int version = 1)
        {
            if (target == null)
            {
                throw new ArgumentException($"Parameter '{nameof(target)}' cannot be null. Example use: new Target(new uint256(\"0000ffff00000000000000000000000000000000000000000000000000000000\"))");
            }

            if (consensusFactory == null)
            {
                throw new ArgumentException($"Parameter '{nameof(consensusFactory)}' cannot be null. Use 'new ConsensusFactory()' for Bitcoin-like proof-of-work blockchains" +
                                            "and 'new PosConsensusFactory()' for Stratis-like proof-of-stake blockchains.");
            }

            if (string.IsNullOrEmpty(coinbaseText))
            {
                throw new ArgumentException($"Parameter '{nameof(coinbaseText)}' cannot be null. Use a news headline or any other appropriate string.");
            }

            if (coinbaseText.Length >= 92)
            {
                throw new ArgumentException($"Parameter '{nameof(coinbaseText)}' should be shorter than 92 characters.");
            }

            if (genesisReward == null)
            {
                throw new ArgumentException($"Parameter '{nameof(genesisReward)}' cannot be null. Example use: 'Money.Coins(50m)'.");
            }

            DateTimeOffset time     = DateTimeOffset.Now;
            uint           unixTime = Utils.DateTimeToUnixTime(time);

            Transaction txNew = consensusFactory.CreateTransaction();

            txNew.Version = (uint)version;
            txNew.Time    = unixTime;
            txNew.AddInput(new TxIn()
            {
                ScriptSig = new Script(
                    Op.GetPushOp(0),
                    new Op()
                {
                    Code     = (OpcodeType)0x1,
                    PushData = new[] { (byte)42 }
                },
                    Op.GetPushOp(Encoders.ASCII.DecodeData(coinbaseText)))
            });

            txNew.AddOutput(new TxOut()
            {
                Value = genesisReward,
            });

            Block genesis = consensusFactory.CreateBlock();

            genesis.Header.BlockTime = time;
            genesis.Header.Bits      = target;
            genesis.Header.Nonce     = 0;
            genesis.Header.Version   = version;
            genesis.Transactions.Add(txNew);
            genesis.Header.HashPrevBlock = uint256.Zero;
            genesis.UpdateMerkleRoot();

            // Iterate over the nonce until the proof-of-work is valid.
            // This will mean the block header hash is under the target.
            while (!genesis.CheckProofOfWork())
            {
                genesis.Header.Nonce++;
                if (genesis.Header.Nonce == 0)
                {
                    genesis.Header.Time++;
                }
            }

            return(genesis);
        }
        public static void ReadWrite(this IBitcoinSerializable serializable, byte[] bytes, ConsensusFactory consensusFactory)
        {
            if (consensusFactory == null)
            {
                throw new ArgumentException("{0} cannot be null", nameof(consensusFactory));
            }

            using (var stream = new MemoryStream(bytes))
            {
                serializable.ReadWrite(new BitcoinStream(stream, false, consensusFactory));
            }
        }