public override SInt64Value CheckDividends(CheckDividendsInput input) { var termNumber = input.TermNumber; var ticketsAmount = input.TicketsAmount; var lockTime = input.LockTime; var currentTermNumber = State.ConsensusContract.GetCurrentTermNumber.Call(new Empty()).Value; if (termNumber >= currentTermNumber) { return(new SInt64Value()); } var totalWeights = State.TotalWeightsMap[termNumber]; if (totalWeights > 0) { var totalDividends = State.DividendsMap[termNumber]; if (totalDividends > 0) { var weights = VotingRecord.CalculateWeight(ticketsAmount, lockTime) * totalDividends / totalWeights; return(new SInt64Value { Value = weights }); } } return(new SInt64Value()); }
public override SInt64Value GetLatestRequestDividendsTermNumber(VotingRecord input) { var termNumber = State.LastRequestedDividendsMap[input.TransactionId]; if (termNumber != 0) { return(new SInt64Value { Value = termNumber }); } return(new SInt64Value { Value = input.TermNumber }); }
public override SInt64Value GetAvailableDividends(VotingRecord input) { var votingRecord = input; long dividends = 0; var start = votingRecord.TermNumber + 1; var lastRequestTermNumber = State.LastRequestedDividendsMap[votingRecord.TransactionId]; if (lastRequestTermNumber > 0) { start = lastRequestTermNumber + 1; } var voteInfo = new VoteInfo { Record = votingRecord, Age = State.ConsensusContract.GetBlockchainAge.Call(new Empty()).Value }; var end = Math.Min(GetExpireTermNumber(voteInfo).Value, State.ConsensusContract.GetCurrentTermNumber.Call(new Empty()).Value - 1); for (var i = start; i <= end; i++) { var totalWeights = State.TotalWeightsMap[i]; if (totalWeights > 0) { var totalDividends = State.DividendsMap[i]; if (totalDividends > 0) { dividends += totalDividends * votingRecord.Weight / totalWeights; } } } return(new SInt64Value { Value = dividends }); }
/// <summary> /// Transfer dividends to miners. /// </summary> /// <param name="input"></param> /// <returns></returns> // ReSharper disable once InconsistentNaming public override SInt64Value TransferDividends(VotingRecord input) { var votingRecord = input; if (State.ConsensusContract.Value == null) { State.ConsensusContract.Value = State.BasicContractZero.GetContractAddressByName.Call(State.ConsensusContractSystemName.Value); } Assert(Context.Sender == State.ConsensusContract.Value, "Only consensus contract can transfer dividends."); var dividendsOwner = votingRecord.From; var dividendsOwnerAddress = Address.FromPublicKey(ByteArrayHelpers.FromHexString(dividendsOwner)); var startTermNumber = votingRecord.TermNumber + 1; var history = State.LastRequestedDividendsMap[votingRecord.TransactionId]; if (history > 0) { startTermNumber = history + 1; } var voteInfo = new VoteInfo() { Record = votingRecord, Age = State.ConsensusContract.GetBlockchainAge.Call(new Empty()).Value }; var endTermNumber = Math.Min(GetExpireTermNumber(voteInfo).Value, State.ConsensusContract.GetCurrentTermNumber.Call(new Empty()).Value - 1); // Record last requested dividends term number. var actualTermNumber = startTermNumber; long totalDividendsAmount = 0; for (var i = startTermNumber; i <= endTermNumber; i++) { var totalWeights = State.TotalWeightsMap[i]; Assert(totalWeights > 0, $"Total weights of term {i} not found."); var dividends = State.DividendsMap[i]; Assert(dividends > 0, $"Dividends of term {i} not found."); totalDividendsAmount += dividends * votingRecord.Weight / totalWeights; actualTermNumber = i; } if (State.TokenContract.Value == null) { State.TokenContract.Value = State.BasicContractZero.GetContractAddressByName.Call(State.TokenContractSystemName.Value); } State.TokenContract.Transfer.Send(new TransferInput { To = dividendsOwnerAddress, Amount = totalDividendsAmount, Symbol = Context.Variables.NativeSymbol, Memo = "Transfer dividends." }); Context.LogDebug(() => $"Gonna transfer {totalDividendsAmount} dividends to {dividendsOwnerAddress}"); State.LastRequestedDividendsMap[votingRecord.TransactionId] = actualTermNumber; return(new SInt64Value() { Value = totalDividendsAmount }); }