Пример #1
0
    protected void Page_Load(object sender, EventArgs e)
    {
        // Page.ClientScript.RegisterStartupScript(this.GetType(), "alert", "+();", true);
        //aa = new string[] { "1","3","5","7" };
        //json 早上用用看
        // aa = Request.QueryString["1,2,3,4,5,6,7"];
        //Response.Write("A"+aa);

        POW     p   = new POW();
        MWArray mw  = p.CalcPow((MWArray)2, (MWArray)10);//計算2的10次方
        int     res = int.Parse(mw.ToString());

        Response.Write(res);
    }
Пример #2
0
        public IRpcMethodResult GetDifficulty()
        {
            try
            {
                var blockComponent = new BlockComponent();
                var height         = blockComponent.GetLatestHeight();
                var newHeight      = height + 1;
                var previousBlock  = blockComponent.GetBlockMsgByHeight(height);
                var prev4032Block  = blockComponent.GetBlockMsgByHeight(newHeight - POW.DiffiucltyAdjustStep);

                long prevBits = 0;

                if (previousBlock != null)
                {
                    prevBits = previousBlock.Header.Bits;
                }

                var work   = new POW(newHeight);
                var bits   = work.CalculateNextWorkTarget(height, prevBits, prev4032Block);
                var target = work.ConvertBitsToBigInt(bits).ToString("X").PadLeft(64, '0');

                var result = new GetDifficultyOM()
                {
                    height     = newHeight,
                    hashTarget = target
                };
                return(Ok(result));
            }
            catch (CommonException ce)
            {
                return(Error(ce.ErrorCode, ce.Message, ce));
            }
            catch (Exception ex)
            {
                return(Error(ErrorCode.UNKNOWN_ERROR, ex.Message, ex));
            }
        }
Пример #3
0
        private bool blockMining(BlockMsg block)
        {
            var work      = new POW(block.Header.Height);
            var blockData = new List <byte>();

            foreach (var tx in block.Transactions)
            {
                blockData.AddRange(tx.Serialize());
            }


            Parallel.For(0L, Int64.MaxValue, new ParallelOptions {
                MaxDegreeOfParallelism = 4
            }, (i, loopState) =>
                         //for (long i = 0; i < Int64.MaxValue; i++)
            {
                //var latestHeight = this.blockComponent.GetLatestHeight();

                //if(latestHeight > -1 && latestHeight >= block.Header.Height)
                //{
                //    loopState.Stop();
                //}

                var newBuffer  = new List <byte>(blockData.ToArray());
                var nonceBytes = BitConverter.GetBytes(i);

                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(nonceBytes);
                }

                newBuffer.AddRange(nonceBytes);
                var result = Base16.Encode(
                    HashHelper.Hash(
                        newBuffer.ToArray()
                        ));

                if (work.Verify(block.Header.Bits, result))
                {
                    block.Header.Timestamp = Time.EpochTime;
                    block.Header.Nonce     = i;
                    block.Header.Hash      = block.Header.GetHash();

                    //block.Transactions[0].Timestamp = block.Header.Timestamp;
                    //block.Transactions[0].Hash = block.Transactions[0].GetHash();
                    loopState.Stop();
                    //break;

                    LogHelper.Debug("A New Block " + block.Header.Height + " has been created, the correct nonce is " + i);
                }
                else
                {
                }
            }
                         );

            if (block.Header.Nonce >= 0)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #4
