Пример #1
0
        public void NewTransaction(IAccount iAccount, Sha256Ripemd160Hash address, CurrencyUnit amount, CurrencyUnit fee)
        {
            if (!isSystemStarted)
                throw new InvalidOperationException("core_not_started");

            Account account = iAccount as Account;
            if (account == null)
                throw new ArgumentException("iaccount_type");

            utxodb.Open();

            List<Utxo> utxosList = blockChain.GetAllUtxos(account.Address.Hash);
            utxosList.Sort((a, b) =>
            {
                if (a.blockIndex < b.blockIndex)
                    return -1;
                else if (a.blockIndex > b.blockIndex)
                    return 1;

                if (a.txIndex < b.txIndex)
                    return -1;
                else if (a.txIndex > b.txIndex)
                    return 1;

                if (a.txOutIndex < b.txOutIndex)
                    return -1;
                else if (a.txOutIndex > b.txOutIndex)
                    return 1;

                return 0;
            });
            Utxo[] utxos = utxosList.ToArray();

            utxodb.Close();

            List<TransactionInput> usedTxInList = new List<TransactionInput>();
            foreach (var unconfirmedTh in transactionHistories.unconfirmedTransactionHistories.ToArray())
                for (int i = 0; i < unconfirmedTh.prevTxOuts.Length; i++)
                    if (unconfirmedTh.prevTxOuts[i].Address.Equals(account.Address.Hash))
                        usedTxInList.Add(unconfirmedTh.transaction.TxInputs[i]);
            usedTxInList.Sort((a, b) =>
            {
                if (a.PrevTxBlockIndex < b.PrevTxBlockIndex)
                    return -1;
                else if (a.PrevTxBlockIndex > b.PrevTxBlockIndex)
                    return 1;

                if (a.PrevTxIndex < b.PrevTxIndex)
                    return -1;
                else if (a.PrevTxIndex > b.PrevTxIndex)
                    return 1;

                if (a.PrevTxOutputIndex < b.PrevTxOutputIndex)
                    return -1;
                else if (a.PrevTxOutputIndex > b.PrevTxOutputIndex)
                    return 1;

                return 0;
            });
            TransactionInput[] usedTxIns = usedTxInList.ToArray();

            List<Utxo> unusedUtxosList = new List<Utxo>();

            int position = -1;
            for (int i = 0; i < usedTxIns.Length; i++)
            {
                bool flag = false;
                while (position < utxos.Length)
                {
                    position++;

                    if (usedTxIns[i].PrevTxBlockIndex == utxos[position].blockIndex && usedTxIns[i].PrevTxIndex == utxos[position].txIndex && usedTxIns[i].PrevTxOutputIndex == utxos[position].txOutIndex)
                    {
                        flag = true;

                        break;
                    }
                    else
                        unusedUtxosList.Add(utxos[position]);
                }

                if (!flag)
                    throw new InvalidOperationException();
            }

            long rawFeeAndAmount = amount.rawAmount + fee.rawAmount;

            List<Utxo> useUtxosList = new List<Utxo>();
            long rawFeeAndAmountAndChange = 0;

            bool flag2 = false;
            foreach (var utxo in unusedUtxosList)
            {
                useUtxosList.Add(utxo);

                if ((rawFeeAndAmountAndChange += utxo.amount.rawAmount) > rawFeeAndAmount)
                {
                    flag2 = true;

                    break;
                }
            }

            if (!flag2)
                for (int i = position + 1; i < utxos.Length; i++)
                {
                    useUtxosList.Add(utxos[i]);

                    if ((rawFeeAndAmountAndChange += utxos[i].amount.rawAmount) > rawFeeAndAmount)
                    {
                        flag2 = true;

                        break;
                    }
                }

            if (!flag2)
                throw new InvalidOperationException();

            Utxo[] useUtxos = useUtxosList.ToArray();

            TransactionInput[] txIns = new TransactionInput[useUtxos.Length];
            for (int i = 0; i < txIns.Length; i++)
            {
                txIns[i] = new TransactionInput();
                txIns[i].LoadVersion0(useUtxos[i].blockIndex, useUtxos[i].txIndex, useUtxos[i].txOutIndex, account.Ecdsa256KeyPair.pubKey);
            }

            long rawChange = rawFeeAndAmountAndChange - rawFeeAndAmount;

            TransactionOutput[] txOuts = new TransactionOutput[rawChange == 0 ? 1 : 2];
            txOuts[0] = new TransactionOutput();
            txOuts[0].LoadVersion0(address, amount);
            if (rawChange != 0)
            {
                txOuts[1] = new TransactionOutput();
                txOuts[1].LoadVersion0(account.Address.Hash, new CurrencyUnit(rawChange));
            }

            TransactionOutput[] prevTxOuts = new TransactionOutput[useUtxos.Length];
            for (int i = 0; i < prevTxOuts.Length; i++)
                prevTxOuts[i] = blockChain.GetMainBlock(txIns[i].PrevTxBlockIndex).Transactions[txIns[i].PrevTxIndex].TxOutputs[txIns[i].PrevTxOutputIndex];

            Ecdsa256PrivKey[] privKeys = new Ecdsa256PrivKey[useUtxos.Length];
            for (int i = 0; i < privKeys.Length; i++)
                privKeys[i] = account.Ecdsa256KeyPair.privKey;

            TransferTransaction ttx = new TransferTransaction();
            ttx.LoadVersion0(txIns, txOuts);
            ttx.Sign(prevTxOuts, privKeys);

            creaNodeTest.DiffuseNewTransaction(ttx);
        }
