Ejemplo n.º 1
0
        public IRpcMethodResult SignMessage(string address, string message)
        {
            try
            {
                var account = new AccountComponent().GetAccountById(address);

                if (account == null || string.IsNullOrWhiteSpace(account.PrivateKey))
                {
                    throw new CommonException(ErrorCode.Service.Account.ACCOUNT_NOT_FOUND);
                }

                ECDsa dsa        = ECDsa.ImportPrivateKey(Base16.Decode(DecryptPrivateKey(account.PrivateKey)));
                var   signResult = Base16.Encode(dsa.SingnData(Encoding.UTF8.GetBytes(message)));

                var result = new
                {
                    signature = signResult,
                    publicKey = account.PublicKey
                };

                return(Ok(result));
            }
            catch (CommonException ce)
            {
                return(Error(ce.ErrorCode, ce.Message, ce));
            }
            catch (Exception ex)
            {
                return(Error(ErrorCode.UNKNOWN_ERROR, ex.Message, ex));
            }
        }
Ejemplo n.º 2
0
        public Account ImportAccount(string privateKeyText)
        {
            var dac = AccountDac.Default;

            byte[] privateKey = Base16.Decode(privateKeyText);
            byte[] publicKey;
            using (var dsa = ECDsa.ImportPrivateKey(privateKey))
            {
                publicKey = dsa.PublicKey;
            }

            var     id      = AccountIdHelper.CreateAccountAddress(publicKey);
            Account account = dac.SelectById(id);

            if (account == null)
            {
                account             = new Account();
                account.Id          = AccountIdHelper.CreateAccountAddress(publicKey);
                account.PrivateKey  = Base16.Encode(privateKey);
                account.PublicKey   = Base16.Encode(publicKey);
                account.Balance     = 0;
                account.IsDefault   = false;
                account.WatchedOnly = false;

                AccountDac.Default.Insert(account);
            }

            return(account);
        }
Ejemplo n.º 3
0
        public static string BuildUnlockScript(string transactionHash, int outputIndex, byte[] privateKey, byte[] publicKey)
        {
            var data = new List <byte>();

            data.AddRange(Base16.Decode(transactionHash));

            var indexBytes = BitConverter.GetBytes(outputIndex);

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

            data.AddRange(indexBytes);

            using (var dsa = ECDsa.ImportPrivateKey(privateKey))
            {
                if (Base16.Encode(dsa.PublicKey) != Base16.Encode(publicKey))
                {
                    throw new CommonException(ErrorCode.Engine.Transaction.Verify.PRIVATE_KEY_IS_ERROR);
                }

                var signature = dsa.SingnData(data.ToArray());

                return(string.Format(
                           UNLOCK_SCRIPT_TEMPLATE,
                           Base16.Encode(signature),
                           Base16.Encode(dsa.PublicKey)
                           ));
            }
        }
