public ActionResult CreateNewStatement(TrustLessModelLib.Statement statement)
        {
            using (DataContext context = new DataContext())
            {
                if (!PersonController.ValidateLoginSession(context,statement.Person.LoginSession.Token))
                    return new HttpStatusCodeResult((int)HttpStatusCode.Forbidden);

                var match =
                    context.Statements.FirstOrDefault(x => x.MedicinOne == statement.MedicinOne && x.MedicinTwo == statement.MedicinTwo);

                //Does a statement already exists with the same two medicins.
                if (match != null) // && IsStatementValid(context,match)
                    return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest);

                //Security: Don't allow user to specify the person who created the statement. Set it to the current user logged in.
                statement.Person =
                    context.Persons.FirstOrDefault(x => x.Username == statement.Person.Username);

                //If the person does not exist, abort.
                if (statement.Person == null)
                    return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest);

                //Rule: refuse a user with zero trust from creating statements.
                if (CalculateBayesianModelTrust(statement.Person) == 0)
                    return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest);

                context.Statements.Add(statement);

                //Add recommendation from user
                var recommendation = new TrustLessModelLib.Recommendation(){ Person = statement.Person, Statement = statement, IsRecommended = true, Transaction = null, Description = statement.Description, CreationDate = DateTime.Now};

                //This will fail if a racecondition was to add two recommendations (given that our key assignment of the table ensures only one of the same recommendation exist).
                context.Recommendations.Add (recommendation);
                context.SaveChanges ();

                BlockChain.MakeRecommendation (context, recommendation);

                return new HttpStatusCodeResult((int)HttpStatusCode.Created);
            }
        }
Example #2
0
        /// <summary>
        /// Issues an S or F to a user for a recommendation.
        /// </summary>
        /// <param name="recommendation">Recommendation</param>
        /// <param name="rewardUser">true for S asset and false for F</param>
        public static void Issue(TrustLessModelLib.Recommendation recommendation, bool rewardUser)
        {
            string chainName = WebConfigurationManager.AppSettings["ChainName"];
                string nodeIp = WebConfigurationManager.AppSettings["NodeIp"];
                MultiChainClient client = new MultiChainClient(chainName,nodeIp);

                GetTxOutResponse getTxOutResponse = client.GetTxOut(recommendation.Transaction.Tx,recommendation.Transaction.Vout);
            if (getTxOutResponse == null)
                return;

            Dictionary<string,int> amount = new Dictionary<string, int>();
                amount.Add(getTxOutResponse.assets.First(x => x.name.StartsWith(rewardUser ? "S_" : "F_")).name,1);

                string multichainPublicKey = WebConfigurationManager.AppSettings["MultichainPublicKey"];
            var resp = client.CreateRawTransaction (recommendation.Person.PublicKey, recommendation.Transaction.Tx,recommendation.Transaction.Vout, amount);
                var respAppendRawChange = client.AppendRawChange (resp.Hex, multichainPublicKey);
            var respSignTransaction = client.SignRawTransaction (respAppendRawChange.Hex);
            if (respSignTransaction.complete) {
                var respSendRawTransaction = client.SendRawTransaction (respSignTransaction.hex);
                if (String.IsNullOrEmpty (respSendRawTransaction.TransactionId))
                    client.LockUnspent (true,  recommendation.Transaction.Tx,recommendation.Transaction.Vout);
            }
        }
Example #3
0
        /// <summary>
        /// Reserves/locks away one S and F asset and sets the recommendation to reference these assets.
        /// </summary>
        /// <param name="db">DataContext</param>
        /// <param name="recommendation">Recommendation</param>
        public static void MakeRecommendation(DataContext db, TrustLessModelLib.Recommendation recommendation)
        {
            string chainName = WebConfigurationManager.AppSettings["ChainName"];
            string nodeIp = WebConfigurationManager.AppSettings["NodeIp"];
            MultiChainClient client = new MultiChainClient(chainName,nodeIp);
            Dictionary<string,int> dictionary = new Dictionary<string, int>();
            AddressBalance[] addressBalances = client.GetTotalBalances ().Balances;
            var lastFasset = addressBalances.OrderBy (x => x.name).LastOrDefault (x => x.name.StartsWith ("F_"));
            var lastSasset = addressBalances.OrderBy (x => x.name).LastOrDefault (x => x.name.StartsWith ("S_"));
            if (lastFasset == null || lastSasset == null) {
                GenerateFunds (client);
                MakeRecommendation (db, recommendation);
                return;
            }
            string lastF = lastFasset.name;
            string lastS = lastSasset.name;

            dictionary.Add(lastF,1);
            dictionary.Add(lastS,1);
            try
            {
                var resp = client.PrepareLockUnspent(dictionary);

                recommendation.Transaction = new ReservedTransaction()
                {
                    Tx = resp.txid,
                    Vout = resp.vout
                };
            }
            catch {
                //Insurficient funds
                GenerateFunds(client);
                MakeRecommendation (db, recommendation);
                return;
            }

            db.SaveChanges ();
        }
        /// <summary>
        /// Rewards users that have made a correct recommendation with an S asset and punishes users
        /// who were wrong in their recommendation.
        /// </summary>
        /// <param name="context">DataContext</param>
        /// <param name="statement">Statement</param>
        private void IssueTrustForStatement(DataContext context,TrustLessModelLib.Statement statement)
        {
            var recommendations =
                context.Recommendations.Include("Person").Include("Transaction").Where(x => x.StatementId== statement.Id && x.Transaction != null).ToList();

            int sAmount = recommendations.Count (x => x.IsRecommended) +1;
            int fAmount = recommendations.Count (x => !x.IsRecommended);

            foreach (Recommendation recommendation in recommendations) {
                if (sAmount >= fAmount) {
                    if (recommendation.IsRecommended) {
                        BlockChain.Issue (recommendation,true);
                    } else {
                        BlockChain.Issue (recommendation,false);
                    }
                } else {
                    if (recommendation.IsRecommended) {
                        BlockChain.Issue (recommendation,false);
                    } else {
                        BlockChain.Issue (recommendation,true);
                    }
                }
            }
        }
        /// <summary>
        /// Returns a boolean clarifying that a statement is complete.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="statement"></param>
        /// <returns></returns>
        private bool IsStatementRecommendationsComplete(DataContext context,TrustLessModelLib.Statement statement)
        {
            var recommendationAmount =
                context.Recommendations.Count(x => x.StatementId== statement.Id && x.Transaction != null);

            int maxVotings = Convert.ToInt32(WebConfigurationManager.AppSettings["MaxVotings"]);
            return recommendationAmount >= maxVotings;
        }