protected void Page_Load(object sender, EventArgs e)
        {
            PageAccessRequired       = new Access(CurrentOrganization, AccessAspect.BookkeepingDetails, AccessType.Read);
            this._authenticationData = GetAuthenticationDataAndCulture();

            HotBitcoinAddresses addresses = HotBitcoinAddresses.ForOrganization(_authenticationData.CurrentOrganization);

            foreach (HotBitcoinAddress address in addresses)
            {
                if (address.Chain == BitcoinChain.Core)
                {
                    // These shouldn't exist much, so make sure that we have the equivalent Cash address registered
                    try
                    {
                        HotBitcoinAddress.FromAddress(BitcoinChain.Cash, address.ProtocolLevelAddress);
                    }
                    catch (ArgumentException)
                    {
                        // We didn't have it, so create it
                        BitcoinUtility.TestUnspents(BitcoinChain.Cash, address.ProtocolLevelAddress);
                    }
                }
            }

            Response.ContentType = "application/json";
            Response.Output.WriteLine(FormatJson(addresses));
            Response.End();
        }
Exemplo n.º 2
0
        static public AjaxCallResult ProcessTransactionReceived(string guid, string txHash)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture(); // just to make sure we're called properly
            BitcoinChain       chain    = BitcoinChain.Cash;

            string bitcoinAddress = (string)GuidCache.Get(guid);

            if (BitcoinUtility.TestUnspents(chain, bitcoinAddress))
            {
                HotBitcoinAddressUnspents unspents = HotBitcoinAddress.FromAddress(chain, bitcoinAddress).Unspents;
                Int64 satoshisReceived             = unspents.Last().AmountSatoshis;

                if (unspents.Last().TransactionHash != txHash && txHash.Length > 0)
                {
                    // Race condition.
                    Debugger.Break();
                }

                HotBitcoinAddressUnspent utxoToReturn = unspents.Last();

                Swarmops.Logic.Financial.Money moneyReceived = new Swarmops.Logic.Financial.Money(satoshisReceived,
                                                                                                  Currency.BitcoinCash);

                // Create success message and ledger transaction
                string successMessage = string.Empty;

                // TODO: Get the tx, get the input

                string returnAddress = BitcoinUtility.GetInputAddressesForTransaction(chain, txHash) [0]; // assumes at least one input address

                // Return the money, too. Set fee for a 300-byte transaction.

                ReturnBitcoinEchoUtxoOrder backendOrder = new ReturnBitcoinEchoUtxoOrder(utxoToReturn);
                backendOrder.Create(authData.CurrentOrganization, authData.CurrentUser);

                string tx1Description = "Bitcoin technical echo test (will be repaid immediately)";


                if (authData.CurrentOrganization.Currency.IsBitcoinCash)
                {
                    // The ledger is native bitcoin, so cent units are satoshis

                    FinancialTransaction ledgerTx1 = FinancialTransaction.Create(authData.CurrentOrganization,
                                                                                 DateTime.UtcNow, tx1Description);
                    ledgerTx1.AddRow(authData.CurrentOrganization.FinancialAccounts.DebtsOther, -(satoshisReceived), authData.CurrentUser);
                    ledgerTx1.AddRow(authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot, satoshisReceived, authData.CurrentUser);
                    ledgerTx1.BlockchainHash = txHash;

                    // The return payment will be logged when made, so its hash can be recorded

                    if (satoshisReceived % 100 == 0)
                    {
                        successMessage = string.Format(Resources.Pages.Admin.BitcoinEchoTest_FundsReceivedNative,
                                                       (satoshisReceived / 100.0).ToString("N0"));
                    }
                    else
                    {
                        successMessage = string.Format(Resources.Pages.Admin.BitcoinEchoTest_FundsReceivedNative,
                                                       (satoshisReceived / 100.0).ToString("N2"));
                    }
                }
                else
                {
                    // The ledger is NOT native bitcoin, so we'll need to convert currencies

                    long orgNativeCents            = moneyReceived.ToCurrency(authData.CurrentOrganization.Currency).Cents;
                    FinancialTransaction ledgerTx1 = FinancialTransaction.Create(authData.CurrentOrganization,
                                                                                 DateTime.UtcNow, tx1Description);
                    ledgerTx1.AddRow(authData.CurrentOrganization.FinancialAccounts.DebtsOther, -orgNativeCents, authData.CurrentUser);
                    ledgerTx1.AddRow(authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot, orgNativeCents, authData.CurrentUser).AmountForeignCents = new Swarmops.Logic.Financial.Money(satoshisReceived, Currency.BitcoinCash);
                    ledgerTx1.BlockchainHash = txHash;

                    // The second transaction is logged when executed in the back-end order

                    successMessage = string.Format(Resources.Pages.Admin.BitcoinEchoTest_FundsReceived,
                                                   authData.CurrentOrganization.Currency.DisplayCode, orgNativeCents / 100.0, satoshisReceived / 100.0);
                }

                return(new AjaxCallResult()
                {
                    DisplayMessage = successMessage, Success = true
                });

                // TODO: Ack donation via mail?
                // TODO: Notify CFO/etc of donation?
            }

            return(new AjaxCallResult()
            {
                Success = false
            });
        }
