Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: casascius on July 01, 2011, 06:30:16 PM



Title: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: casascius on July 01, 2011, 06:30:16 PM
http://166.70.147.8/btc/addressutil.jpg

This is a utility I made that does all of the following conversions:

BTCAddress <---> PubHash <---- PublicKey <---- PrivateKey <---> WalletImportFormatPrivateKey.

It can also generate new Bitcoin addresses, as well as Testnet and Namecoin.  It will correct single-character typos in Bitcoin addresses and private keys.

It requires the BouncyCastle Crypto library at http://www.bouncycastle.org/csharp/ (just the compiled assembly is fine).

You will have to compile it yourself.  I don't want to look like a trojan scammer.

File: Form1.cs
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
using System.Security.Cryptography;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Math.EC;

namespace BtcAddress {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private byte[] Base58ToByteArray(string base58) {

            Org.BouncyCastle.Math.BigInteger bi2 = new Org.BouncyCastle.Math.BigInteger("0");
            string b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

            bool IgnoreChecksum=false;

            foreach (char c in base58) {
                if (b58.IndexOf(c) != -1) {
                    bi2 = bi2.Multiply(new Org.BouncyCastle.Math.BigInteger("58"));
                    bi2 = bi2.Add(new Org.BouncyCastle.Math.BigInteger(b58.IndexOf(c).ToString()));
                } else if (c=='?') {
                    IgnoreChecksum = true;
                } else {
                    return null;
                }
            }

            byte[] bb = bi2.ToByteArrayUnsigned();

            // interpret leading '1's as leading zero bytes
            foreach (char c in base58) {
                if (c != '1') break;
                byte[] bbb = new byte[bb.Length + 1];
                Array.Copy(bb, 0, bbb, 1, bb.Length);
                bb = bbb;
            }
            
            if (bb.Length < 4) return null;

            if (IgnoreChecksum == false) {
                SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider();
                byte[] checksum = sha256.ComputeHash(bb, 0, bb.Length - 4);
                checksum = sha256.ComputeHash(checksum);
                for (int i = 0; i < 4; i++) {
                    if (checksum[i] != bb[bb.Length - 4 + i]) return null;
                }
            }

            byte[] rv = new byte[bb.Length - 4];
            Array.Copy(bb, 0, rv, 0, bb.Length - 4);
            return rv;
        }

        private string ByteArrayToString(byte[] ba) {
            return ByteArrayToString(ba, 0, ba.Length);
        }

        private string ByteArrayToString(byte[] ba, int offset, int count) {
            string rv = "";
            int usedcount = 0;
            for (int i=offset; usedcount<count; i++,usedcount++) {            
                rv += String.Format("{0:X2}", ba[i]) + " ";
            }
            return rv;
        }

        private string ByteArrayToBase58(byte[] ba) {
            Org.BouncyCastle.Math.BigInteger addrremain = new Org.BouncyCastle.Math.BigInteger(1,ba);

            Org.BouncyCastle.Math.BigInteger big0 = new Org.BouncyCastle.Math.BigInteger("0");
            Org.BouncyCastle.Math.BigInteger big58 = new Org.BouncyCastle.Math.BigInteger("58");

            string b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

            string rv = "";

            while (addrremain.CompareTo(big0) > 0) {
                int d = Convert.ToInt32(addrremain.Mod(big58).ToString());
                addrremain = addrremain.Divide(big58);
                rv = b58.Substring(d, 1) + rv;
            }

            // handle leading zeroes
            foreach (byte b in ba) {
                if (b != 0) break;
                rv = "1" + rv;

            }
            return rv;
        }


        private string ByteArrayToBase58Check(byte[] ba) {

            byte[] bb = new byte[ba.Length + 4];
            Array.Copy(ba, bb, ba.Length);
            SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider();
            byte[] thehash = sha256.ComputeHash(ba);
            thehash = sha256.ComputeHash(thehash);
            for (int i = 0; i < 4; i++) bb[ba.Length + i] = thehash[i];
            return ByteArrayToBase58(bb);
        }

        private void button4_Click(object sender, EventArgs e) {

            var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");


        }

        private byte[] GetHexBytes(string source, int minimum) {
            byte[] hex = GetHexBytes(source);
            if (hex == null) return null;
            // assume leading zeroes if we're short a few bytes
            if (hex.Length > (minimum-6) && hex.Length < minimum) {
                byte[] hex2 = new byte[minimum];
                Array.Copy(hex, 0, hex2, minimum - hex.Length, hex.Length);
                hex = hex2;
            }
            // clip off one overhanging leading zero if present
            if (hex.Length == minimum + 1 && hex[0] == 0) {
                byte[] hex2 = new byte[minimum];
                Array.Copy(hex, 1, hex2, 0, minimum);
                hex = hex2;

            }

            return hex;
        }


