예제 #1
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            var result = Base58Data.GetFromBase58Data(reader.Value.ToString());

            if (result == null)
            {
                throw new JsonException($"Invalid  object of type {objectType.Name} path {reader.Path}");
            }
            if (Network != null)
            {
                if (result.Network != Network)
                {
                    throw new JsonException($"Invalid  object of type {objectType.Name} path {reader.Path}");
                }
            }
            if (!objectType.GetTypeInfo().IsAssignableFrom(result.GetType().GetTypeInfo()))
            {
                throw new JsonException($"Invalid  object of type {objectType.Name} path {reader.Path}");
            }
            return(result);
        }
예제 #2
0
        public static WhatIsBase58 GetFromBase58Data(string data)
        {
            var b58 = Base58Data.GetFromBase58Data(data);

            if (b58 != null)
            {
                switch (b58.Type)
                {
                case Base58Type.SCRIPT_ADDRESS:
                case Base58Type.PUBKEY_ADDRESS:
                case Base58Type.WITNESS_P2WPKH:
                case Base58Type.WITNESS_P2WSH:
                    return(new WhatIsAddress((BitcoinAddress)b58));

                case Base58Type.SECRET_KEY:
                    return(new WhatIsPrivateKey((BitcoinSecret)b58));

                case Base58Type.COLORED_ADDRESS:
                    return(new WhatIsColoredAddress((BitcoinColoredAddress)b58));

                default:
                    return(new WhatIsBase58(b58));
                }
            }
            throw new FormatException("Not a base58");
        }
예제 #3
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            var result = Base58Data.GetFromBase58Data(reader.Value.ToString());

            if (result == null)
            {
                throw new JsonObjectException("Invalid Base58Check data", reader);
            }
            if (Network != null)
            {
                if (result.Network != Network)
                {
                    throw new JsonObjectException("Invalid Base58Check network", reader);
                }
            }
            if (!objectType.GetTypeInfo().IsAssignableFrom(result.GetType().GetTypeInfo()))
            {
                throw new JsonObjectException("Invalid Base58Check type expected " + objectType.Name + ", actual " + result.GetType().Name, reader);
            }
            return(result);
        }
예제 #4
0
        public void CannotCreateAddressEmpty()
        {
            Network        network;
            DataTypePrefix type;

            Assert.Throws <FormatException>(() => Base58Data.FromString("", out network, out type));
        }
예제 #5
0
        public void CannotCreateAddressFromUnsupportedDataType()
        {
            Network        network;
            DataTypePrefix type;
            var            data  = Base58Data.FromString("1ApqRi7vWrh3gR4jJ6LXhAXRKWTu55mrqP", out network, out type);
            var            bytes = network.GetPrefixBytes(DataTypePrefix.ExtPrivateKey).Concat(data).ToArray();

            Assert.Throws <NotSupportedException>(() => Address.FromString(Encoders.Base58Check.GetString(bytes)));
        }
예제 #6
0
        public void CannotCreateAddressxxxx()
        {
            Network        network;
            DataTypePrefix type;
            var            data = Base58Data.FromString("1ApqRi7vWrh3gR4jJ6LXhAXRKWTu55mrqP", out network, out type);
            var            bytes = new byte[] { 0xff, 0xff }.Concat(data).ToArray();

            Assert.Throws <FormatException>(() => Address.FromString(Encoders.Base58Check.GetString(bytes)));
        }
예제 #7
0
        public static HdKey Parse(string wif)
        {
            DataTypePrefix prefix;
            Network        network;
            var            bytes = Base58Data.FromString(wif, out network, out prefix);

            if (prefix != DataTypePrefix.ExtPrivateKey)
            {
                throw new NotSupportedException("not a valid extended private key");
            }

            var depth       = bytes[0];
            var fingerprint = bytes.Slice(1, FingerprintLength);
            var child       = Packer.BigEndian.ToUInt32(bytes, 5);
            var chain       = bytes.Slice(9, ChainCodeLength);
            var key         = bytes.Slice(42, KeyLength);

            return(new HdKey(new Key(key), chain, depth, child, fingerprint));
        }
예제 #8
0
        public static Key Parse(string wif)
        {
            Network        network;
            DataTypePrefix type;
            var            bytes = Base58Data.FromString(wif, out network, out type);

            if (type != DataTypePrefix.PrivateKey)
            {
                throw new FormatException("No private key format");
            }
            var isCompressed = bytes.Length == 33 && bytes[32] == 0x01;
            var valid        = bytes.Length == 32 || (isCompressed && bytes.Length == 33);

            if (!valid)
            {
                throw new FormatException("No private key format");
            }
            var key = isCompressed ? bytes.Slice(0, 32) : bytes;

            return(new Key(key, isCompressed));
        }