Exemplo n.º 3
0
        static public AjaxCallResult ProcessTransactionReceived(string guid, string txHash)
        {
            BitcoinChain chain = BitcoinChain.Cash;

            AuthenticationData authData = GetAuthenticationDataAndCulture(); // just to make sure we're called properly

            string bitcoinAddress = (string)GuidCache.Get(guid);

            if (BitcoinUtility.TestUnspents(chain, bitcoinAddress))
            {
                HotBitcoinAddressUnspents unspents = HotBitcoinAddress.FromAddress(chain, bitcoinAddress).Unspents;

                // TODO: Update the HotBitcoinAddress with the new amount?

                HotBitcoinAddressUnspent unspent = null;
                Int64 satoshisReceived           = 0;

                foreach (HotBitcoinAddressUnspent potentialUnspent in unspents)
                {
                    if (potentialUnspent.TransactionHash == txHash)
                    {
                        satoshisReceived = potentialUnspent.AmountSatoshis;
                        unspent          = potentialUnspent;
                    }
                }

                if (unspent == null)  // Supplied transaction hash was not found in collection
                {
                    Debugger.Break(); // TODO: Something else than break the debugger
                }

                Swarmops.Logic.Financial.Money moneyReceived = new Swarmops.Logic.Financial.Money(satoshisReceived,
                                                                                                  Currency.BitcoinCash);

                // Make sure that the hotwallet native currency is bitcoin cash
                authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot.ForeignCurrency = Currency.BitcoinCash;

                // Create success message and ledger transaction
                string successMessage = string.Empty;

                FinancialTransaction testTransaction = null;
                try
                {
                    testTransaction = FinancialTransaction.FromBlockchainHash(authData.CurrentOrganization, txHash);

                    // We've already seen this donation! Something is seriously bogus here
                    Debugger.Break();
                    return(new AjaxCallResult()
                    {
                        DisplayMessage = successMessage, Success = true
                    });
                }
                catch (ArgumentException)
                {
                    // This exception is expected - the transaction should not yet exist
                }

                if (authData.CurrentOrganization.Currency.IsBitcoinCash)
                {
                    // The ledger is native bitcoin cash, so units are Satoshis

                    FinancialTransaction ledgerTx = FinancialTransaction.Create(authData.CurrentOrganization,
                                                                                DateTime.UtcNow, "Donation (bitcoin to hotwallet)");
                    ledgerTx.AddRow(authData.CurrentOrganization.FinancialAccounts.IncomeDonations, -satoshisReceived, authData.CurrentUser);
                    ledgerTx.AddRow(authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot, satoshisReceived, authData.CurrentUser);
                    ledgerTx.BlockchainHash = txHash;

                    if (satoshisReceived % 100 == 0)
                    {
                        successMessage = string.Format(Resources.Pages.Financial.Donate_FundsReceivedNative,
                                                       (satoshisReceived / 100.0).ToString("N0"));
                    }
                    else
                    {
                        successMessage = string.Format(Resources.Pages.Financial.Donate_FundsReceivedNative,
                                                       (satoshisReceived / 100.0).ToString("N2"));
                    }
                }
                else
                {
                    // The ledger is NOT native bitcoin, so we'll need to convert currencies

                    long orgNativeCents           = moneyReceived.ToCurrency(authData.CurrentOrganization.Currency).Cents;
                    FinancialTransaction ledgerTx = FinancialTransaction.Create(authData.CurrentOrganization,
                                                                                DateTime.UtcNow, "Donation (bitcoin to hotwallet)");
                    ledgerTx.AddRow(authData.CurrentOrganization.FinancialAccounts.IncomeDonations, -orgNativeCents, authData.CurrentUser);
                    ledgerTx.AddRow(authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot, orgNativeCents, authData.CurrentUser).AmountForeignCents = new Swarmops.Logic.Financial.Money(satoshisReceived, Currency.BitcoinCash);
                    ledgerTx.BlockchainHash = txHash;

                    successMessage = string.Format(Resources.Pages.Financial.Donate_FundsReceived,
                                                   authData.CurrentOrganization.Currency.DisplayCode, orgNativeCents / 100.0, satoshisReceived / 100.0);
                }

                return(new AjaxCallResult()
                {
                    DisplayMessage = successMessage, Success = true
                });

                // TODO: Ack donation via mail?
                // TODO: Notify CFO/etc of donation?
            }

            return(new AjaxCallResult()
            {
                Success = false
            });
        }
