Пример #1
0
        /// <summary>
        /// 根据block信息更新UTXO pool,同时返回该block生成的utxo list,用来提示该block收到了多少钱
        /// </summary>
        /// <param name="block"></param>
        /// <returns>just for update key corresponding value</returns>
        public UTXOPool BlockData2UTXOPool(bool bCommitedPool, Block block)
        {
            LogHelper.WriteMethodLog(true);
            LogHelper.WriteInfoLog("bCommitedPool: " + bCommitedPool.ToString());
            UTXOPool utxopoll = new UTXOPool();

            if (bCommitedPool)
            {
                utxopoll = this.CommitedUtxoPool;
            }
            else
            {
                utxopoll = this.UnCommitedUtxoPool;
            }



            UTXOPool sigleBlockPool = new UTXOPool();

            foreach (Transaction eTransaction in block.listTransactions)
            {
                foreach (Input eInput in eTransaction.listInputs)
                {
                    UTXO utxo = this.input2UTXO(eInput);
                    if (utxopoll.contains(utxo))
                    {
                        utxopoll.removeUTXO(utxo);
                    }
                    else
                    {
                        // 初始化时由于leveldb 树形结构第一个可能创世块,所以先记下来在后面再remove
                        if (utxo.getTxHash() != ConstHelper.BC_BaseCoinInputTxHash)
                        {
                            tempUTXOList.Add(utxo);
                        }
                    }
                }

                for (int i = 0; i < eTransaction.listOutputs.Count; i++)
                {
                    // hash is transaction hash
                    UTXO utxo1 = new UTXO(eTransaction.getHash(), (uint)i);

                    utxopoll.addUTXO(utxo1, eTransaction.listOutputs[i]);
                    sigleBlockPool.addUTXO(utxo1, eTransaction.listOutputs[i]);
                }
            }
            LogHelper.WriteMethodLog(false);
            return(sigleBlockPool);
        }
Пример #2
0
        /**
         * @return true if:
         * (1) all outputs claimed by {@code tx} are in the current UTXO pool,
         * (2) the signatures on each input of {@code tx} are valid,
         * (3) no UTXO is claimed multiple times by {@code tx},
         * (4) all of {@code tx}s output values are non-negative, and
         * (5) the sum of {@code tx}s input values is greater than or equal to the sum of its output
         *     values; and false otherwise.
         */
        public bool isValidTx(Transaction tx)
        {
            LogHelper.WriteMethodLog(true);
            if (tx.listInputs.Count == 0 || tx.listOutputs.Count == 0)
            {
                LogHelper.WriteInfoLog("empty input|output");
                return(false);
            }

            // IMPLEMENT THIS
            double sumOut = 0;
            double sumIn  = 0;

            Dictionary <string, UTXO> dicUsed = new Dictionary <string, UTXO>();

            for (int i = 0; i < tx.numInputs(); i++)
            {
                Input input = tx.getInput(i);

                UTXO utxo = new UTXO(input.PreTxHash, (uint)input.OutputIndex);
                if (!CommitedUtxoPool.contains(utxo))
                {
                    LogHelper.WriteInfoLog(" utxoPool not contain utxo:");
                    return(false); //check (1),utox 包含该交易返回false
                }

                Output PreOutput = CommitedUtxoPool.getTxOutput(utxo); // the consume coin correspond prev output coin;
                sumIn += PreOutput.value;                              //(5) 计算input 指向的pre output 的value,最后保证输入的value等于该笔交易输出的
                string strOriginalTxt = tx.getRawDataToSign(i);
                if (!Cryptor.VerifySignature(input.ScriptSig, PreOutput.scriptPubKey, strOriginalTxt))
                {
                    LogHelper.WriteInfoLog(" VerifySignature fail");
                    return(false);//check(2)
                }


                bool bIsContain = dicUsed.ContainsKey(utxo.utoxHashCode());
                if (!bIsContain) // UTXO不会被重复添加
                {
                    dicUsed.Add(utxo.utoxHashCode(), utxo);
                }
                else
                {
                    LogHelper.WriteInfoLog(" double spend :" + utxo.utoxHashCode());
                    return(false);
                }
            }
            foreach (Output output in tx.getOutputs())
            {
                if (output.value < 0)
                {
                    LogHelper.WriteInfoLog(" output.value < 0 ");
                    return(false);//check(5)
                }
                sumOut += output.value;
            }
            if (sumIn < sumOut)
            {
                LogHelper.WriteInfoLog(" sumIn < sumOut ");
                return(false);//check(5);
            }
            LogHelper.WriteInfoLog("Valid Tx");
            return(true);
        }