Пример #2
0
        public BlockContext CreateNextValidBlock()
        {
            currentBIndex++;

            if (currentBIndex == 0)
            {
                Block blk = new GenesisBlock();

                blks.Add(blk);

                Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>> unspentTxOutsDictClone2 = new Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>>();
                Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>> spentTxOutsDictClone2 = new Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>>();

                for (int i = 0; i < keyPairs.Length; i++)
                {
                    unspentTxOutsDictClone2.Add(addresses[i], new List<TransactionOutputContext>());
                    foreach (var toc in unspentTxOutsDict[addresses[i]])
                        unspentTxOutsDictClone2[addresses[i]].Add(toc);
                    spentTxOutsDictClone2.Add(addresses[i], new List<TransactionOutputContext>());
                    foreach (var toc in spentTxOutsDict[addresses[i]])
                        spentTxOutsDictClone2[addresses[i]].Add(toc);
                }

                return new BlockContext(blk, new TransactionOutput[][] { }, 0, unspentTxOutsDictClone2, spentTxOutsDictClone2);
            }

            int numOfSpendTxs = maxNumOfSpendTxs.RandomNum() + 1;
            int[] numOfSpendTxOutss = new int[numOfSpendTxs];
            for (int i = 0; i < numOfSpendTxOutss.Length; i++)
                numOfSpendTxOutss[i] = maxNumOfSpendTxOuts.RandomNum() + 1;

            TransactionOutputContext[][] spendTxOutss = new TransactionOutputContext[numOfSpendTxs][];
            for (int i = 0; i < spendTxOutss.Length; i++)
            {
                if (unspentTxOuts.Count == 0)
                    break;

                spendTxOutss[i] = new TransactionOutputContext[numOfSpendTxOutss[i]];

                for (int j = 0; j < spendTxOutss[i].Length; j++)
                {
                    int index = unspentTxOuts.Count.RandomNum();

                    spendTxOutss[i][j] = unspentTxOuts[index];

                    spentTxOutsDict[unspentTxOuts[index].address].Add(unspentTxOuts[index]);
                    unspentTxOutsDict[unspentTxOuts[index].address].Remove(unspentTxOuts[index]);

                    spentTxOuts.Add(unspentTxOuts[index]);
                    unspentTxOuts.RemoveAt(index);

                    if (unspentTxOuts.Count == 0)
                        break;
                }
            }

            long fee = 0;
            List<TransferTransaction> transferTxs = new List<TransferTransaction>();
            List<TransactionOutput[]> prevTxOutsList = new List<TransactionOutput[]>();
            for (int i = 0; i < spendTxOutss.Length; i++)
            {
                if (spendTxOutss[i] == null)
                    break;

                long sumRawAmount = 0;

                List<TransactionInput> txInputsList = new List<TransactionInput>();
                for (int j = 0; j < spendTxOutss[i].Length; j++)
                {
                    if (spendTxOutss[i][j] == null)
                        break;

                    txInputsList.Add(spendTxOutss[i][j].GenerateTransactionInput());

                    sumRawAmount += spendTxOutss[i][j].amount.rawAmount;
                }

                TransactionInput[] txIns = txInputsList.ToArray();

                int num = sumRawAmount > 1000000 ? (int)Math.Ceiling(((avgIORatio - 1) * 2) * 1.RandomDouble() * txIns.Length) : 1;

                TransactionOutputContext[] txOutsCon = new TransactionOutputContext[num];
                TransactionOutput[] txOuts = new TransactionOutput[num];
                for (int j = 0; j < txOutsCon.Length; j++)
                {
                    long outAmount = 0;
                    if (sumRawAmount > 1000000)
                    {
                        long sumRawAmountDivided = sumRawAmount / 1000000;

                        int subtract = ((int)sumRawAmountDivided / 2).RandomNum() + 1;

                        outAmount = (long)subtract * 1000000;
                    }
                    else
                        outAmount = sumRawAmount;

                    sumRawAmount -= outAmount;

                    int index = numOfKeyPairs.RandomNum();

                    txOutsCon[j] = new TransactionOutputContext(currentBIndex, i + 1, j, new CurrencyUnit(outAmount), addresses[index], keyPairs[index]);
                    txOuts[j] = txOutsCon[j].GenerateTrasactionOutput();
                }

                fee += sumRawAmount;

                for (int j = 0; j < txOutsCon.Length; j++)
                {
                    unspentTxOutsDict[txOutsCon[j].address].Add(txOutsCon[j]);

                    unspentTxOuts.Add(txOutsCon[j]);
                }

                TransactionOutput[] prevTxOuts = new TransactionOutput[txIns.Length];
                Ecdsa256PrivKey[] privKeys = new Ecdsa256PrivKey[txIns.Length];
                for (int j = 0; j < prevTxOuts.Length; j++)
                {
                    prevTxOuts[j] = spendTxOutss[i][j].GenerateTrasactionOutput();
                    privKeys[j] = spendTxOutss[i][j].keyPair.privKey;
                }

                TransferTransaction tTx = new TransferTransaction();
                tTx.LoadVersion0(txIns, txOuts);
                tTx.Sign(prevTxOuts, privKeys);

                transferTxs.Add(tTx);
                prevTxOutsList.Add(prevTxOuts);
            }

            long rewardAndFee = TransactionalBlock.GetRewardToMiner(currentBIndex, 0).rawAmount + fee;

            TransactionOutputContext[] coinbaseTxOutsCon = new TransactionOutputContext[numOfCoinbaseTxOuts];
            TransactionOutput[] coinbaseTxOuts = new TransactionOutput[numOfCoinbaseTxOuts];
            for (int i = 0; i < coinbaseTxOutsCon.Length; i++)
            {
                long outAmount2 = 0;
                if (i != coinbaseTxOutsCon.Length - 1)
                {
                    long rewardAndFeeDevided = rewardAndFee / 1000000;

                    int subtract2 = ((int)rewardAndFeeDevided / 2).RandomNum() + 1;

                    outAmount2 = (long)subtract2 * 1000000;

                    rewardAndFee -= outAmount2;
                }
                else
                    outAmount2 = rewardAndFee;

                int index = numOfKeyPairs.RandomNum();

                coinbaseTxOutsCon[i] = new TransactionOutputContext(currentBIndex, 0, i, new CurrencyUnit(outAmount2), addresses[index], keyPairs[index]);
                coinbaseTxOuts[i] = coinbaseTxOutsCon[i].GenerateTrasactionOutput();
            }

            CoinbaseTransaction coinbaseTx = new CoinbaseTransaction();
            coinbaseTx.LoadVersion0(coinbaseTxOuts);

            for (int i = 0; i < coinbaseTxOutsCon.Length; i++)
            {
                unspentTxOutsDict[coinbaseTxOutsCon[i].address].Add(coinbaseTxOutsCon[i]);

                unspentTxOuts.Add(coinbaseTxOutsCon[i]);
            }

            prevTxOutsList.Insert(0, new TransactionOutput[] { });

            Difficulty<Creahash> diff = new Difficulty<Creahash>(HASHBASE.FromHash<Creahash>(new byte[] { 0, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }));
            byte[] nonce = new byte[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            BlockHeader bh = new BlockHeader();
            bh.LoadVersion0(currentBIndex, blks[blks.Count - 1].Id, DateTime.Now, diff, nonce);

            NormalBlock nblk = new NormalBlock();
            nblk.LoadVersion0(bh, coinbaseTx, transferTxs.ToArray());
            nblk.UpdateMerkleRootHash();

            blks.Add(nblk);

            Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>> unspentTxOutsDictClone = new Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>>();
            Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>> spentTxOutsDictClone = new Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>>();

            for (int i = 0; i < keyPairs.Length; i++)
            {
                unspentTxOutsDictClone.Add(addresses[i], new List<TransactionOutputContext>());
                foreach (var toc in unspentTxOutsDict[addresses[i]])
                    unspentTxOutsDictClone[addresses[i]].Add(toc);
                spentTxOutsDictClone.Add(addresses[i], new List<TransactionOutputContext>());
                foreach (var toc in spentTxOutsDict[addresses[i]])
                    spentTxOutsDictClone[addresses[i]].Add(toc);
            }

            BlockContext blkCon = new BlockContext(nblk, prevTxOutsList.ToArray(), fee, unspentTxOutsDictClone, spentTxOutsDictClone);

            return blkCon;
        }
Пример #3
0
        //TransactionOutput、TransactionInput、CoinbaseTransaction、TransferTransactionのテスト
        public static void Test10()
        {
            Ecdsa256KeyPair keypair1 = new Ecdsa256KeyPair(true);
            Ecdsa256KeyPair keypair2 = new Ecdsa256KeyPair(true);
            Ecdsa256KeyPair keypair3 = new Ecdsa256KeyPair(true);

            Sha256Ripemd160Hash address1 = new Sha256Ripemd160Hash(keypair1.pubKey.pubKey);
            CurrencyUnit amount1 = new Creacoin(50.0m);
            Sha256Ripemd160Hash address2 = new Sha256Ripemd160Hash(keypair2.pubKey.pubKey);
            CurrencyUnit amount2 = new Creacoin(25.0m);
            Sha256Ripemd160Hash address3 = new Sha256Ripemd160Hash(keypair3.pubKey.pubKey);
            CurrencyUnit amount3 = new Yumina(0.01m);

            TransactionOutput txOut1 = new TransactionOutput();
            txOut1.LoadVersion0(address1, amount1);
            TransactionOutput txOut2 = new TransactionOutput();
            txOut2.LoadVersion0(address2, amount2);
            TransactionOutput txOut3 = new TransactionOutput();
            txOut3.LoadVersion0(address3, amount3);

            if (txOut1.Address != address1)
                throw new Exception("test10_1");
            if (txOut1.Amount != amount1)
                throw new Exception("test10_2");

            byte[] txOutBytes = txOut1.ToBinary();

            if (txOutBytes.Length != 29)
                throw new Exception("test10_3");

            TransactionOutput txOutRestore = SHAREDDATA.FromBinary<TransactionOutput>(txOutBytes, 0);

            if (!txOut1.Address.Equals(txOutRestore.Address))
                throw new Exception("test10_4");
            if (txOut1.Amount.rawAmount != txOutRestore.Amount.rawAmount)
                throw new Exception("test10_5");

            TransactionInput txIn1 = new TransactionInput();
            txIn1.LoadVersion0(0, 0, 0, keypair1.pubKey);
            TransactionInput txIn2 = new TransactionInput();
            txIn2.LoadVersion0(1, 0, 0, keypair2.pubKey);
            TransactionInput txIn3 = new TransactionInput();
            txIn3.LoadVersion0(2, 0, 0, keypair3.pubKey);

            if (txIn1.PrevTxBlockIndex != 0)
                throw new Exception("test10_6");
            if (txIn1.PrevTxIndex != 0)
                throw new Exception("test10_7");
            if (txIn1.PrevTxOutputIndex != 0)
                throw new Exception("test10_8");
            if (txIn1.SenderPubKey != keypair1.pubKey)
                throw new Exception("test10_9");

            TransactionOutput[] txOuts = new TransactionOutput[] { txOut1, txOut2, txOut3 };

            CoinbaseTransaction cTx = new CoinbaseTransaction();
            cTx.LoadVersion0(txOuts);

            if (cTx.TxOutputs != txOuts)
                throw new Exception("test10_10");
            if (cTx.TxInputs.Length != 0)
                throw new Exception("test10_11");

            byte[] cTxBytes = cTx.ToBinary();

            if (cTxBytes.Length != 97)
                throw new Exception("test10_12");

            CoinbaseTransaction cTxRestore = SHAREDDATA.FromBinary<CoinbaseTransaction>(cTxBytes);

            if (!cTx.Id.Equals(cTxRestore.Id))
                throw new Exception("test10_13");

            if (cTx.Verify())
                throw new Exception("test10_14");
            if (cTx.VerifyNotExistDustTxOutput())
                throw new Exception("test10_15");
            if (!cTx.VerifyNumberOfTxInputs())
                throw new Exception("test10_16");
            if (!cTx.VerifyNumberOfTxOutputs())
                throw new Exception("test10_17");

            TransactionOutput[] txOuts2 = new TransactionOutput[11];
            for (int i = 0; i < txOuts2.Length; i++)
                txOuts2[i] = txOut1;

            CoinbaseTransaction cTx2 = new CoinbaseTransaction();
            cTx2.LoadVersion0(txOuts2);

            if (cTx2.Verify())
                throw new Exception("test10_18");
            if (!cTx2.VerifyNotExistDustTxOutput())
                throw new Exception("test10_19");
            if (!cTx2.VerifyNumberOfTxInputs())
                throw new Exception("test10_20");
            if (cTx2.VerifyNumberOfTxOutputs())
                throw new Exception("test10_21");

            TransactionOutput[] txOuts3 = new TransactionOutput[] { txOut1, txOut2 };

            CoinbaseTransaction cTx3 = new CoinbaseTransaction();
            cTx3.LoadVersion0(txOuts3);

            if (!cTx3.Verify())
                throw new Exception("test10_22");
            if (!cTx3.VerifyNotExistDustTxOutput())
                throw new Exception("test10_23");
            if (!cTx3.VerifyNumberOfTxInputs())
                throw new Exception("test10_24");
            if (!cTx3.VerifyNumberOfTxOutputs())
                throw new Exception("test10_25");

            TransactionInput[] txIns = new TransactionInput[] { txIn1, txIn2, txIn3 };

            TransferTransaction tTx1 = new TransferTransaction();
            tTx1.LoadVersion0(txIns, txOuts);
            tTx1.Sign(txOuts, new DSAPRIVKEYBASE[] { keypair1.privKey, keypair2.privKey, keypair3.privKey });

            if (tTx1.TxInputs != txIns)
                throw new Exception("test10_26");
            if (tTx1.TxOutputs != txOuts)
                throw new Exception("test10_27");

            byte[] txInBytes = txIn1.ToBinary();

            if (txInBytes.Length != 153)
                throw new Exception("test10_28");

            TransactionInput txInRestore = SHAREDDATA.FromBinary<TransactionInput>(txInBytes, 0);

            if (txIn1.PrevTxBlockIndex != txInRestore.PrevTxBlockIndex)
                throw new Exception("test10_29");
            if (txIn1.PrevTxIndex != txInRestore.PrevTxIndex)
                throw new Exception("test10_30");
            if (txIn1.PrevTxOutputIndex != txInRestore.PrevTxOutputIndex)
                throw new Exception("test10_31");
            if (!txIn1.SenderPubKey.pubKey.BytesEquals(txInRestore.SenderPubKey.pubKey))
                throw new Exception("test10_32");
            if (!txIn1.SenderSignature.signature.BytesEquals(txInRestore.SenderSignature.signature))
                throw new Exception("test10_33");

            byte[] tTxBytes = tTx1.ToBinary();

            if (tTxBytes.Length != 557)
                throw new Exception("test10_34");

            TransferTransaction tTxRestore = SHAREDDATA.FromBinary<TransferTransaction>(tTxBytes);

            if (!tTx1.Id.Equals(tTxRestore.Id))
                throw new Exception("test10_35");

            if (tTx1.Verify(txOuts))
                throw new Exception("test10_36");
            if (tTx1.VerifyNotExistDustTxOutput())
                throw new Exception("test10_37");
            if (!tTx1.VerifyNumberOfTxInputs())
                throw new Exception("test10_38");
            if (!tTx1.VerifyNumberOfTxOutputs())
                throw new Exception("test10_39");
            if (!tTx1.VerifySignature(txOuts))
                throw new Exception("test10_40");
            if (!tTx1.VerifyPubKey(txOuts))
                throw new Exception("test10_41");
            if (!tTx1.VerifyAmount(txOuts))
                throw new Exception("test10_42");
            if (tTx1.GetFee(txOuts).rawAmount != 0)
                throw new Exception("test10_43");

            TransactionOutput[] txOuts4 = new TransactionOutput[] { txOut2, txOut1, txOut3 };

            if (tTx1.Verify(txOuts4))
                throw new Exception("test10_44");
            if (tTx1.VerifySignature(txOuts4))
                throw new Exception("test10_45");
            if (tTx1.VerifyPubKey(txOuts4))
                throw new Exception("test10_46");

            byte temp2 = tTx1.TxInputs[0].SenderSignature.signature[0];

            tTx1.TxInputs[0].SenderSignature.signature[0] = 0;

            if (tTx1.Verify(txOuts))
                throw new Exception("test10_47");
            if (tTx1.VerifySignature(txOuts))
                throw new Exception("test10_48");
            if (!tTx1.VerifyPubKey(txOuts))
                throw new Exception("test10_49");

            tTx1.TxInputs[0].SenderSignature.signature[0] = temp2;

            TransferTransaction tTx2 = new TransferTransaction();
            tTx2.LoadVersion0(txIns, txOuts);
            tTx2.Sign(txOuts, new DSAPRIVKEYBASE[] { keypair2.privKey, keypair1.privKey, keypair3.privKey });

            if (tTx2.Verify(txOuts))
                throw new Exception("test10_50");
            if (tTx2.VerifySignature(txOuts))
                throw new Exception("test10_51");
            if (!tTx2.VerifyPubKey(txOuts))
                throw new Exception("test10_52");

            TransferTransaction tTx3 = new TransferTransaction();
            tTx3.LoadVersion0(txIns, txOuts);
            tTx3.Sign(txOuts, new DSAPRIVKEYBASE[] { keypair1.privKey, keypair2.privKey, keypair3.privKey });

            byte temp = tTx3.TxInputs[0].SenderPubKey.pubKey[0];

            tTx3.TxInputs[0].SenderPubKey.pubKey[0] = 0;

            if (tTx3.Verify(txOuts))
                throw new Exception("test10_50");
            if (tTx3.VerifySignature(txOuts))
                throw new Exception("test10_51");
            if (tTx3.VerifyPubKey(txOuts))
                throw new Exception("test10_52");

            tTx3.TxInputs[0].SenderPubKey.pubKey[0] = temp;

            TransferTransaction tTx4 = new TransferTransaction();
            tTx4.LoadVersion0(txIns, txOuts2);
            tTx4.Sign(txOuts, new DSAPRIVKEYBASE[] { keypair1.privKey, keypair2.privKey, keypair3.privKey });

            if (tTx4.Verify(txOuts))
                throw new Exception("test10_53");
            if (!tTx4.VerifyNotExistDustTxOutput())
                throw new Exception("test10_54");
            if (!tTx4.VerifyNumberOfTxInputs())
                throw new Exception("test10_55");
            if (tTx4.VerifyNumberOfTxOutputs())
                throw new Exception("test10_56");
            if (!tTx4.VerifySignature(txOuts))
                throw new Exception("test10_57");
            if (!tTx4.VerifyPubKey(txOuts))
                throw new Exception("test10_58");
            if (tTx4.VerifyAmount(txOuts))
                throw new Exception("test10_59");
            if (tTx4.GetFee(txOuts).rawAmount != -47499990000)
                throw new Exception("test10_60");

            TransferTransaction tTx5 = new TransferTransaction();
            tTx5.LoadVersion0(txIns, txOuts3);
            tTx5.Sign(txOuts, new DSAPRIVKEYBASE[] { keypair1.privKey, keypair2.privKey, keypair3.privKey });

            if (!tTx5.Verify(txOuts))
                throw new Exception("test10_61");
            if (!tTx5.VerifyNotExistDustTxOutput())
                throw new Exception("test10_62");
            if (!tTx5.VerifyNumberOfTxInputs())
                throw new Exception("test10_63");
            if (!tTx5.VerifyNumberOfTxOutputs())
                throw new Exception("test10_64");
            if (!tTx5.VerifySignature(txOuts))
                throw new Exception("test10_65");
            if (!tTx5.VerifyPubKey(txOuts))
                throw new Exception("test10_66");
            if (!tTx5.VerifyAmount(txOuts))
                throw new Exception("test10_67");
            if (tTx5.GetFee(txOuts).rawAmount != 10000)
                throw new Exception("test10_68");

            TransactionInput[] txIns2 = new TransactionInput[101];
            for (int i = 0; i < txIns2.Length; i++)
                txIns2[i] = txIn1;

            TransactionOutput[] txOuts5 = new TransactionOutput[txIns2.Length];
            for (int i = 0; i < txOuts5.Length; i++)
                txOuts5[i] = txOut1;

            Ecdsa256PrivKey[] privKeys = new Ecdsa256PrivKey[txIns2.Length];
            for (int i = 0; i < privKeys.Length; i++)
                privKeys[i] = keypair1.privKey;

            TransferTransaction tTx6 = new TransferTransaction();
            tTx6.LoadVersion0(txIns2, txOuts3);
            tTx6.Sign(txOuts5, privKeys);

            if (tTx6.Verify(txOuts5))
                throw new Exception("test10_61");
            if (!tTx6.VerifyNotExistDustTxOutput())
                throw new Exception("test10_62");
            if (tTx6.VerifyNumberOfTxInputs())
                throw new Exception("test10_63");
            if (!tTx6.VerifyNumberOfTxOutputs())
                throw new Exception("test10_64");
            if (!tTx6.VerifySignature(txOuts5))
                throw new Exception("test10_65");
            if (!tTx6.VerifyPubKey(txOuts5))
                throw new Exception("test10_66");
            if (!tTx6.VerifyAmount(txOuts5))
                throw new Exception("test10_67");
            if (tTx6.GetFee(txOuts5).rawAmount != 497500000000)
                throw new Exception("test10_68");

            byte[] cTxBytes2 = SHAREDDATA.ToBinary<Transaction>(cTx);

            if (cTxBytes2.Length != 117)
                throw new Exception("test10_69");

            CoinbaseTransaction cTxRestore2 = SHAREDDATA.FromBinary<Transaction>(cTxBytes2) as CoinbaseTransaction;

            if (!cTx.Id.Equals(cTxRestore2.Id))
                throw new Exception("test10_70");

            byte[] tTxBytes2 = SHAREDDATA.ToBinary<Transaction>(tTx6);

            if (tTxBytes2.Length != 15445)
                throw new Exception("test10_71");

            TransferTransaction tTxRestore2 = SHAREDDATA.FromBinary<Transaction>(tTxBytes2) as TransferTransaction;

            if (!tTx6.Id.Equals(tTxRestore2.Id))
                throw new Exception("test10_72");

            Sha256Sha256Hash ctxid = new Sha256Sha256Hash(cTxBytes);

            if (!ctxid.Equals(cTx.Id))
                throw new Exception("test10_73");

            Sha256Sha256Hash ttxid = new Sha256Sha256Hash(tTx6.ToBinary());

            if (!ttxid.Equals(tTx6.Id))
                throw new Exception("test10_74");

            Console.WriteLine("test10_succeeded");
        }
Пример #4
0
        public void NewTransaction(IAccount iAccount, Sha256Ripemd160Hash address, CurrencyUnit amount, CurrencyUnit fee)
        {
            if (!isSystemStarted)
            {
                throw new InvalidOperationException("core_not_started");
            }

            Account account = iAccount as Account;

            if (account == null)
            {
                throw new ArgumentException("iaccount_type");
            }

            utxodb.Open();

            List <Utxo> utxosList = blockChain.GetAllUtxos(account.Address.Hash);

            utxosList.Sort((a, b) =>
            {
                if (a.blockIndex < b.blockIndex)
                {
                    return(-1);
                }
                else if (a.blockIndex > b.blockIndex)
                {
                    return(1);
                }

                if (a.txIndex < b.txIndex)
                {
                    return(-1);
                }
                else if (a.txIndex > b.txIndex)
                {
                    return(1);
                }

                if (a.txOutIndex < b.txOutIndex)
                {
                    return(-1);
                }
                else if (a.txOutIndex > b.txOutIndex)
                {
                    return(1);
                }

                return(0);
            });
            Utxo[] utxos = utxosList.ToArray();

            utxodb.Close();

            List <TransactionInput> usedTxInList = new List <TransactionInput>();

            foreach (var unconfirmedTh in transactionHistories.unconfirmedTransactionHistories.ToArray())
            {
                for (int i = 0; i < unconfirmedTh.prevTxOuts.Length; i++)
                {
                    if (unconfirmedTh.prevTxOuts[i].Address.Equals(account.Address.Hash))
                    {
                        usedTxInList.Add(unconfirmedTh.transaction.TxInputs[i]);
                    }
                }
            }
            usedTxInList.Sort((a, b) =>
            {
                if (a.PrevTxBlockIndex < b.PrevTxBlockIndex)
                {
                    return(-1);
                }
                else if (a.PrevTxBlockIndex > b.PrevTxBlockIndex)
                {
                    return(1);
                }

                if (a.PrevTxIndex < b.PrevTxIndex)
                {
                    return(-1);
                }
                else if (a.PrevTxIndex > b.PrevTxIndex)
                {
                    return(1);
                }

                if (a.PrevTxOutputIndex < b.PrevTxOutputIndex)
                {
                    return(-1);
                }
                else if (a.PrevTxOutputIndex > b.PrevTxOutputIndex)
                {
                    return(1);
                }

                return(0);
            });
            TransactionInput[] usedTxIns = usedTxInList.ToArray();

            List <Utxo> unusedUtxosList = new List <Utxo>();

            int position = -1;

            for (int i = 0; i < usedTxIns.Length; i++)
            {
                bool flag = false;
                while (position < utxos.Length)
                {
                    position++;

                    if (usedTxIns[i].PrevTxBlockIndex == utxos[position].blockIndex && usedTxIns[i].PrevTxIndex == utxos[position].txIndex && usedTxIns[i].PrevTxOutputIndex == utxos[position].txOutIndex)
                    {
                        flag = true;

                        break;
                    }
                    else
                    {
                        unusedUtxosList.Add(utxos[position]);
                    }
                }

                if (!flag)
                {
                    throw new InvalidOperationException();
                }
            }

            long rawFeeAndAmount = amount.rawAmount + fee.rawAmount;

            List <Utxo> useUtxosList             = new List <Utxo>();
            long        rawFeeAndAmountAndChange = 0;

            bool flag2 = false;

            foreach (var utxo in unusedUtxosList)
            {
                useUtxosList.Add(utxo);

                if ((rawFeeAndAmountAndChange += utxo.amount.rawAmount) > rawFeeAndAmount)
                {
                    flag2 = true;

                    break;
                }
            }

            if (!flag2)
            {
                for (int i = position + 1; i < utxos.Length; i++)
                {
                    useUtxosList.Add(utxos[i]);

                    if ((rawFeeAndAmountAndChange += utxos[i].amount.rawAmount) > rawFeeAndAmount)
                    {
                        flag2 = true;

                        break;
                    }
                }
            }

            if (!flag2)
            {
                throw new InvalidOperationException();
            }

            Utxo[] useUtxos = useUtxosList.ToArray();

            TransactionInput[] txIns = new TransactionInput[useUtxos.Length];
            for (int i = 0; i < txIns.Length; i++)
            {
                txIns[i] = new TransactionInput();
                txIns[i].LoadVersion0(useUtxos[i].blockIndex, useUtxos[i].txIndex, useUtxos[i].txOutIndex, account.Ecdsa256KeyPair.pubKey);
            }

            long rawChange = rawFeeAndAmountAndChange - rawFeeAndAmount;

            TransactionOutput[] txOuts = new TransactionOutput[rawChange == 0 ? 1 : 2];
            txOuts[0] = new TransactionOutput();
            txOuts[0].LoadVersion0(address, amount);
            if (rawChange != 0)
            {
                txOuts[1] = new TransactionOutput();
                txOuts[1].LoadVersion0(account.Address.Hash, new CurrencyUnit(rawChange));
            }

            TransactionOutput[] prevTxOuts = new TransactionOutput[useUtxos.Length];
            for (int i = 0; i < prevTxOuts.Length; i++)
            {
                prevTxOuts[i] = blockChain.GetMainBlock(txIns[i].PrevTxBlockIndex).Transactions[txIns[i].PrevTxIndex].TxOutputs[txIns[i].PrevTxOutputIndex];
            }

            Ecdsa256PrivKey[] privKeys = new Ecdsa256PrivKey[useUtxos.Length];
            for (int i = 0; i < privKeys.Length; i++)
            {
                privKeys[i] = account.Ecdsa256KeyPair.privKey;
            }

            TransferTransaction ttx = new TransferTransaction();

            ttx.LoadVersion0(txIns, txOuts);
            ttx.Sign(prevTxOuts, privKeys);

            creaNodeTest.DiffuseNewTransaction(ttx);
        }