예제 #9
0
 public WhatIsBase58(Base58Data data)
 {
     Base58  = data.ToString();
     Type    = ToString(data.Type);
     Network = data.Network;
 }
예제 #10
0
 public string ToString(Network network)
 {
     return(Base58Data.ToString(ToByteArray(), DataTypePrefix.ExtPrivateKey, network));
 }
예제 #11
0
        public string ToString(Network network)
        {
            var key = _isCompressed ? _key.Concat(ByteArray.One) : _key;

            return(Base58Data.ToString(key, DataTypePrefix.PrivateKey, network));
        }
예제 #12
0
 public void CannotCreateInvalidAddress()
 {
     Assert.Throws <FormatException>(
         () => Base58Data.FromString("8ApqRi7vWrh3gR4jJ6LXhAXRKWTu55mrqP"));
 }
예제 #13
0
        public void CanGeneratePubKeysAndAddress()
        {
            //Took from http://brainwallet.org/ and http://procbits.com/2013/08/27/generating-a-bitcoin-address-with-javascript
            var tests = new[]
            {
                new
                {
                    PrivateKeyWIF           = "5Hx15HFGyep2CfPxsJKe2fXJsCVn5DEiyoeGGF6JZjGbTRnqfiD",
                    CompressedPrivateKeyWIF = "KwomKti1X3tYJUUMb1TGSM2mrZk1wb1aHisUNHCQXTZq5auC2qc3",
                    PubKey            = "04d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6fbdd594388756a7beaf73b4822bc22d36e9bda7db82df2b8b623673eefc0b7495",
                    CompressedPubKey  = "03d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6f",
                    Address           = "16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS",
                    CompressedAddress = "1FkKMsKNJqWSDvTvETqcCeHcUQQ64kSC6s",
                    Hash160           = "3c176e659bea0f29a3e9bf7880c112b1b31b4dc8",
                    CompressedHash160 = "a1c2f92a9dacbd2991c3897724a93f338e44bdc1",
                    DER           = "3082011302010104201184cd2cdd640ca42cfc3a091c51d549b2f016d454b2774019c2b2d2e08529fda081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a14403420004d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6fbdd594388756a7beaf73b4822bc22d36e9bda7db82df2b8b623673eefc0b7495",
                    CompressedDER = "3081d302010104201184cd2cdd640ca42cfc3a091c51d549b2f016d454b2774019c2b2d2e08529fda08185308182020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a12403220003d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6f"
                },
                new
                {
                    PrivateKeyWIF           = "5J7WTMRn1vjZ9udUxNCLq7F9DYEJiqRCjstiBrY6mDjnaomd6kZ",
                    CompressedPrivateKeyWIF = "KxXj1KAMh6ApvKJ2PNZ4XLZRGLqjDehppFdEnueGSBDrC2Hfe7vt",
                    PubKey            = "0493e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd105500897eb030c033cdab160f31c36df0ea38330fdd69677df49cd14826902022d17f3f",
                    CompressedPubKey  = "0393e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd10550089",
                    Address           = "1MZmwgyMyjM11uA6ZSpgn1uK3LBWCzvV6e",
                    CompressedAddress = "1AECNr2TDye8dpC1TeDH3eJpGoZ7dNPy4g",
                    Hash160           = "e19557c8f8fb53a964c5dc7bfde86d806709f7c5",
                    CompressedHash160 = "6538094af65453ea279f14d1a04b408e3adfebd7",
                    DER           = "308201130201010420271ac4d7056937c156abd828850d05df0697dd662d3c1b0107f53a387b4c176ca081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a1440342000493e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd105500897eb030c033cdab160f31c36df0ea38330fdd69677df49cd14826902022d17f3f",
                    CompressedDER = "3081d30201010420271ac4d7056937c156abd828850d05df0697dd662d3c1b0107f53a387b4c176ca08185308182020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a1240322000393e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd10550089"
                }
            };

            foreach (var test in tests)
            {
                var privateKey = Key.Parse(test.PrivateKeyWIF);
                Assert.AreEqual(test.PubKey, privateKey.PubKey.ToString());
                Assert.AreEqual(Encoders.Hex.GetString(Base58Data.FromString(test.PrivateKeyWIF)), privateKey.ToString());

                var address = Address.FromString(test.Address);
                Assert.AreEqual(KeyId.Parse(test.Hash160), address.Destination);
                Assert.AreEqual(KeyId.Parse(test.Hash160), privateKey.PubKey.Hash);
                Assert.AreEqual(address.ScriptPubKey.ToString(), privateKey.PubKey.ToAddress(Network.BitcoinMain).ScriptPubKey.ToString());
                Assert.True(privateKey.PubKey.IsCanonical);
                Assert.AreEqual(test.Address, privateKey.PubKey.ToString(Network.BitcoinMain));
                Assert.AreEqual(address.ScriptPubKey.ToString(), privateKey.PubKey.Hash.ScriptPubKey.ToString());
                Assert.AreEqual(address.ScriptPubKey.ToString(), new KeyId(privateKey.PubKey).ScriptPubKey.ToString());

                var compressedPrivKey = new Key(privateKey.ToByteArray(), true);
                Assert.AreEqual(test.CompressedPrivateKeyWIF, compressedPrivKey.ToString(Network.BitcoinMain));
                Assert.AreEqual(test.CompressedPubKey, compressedPrivKey.PubKey.ToString());
                // Assert.True(compressedPrivKey.PubKey.IsCompressed);
                Assert.True(compressedPrivKey.PubKey.IsCanonical);
                Assert.AreEqual(test.CompressedAddress, compressedPrivKey.PubKey.ToString(Network.BitcoinMain));

                var compressedAddr = Address.FromString(test.CompressedAddress);
                Assert.AreEqual(KeyId.Parse(test.CompressedHash160), compressedAddr.Destination);
                Assert.AreEqual(KeyId.Parse(test.CompressedHash160), compressedPrivKey.PubKey.Hash);
                Assert.AreEqual(compressedAddr.ScriptPubKey.ToString(), compressedPrivKey.PubKey.Hash.ScriptPubKey.ToString());
            }
        }