        private byte[] GetHexBytes(string source) {


            List<byte> bytes = new List<byte>();
            // copy s into ss, adding spaces between each byte
            string s = source;
            string ss = "";
            int currentbytelength = 0;
            foreach (char c in s.ToCharArray()) {
                if (c == ' ') {                    
                    currentbytelength = 0;
                } else {
                    currentbytelength++;
                    if (currentbytelength == 3) {
                        currentbytelength = 1;
                        ss += ' ';
                    }
                }
                ss += c;
            }

            foreach (string b in ss.Split(' ')) {
                int v = 0;
                if (b.Trim() == "") continue;
                foreach (char c in b.ToCharArray()) {
                    if (c >= '0' && c <= '9') {
                        v *= 16;
                        v += (c - '0');

                    } else if (c >= 'a' && c <= 'f') {
                        v *= 16;
                        v += (c - 'a' + 10);
                    } else if (c >= 'A' && c <= 'F') {
                        v *= 16;
                        v += (c - 'A' + 10);
                    }

                }
                v &= 0xff;
                bytes.Add((byte)v);
            }            
            return bytes.ToArray();          
        }

        private byte[] ValidateAndGetHexPrivateKey(byte leadingbyte) {
            byte[] hex = GetHexBytes(txtPrivHex.Text, 32);

            if (hex == null || hex.Length < 32 || hex.Length > 33) {
                MessageBox.Show("Hex is not 32 or 33 bytes.");
                return null;
            }

            // if leading 00, change it to 0x80
            if (hex.Length == 33) {
                if (hex[0] == 0 || hex[0] == 0x80) {
                    hex[0] = 0x80;
                } else {
                    MessageBox.Show("Not a valid private key");
                    return null;
                }
            }

            // add 0x80 byte if not present
            if (hex.Length == 32) {
                byte[] hex2 = new byte[33];
                Array.Copy(hex, 0, hex2, 1, 32);
                hex2[0] = 0x80;
                hex = hex2;
            }

            hex[0] = leadingbyte;
            return hex;

        }


        private byte[] ValidateAndGetHexPublicKey() {
            byte[] hex = GetHexBytes(txtPubHex.Text, 64);

            if (hex == null || hex.Length < 64 || hex.Length > 65) {
                MessageBox.Show("Hex is not 64 or 65 bytes.");
                return null;
            }

            // if leading 00, change it to 0x80
            if (hex.Length == 65) {
                if (hex[0] == 0 || hex[0] == 4) {
                    hex[0] = 4;
                } else {
                    MessageBox.Show("Not a valid public key");
                    return null;
                }
            }

            // add 0x80 byte if not present
            if (hex.Length == 64) {
                byte[] hex2 = new byte[65];
                Array.Copy(hex, 0, hex2, 1, 64);
                hex2[0] = 4;
                hex = hex2;
            }            
            return hex;
        }

        private byte[] ValidateAndGetHexPublicHash() {
            byte[] hex = GetHexBytes(txtPubHash.Text, 20);

            if (hex == null || hex.Length != 20 ) {
                MessageBox.Show("Hex is not 20 bytes.");
                return null;
            }
            return hex;
        }


        private void btnPrivHexToWIF_Click(object sender, EventArgs e) {
            byte[] hex = ValidateAndGetHexPrivateKey(0x80);
            if (hex==null) return;
            txtPrivWIF.Text = ByteArrayToBase58Check(hex);
        }

        private void btnPrivWIFToHex_Click(object sender, EventArgs e) {
            byte[] hex = Base58ToByteArray(txtPrivWIF.Text);
            if (hex == null) {
                int L = txtPrivWIF.Text.Length;
                if (L >= 50 && L <= 52) {
                    if (MessageBox.Show("Private key is not valid.  Attempt to correct?", "Invalid address", MessageBoxButtons.YesNo) == DialogResult.Yes) {
                        CorrectWIF();
                        return;
                    }
                } else {
                    MessageBox.Show("WIF private key is not valid.");
                }
                return;
            }
            if (hex.Length != 33) {
                MessageBox.Show("WIF private key is not valid (wrong byte count, should be 33, was " + hex.Length + ")");
                return;
            }

            txtPrivHex.Text = ByteArrayToString(hex, 1, 32);


        }

