private string FormatAnswer(BlockchainVoteModelPlainText answers)
        {
            var answerText = "";

            foreach (var q in _questions)
            {
                if (answerText != "")
                {
                    answerText += "\n";
                }
                answerText += $"Question: {q.Question}\n";
                var answer = answers.Answers.FirstOrDefault(a => a.Question == q.Number);
                if (answer == null)
                {
                    answerText += "Answer Not Found!";
                }
                else
                {
                    answerText += "Answer: " + answer.Answer;
                }
            }
            return(answerText);
        }
Exemple #2
0
        public async Task <string> Vote(List <QuestionViewModel> questions, BlockchainDetails blockchain, IProgress <int> progress)
        {
            var voteClient = new VoteClient();

            progress.Report(1);

            try
            {
                // Create our random voting token
                var token = GenerateRandomToken();

                // Get the registrar's public key, to use for the blind signature
                var keyStr = await voteClient.GetPublicKey(Model.Name);

                var key = RsaTools.PublicKeyFromString(keyStr);

                // Blind our token
                progress.Report(2);
                var blindedToken = RsaTools.BlindMessage(token, key);

                // Get the token signed by the registrar
                var blindSignature = await voteClient.GetBlindSignature(Model.Name, blindedToken.Blinded.ToString());

                // Unblind the token
                var unblindedToken = RsaTools.UnblindMessage(new BigInteger(blindSignature), blindedToken.Random,
                                                             key);

                // Here we would normally sleep until a random number of other voters have had tokens blindly signed by the registrar.
                // This would be possible through observation of the root stream using the voters key, or a maximum timeout.
                // However, given that this is a prototype, there is not enough traffic to make this feasible.
                progress.Report(3);

                // Create a wallet address to vote from
                var walletId = await Model.GetNewWalletAddress();

                // Request a voting asset (currency)
                progress.Report(4);
                var regiMeta = await voteClient.GetVote(Model.Name, walletId, token, unblindedToken.ToString());

                // Wait until the currency has been confirmed
                progress.Report(5);
                await Model.ConfirmVoteAllocated();

                // Where the transaction's currency comes from
                progress.Report(6);
                var txIds = new List <CreateRawTransactionTxIn>
                {
                    new CreateRawTransactionTxIn {
                        TxId = regiMeta.TxId, Vout = 0
                    }
                };

                // Where the transaction's currency goes to (registrar)
                var toInfo = new List <CreateRawTransactionAmount>
                {
                    new CreateRawTransactionAsset
                    {
                        Address = regiMeta.RegistrarAddress,
                        Qty     = 1,
                        Name    = MultiChainTools.VOTE_ASSET_NAME
                    }
                };

                // Create our list of answers
                var answers = questions.Select(q => new BlockchainVoteAnswerModel
                {
                    Answer   = q.SelectedAnswer.Answer,
                    Question = q.QuestionNumber
                }).ToList();


                // Send our vote, encrytped if required
                if (blockchain.ShouldEncryptResults)
                {
                    var encryptKey       = RsaTools.PublicKeyFromString(blockchain.EncryptKey);
                    var encryptedAnswers = new BlockchainVoteModelEncrypted
                    {
                        MagicWords = regiMeta.Words,
                        Answers    = RsaTools.EncryptMessage(JsonConvert.SerializeObject(answers), encryptKey)
                    };

                    await Model.WriteTransaction(txIds, toInfo, encryptedAnswers);
                }
                else
                {
                    // Send vote in plaintext (live readable results)
                    var answerModel = new BlockchainVoteModelPlainText
                    {
                        MagicWords = regiMeta.Words,
                        Answers    = answers
                    };

                    await Model.WriteTransaction(txIds, toInfo, answerModel);
                }

                return(regiMeta.Words);
            }
            catch (ApiException)
            {
                progress.Report(-1);
                throw new CouldNotVoteException();
            }
            catch (Exception e)
            {
                progress.Report(-1);
                Debug.WriteLine(e.Message);
                throw new CouldNotVoteException();
            }
        }