示例#1
0
        public static bool IsExpired(this VotingRecord votingRecord, long currentAge)
        {
            var lockExpiredAge = votingRecord.VoteAge;

            foreach (var day in votingRecord.LockDaysList)
            {
                lockExpiredAge += day;
            }

            return(lockExpiredAge <= currentAge);
        }
示例#2
0
        public override Hash Vote(VoteInput input)
        {
            var candidatePublicKey = input.CandidatePublicKey;
            var amount             = input.Amount;
            var lockTime           = input.LockTime;

            Assert(lockTime.InRange(90, 1095),
                   ContractErrorCode.GetErrorMessage(ContractErrorCode.InvalidOperation, "Lock days is illegal."));

            // Cannot vote to non-candidate.
            var candidates = State.CandidatesField.Value;

            Assert(candidates != null, ContractErrorCode.GetErrorMessage(ContractErrorCode.NotFound, "No candidate."));
            Assert(candidates != null && candidates.PublicKeys.Contains(candidatePublicKey),
                   ContractErrorCode.GetErrorMessage(ContractErrorCode.InvalidOperation,
                                                     "Target didn't announce election."));

            var voterPublicKey = Context.RecoverPublicKey().ToHex();

            // A candidate cannot vote to anybody.
            Assert(candidates != null && !candidates.PublicKeys.Contains(voterPublicKey),
                   ContractErrorCode.GetErrorMessage(ContractErrorCode.InvalidOperation, "Candidate can't vote."));

            // Transfer the tokens to Consensus Contract address.
            State.TokenContract.Lock.Send(new LockInput
            {
                From   = Context.Sender,
                To     = Context.Self,
                Symbol = Context.Variables.NativeSymbol,
                Amount = amount,
                LockId = Context.TransactionId,
                Usage  = "Lock for getting tickets."
            });

            var currentTermNumber  = State.CurrentTermNumberField.Value;
            var currentRoundNumber = State.CurrentRoundNumberField.Value;

            // To make up a VotingRecord instance.
            TryToGetBlockchainStartTimestamp(out var blockchainStartTimestamp);

            var votingRecord = new VotingRecord
            {
                Count           = amount,
                From            = voterPublicKey,
                To              = candidatePublicKey,
                RoundNumber     = currentRoundNumber,
                TransactionId   = Context.TransactionId,
                VoteAge         = CurrentAge,
                UnlockAge       = CurrentAge + (long)lockTime,
                TermNumber      = currentTermNumber,
                VoteTimestamp   = blockchainStartTimestamp.ToDateTime().AddMinutes(CurrentAge).ToTimestamp(),
                UnlockTimestamp = blockchainStartTimestamp.ToDateTime().AddMinutes(CurrentAge + (long)lockTime)
                                  .ToTimestamp()
            };

            votingRecord.LockDaysList.Add(lockTime);

            // Add the transaction id of this voting record to the tickets information of the voter.
            var tickets = State.TicketsMap[voterPublicKey.ToStringValue()];

            if (tickets != null)
            {
                tickets.VoteToTransactions.Add(votingRecord.TransactionId);
            }
            else
            {
                tickets = new Tickets {
                    PublicKey = voterPublicKey
                };
                tickets.VoteToTransactions.Add(votingRecord.TransactionId);
            }

            tickets.VotedTickets        += votingRecord.Count;
            tickets.HistoryVotedTickets += votingRecord.Count;
            State.TicketsMap[voterPublicKey.ToStringValue()] = tickets;

            // Add the transaction id of this voting record to the tickets information of the candidate.
            var candidateTickets = State.TicketsMap[candidatePublicKey.ToStringValue()];

            if (candidateTickets != null)
            {
                candidateTickets.VoteFromTransactions.Add(votingRecord.TransactionId);
            }
            else
            {
                candidateTickets = new Tickets {
                    PublicKey = candidatePublicKey
                };
                candidateTickets.VoteFromTransactions.Add(votingRecord.TransactionId);
            }

            candidateTickets.ObtainedTickets        += votingRecord.Count;
            candidateTickets.HistoryObtainedTickets += votingRecord.Count;
            State.TicketsMap[candidatePublicKey.ToStringValue()] = candidateTickets;

            // Update the amount of votes (voting records of whole system).
            State.VotesCountField.Value += 1;

            // Update the amount of tickets.
            State.TicketsCountField.Value += votingRecord.Count;

            // Add this voting record to voting records map.
            State.VotingRecordsMap[votingRecord.TransactionId] = votingRecord;

            // Tell Dividends Contract to add weights for this voting record.
            State.DividendContract.AddWeights.Send(new Dividend.WeightsInfo()
            {
                TermNumber = currentTermNumber + 1, Weights = votingRecord.Weight
            });

            Context.LogDebug(() => $"Weights of vote {votingRecord.TransactionId.ToHex()}: {votingRecord.Weight}");

            return(Context.TransactionId);
        }