        private void btnPrivToPub_Click(object sender, EventArgs e) {
            byte[] hex = ValidateAndGetHexPrivateKey(0x00);
            if (hex==null) return;
            var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");
            Org.BouncyCastle.Math.BigInteger Db = new Org.BouncyCastle.Math.BigInteger(hex);
            ECPoint dd = ps.G.Multiply(Db);

            byte[] pubaddr = new byte[65];
            byte[] Y = dd.Y.ToBigInteger().ToByteArray();
            Array.Copy(Y, 0, pubaddr, 64 - Y.Length + 1, Y.Length);
            byte[] X = dd.X.ToBigInteger().ToByteArray();
            Array.Copy(X, 0, pubaddr, 32 - X.Length + 1, X.Length);
            pubaddr[0] = 4;

            txtPubHex.Text = ByteArrayToString(pubaddr);

        }

        private void btnPubHexToHash_Click(object sender, EventArgs e) {
            byte[] hex = ValidateAndGetHexPublicKey();
            if (hex == null) return;

            SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider();
            byte[] shaofpubkey = sha256.ComputeHash(hex);

            RIPEMD160 rip = System.Security.Cryptography.RIPEMD160.Create();
            byte[] ripofpubkey = rip.ComputeHash(shaofpubkey);

            txtPubHash.Text = ByteArrayToString(ripofpubkey);

        }

        private void btnPubHashToAddress_Click(object sender, EventArgs e) {
            byte[] hex = ValidateAndGetHexPublicHash();
            if (hex == null) return;

            byte[] hex2 = new byte[21];
            Array.Copy(hex, 0, hex2, 1, 20);

            int cointype = 0;
            if (Int32.TryParse(cboCoinType.Text, out cointype) == false) cointype = 0;

            if (cboCoinType.Text == "Testnet") cointype = 111;
            if (cboCoinType.Text == "Namecoin") cointype = 52;
            hex2[0] = (byte)(cointype & 0xff);
            txtBtcAddr.Text = ByteArrayToBase58Check(hex2);
            
        }

        private void btnAddressToPubHash_Click(object sender, EventArgs e) {
            byte[] hex = Base58ToByteArray(txtBtcAddr.Text);
            if (hex == null || hex.Length != 21) {
                int L = txtBtcAddr.Text.Length;
                if (L >= 33 && L <= 34) {
                    if (MessageBox.Show("Address is not valid.  Attempt to correct?", "Invalid address", MessageBoxButtons.YesNo) == DialogResult.Yes) {
                        CorrectBitcoinAddress();
                        return;
                    }
                } else {
                    MessageBox.Show("Address is not valid.");
                }
                return;
            }
            txtPubHash.Text = ByteArrayToString(hex, 1, 20);

        }

        private void btnGenerate_Click(object sender, EventArgs e) {

            ECKeyPairGenerator gen = new ECKeyPairGenerator();
            var secureRandom = new SecureRandom();
            var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");
            var ecParams = new ECDomainParameters(ps.Curve, ps.G, ps.N, ps.H);
            var keyGenParam = new ECKeyGenerationParameters(ecParams, secureRandom);
            gen.Init(keyGenParam);

            AsymmetricCipherKeyPair kp = gen.GenerateKeyPair();

            ECPrivateKeyParameters priv = (ECPrivateKeyParameters)kp.Private;

            byte[] hexpriv = priv.D.ToByteArrayUnsigned();
            txtPrivHex.Text = ByteArrayToString(hexpriv);

            btnPrivHexToWIF_Click(null, null);
            btnPrivToPub_Click(null, null);
            btnPubHexToHash_Click(null, null);
            btnPubHashToAddress_Click(null, null);

        }

        private void btnBlockExplorer_Click(object sender, EventArgs e) {
            try {
                if (cboCoinType.Text == "Testnet") {
                    Process.Start("http://www.blockexplorer.com/testnet/address/" + txtBtcAddr.Text);
                } else if (cboCoinType.Text == "Namecoin") {
                    Process.Start("http://explorer.dot-bit.org/a/" + txtBtcAddr.Text);
                } else {
                    Process.Start("http://www.blockexplorer.com/address/" + txtBtcAddr.Text);
                }
            } catch { }
        }

        private void CorrectBitcoinAddress() {
            txtBtcAddr.Text = Correction(txtBtcAddr.Text);
        }

        private string Correction(string btcaddr) {
            
            int btcaddrlen = btcaddr.Length;
            string b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

            for (int i = 0; i < btcaddrlen; i++) {
                for (int j = 0; j < 58; j++) {
                    string attempt = btcaddr.Substring(0, i) + b58.Substring(j, 1) + btcaddr.Substring(i + 1);
                    byte[] bytes = Base58ToByteArray(attempt);
                    if (bytes != null) {
                        MessageBox.Show("Correction was successful.  Try your request again.");
                        return attempt;
                    }
                }
            }
            return btcaddr;
        }