Exemplo n.º 4
0
        internal static void ProcessBitcoinTransaction(JObject blockchainTransaction)
        {
            /* Format:
             *
             *  {
             *      "op": "utx",
             *      "x": {
             *          "lock_time": 0,
             *          "ver": 1,
             *          "size": 192,
             *          "inputs": [
             *              {
             *                  "sequence": 4294967295,
             *                  "prev_out": {
             *                      "spent": true,
             *                      "tx_index": 99005468,
             *                      "type": 0,
             *                      "addr": "1BwGf3z7n2fHk6NoVJNkV32qwyAYsMhkWf",
             *                      "value": 65574000,
             *                      "n": 0,
             *                      "script": "76a91477f4c9ee75e449a74c21a4decfb50519cbc245b388ac"
             *                  },
             *                  "script": "483045022100e4ff962c292705f051c2c2fc519fa775a4d8955bce1a3e29884b2785277999ed02200b537ebd22a9f25fbbbcc9113c69c1389400703ef2017d80959ef0f1d685756c012102618e08e0c8fd4c5fe539184a30fe35a2f5fccf7ad62054cad29360d871f8187d"
             *              }
             *          ],
             *          "time": 1440086763,
             *          "tx_index": 99006637,
             *          "vin_sz": 1,
             *          "hash": "0857b9de1884eec314ecf67c040a2657b8e083e1f95e31d0b5ba3d328841fc7f",
             *          "vout_sz": 1,
             *          "relayed_by": "127.0.0.1",
             *          "out": [
             *              {
             *                  "spent": false,
             *                  "tx_index": 99006637,
             *                  "type": 0,
             *                  "addr": "1A828tTnkVFJfSvLCqF42ohZ51ksS3jJgX",
             *                  "value": 65564000,
             *                  "n": 0,
             *                  "script": "76a914640cfdf7b79d94d1c980133e3587bd6053f091f388ac"
             *              }
             *          ]
             *      }
             *  }
             */

            Console.WriteLine(" - transaction received");

            if (_transactionCache == null)
            {
                _transactionCache = new SerializableDictionary <string, JObject>();
            }

            string txHash = (string)blockchainTransaction["x"]["hash"];

            _transactionCache[txHash] = (JObject)blockchainTransaction["x"];

            foreach (JObject outpoint in blockchainTransaction["x"]["out"])
            {
                Satoshis satoshis      = Int64.Parse((string)outpoint["value"]);
                string   addressString = (string)outpoint["addr"];

                HotBitcoinAddress hotAddress = null;

                try
                {
                    hotAddress = HotBitcoinAddress.FromAddress(BitcoinChain.Cash, addressString);
                }
                catch (ArgumentException)
                {
                    // Ignore this - it means the addressString isn't ours
                    continue;
                }

                if (hotAddress != null)
                {
                    JObject json = new JObject();
                    json["MessageType"] = "BitcoinReceived";
                    json["Address"]     = addressString;
                    json["Hash"]        = txHash;

                    Currency currency = hotAddress.Organization.Currency;
                    json["OrganizationId"] = hotAddress.OrganizationId.ToString();
                    json["Currency"]       = currency.Code;
                    Swarmops.Logic.Financial.Money organizationCents = new Money(satoshis, Currency.BitcoinCore).ToCurrency(currency);
                    json["Satoshis"]       = satoshis.ToString();
                    json["Cents"]          = organizationCents.Cents.ToString();
                    json["CentsFormatted"] = String.Format("{0:N2}", organizationCents.Cents / 100.0);

                    _socketServer.WebSocketServices.Broadcast(json.ToString());

                    // TODO: Examine what address this is, handle accordingly
                }
            }
        }