Ejemplo n.º 4
0
        public bool ForgeBlock(string startId, string minerAddress, long nonce, out BlockMsg successBlock)
        {
            successBlock = null;
            var block = RedisManager.Current.GetDataInRedis <BlockMsg>(startId);

            if (block == null)
            {
                return(false);
            }

            LogHelper.Info("Forge Block 7");

            //区块由矿池生成,奖励由矿池分配给矿工
            block.Header.GeneratorId = minerAddress;
            block.Header.Nonce       = nonce;
            block.Header.Timestamp   = Time.EpochTime;

            var dsa = ECDsa.ImportPrivateKey(_poolPrivateKey);

            block.Header.BlockSignature   = Base16.Encode(dsa.SingnData(Base16.Decode(block.Header.PayloadHash)));
            block.Header.BlockSigSize     = block.Header.BlockSignature.Length;
            block.Header.Hash             = block.Header.GetHash();
            block.Header.TotalTransaction = block.Transactions.Count;

            var result = NodeApi.Current.ForgeBlock(block);

            if (result)
            {
                //关闭挖矿
                PoolCenterJob.Current.StopMining(true, startId);
                RedisManager.Current.SaveDataToRedis(startId, block);
                successBlock = block;
                var currentTime = Time.EpochTime;
                var startTime   = block.Header.Timestamp;

                if (block.Header.Height == this.currentBlockHeight)
                {
                    startTime = this.currentBlockStartTime;
                    LogHelper.Info($"block start time is {Time.GetLocalDateTime(startTime)}");
                }

                //ConfigurationTool.GetAppSettings<PoolCenterSetting>("PoolCenterSetting").GenerateBlockDelayTime;
                int generateBlockDelaySeconds = ConfigCenter.ConfigPoolCenter.GenerateBlockDelayTime;
                if (currentTime - startTime < generateBlockDelaySeconds)
                {
                    var waitTime = generateBlockDelaySeconds - (int)(currentTime - startTime);
                    LogHelper.Info($"Block generate time {currentTime - startTime} less than {generateBlockDelaySeconds/1000} seconds, wait for a moment");
                    System.Threading.Thread.Sleep(waitTime);
                }
            }

            LogHelper.Info("ForgeBlock Result = " + result);
            return(result);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 创建新的区块
        /// </summary>
        /// <param name="minerName"></param>
        /// <param name="generatorId"></param>
        /// <param name="accountId"></param>
        /// <returns></returns>
        public BlockMsg CreateNewBlock(string minerName, string generatorId, string remark = null, 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;
            string lastBlockGenerator = null;

            //获取最后一个区块
            var blockEntity = blockDac.SelectLast();

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

            long totalSize    = 0;
            long maxSize      = BlockSetting.MAX_BLOCK_SIZE - (1 * 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;
                }
            }

            var minerAccountId = minerAccount.Id;

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

            headerMsg.Hash              = Base16.Encode(HashHelper.EmptyHash());
            headerMsg.GeneratorId       = generatorId;
            newBlockMsg.Header          = headerMsg;
            headerMsg.Height            = lastBlockHeight + 1;
            headerMsg.PreviousBlockHash = lastBlockHash;

            if (headerMsg.Height == 0)
            {
                minerAccountId = BlockSetting.GenesisBlockReceiver;
                remark         = BlockSetting.GenesisBlockRemark;
            }

            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 prevBlockMsg     = null;
            BlockMsg prevStepBlockMsg = null;

            if (blockEntity != null)
            {
                prevBlockMsg = this.convertEntityToBlockMsg(blockEntity);
            }

            if (headerMsg.Height >= POC.DIFFIUCLTY_ADJUST_STEP)
            {
                prevStepBlockMsg = this.GetBlockMsgByHeight(headerMsg.Height - POC.DIFFIUCLTY_ADJUST_STEP - 1);
            }

            var newBlockReward = POC.GetNewBlockReward(headerMsg.Height);

            headerMsg.Bits             = POC.CalculateBaseTarget(headerMsg.Height, prevBlockMsg, prevStepBlockMsg);
            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, remark);
            coinbaseInputMsg.Size = coinbaseInputMsg.UnlockScript.Length;

            var coinbaseOutputMsg = new OutputMsg();

            coinbaseTxMsg.Outputs.Add(coinbaseOutputMsg);
            coinbaseOutputMsg.Amount     = newBlockReward + totalFee;
            coinbaseOutputMsg.LockScript = Script.BuildLockScipt(minerAccountId);
            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);
            }

            headerMsg.PayloadHash = newBlockMsg.GetPayloadHash();
            var dsa        = ECDsa.ImportPrivateKey(Base16.Decode(minerAccount.PrivateKey));
            var signResult = dsa.SingnData(Base16.Decode(headerMsg.PayloadHash));

            headerMsg.BlockSignature   = Base16.Encode(signResult);
            headerMsg.BlockSigSize     = headerMsg.BlockSignature.Length;
            headerMsg.TotalTransaction = newBlockMsg.Transactions.Count;
            return(newBlockMsg);
        }