0
        public BlockMsg CreateNewBlock(string minerName, string accountId = null)
        {
            var accountDac      = new AccountDac();
            var blockDac        = new BlockDac();
            var outputDac       = new OutputDac();
            var txDac           = new TransactionDac();
            var txPool          = TransactionPool.Instance;
            var transactionMsgs = new List <TransactionMsg>();

            long   lastBlockHeight = -1;
            string lastBlockHash   = Base16.Encode(HashHelper.EmptyHash());
            long   lastBlockBits   = -1;

            var blockEntity = blockDac.SelectLast();

            if (blockEntity != null)
            {
                lastBlockHeight = blockEntity.Height;
                lastBlockHash   = blockEntity.Hash;
                lastBlockBits   = blockEntity.Bits;
            }

            long totalSize    = 0;
            long maxSize      = BlockSetting.MAX_BLOCK_SIZE - (500 * 1024);
            var  poolItemList = txPool.MainPool.OrderByDescending(t => t.FeeRate).ToList();
            var  index        = 0;

            while (totalSize < maxSize && index < poolItemList.Count)
            {
                var tx = poolItemList[index].Transaction;

                if (tx != null && transactionMsgs.Where(t => t.Hash == tx.Hash).Count() == 0)
                {
                    if (txDac.SelectByHash(tx.Hash) == null)
                    {
                        transactionMsgs.Add(tx);
                        totalSize += tx.Size;
                    }
                    else
                    {
                        txPool.RemoveTransaction(tx.Hash);
                    }
                }
                else
                {
                    break;
                }

                index++;
            }


            var minerAccount = accountDac.SelectDefaultAccount();

            if (accountId != null)
            {
                var account = accountDac.SelectById(accountId);

                if (account != null && !string.IsNullOrWhiteSpace(account.PrivateKey))
                {
                    minerAccount = account;
                }
            }

            BlockMsg       newBlockMsg = new BlockMsg();
            BlockHeaderMsg headerMsg   = new BlockHeaderMsg();

            newBlockMsg.Header          = headerMsg;
            headerMsg.Height            = lastBlockHeight + 1;
            headerMsg.PreviousBlockHash = lastBlockHash;


            long totalAmount = 0;
            long totalFee    = 0;

            foreach (var tx in transactionMsgs)
            {
                long totalInputsAmount = 0L;
                long totalOutputAmount = 0L;

                foreach (var input in tx.Inputs)
                {
                    var utxo = outputDac.SelectByHashAndIndex(input.OutputTransactionHash, input.OutputIndex);

                    if (utxo != null)
                    {
                        totalInputsAmount += utxo.Amount;
                    }
                }

                foreach (var output in tx.Outputs)
                {
                    totalOutputAmount += output.Amount;
                }

                totalAmount += totalOutputAmount;
                totalFee    += (totalInputsAmount - totalOutputAmount);
            }

            var      work = new POW(headerMsg.Height);
            BlockMsg previous4032Block = null;

            if (headerMsg.Height > POW.DiffiucltyAdjustStep)
            {
                previous4032Block = this.GetBlockMsgByHeight(headerMsg.Height - POW.DiffiucltyAdjustStep);
            }

            var newBlockReward = work.GetNewBlockReward();

            headerMsg.Bits             = work.CalculateNextWorkTarget(lastBlockHeight, lastBlockBits, previous4032Block);
            headerMsg.TotalTransaction = transactionMsgs.Count + 1;

            var coinbaseTxMsg = new TransactionMsg();

            coinbaseTxMsg.Timestamp = Time.EpochTime;
            coinbaseTxMsg.Locktime  = 0;

            var coinbaseInputMsg = new InputMsg();

            coinbaseTxMsg.Inputs.Add(coinbaseInputMsg);
            coinbaseInputMsg.OutputIndex           = 0;
            coinbaseInputMsg.OutputTransactionHash = Base16.Encode(HashHelper.EmptyHash());
            coinbaseInputMsg.UnlockScript          = Script.BuildMinerScript(minerName);
            coinbaseInputMsg.Size = coinbaseInputMsg.UnlockScript.Length;

            var coinbaseOutputMsg = new OutputMsg();

            coinbaseTxMsg.Outputs.Add(coinbaseOutputMsg);
            coinbaseOutputMsg.Amount     = newBlockReward + totalFee;
            coinbaseOutputMsg.LockScript = Script.BuildLockScipt(minerAccount.Id);
            coinbaseOutputMsg.Size       = coinbaseOutputMsg.LockScript.Length;
            coinbaseOutputMsg.Index      = 0;

            coinbaseTxMsg.Hash = coinbaseTxMsg.GetHash();

            newBlockMsg.Transactions.Insert(0, coinbaseTxMsg);

            foreach (var tx in transactionMsgs)
            {
                newBlockMsg.Transactions.Add(tx);
            }

            return(newBlockMsg);
        }