        private void CorrectWIF() {
            txtPrivWIF.Text = Correction(txtPrivWIF.Text);
        }
    }
}



File: Form1.Designer.cs
Code:
namespace BtcAddress {
    partial class Form1 {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing) {
            if (disposing && (components != null)) {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent() {
            this.txtPrivWIF = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.txtPrivHex = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.txtPubHex = new System.Windows.Forms.TextBox();
            this.label4 = new System.Windows.Forms.Label();
            this.txtPubHash = new System.Windows.Forms.TextBox();
            this.label5 = new System.Windows.Forms.Label();
            this.txtBtcAddr = new System.Windows.Forms.TextBox();
            this.btnAddressToPubHash = new System.Windows.Forms.Button();
            this.btnPubHashToAddress = new System.Windows.Forms.Button();
            this.btnPubHexToHash = new System.Windows.Forms.Button();
            this.btnPrivToPub = new System.Windows.Forms.Button();
            this.btnPrivWIFToHex = new System.Windows.Forms.Button();
            this.btnPrivHexToWIF = new System.Windows.Forms.Button();
            this.btnGenerate = new System.Windows.Forms.Button();
            this.btnBlockExplorer = new System.Windows.Forms.Button();
            this.cboCoinType = new System.Windows.Forms.ComboBox();
            this.SuspendLayout();
            //
            // txtPrivWIF
            //
            this.txtPrivWIF.Location = new System.Drawing.Point(103, 12);
            this.txtPrivWIF.Name = "txtPrivWIF";
            this.txtPrivWIF.Size = new System.Drawing.Size(557, 20);
            this.txtPrivWIF.TabIndex = 7;
            //
            // label1
            //
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(7, 15);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(90, 13);
            this.label1.TabIndex = 8;
            this.label1.Text = "Private Key (WIF)";
            //
            // txtPrivHex
            //
            this.txtPrivHex.Location = new System.Drawing.Point(103, 70);
            this.txtPrivHex.Name = "txtPrivHex";
            this.txtPrivHex.Size = new System.Drawing.Size(557, 20);
            this.txtPrivHex.TabIndex = 9;
            //
            // label2
            //
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(7, 73);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(89, 13);
            this.label2.TabIndex = 10;
            this.label2.Text = "Private Key (Hex)";
            //
            // label3
            //
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(7, 131);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(85, 13);
            this.label3.TabIndex = 12;
            this.label3.Text = "Public Key (Hex)";
            //
            // txtPubHex
            //
            this.txtPubHex.Location = new System.Drawing.Point(103, 128);
            this.txtPubHex.Multiline = true;
            this.txtPubHex.Name = "txtPubHex";
            this.txtPubHex.Size = new System.Drawing.Size(557, 43);
            this.txtPubHex.TabIndex = 11;
            //
            // label4
            //
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(7, 216);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(91, 13);
            this.label4.TabIndex = 14;
            this.label4.Text = "Public Key (Hash)";
            //
            // txtPubHash
            //
            this.txtPubHash.Location = new System.Drawing.Point(103, 213);
            this.txtPubHash.Name = "txtPubHash";
            this.txtPubHash.Size = new System.Drawing.Size(557, 20);
            this.txtPubHash.TabIndex = 13;
            //
            // label5
            //
            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(7, 274);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(45, 13);
            this.label5.TabIndex = 16;
            this.label5.Text = "Address";
            //
            // txtBtcAddr
            //
            this.txtBtcAddr.Location = new System.Drawing.Point(103, 271);
            this.txtBtcAddr.Name = "txtBtcAddr";
            this.txtBtcAddr.Size = new System.Drawing.Size(557, 20);
            this.txtBtcAddr.TabIndex = 15;
            //
            // btnAddressToPubHash
            //
            this.btnAddressToPubHash.Location = new System.Drawing.Point(286, 235);
            this.btnAddressToPubHash.Name = "btnAddressToPubHash";
            this.btnAddressToPubHash.Size = new System.Drawing.Size(46, 30);
            this.btnAddressToPubHash.TabIndex = 18;
            this.btnAddressToPubHash.Text = "▲";
            this.btnAddressToPubHash.UseVisualStyleBackColor = true;
            this.btnAddressToPubHash.Click += new System.EventHandler(this.btnAddressToPubHash_Click);
            //
            // btnPubHashToAddress
            //
            this.btnPubHashToAddress.Location = new System.Drawing.Point(334, 235);
            this.btnPubHashToAddress.Name = "btnPubHashToAddress";
            this.btnPubHashToAddress.Size = new System.Drawing.Size(46, 30);
            this.btnPubHashToAddress.TabIndex = 19;
            this.btnPubHashToAddress.Text = "▼";
            this.btnPubHashToAddress.UseVisualStyleBackColor = true;
            this.btnPubHashToAddress.Click += new System.EventHandler(this.btnPubHashToAddress_Click);
            //
            // btnPubHexToHash
            //
            this.btnPubHexToHash.Location = new System.Drawing.Point(334, 177);
            this.btnPubHexToHash.Name = "btnPubHexToHash";
            this.btnPubHexToHash.Size = new System.Drawing.Size(46, 30);
            this.btnPubHexToHash.TabIndex = 21;
            this.btnPubHexToHash.Text = "▼";
            this.btnPubHexToHash.UseVisualStyleBackColor = true;
            this.btnPubHexToHash.Click += new System.EventHandler(this.btnPubHexToHash_Click);
            //
            // btnPrivToPub
            //
            this.btnPrivToPub.Location = new System.Drawing.Point(334, 92);
            this.btnPrivToPub.Name = "btnPrivToPub";
            this.btnPrivToPub.Size = new System.Drawing.Size(46, 30);
            this.btnPrivToPub.TabIndex = 23;
            this.btnPrivToPub.Text = "▼";
            this.btnPrivToPub.UseVisualStyleBackColor = true;
            this.btnPrivToPub.Click += new System.EventHandler(this.btnPrivToPub_Click);
            //
            // btnPrivWIFToHex
            //
            this.btnPrivWIFToHex.Location = new System.Drawing.Point(334, 34);
            this.btnPrivWIFToHex.Name = "btnPrivWIFToHex";
            this.btnPrivWIFToHex.Size = new System.Drawing.Size(46, 30);
            this.btnPrivWIFToHex.TabIndex = 25;
            this.btnPrivWIFToHex.Text = "▼";
            this.btnPrivWIFToHex.UseVisualStyleBackColor = true;
            this.btnPrivWIFToHex.Click += new System.EventHandler(this.btnPrivWIFToHex_Click);
            //
            // btnPrivHexToWIF
            //
            this.btnPrivHexToWIF.Location = new System.Drawing.Point(286, 34);
            this.btnPrivHexToWIF.Name = "btnPrivHexToWIF";
            this.btnPrivHexToWIF.Size = new System.Drawing.Size(46, 30);
            this.btnPrivHexToWIF.TabIndex = 24;
            this.btnPrivHexToWIF.Text = "▲";
            this.btnPrivHexToWIF.UseVisualStyleBackColor = true;
            this.btnPrivHexToWIF.Click += new System.EventHandler(this.btnPrivHexToWIF_Click);
            //
            // btnGenerate
            //
            this.btnGenerate.Location = new System.Drawing.Point(492, 34);
            this.btnGenerate.Name = "btnGenerate";
            this.btnGenerate.Size = new System.Drawing.Size(168, 30);
            this.btnGenerate.TabIndex = 26;
            this.btnGenerate.Text = "Generate Address";
            this.btnGenerate.UseVisualStyleBackColor = true;
            this.btnGenerate.Click += new System.EventHandler(this.btnGenerate_Click);
            //
            // btnBlockExplorer
            //
            this.btnBlockExplorer.Location = new System.Drawing.Point(492, 235);
            this.btnBlockExplorer.Name = "btnBlockExplorer";
            this.btnBlockExplorer.Size = new System.Drawing.Size(167, 29);
            this.btnBlockExplorer.TabIndex = 27;
            this.btnBlockExplorer.Text = "Block Explorer";
            this.btnBlockExplorer.UseVisualStyleBackColor = true;
            this.btnBlockExplorer.Click += new System.EventHandler(this.btnBlockExplorer_Click);
            //
            // cboCoinType
            //
            this.cboCoinType.FormattingEnabled = true;
            this.cboCoinType.Items.AddRange(new object[] {
            "Bitcoin",
            "Testnet",
            "Namecoin"});
            this.cboCoinType.Location = new System.Drawing.Point(382, 239);
            this.cboCoinType.Name = "cboCoinType";
            this.cboCoinType.Size = new System.Drawing.Size(101, 21);
            this.cboCoinType.TabIndex = 29;
            this.cboCoinType.Text = "Bitcoin";
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(670, 302);
            this.Controls.Add(this.cboCoinType);
            this.Controls.Add(this.btnBlockExplorer);
            this.Controls.Add(this.btnGenerate);
            this.Controls.Add(this.btnPrivWIFToHex);
            this.Controls.Add(this.btnPrivHexToWIF);
            this.Controls.Add(this.btnPrivToPub);
            this.Controls.Add(this.btnPubHexToHash);
            this.Controls.Add(this.btnPubHashToAddress);
            this.Controls.Add(this.btnAddressToPubHash);
            this.Controls.Add(this.label5);
            this.Controls.Add(this.txtBtcAddr);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.txtPubHash);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.txtPubHex);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.txtPrivHex);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.txtPrivWIF);
            this.Name = "Form1";
            this.Text = "Bitcoin Address Utility by Casascius (Beta, No Warranty)";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.TextBox txtPrivWIF;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox txtPrivHex;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.TextBox txtPubHex;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox txtPubHash;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.TextBox txtBtcAddr;
        private System.Windows.Forms.Button btnAddressToPubHash;
        private System.Windows.Forms.Button btnPubHashToAddress;
        private System.Windows.Forms.Button btnPubHexToHash;
        private System.Windows.Forms.Button btnPrivToPub;
        private System.Windows.Forms.Button btnPrivWIFToHex;
        private System.Windows.Forms.Button btnPrivHexToWIF;
        private System.Windows.Forms.Button btnGenerate;
        private System.Windows.Forms.Button btnBlockExplorer;
        private System.Windows.Forms.ComboBox cboCoinType;

    }
}




