コード例 #1
0
        public void Voted(BlockchainDetails blockchain, string words)
        {
            CopyStatus  = "";
            MagicWords  = words;
            _blockchain = blockchain;

            Encrypted = blockchain.ShouldEncryptResults;
            ProceedCommand.RaiseCanExecuteChanged();
        }
コード例 #2
0
        private async Task ConnectToBlockchain(BlockchainDetails blockchain)
        {
            if (MultiChainVm.Connected)
            {
                if (MultiChainVm.Model.Name != blockchain.ChainString)
                {
                    await MultiChainVm.Disconnect();
                }
                else
                {
                    return;
                }
            }

            await MultiChainVm.Connect(blockchain.Host, blockchain.Port, blockchain.ChainString);
        }
コード例 #3
0
        private async Task ConnectToBlockchain(BlockchainDetails blockchain)
        {
            if (MultiChainVm.Connected)
            {
                if (MultiChainVm.Model.Name != blockchain.ChainString)
                {
                    await MultiChainVm.Disconnect();
                }
                else
                {
                    return;
                }
            }

            await MultiChainVm.Connect(blockchain.Host, blockchain.Port, blockchain.ChainString);

            // Ensure our questions have been loaded. Connection may be slow
            await MultiChainVm.Model.WaitUntilBlockchainSynced(3, new Progress <BlockchainSyncProgress>());
        }
コード例 #4
0
 public BlockchainViewModel(BlockchainDetails model)
 {
     _model = model;
 }
コード例 #5
0
        private async Task GetResults(BlockchainDetails blockchain)
        {
            // Ensure the blockchain is up to date
            var progressModel = new Progress <BlockchainSyncProgress>(UpdateProgress);
            await MultiChainVm.Model.WaitUntilBlockchainSynced(blockchain.Blocks, progressModel);

            try
            {
                // Read the questions from the blockchain
                _questions = await MultiChainVm.Model.GetQuestions();

                var decryptKey = "";

                // Blockchain encrypted, so we need the decryption key to read the results
                if (blockchain.ShouldEncryptResults)
                {
                    decryptKey = await _voteClient.GetDecryptKey(blockchain.ChainString);
                }

                // Get answers from blockchain
                _answers =
                    await MultiChainVm.Model.GetResults(blockchain.WalletId, decryptKey);

                // For each question, get its total for each answer
                var results = _questions.Select(question =>
                {
                    // Setup response dictionary, answer -> num votes
                    var options = question.Answers.ToDictionary(a => a.Answer, a => 0);
                    foreach (var answer in _answers)
                    {
                        foreach (var questionAnswer in answer.Answers.Where(a => a.Question == question.Number))
                        {
                            // In case we have anything unusual going on
                            if (!options.ContainsKey(questionAnswer.Answer))
                            {
                                Debug.WriteLine(
                                    $"Unexpected answer for question {questionAnswer.Question}: {questionAnswer.Answer}");
                                continue;
                            }
                            options[questionAnswer.Answer]++;
                        }
                    }

                    return(new
                    {
                        question.Number,
                        question.Question,
                        Results = options
                    });
                }).ToList();

                var chartVms = results.Select(q => new ChartViewModel(q.Results)
                {
                    Question = q.Question
                }).ToList();

                Ui(() =>
                {
                    Loading = false;
                    Results.Clear();
                    Results.AddRange(chartVms);

                    TotalResults   = chartVms.Count;
                    CurrentResults = 1;
                    TransitionView.ShowPage(Results.First());
                });
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
        }
コード例 #6
0
        public void SelectVote(BlockchainDetails blockchain)
        {
            _currentDetails = blockchain;

            Connect();
        }
コード例 #7
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();
            }
        }