void RefreshWalletUI() { //INTERESTING every mnemonic can be derived to its equivalent private key //Which is used to sign transactions MnemonicInputField.text = WalletMnemonic.ToString(); PrivateKeyInputField.text = WalletMnemonic.DeriveExtKey().ToString(Network.Main); AddressText.text = m_address.ToString(); StopAllCoroutines(); //INTERESTING Mobile wallets uses "bitcoin:<address>" as the encoded string in QR images StartCoroutine(LoadQR("bitcoin:" + m_address.ToString())); }
IEnumerator SendSat(string recipientAddress, int amountSat, int feeSat) { Log("Requesting transaction outputs for address " + m_address.ToString()); SetSendPanelInteractable(false); //INPUT: money coming from an address //OUTPUT: money going to an address //Request all unspent transactions related to this address //https://live.blockcypher.com/btc/address/<address> shows the same but nicely WWW wwwTxo = new WWW("https://blockchain.info/unspent?active=" + m_address.ToString() + ""); yield return(wwwTxo); if (wwwTxo.error != null) { Log("Cannot get utxo from \"" + wwwTxo.url + "\"\nError: " + wwwTxo.error); SetSendPanelInteractable(true); } else { // { // "unspent_outputs": [ // { // "tx_hash": "aed0a61f789e80975425685ef65ba0a0e388db0c001dfd9e548e896fe39c1067", // "tx_hash_big_endian": "67109ce36f898e549efd1d000cdb88e3a0a05bf65e68255497809e781fa6d0ae", // "tx_output_n": 0, // "script": "76a914717ee27eca5ed0bd30fde351a19439ed96bdcb3f88ac", // "value": 2176, // "value_hex": "0880", // "confirmations": 0, // "tx_index": 461965676 // } // ] // } JSONObject utxos = new JSONObject(wwwTxo.text); //Get all unspent outputs using my address List <Coin> unspentCoins = new List <Coin>(); for (int i = 0; i < utxos["unspent_outputs"].Count; i++) { string txHash = utxos["unspent_outputs"][i]["tx_hash_big_endian"].str; uint outputIndex = (uint)utxos["unspent_outputs"][i]["tx_output_n"].n; int valueUnspent = (int)utxos["unspent_outputs"][i]["value"].n; Log(valueUnspent + " unspent!"); unspentCoins.Add(new Coin( new uint256(txHash), //Hash of the transaction this output is comming from outputIndex, //Index of the transaction output within the transaction Money.Satoshis(valueUnspent), //Amount of money this output has m_address.ScriptPubKey)); //Script to solve to spend this output } //+info about how to use TransactionBuilder can be found here //https://csharp.hotexamples.com/examples/NBitcoin/TransactionBuilder/-/php-transactionbuilder-class-examples.html TransactionBuilder txBuilder = Network.Main.CreateTransactionBuilder(); txBuilder.AddKeys(WalletMnemonic.DeriveExtKey().PrivateKey); txBuilder.AddCoins(unspentCoins); txBuilder.Send(BitcoinAddress.Create(recipientAddress, Network.Main), Money.Satoshis(amountSat)); txBuilder.SendFees(Money.Satoshis(feeSat)); txBuilder.SetChange(m_address); Transaction tx = txBuilder.BuildTransaction(true); Log(tx.ToHex().ToString()); //Submit raw transaction to a bitcoin node //In this case we use blockchain.info API WWWForm form = new WWWForm(); form.AddField("tx", tx.ToHex()); WWW wwwRawTx = new WWW("https://blockchain.info/pushtx", form); yield return(wwwRawTx); if (wwwRawTx.error != null) { Log("Error submitting raw transaction " + wwwRawTx.error, true); } else { Log(wwwTxo.text); Log("Transaction sent!"); yield return(new WaitForSeconds(3f)); Application.OpenURL("https://www.blockchain.com/btc/address/" + m_address); yield return(StartCoroutine(RefreshBalance())); } } SetSendPanelInteractable(true); }