File: Program.cs
Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace BtcAddress {
    static class Program {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}



Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: bitlotto on July 01, 2011, 06:52:57 PM
Pretty neat! It would be need to have on a windows Live CD! ;)

Kind of related but what would an address that has this look like with check sum:

sacrifice4othersprosperity ;)



Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: casascius on July 01, 2011, 06:57:30 PM
Pretty neat! It would be need to have on a windows Live CD! ;)

Kind of related but what would an address that has this look like with check sum:

sacrifice4othersprosperity ;)



5Jsacrifice4othersprosperity7yjoaJR7mF7Sm1kEibnLCp8  --> 15N3i5weYye7UB4G3G3UbJsn2Bym8LWvFm

In my utility, you can substitute characters in the private key, and have the utility recalculate the checksum.  Of course you can only substitute characters within the base 58 alphabet, so that eliminates O 0 I l.

Generate a random address, and then add a question mark to the WIF private key (turns off checksum).  Substitute characters.  Convert to hex, and then back to WIF (which will replace the checksum with a valid one).  Note that if you change the total number of characters away from 51, you'll get back garbage, so make sure that the character count is correct.

This is how I made my "vanity private keys".

Once you have a working vanity private key that stays the same no matter which way you convert it, then generate the public key and bitcoin address from it.


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: SgtSpike on July 01, 2011, 07:03:05 PM
Neat project!

