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); }
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; }
//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"); }
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); }