Exemplo n.º 5
0
        static public AjaxCallResult CheckTransactionReceived(string guid, string txHash)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture(); // just to make sure we're called properly

            string bitcoinAddress = (string)GuidCache.Get(guid);

            if (BitcoinUtility.TestUnspents(bitcoinAddress))
            {
                HotBitcoinAddressUnspents unspents = HotBitcoinAddress.FromAddress(bitcoinAddress).Unspents;

                // TODO: Update the HotBitcoinAddress with the new amount?

                Int64 satoshisReceived = unspents.Last().AmountSatoshis;

                if (unspents.Last().TransactionHash != txHash && txHash.Length > 0)
                {
                    // Race condition.
                    Debugger.Break();
                }

                Swarmops.Logic.Financial.Money moneyReceived = new Swarmops.Logic.Financial.Money(satoshisReceived,
                                                                                                  Currency.Bitcoin);

                // Make sure that the hotwallet native currency is bitcoin
                authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot.ForeignCurrency = Currency.Bitcoin;

                // Create success message and ledger transaction
                string successMessage = string.Empty;

                // TODO: Get the tx, get the input

                string returnAddress = BitcoinUtility.GetInputAddressesForTransaction(txHash) [0]; // assumes at least one input address

                if (authData.CurrentOrganization.Currency.IsBitcoin)
                {
                    // The ledger is native bitcoin, so units are Satoshis

                    FinancialTransaction ledgerTx = FinancialTransaction.Create(authData.CurrentOrganization,
                                                                                DateTime.UtcNow, "Bitcoin echo test (will be repaid immediately)");
                    ledgerTx.AddRow(authData.CurrentOrganization.FinancialAccounts.DebtsOther, -satoshisReceived, authData.CurrentUser);
                    ledgerTx.AddRow(authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot, satoshisReceived, authData.CurrentUser);
                    ledgerTx.BlockchainHash = txHash;

                    if (satoshisReceived % 100 == 0)
                    {
                        successMessage = string.Format(Resources.Pages.Admin.BitcoinEchoTest_FundsReceivedNative,
                                                       (satoshisReceived / 100.0).ToString("N0"));
                    }
                    else
                    {
                        successMessage = string.Format(Resources.Pages.Admin.BitcoinEchoTest_FundsReceivedNative,
                                                       (satoshisReceived / 100.0).ToString("N2"));
                    }

                    // TODO: Log the payout back, as an inbound invoice for immediate payout
                }
                else
                {
                    // The ledger is NOT native bitcoin, so we'll need to convert currencies

                    long orgNativeCents           = moneyReceived.ToCurrency(authData.CurrentOrganization.Currency).Cents;
                    FinancialTransaction ledgerTx = FinancialTransaction.Create(authData.CurrentOrganization,
                                                                                DateTime.UtcNow, "Bitcoin echo test (will be repaid immediately)");
                    ledgerTx.AddRow(authData.CurrentOrganization.FinancialAccounts.DebtsOther, -orgNativeCents, authData.CurrentUser);
                    ledgerTx.AddRow(authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot, orgNativeCents, authData.CurrentUser).AmountForeignCents = new Swarmops.Logic.Financial.Money(satoshisReceived, Currency.Bitcoin);
                    ledgerTx.BlockchainHash = txHash;

                    successMessage = string.Format(Resources.Pages.Admin.BitcoinEchoTest_FundsReceived,
                                                   authData.CurrentOrganization.Currency.DisplayCode, orgNativeCents / 100.0, satoshisReceived / 100.0);

                    // TODO: Create a payout back for this amount -- needs to be specified in bitcoin -- as an inbound invoice
                }

                return(new AjaxCallResult()
                {
                    DisplayMessage = successMessage, Success = true
                });

                // TODO: Ack donation via mail?
                // TODO: Notify CFO/etc of donation?
            }

            return(new AjaxCallResult()
            {
                Success = false
            });
        }