Пример #5
0
        public bool VerifyBlock(BlockMsg newBlock)
        {
            if (this.exists(newBlock.Header.Hash))
            {
                throw new CommonException(ErrorCode.Engine.Block.Verify.BLOCK_HAS_BEEN_EXISTED);
            }

            if (newBlock.Header.Hash != newBlock.Header.GetHash())
            {
                throw new CommonException(ErrorCode.Engine.Block.Verify.BLOCK_HASH_ERROR);
            }

            var blockComponent = new BlockComponent();
            var previousBlock  = this.GetBlockMsgByHash(newBlock.Header.PreviousBlockHash);

            if (newBlock.Header.Height > 0 && previousBlock == null)
            {
                throw new CommonException(ErrorCode.Engine.Block.Verify.PREV_BLOCK_NOT_EXISTED);
            }

            if ((newBlock.Header.Timestamp > Time.EpochTime && (newBlock.Header.Timestamp - Time.EpochTime) > 2 * 60 * 60 * 1000) ||
                (previousBlock != null && newBlock.Header.Timestamp <= previousBlock.Header.Timestamp))
            {
                throw new CommonException(ErrorCode.Engine.Block.Verify.BLOCK_TIME_IS_ERROR);
            }

            if (newBlock.Serialize().Length > BlockSetting.MAX_BLOCK_SIZE)
            {
                throw new CommonException(ErrorCode.Engine.Block.Verify.BLOCK_SIZE_LARGE_THAN_LIMIT);
            }

            var work        = new POW(newBlock.Header.Height);
            var txComponent = new TransactionComponent();

            if (newBlock.Transactions.Count > 0)
            {
                var coinbase = newBlock.Transactions[0];
                var reward   = work.GetNewBlockReward();
                var totalFee = 0L;

                if (newBlock.Transactions.Count > 1)
                {
                    for (int i = 1; i < newBlock.Transactions.Count; i++)
                    {
                        long fee;
                        if (txComponent.VerifyTransaction(newBlock.Transactions[i], out fee))
                        {
                            totalFee += fee;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }

                if (coinbase.Inputs.Count != 1 || coinbase.Outputs.Count != 1 || coinbase.Inputs[0].OutputTransactionHash != Base16.Encode(HashHelper.EmptyHash()))
                {
                    throw new CommonException(ErrorCode.Engine.Transaction.Verify.COINBASE_FORMAT_ERROR);
                }
                else
                {
                    var output = coinbase.Outputs[0];

                    if (output.Amount > BlockSetting.OUTPUT_AMOUNT_MAX)
                    {
                        throw new CommonException(ErrorCode.Engine.Transaction.Verify.OUTPUT_EXCEEDED_THE_LIMIT);
                    }

                    if (!Script.VerifyLockScriptFormat(output.LockScript))
                    {
                        throw new CommonException(ErrorCode.Engine.Transaction.Verify.SCRIPT_FORMAT_ERROR);
                    }

                    if (output.Amount != (totalFee + reward))
                    {
                        throw new CommonException(ErrorCode.Engine.Transaction.Verify.COINBASE_OUTPUT_AMOUNT_ERROR);
                    }
                }
            }


            var prev4032Block = this.GetBlockMsgByHeight(newBlock.Header.Height - POW.DiffiucltyAdjustStep);

            long previousBlockHeight = -1;
            long previousBlockBits   = -1;

            if (previousBlock != null)
            {
                previousBlockHeight = previousBlock.Header.Height;
                previousBlockBits   = previousBlock.Header.Bits;
            }

            if (work.CalculateNextWorkTarget(previousBlockHeight, previousBlockBits, prev4032Block) != newBlock.Header.Bits)
            {
                throw new CommonException(ErrorCode.Engine.Block.Verify.BITS_IS_WRONG);
            }

            var hashResult = this.GetMiningWorkResult(newBlock);

            if (work.Verify(newBlock.Header.Bits, hashResult))
            {
                return(true);
            }
            else
            {
                throw new CommonException(ErrorCode.Engine.Block.Verify.POW_VERIFY_FAIL);
            }
        }