예제 #14
0
 public string ToString(Network network)
 {
     return(Base58Data.ToString(_bytes, DataTypePrefix.EncryptedKeyNoEC, network));
 }
예제 #15
0
        private async void buttonSign_Click(object sender, EventArgs e)
        {
            var privKey           = textPrivateKey.Text;
            var unsignedText      = textCommitmentToSign.Text;
            var feeTxId           = textBoxFeeTransactionId.Text;
            var feeTxOutputNumber = textBoxFeeOutputNumber.Text;
            var feePrivateKey     = textFeePrivateKey.Text;
            var sigHashType       = SigHash.All | SigHash.AnyoneCanPay;

            var settings = Settings.ReadAppSettings();

            textSignedTransaction.Text = string.Empty;

            if (string.IsNullOrEmpty(privKey))
            {
                Alert("Private key should have a value.");
                return;
            }
            BitcoinSecret secret = null;

            try
            {
                secret = Base58Data.GetFromBase58Data(privKey, settings.Network) as BitcoinSecret;
                if (secret == null)
                {
                    Alert("Not a valid private key specified.");
                    return;
                }
            }
            catch (Exception exp)
            {
                Alert(exp.ToString());
                return;
            }

            if (string.IsNullOrEmpty(unsignedText))
            {
                Alert("Unsigned commitment should have a value.");
                return;
            }

            if (string.IsNullOrEmpty(feeTxId))
            {
                Alert("Transaction Id for fee should have a value.");
                return;
            }

            if (string.IsNullOrEmpty(feeTxOutputNumber))
            {
                Alert("Transaction output number for fee should have a value.");
                return;
            }

            if (string.IsNullOrEmpty(feePrivateKey))
            {
                Alert("The private key for the address holding the fee should have a value.");
                return;
            }

            BitcoinSecret feeSecret = null;

            try
            {
                feeSecret = Base58Data.GetFromBase58Data(feePrivateKey, settings.Network) as BitcoinSecret;
                if (feeSecret == null)
                {
                    Alert("Not a valid private key for fee specified.");
                    return;
                }
            }
            catch (Exception exp)
            {
                Alert(exp.ToString());
                return;
            }

            Transaction commitmentTransaction = null;

            try
            {
                commitmentTransaction = new Transaction(unsignedText);
            }
            catch (Exception exp)
            {
                Alert(string.Format("Error in creating transaction: {0}", exp.ToString()));
                return;
            }

            try
            {
                commitmentTransaction = await AddFeeToTx(commitmentTransaction, feeTxId, feeTxOutputNumber);

                var outputTx = commitmentTransaction.ToHex();

                outputTx = await Helper.Helper.SignTransactionWorker
                               (new TransactionSignRequest { PrivateKey = feePrivateKey, TransactionToSign = outputTx }, sigHashType);

                outputTx = await Helper.Helper.SignTransactionWorker
                               (new TransactionSignRequest { PrivateKey = privKey, TransactionToSign = outputTx }, sigHashType);

                textSignedTransaction.Text = outputTx;
            }
            catch (Exception exp)
            {
                Alert(exp.ToString());
            }
        }