What do you plan to use the vanity private keys for?  Is there a point to it?  Seems like a waste to put the vanity in the only piece of information that isn't revealed to the public.


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: casascius on July 01, 2011, 07:07:48 PM
Neat project!

What do you plan to use the vanity private keys for?  Is there a point to it?  Seems like a waste to put the vanity in the only piece of information that isn't revealed to the public.

Nothing in particular... however, the application of delivering private keys will likely have plenty of uses, all of which could contain vanity private keys...

  • Bitbills
  • Offline savings wallets (paper wallets)
  • Bitcoin giveaways (where appropriate, the giver can take back the BTC if the recipient never redeems them... e.g. geocaching)
  • Poker chips with embedded bitcoin value
  • Bitcoin retail cards (where a person can buy BTC in a retail setting the same way they buy a gift card... they scratch off private key to get their coins)
  • Computerless transfer of coin value between parties who trust one another (like a cheque)


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: bitlotto on July 01, 2011, 07:08:32 PM
Neat project!

What do you plan to use the vanity private keys for?  Is there a point to it?  Seems like a waste to put the vanity in the only piece of information that isn't revealed to the public.
Perhaps a Bitcoin card manufacturer could put a PIN into the private key. Then when you redeem it the merchant will ask for the missing part?


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: casascius on July 01, 2011, 07:10:05 PM
Neat project!

What do you plan to use the vanity private keys for?  Is there a point to it?  Seems like a waste to put the vanity in the only piece of information that isn't revealed to the public.
Perhaps a Bitcoin card manufacturer could put a PIN into the private key. Then when you redeem it the merchant will ask for the missing part?

That would not be secure, one knowing "most" of a private key could easily brute-force the remainder.


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: bitlotto on July 01, 2011, 07:12:43 PM
Neat project!

