public Dictionary <string, BlockSub> GetMinerReward_SOLO(long minHeight, long maxHeight) { Dictionary <string, BlockSub> minerTransfer = new Dictionary <string, BlockSub>(); if (httpPool != null) { string addressIn = Wallet.GetWallet().GetCurWallet().ToAddress(); for (long rewardheight = minHeight; rewardheight < maxHeight; rewardheight++) { Dictionary <string, MinerTask> miners = null; using (DbSnapshot snapshot = PoolDBStore.GetSnapshot()) { string json = snapshot.Get("Pool_H2_" + rewardheight); if (!string.IsNullOrEmpty(json)) { miners = JsonHelper.FromJson <Dictionary <string, MinerTask> >(json); } } if (miners != null) { var mcblk = GetMcBlock(rewardheight); if (mcblk != null && mcblk.Address == ownerAddress) { var miner = miners.Values.FirstOrDefault(c => c.random.IndexOf(mcblk.random) != -1); if (miner != null) { BigFloat reward = new BigFloat(Consensus.GetReward(rewardheight)); reward = reward * (1.0f - GetServiceFee()); var transfer = new BlockSub(); transfer.addressIn = addressIn; transfer.addressOut = miner.address; string pay = BigHelper.Round8(reward.ToString()); if (minerTransfer.TryGetValue(miner.address, out transfer)) { transfer.amount = BigHelper.Add(transfer.amount, pay); } else { transfer = new BlockSub(); transfer.addressIn = addressIn; transfer.addressOut = miner.address; transfer.amount = BigHelper.Sub(pay, "0.002"); // 扣除交易手续费 transfer.type = "100%"; // 有效提交百分比 transfer.data = CryptoHelper.Sha256($"{mcblk.hash}_{maxHeight}_{ownerAddress}_{miner.address}_Reward_SOLO"); minerTransfer.Add(transfer.addressOut, transfer); } } } } } } return(minerTransfer); }
static public bool Transfer(string addressIn, string addressOut, string amount) { var transfer = LuaVMStack.s_transfer; var dbSnapshot = LuaVMStack.s_dbSnapshot; var height = LuaVMStack.s_transfer.height; var transferShow = Entity.Root.GetComponent <Consensus>().transferShow; if (BigHelper.Less(amount, "0", true)) { throw new Exception("Transfer amount Less 0"); } if (transfer.addressIn != addressIn && LuaVMStack.s_consAddress != addressIn && LuaVMStack.s_sender != addressIn) { throw new Exception("Transfer address error"); } if (height != 1) { Account accountIn = dbSnapshot.Accounts.Get(addressIn); if (accountIn == null) { throw new Exception("Transfer accountIn error"); } if (BigHelper.Less(accountIn.amount, amount, false)) { throw new Exception("Transfer accountIn.amount is not enough"); } accountIn.amount = BigHelper.Sub(accountIn.amount, amount); dbSnapshot.Accounts.Add(accountIn.address, accountIn); if (transferShow) { dbSnapshot.BindTransfer2Account(addressIn, transfer.hash); } } Account accountOut = dbSnapshot.Accounts.Get(addressOut) ?? new Account() { address = addressOut, amount = "0", nonce = 0 }; accountOut.amount = BigHelper.Add(accountOut.amount, amount); dbSnapshot.Accounts.Add(accountOut.address, accountOut); if (transferShow) { dbSnapshot.BindTransfer2Account(addressOut, transfer.hash); transfer.height = height; dbSnapshot.Transfers.Add(transfer.hash, transfer); } return(true); }
// Miner reward, only after confirming that it cannot be rolled back public Dictionary <string, BlockSub> GetMinerReward_PPLNS(long minHeight, long maxHeight) { Dictionary <string, BlockSub> minerTransfer = new Dictionary <string, BlockSub>(); if (httpPool != null) { string addressIn = Wallet.GetWallet().GetCurWallet().ToAddress(); for (long rewardheight = minHeight; rewardheight < maxHeight; rewardheight++) { Dictionary <string, MinerTask> miners = null; using (DbSnapshot snapshot = PoolDBStore.GetSnapshot()) { string json = snapshot.Get("Pool_H2_" + rewardheight); if (!string.IsNullOrEmpty(json)) { miners = JsonHelper.FromJson <Dictionary <string, MinerTask> >(json); } } if (miners != null) { var mcblk = GetMcBlock(rewardheight); if (mcblk == null) { throw new Exception($"GetMcBlock({rewardheight}) return null"); } if (mcblk != null && mcblk.Address == ownerAddress) { double reward = Consensus.GetReward(rewardheight); reward = reward * (1.0f - GetServiceFee()); var miner = miners.Values.FirstOrDefault(c => c.random.IndexOf(mcblk.random) != -1); if (miner == null) { continue; } // Total power double powerSum = 0; var Values = miners.Values.ToList(); for (var ii = 0; ii < Values.Count; ii++) { var dic = Values[ii]; if (string.IsNullOrEmpty(dic.address)) { continue; } double power = CalculatePower.Power(dic.diff); if (power < HttpPool.ignorePower) { continue; } powerSum += power; } // Reward for participation BlockSub transfer = null; for (var ii = 0; ii < Values.Count; ii++) { var dic = Values[ii]; if (string.IsNullOrEmpty(dic.address)) { continue; } double power = CalculatePower.Power(dic.diff); double pay = Math.Round(power * reward / powerSum, 8); if (minerTransfer.TryGetValue(dic.address, out transfer)) { if (power < HttpPool.ignorePower) { transfer.height += 1; // 这里表示无效提交数 continue; } transfer.nonce += 1; // 这里表示有效提交数 transfer.amount = BigHelper.Add(transfer.amount, pay.ToString("N8")); } else if (pay >= 0.002) { transfer = new BlockSub(); transfer.nonce = 1; // 这里表示有效提交数 transfer.addressIn = addressIn; transfer.addressOut = dic.address; transfer.amount = BigHelper.Sub(pay.ToString("N8"), "0.002"); // 扣除交易手续费 transfer.data = CryptoHelper.Sha256($"{mcblk.hash}_{maxHeight}_{ownerAddress}_{dic.address}_MinerReward"); if (power < HttpPool.ignorePower) { transfer.height += 1; // 这里表示无效提交数 continue; } minerTransfer.Add(transfer.addressOut, transfer); } } } } } // 有效提交次数越多收益越高 var totalAmount1 = "0"; // 总账1 var totalAmount2 = "0"; // 总账2 foreach (var transfer in minerTransfer.Values) { try { totalAmount1 = BigHelper.Add(totalAmount1, transfer.amount); var totalSubmit = transfer.nonce + transfer.height; var share = (float)transfer.nonce / (float)totalSubmit; transfer.type = $"{Math.Round(share * 100, 2)}%"; // 有效提交百分比 share *= share; transfer.remarks = BigHelper.Mul(share.ToString(), transfer.amount); totalAmount2 = BigHelper.Add(totalAmount2, transfer.remarks); } catch (Exception) { transfer.type = "0%"; transfer.remarks = "0"; } } var totalAmount3 = "0"; // 总账3 foreach (var transfer in minerTransfer.Values) { try { transfer.amount = BigHelper.Div(BigHelper.Mul(transfer.remarks, totalAmount1), totalAmount2); totalAmount3 = BigHelper.Add(totalAmount3, transfer.amount); } catch (Exception) { } } //if (BigHelper.Greater(BigHelper.Abs(BigHelper.Sub(totalAmount1, totalAmount3)), "0.002", true)) //{ // Log.Warning($"|totalAmount1 - totalAmount3| > 0.002 {BigHelper.Sub(totalAmount1, totalAmount3)}"); //} } return(minerTransfer); }
// Miner reward, only after confirming that it cannot be rolled back public Dictionary <string, BlockSub> MinerReward_PPLNS(string today, long minHeight, long maxHeight) { Dictionary <string, BlockSub> minerTransfer = new Dictionary <string, BlockSub>(); if (httpPool != null) { WalletKey walletKey = Wallet.GetWallet().GetCurWallet(); for (long rewardheight = minHeight; rewardheight < maxHeight; rewardheight++) { Dictionary <string, MinerTask> miners = null; using (DbSnapshot snapshot = PoolDBStore.GetSnapshot()) { string json = snapshot.Get("Pool_H_" + rewardheight); if (!string.IsNullOrEmpty(json)) { miners = JsonHelper.FromJson <Dictionary <string, MinerTask> >(json); } } //var miners = httpPool.GetMiner(rewardheight); if (miners != null) { string ownerAddress = Wallet.GetWallet().GetCurWallet().ToAddress(); var mcblk = BlockChainHelper.GetMcBlock(rewardheight); if (mcblk != null && mcblk.Address == ownerAddress) { BigFloat reward = new BigFloat(Consensus.GetReward(rewardheight)); reward = reward * (1.0f - serviceFee); var miner = miners.Values.FirstOrDefault(c => c.random == mcblk.random); if (miner == null) { continue; } // Total power BigFloat diffsum = new BigFloat(0); foreach (var dic in miners.Values) { if (string.IsNullOrEmpty(dic.address)) { continue; } if (dic.diff < 0.99999f) { continue; } diffsum += new BigFloat(dic.diff); } // Reward for participation foreach (var dic in miners.Values) { if (string.IsNullOrEmpty(dic.address)) { continue; } if (dic.diff < 0.99999f) { continue; } var v = new BigFloat(dic.diff); string pay = BigHelper.Round8((v * reward / diffsum).ToString()); if (minerTransfer.TryGetValue(dic.address, out BlockSub transfer)) { transfer.amount = BigHelper.Add(transfer.amount, pay); } else if (BigHelper.Greater(pay, "0.002", false)) { transfer = new BlockSub(); transfer.addressIn = ownerAddress; transfer.addressOut = dic.address; transfer.amount = BigHelper.Sub(pay, "0.002"); // 扣除交易手续费 transfer.type = "transfer"; transfer.data = CryptoHelper.Sha256($"{today}_{maxHeight}_{ownerAddress}_{dic.address}_MinerReward"); minerTransfer.Add(transfer.addressOut, transfer); } } } } } } return(minerTransfer); }