Пример #1
0
        public void SetToP2SH_ExceptionTest()
        {
            PubkeyScript scr = new PubkeyScript();

            byte[]       nba   = null;
            RedeemScript nscr  = null;
            string       naddr = null;

            Assert.Throws <ArgumentNullException>(() => scr.SetToP2SH(nba));
            Assert.Throws <ArgumentOutOfRangeException>(() => scr.SetToP2SH(new byte[19]));
            Assert.Throws <ArgumentNullException>(() => scr.SetToP2SH(nscr));
            Assert.Throws <ArgumentNullException>(() => scr.SetToP2SH(naddr));
            Assert.Throws <ArgumentNullException>(() => scr.SetToP2SH(""));
            Assert.Throws <FormatException>(() => scr.SetToP2SH("$"));
            Assert.Throws <FormatException>(() => scr.SetToP2SH(KeyHelper.Pub1CompAddr));
        }
Пример #2
0
        public void SetToP2PKH_ExceptionTest()
        {
            PubkeyScript scr = new PubkeyScript();

            byte[]    nba   = null;
            PublicKey npub  = null;
            string    naddr = null;

            Assert.Throws <ArgumentNullException>(() => scr.SetToP2PKH(nba));
            Assert.Throws <ArgumentOutOfRangeException>(() => scr.SetToP2PKH(new byte[19]));
            Assert.Throws <ArgumentNullException>(() => scr.SetToP2PKH(npub, true));
            Assert.Throws <ArgumentNullException>(() => scr.SetToP2PKH(naddr));
            Assert.Throws <ArgumentNullException>(() => scr.SetToP2PKH(""));
            Assert.Throws <FormatException>(() => scr.SetToP2PKH("$"));
            Assert.Throws <FormatException>(() => scr.SetToP2PKH("3FuPMWfen385RLwbMsZEVhx9QsHyR6zEmv"));
        }