What do you plan to use the vanity private keys for?  Is there a point to it?  Seems like a waste to put the vanity in the only piece of information that isn't revealed to the public.
Perhaps a Bitcoin card manufacturer could put a PIN into the private key. Then when you redeem it the merchant will ask for the missing part?

That would not be secure, one knowing "most" of a private key could easily brute-force the remainder.
I know. I was grasping at straws. LOL.


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: BitterTea on July 01, 2011, 07:17:47 PM
Not sure if you've seen this or not, but I've been playing around with this for a few days now...

http://code.google.com/p/bitcoinsharp


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: loglow on July 01, 2011, 10:25:16 PM
Would it be possible to include a command line interface (non GUI mode) for this program?

My apologies if it already includes this, and I just somehow missed it.

Thanks much.


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: pointbiz on September 14, 2011, 03:22:01 AM
very nice program!


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: nhodges on September 14, 2011, 04:28:13 AM
Would it be possible to include a command line interface (non GUI mode) for this program?

My apologies if it already includes this, and I just somehow missed it.

Thanks much.

Aren't there already CLI tools for this?


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: casascius on November 07, 2012, 03:19:20 PM
Recent updates posted to https://casascius.com/btcaddress-alpha.zip :

* Banknote voucher printer can now print notes with minikeys.
* New options on the main screen to copy
  • to the clipboard as a QR code graphic for pasting into other programs, where
  • can be bitcoin address, minikey, private key, or public hash.

Other updates that have been described elsewhere but not in this thread:

* Paper Wallet and Banknote Voucher printer allows printing of multiple colors of the winner of the recent Bitcoin Banknote contest.
* Base58 Calculator allows arbitrary conversions of base58 values to hexadecimal and vice versa, regardless of length.  Add a "?" to the end of any base58 string to suspend verification of the checksum.
* Support for compressed public keys and the ability to convert between compressed and uncompressed.
* Classes for managing Bitcoin addresses/pubkeys/privkeys/minikeys have been refactored and are ripe for scraping and using in other projects if needed.  You can gain programmatic access to the functions of the main "Bitcoin address Swiss army knife" screen in your own program simply by appropriating the classes Address, PublicKey, KeyPair, and MiniKeyPair.

As always, this is a program for Windows, and is based on Microsoft .NET and Visual Studio.  Source code is included in the zip.


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: HostFat on November 07, 2012, 03:22:27 PM
Can you put it on github? :)


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: molecular on April 11, 2013, 11:22:30 AM
I fail to make sense of this. Can't even tell which language this is.

Didn't look hard, but maybe someone can give me a hint? How to compile / run?



Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: MashRinx on April 11, 2013, 07:47:22 PM
It's Microsoft's C#.  You can get a free/lite version of Visual Studio 2012 and it may be able to compile it. (I can't think of any reason why it wouldn't be able to, but I haven't tried).  This will hopefully get you going in the right direction though.


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: molecular on April 12, 2013, 10:11:23 AM
It's Microsoft's C#.  You can get a free/lite version of Visual Studio 2012 and it may be able to compile it. (I can't think of any reason why it wouldn't be able to, but I haven't tried).  This will hopefully get you going in the right direction though.

not to downplay this effort, but m$ is just not for me. There's plenty of python / js / java code around, also.


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: samadamsbeer on April 19, 2013, 05:50:08 PM
Thanks for this tool. I was hoping to use this to verify addresses from brainwallet/bitaddress. Can someone explain how to compile this in Linux/Ubuntu step by step? or if you have a compiled version for that OS, awesome! Thx


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: btctousd81 on August 16, 2017, 04:11:31 AM
sorry for bumping old thread.

but icame from google search.

