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
            });
        }
示例#4
0
        /// <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
            });
        }