Пример #3
0
        /// <summary>
        /// Initializes a new instance of <see cref="TxOut"/> using given parameters.
        /// </summary>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="ArgumentOutOfRangeException"/>
        /// <param name="amount">Payment amount in coin's smallest unit (eg. Satoshi).</param>
        /// <param name="pkScript">Public key script</param>
        public TxOut(ulong amount, PubkeyScript pkScript)
        {
            if (amount > 21_000_000_0000_0000)
            {
                throw new ArgumentOutOfRangeException(nameof(amount), "Can not spend more than coin's maximum supply.");
            }
            if (pkScript == null)
            {
                throw new ArgumentNullException(nameof(pkScript), $"Pubkey script can not be null.");
            }

            Amount    = amount;
            PubScript = pkScript;

            maxAmount = 21_000_000_0000_0000;
        }
        public override bool SetOperations()
        {
            Errors = null;

            if (string.IsNullOrEmpty(Address))
            {
                Errors = "Address can not be empty.";
                return(false);
            }
            else if (addrManager.TryGetType(Address, out PubkeyScriptType scrType, out byte[] hash))
            {
                PubkeyScript scr = new PubkeyScript();
                switch (scrType)
                {
                case PubkeyScriptType.P2PKH:
                    scr.SetToP2PKH(hash);
                    break;

                case PubkeyScriptType.P2SH:
                    scr.SetToP2SH(hash);
                    break;

                case PubkeyScriptType.P2WPKH:
                    scr.SetToP2WPKH(hash);
                    break;

                case PubkeyScriptType.P2WSH:
                    scr.SetToP2WSH(hash);
                    break;

                default:
                    Errors = "Undefined script type.";     // This should never happen.
                    return(false);
                }

                OpsToAdd = scr.OperationList;
                return(true);
            }
Пример #5
0
        public void Constructor_EmptyOpsTest()
        {
            var scr = new PubkeyScript(new IOperation[0]);

            Assert.Equal(new byte[0], scr.Data);
        }
Пример #6
0
        public void SetToP2PK_ExceptionTest()
        {
            PubkeyScript scr = new PubkeyScript();

            Assert.Throws <ArgumentNullException>(() => scr.SetToP2PK(null, true));
        }
Пример #7
0
        public void GetSpecialTypeTest(IConsensus consensus, byte[] data, PubkeyScriptSpecialType expected)
        {
            PubkeyScript scr = new PubkeyScript(data);

            Assert.Equal(expected, scr.GetSpecialType(consensus));
        }
Пример #8
0
        public void Constructor_OpsTest()
        {
            var scr = new PubkeyScript(new IOperation[] { new DUPOp(), new PushDataOp(new byte[] { 10, 20, 30 }) });

            Assert.Equal(new byte[] { (byte)OP.DUP, 3, 10, 20, 30 }, scr.Data);
        }
Пример #9
0
        public void GetPublicScriptTypeTest(byte[] data, PubkeyScriptType expected)
        {
            PubkeyScript scr = new PubkeyScript(data);

            Assert.Equal(expected, scr.GetPublicScriptType());
        }
Пример #10
0
        public void ConstructorTest()
        {
            var scr = new PubkeyScript();

            Assert.Empty(scr.Data);
        }
Пример #11
0
        public void IsUnspendableTest(byte[] data, bool expected)
        {
            PubkeyScript scr = new PubkeyScript(data);

            Assert.Equal(expected, scr.IsUnspendable());
        }
Пример #12
0
        public async Task <IBlock> Start(IBlock prev, int height, CancellationToken token)
        {
            // Certain things are hard-coded here because this tool is meant for testing.
            // Eventually it will use IWallet.NextAddress() to get a new address to mine to from the wallet instance
            // and IBlockchain.GetTarget() to mine at the correct difficulty.
            // For now it is a good way of mining any transaction that won't propagate in TestNet by bitcoin core clients.

            var    consensus = new Consensus(height, NetworkType.TestNet);
            string cbText    = "Mined using Denovo v0.1.0";

            // A weak key used only for testing
            using var key = new PrivateKey(new Sha256().ComputeHash(Encoding.UTF8.GetBytes(cbText)));
            var pkScr = new PubkeyScript();

            pkScr.SetToP2WPKH(key.ToPublicKey());

            byte[] commitment = null;

            //var tx1 = new Transaction();
            //tx1.TryDeserialize(new FastStreamReader(Base16.Decode("")), out _);

            ulong fee = 0;

            var coinbase = new Transaction()
            {
                Version  = 1,
                TxInList = new TxIn[]
                {
                    new TxIn(new byte[32], uint.MaxValue, new SignatureScript(height, Encoding.UTF8.GetBytes($"{cbText} by Coding Enthusiast")), uint.MaxValue)
                },
                TxOutList = new TxOut[]
                {
                    new TxOut(consensus.BlockReward + fee, pkScr),
                    new TxOut(0, new PubkeyScript())
                },
                LockTime = new LockTime(height)
            };


            ((PubkeyScript)coinbase.TxOutList[1].PubScript).SetToReturn(Encoding.UTF8.GetBytes("Testing Mining View Model."));


            var block = new Block()
            {
                Header = new BlockHeader()
                {
                    Version   = prev.Header.Version,
                    BlockTime = (uint)UnixTimeStamp.TimeToEpoch(DateTime.UtcNow.AddMinutes(22)),
                    NBits     = 0x1d00ffffU,
                    PreviousBlockHeaderHash = prev.GetBlockHash(false),
                },
                TransactionList = new Transaction[] { coinbase }
            };

            if (block.TransactionList.Length > 1 && commitment != null)
            {
                coinbase.WitnessList = new Witness[1]
                {
                    new Witness(new byte[][] { commitment })
                };

                var temp = new TxOut[coinbase.TxOutList.Length + 1];
                Array.Copy(coinbase.TxOutList, 0, temp, 0, coinbase.TxOutList.Length);
                temp[^ 1] = new TxOut();
Пример #13
0
 /// <summary>
 /// Initializes a new instance of <see cref="TxOut"/> using given parameters of the <see cref="ICoin"/>.
 /// </summary>
 public TxOut()
 {
     PubScript = new PubkeyScript();
     maxAmount = 21_000_000_0000_0000;
 }
Пример #14
0
        public static IEnumerable <object[]> GetTxVerifyCases()
        {
            var c = new MockConsensus()
            {
                expHeight = MockHeight,
                bip65     = true,
                bip112    = true,
                strictDer = true,
                bip147    = true,
                bip16     = true,
                segWit    = true,
            };

            byte[] simpTxHash1 = new byte[32];
            simpTxHash1[1] = 1;
            byte[] simpTxHash2 = new byte[32];
            simpTxHash2[1] = 2;
            byte[] simpTxHash3 = new byte[32];
            simpTxHash3[1] = 3;

            var simpPubScr = new PubkeyScript();
            var simpSigScr = new SignatureScript(new byte[1] {
                (byte)OP._1
            });

            // *** Fee Tests ***

            yield return(new object[]
            {
                new MockUtxoDatabase(simpTxHash1, new MockUtxo()
                {
                    Amount = 0, Index = 0, PubScript = simpPubScr
                }),
                new MockMempool(null),
                c,
                new Transaction()
                {
                    TxInList = new TxIn[1]
                    {
                        new TxIn(simpTxHash1, 0, simpSigScr, uint.MaxValue)
                    },
                    TxOutList = new TxOut[1]
                    {
                        new TxOut(0, simpPubScr)
                    }
                },
                true,  // Verification success
                null,  // Error
                0,     // Added SigOpCount
                0,     // Added fee
                false, // AnySegWit
            });

            yield return(new object[]
            {
                new MockUtxoDatabase(simpTxHash1, new MockUtxo()
                {
                    Amount = 0, Index = 0, PubScript = simpPubScr
                }),
                new MockMempool(null),
                c,
                new Transaction()
                {
                    TxInList = new TxIn[1]
                    {
                        new TxIn(simpTxHash1, 0, simpSigScr, uint.MaxValue)
                    },
                    TxOutList = new TxOut[1]
                    {
                        new TxOut(1, simpPubScr)
                    }
                },
                false,                                       // Verification success
                "Transaction is spending more than it can.", // Error
                0,                                           // Added SigOpCount
                0,                                           // Added fee
                false,                                       // AnySegWit
            });

            yield return(new object[]
            {
                new MockUtxoDatabase(simpTxHash1, new MockUtxo()
                {
                    Amount = 123, Index = 0, PubScript = simpPubScr
                }),
                new MockMempool(null),
                c,
                new Transaction()
                {
                    TxInList = new TxIn[1]
                    {
                        new TxIn(simpTxHash1, 0, simpSigScr, uint.MaxValue)
                    },
                    TxOutList = new TxOut[1]
                    {
                        new TxOut(3, simpPubScr)
                    }
                },
                true,  // Verification success
                null,  // Error
                0,     // Added SigOpCount
                120,   // Added fee
                false, // AnySegWit
            });

            yield return(new object[]
            {
                // Make sure ulong is being used for calculation of fee
                new MockUtxoDatabase(simpTxHash1, new MockUtxo()
                {
                    Amount = Constants.TotalSupply, Index = 0, PubScript = simpPubScr
                }),
                new MockMempool(null),
                c,
                new Transaction()
                {
                    TxInList = new TxIn[1]
                    {
                        new TxIn(simpTxHash1, 0, simpSigScr, uint.MaxValue)
                    },
                    TxOutList = new TxOut[1]
                    {
                        new TxOut(1000, simpPubScr)
                    }
                },
                true,                           // Verification success
                null,                           // Error
                0,                              // Added SigOpCount
                Constants.TotalSupply - 1000UL, // Added fee
                false,                          // AnySegWit
            });

            yield return(new object[]
            {
                new MockUtxoDatabase(new byte[][] { simpTxHash1, simpTxHash2, simpTxHash3 },
                                     new IUtxo[]
                {
                    new MockUtxo()
                    {
                        Amount = 13, Index = 3, PubScript = simpPubScr
                    },
                    new MockUtxo()
                    {
                        Amount = 57, Index = 7, PubScript = simpPubScr
                    },
                    new MockUtxo()
                    {
                        Amount = 73, Index = 5, PubScript = simpPubScr
                    },
                }),
                new MockMempool(null),
                c,
                new Transaction()
                {
                    TxInList = new TxIn[3]
                    {
                        new TxIn(simpTxHash1, 3, simpSigScr, uint.MaxValue),
                        new TxIn(simpTxHash2, 7, simpSigScr, uint.MaxValue),
                        new TxIn(simpTxHash3, 5, simpSigScr, uint.MaxValue),
                    },
                    TxOutList = new TxOut[3]
                    {
                        new TxOut(140, simpPubScr),
                        new TxOut(3, simpPubScr),
                        new TxOut(1, simpPubScr),
                    }
                },
                false,                                       // Verification success
                "Transaction is spending more than it can.", // Error
                0,                                           // Added SigOpCount
                0,                                           // Added fee
                false,                                       // AnySegWit
            });

            yield return(new object[]
            {
                new MockUtxoDatabase(new byte[][] { simpTxHash1, simpTxHash2, simpTxHash3 },
                                     new IUtxo[]
                {
                    new MockUtxo()
                    {
                        Amount = 13, Index = 3, PubScript = simpPubScr
                    },
                    new MockUtxo()
                    {
                        Amount = 57, Index = 7, PubScript = simpPubScr
                    },
                    new MockUtxo()
                    {
                        Amount = 73, Index = 5, PubScript = simpPubScr
                    },
                }),
                new MockMempool(null),
                c,
                new Transaction()
                {
                    TxInList = new TxIn[3]
                    {
                        new TxIn(simpTxHash1, 3, simpSigScr, uint.MaxValue),
                        new TxIn(simpTxHash2, 7, simpSigScr, uint.MaxValue),
                        new TxIn(simpTxHash3, 5, simpSigScr, uint.MaxValue),
                    },
                    TxOutList = new TxOut[3]
                    {
                        new TxOut(12, simpPubScr),
                        new TxOut(6, simpPubScr),
                        new TxOut(50, simpPubScr),
                    }
                },
                true,  // Verification success
                null,  // Error
                0,     // Added SigOpCount
                75,    // Added fee
                false, // AnySegWit
            });

            // *** Transaction Tests (from signtx cases) ***
            foreach (var Case in Helper.ReadResource <JArray>("SignedTxTestData"))
            {
                Transaction prevTx = new Transaction();
                prevTx.TryDeserialize(new FastStreamReader(Helper.HexToBytes(Case["TxToSpend"].ToString())), out string _);
                byte[] prevTxHash = prevTx.GetTransactionHash();
                var    utxoDb     = new MockUtxoDatabase();

                for (int i = 0; i < prevTx.TxOutList.Length; i++)
                {
                    var utxo = new MockUtxo()
                    {
                        Amount    = prevTx.TxOutList[i].Amount,
                        Index     = (uint)i,
                        PubScript = prevTx.TxOutList[i].PubScript
                    };

                    utxoDb.Add(prevTxHash, utxo);
                }

                foreach (var item in Case["Cases"])
                {
                    Transaction      tx     = new Transaction();
                    FastStreamReader stream = new FastStreamReader(Helper.HexToBytes(item["SignedTx"].ToString()));
                    if (!tx.TryDeserialize(stream, out string err))
                    {
                        throw new ArgumentException($"Could not deseralize the given tx case: " +
                                                    $"{item["TestName"]}. Error: {err}");
                    }

                    int   sigOpCount = (int)item["SigOpCount"];
                    ulong fee        = (ulong)item["Fee"];

                    yield return(new object[]
                    {
                        utxoDb,
                        new MockMempool(null),
                        c,
                        tx,
                        true, // Verification success
                        null, // Error
                        sigOpCount,
                        fee,
                        tx.WitnessList != null, // AnySegWit
                    });
                }
            }
        }