is it possible to run this code in linux command line ?


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: Coding Enthusiast on June 01, 2020, 06:36:37 AM
when doing generate, can one choose comp. or uncomp.
currently it is uncompressed. so hope to have an updatet version
This is just a code snippet here, I don't think OP maintains it. I wouldn't expect an update.
You should try using active projects that can be found on GitHub (https://github.com/search?q=bitcoin+language%3Ac%23).

Feel free to take a look at my project Bitcoin.Net (https://github.com/Autarkysoft/Denovo#bitcoinnet), it is in beta.
Examples of creating some addresses:
Code:
var addrBuilder = new Address();

string p2pkh = addrBuilder.GetP2pkh(pubKey, useCompressed: false, netType: NetworkType.TestNet);
string p2sh = addrBuilder.GetP2sh(script);
string nestedSegWit = addrBuilder.GetP2sh_P2wpkh(pubkey, witVer: 0, netType: NetworkType.MainNet);
https://github.com/Autarkysoft/Denovo/blob/642103ca8e7693c02c1867202c3cc1a8fa31ab50/Src/Autarkysoft.Bitcoin/Encoders/Address.cs


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: dextronomous on June 12, 2020, 07:29:05 PM
when doing generate, can one choose comp. or uncomp.
currently it is uncompressed. so hope to have an updatet version
This is just a code snippet here, I don't think OP maintains it. I wouldn't expect an update.
You should try using active projects that can be found on GitHub (https://github.com/search?q=bitcoin+language%3Ac%23).

Feel free to take a look at my project Bitcoin.Net (https://github.com/Autarkysoft/Denovo#bitcoinnet), it is in beta.
Examples of creating some addresses:
Code:
var addrBuilder = new Address();

string p2pkh = addrBuilder.GetP2pkh(pubKey, useCompressed: false, netType: NetworkType.TestNet);
string p2sh = addrBuilder.GetP2sh(script);
string nestedSegWit = addrBuilder.GetP2sh_P2wpkh(pubkey, witVer: 0, netType: NetworkType.MainNet);
https://github.com/Autarkysoft/Denovo/blob/642103ca8e7693c02c1867202c3cc1a8fa31ab50/Src/Autarkysoft.Bitcoin/Encoders/Address.cs

YES thank you,

but is cascasius present at forum, or reading this, i would love to have his app, with options like comp or uncomp. so it would suit some of us better.
thanks


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: Coding Enthusiast on June 13, 2020, 04:16:04 AM
but is cascasius present at forum, or reading this,
Barely. Last activity on bitcointalk (https://bitcointalk.org/index.php?action=profile;u=2676) was 2019-12-29. Last activity on GitHub (https://github.com/casascius) was 2013-02.


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: dextronomous on June 27, 2020, 01:29:33 PM
but is cascasius present at forum, or reading this,
Barely. Last activity on bitcointalk (https://bitcointalk.org/index.php?action=profile;u=2676) was 2019-12-29. Last activity on GitHub (https://github.com/casascius) was 2013-02.

ok, ty

the thing is when manually added the address with balance. it shows 0 btc,
the same when generating,
when the app gonna scan the balance? do you need internet doh? but always show 0?
is there some secret setting that turned this stuff off, to be turned on soon>? or never.



Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: Coding Enthusiast on June 29, 2020, 12:29:29 PM
the thing is when manually added the address with balance. it shows 0 btc,

Possibly because blockexplorer.com no longer works.


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: dextronomous on July 08, 2020, 12:22:02 AM
the thing is when manually added the address with balance. it shows 0 btc,

Possibly because blockexplorer.com no longer works.
well i guess the question remains, could you make the change in there, so we could use it with blockchain. or btc

thanks again


Title: Re: Bitcoin Address Utility
Post by: iquantrix on April 04, 2021, 08:20:21 AM
I have made several attempts at compiling and rebuilding this bitcoin address utility too many times with the same errors every time. The BTC address conversions are not happening as supposed to and am not sure if I am correctly compiling the program or not.
Could someone please reach out and offer some assistance on exactly what is the proper method to compile the project and all the required steps?

Please and Thanks!


Title: Re: Bitcoin Address Utility I made (Visual C#, Source Only)
Post by: dextronomous on April 04, 2021, 07:43:07 PM
Hi there mr Casascius,

is it possible, if you have some spare time, to give this program an update,.
right now it shows 0 balance for everything, manually added addresses, generated ones,
and always show firstly uncompressed addresses, and generates the uncompressed ones first,

this is probably something you already know, during these times, corona thing, have some spare time,
so my question would be actually to give it this upgrade, new version number, and compressed ones first,
and or option to it, and a working explorer, json is unlimited access to blockchain api, so if you could do this,

so when added an address with balance it hasn't scanned it for balance or it shows 0.00 always,

this would be really great, thanks in advance sir,.
or to let it generate addresses from a certain range, bits, thanks anyway.

seems i got the compressed out of my way, i got that part, still not seeing balance if manually added or any generated key?
awaiting your responses sir.. :o


Title: Re: Bitcoin Address Utility
Post by: NotATether on April 05, 2021, 09:16:02 AM
Could someone please reach out and offer some assistance on exactly what is the proper method to compile the project and all the required steps?

Maybe you didn't add the BouncyCastle assembly to the Visual Studio project's property sheet?

This is a Windows.Forms program, I vaguely remember tinkering with that framework and some other assemblies to make screensavers several months ago so it would be easier on you if I published a VS .sln of Mike Caldwell's tool on Github, right?