示例#1
0
        public static Script GetScriptPubKey(this string bech32Address)
        {
            if (bech32Address == null)
            {
                throw new ArgumentNullException(nameof(bech32Address));
            }

            if (bech32Address.Length == C.PubKeyHashAddressLength && bech32Address.StartsWith(PubKeyAddressPrefix))
            {
                var hash160 = PubKeyAddressEncoder.Decode(bech32Address, out var witnessVersion);
                KeyHelper.CheckBytes(hash160, 20);

                if (witnessVersion != 0)
                {
                    InvalidAddress(bech32Address);
                }

                return(new Script(OpcodeType.OP_0, Op.GetPushOp(hash160)));
            }

            if (bech32Address.Length == C.ScriptAddressLength && bech32Address.StartsWith(ScriptAddressPrefix))
            {
                var hash256 = PubKeyAddressEncoder.Decode(bech32Address, out var witnessVersion);
                KeyHelper.CheckBytes(hash256, 32);

                if (witnessVersion != 0)
                {
                    InvalidAddress(bech32Address);
                }

                return(new Script(OpcodeType.OP_0, Op.GetPushOp(hash256)));
            }

            throw InvalidAddress(bech32Address);
        }
        public void ValidAddress()
        {
            foreach (string[] address in VALID_ADDRESS)
            {
                byte          witVer;
                byte[]        witProg;
                Bech32Encoder encoder = bech32;
                try
                {
                    witProg = bech32.Decode(address[0], out witVer);
                    encoder = bech32;
                }
                catch
                {
                    witProg = tbech32.Decode(address[0], out witVer);
                    encoder = tbech32;
                }

                byte[] scriptPubkey = Scriptpubkey(witVer, witProg);
                string hex          = string.Join("", scriptPubkey.Select(x => x.ToString("x2")));
                Assert.Equal(hex, address[1]);

                string addr = encoder.Encode(witVer, witProg);
                Assert.Equal(address[0].ToLowerInvariant(), addr);
            }
        }
        public void CanDetectError()
        {
            Bech32Encoder bech = Encoders.Bech32("bc");
            byte          wit;
            var           ex = Assert.Throws <Bech32FormatException>(() => bech.Decode("bc1zw508e6qejxtdg4y5r3zarvaryvg6kdaj", out wit));

            Assert.Single(ex.ErrorIndexes);
            Assert.Equal(8, ex.ErrorIndexes[0]);

            ex = Assert.Throws <Bech32FormatException>(() => bech.Decode("bc1zw508e6qeextdg4y5r3zarvaryvg6kdaj", out wit));
            Assert.Equal(2, ex.ErrorIndexes.Length);
            Assert.Equal(8, ex.ErrorIndexes[0]);
            Assert.Equal(12, ex.ErrorIndexes[1]);
        }
示例#4
0
        public BitcoinWitPubKeyAddress(string bech32, Network expectedNetwork)
            : base(Validate(bech32, expectedNetwork), expectedNetwork)
        {
            Bech32Encoder encoder = expectedNetwork.GetBech32Encoder(Bech32Type.WITNESS_PUBKEY_ADDRESS, true);
            byte          witVersion;

            byte[] decoded = encoder.Decode(bech32, out witVersion);
            this._Hash = new WitKeyId(decoded);
        }
示例#5
0
        public BitcoinWitScriptAddress(string bech32, Network expectedNetwork = null)
            : base(Validate(bech32, expectedNetwork), expectedNetwork)
        {
            Bech32Encoder encoder = expectedNetwork.GetBech32Encoder(Bech32Type.WITNESS_SCRIPT_ADDRESS, true);
            byte          witVersion;

            byte[] decoded = encoder.Decode(bech32, out witVersion);
            this._Hash = new WitScriptId(decoded);
        }
示例#6
0
        private static string GetBase58(PubKey blindingKey, BitcoinAddress address)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }
            if (blindingKey == null)
            {
                throw new ArgumentNullException(nameof(blindingKey));
            }

            if (address is BitcoinBlindedAddress ba)
            {
                address = ba.UnblindedAddress;
            }
            if (!(address is IBase58Data))
            {
                byte          witVer;
                byte[]        witProg;
                var           blech32Encoder = address.Network.GetBech32Encoder(Bech32Type.BLINDED_ADDRESS, true);
                Bech32Encoder bech32Encoder  = null;
                switch (address)
                {
                case BitcoinWitPubKeyAddress _:
                    bech32Encoder = address.Network.GetBech32Encoder(Bech32Type.WITNESS_PUBKEY_ADDRESS, true);
                    break;

                case BitcoinWitScriptAddress _:
                    bech32Encoder = address.Network.GetBech32Encoder(Bech32Type.WITNESS_SCRIPT_ADDRESS, true);
                    break;

                default:
                    throw new ArgumentException($"no bech32 encoder for {address.GetType()} found");
                }

                witProg = bech32Encoder.Decode(address.ToString(), out witVer);
                return(blech32Encoder.Encode(witVer, blindingKey.ToBytes().Concat(witProg)));
            }
            else
            {
                var network = address.Network;
                var keyId   = address.ScriptPubKey.GetDestination();
                if (keyId == null)
                {
                    throw new ArgumentException("The passed address can't be reduced to a hash");
                }
                var bytes = address.Network.GetVersionBytes(Base58Type.BLINDED_ADDRESS, true).Concat(
                    network.GetVersionBytes(((IBase58Data)address).Type, true), blindingKey.ToBytes(),
                    keyId.ToBytes());
                return(NBitcoin.DataEncoders.Encoders.Base58Check.EncodeData(bytes));
            }
        }
示例#7
0
        public void ValidAddress()
        {
            foreach (var address in VALID_ADDRESS)
            {
                Bech32Encoder encoder      = Bech32Encoder.ExtractEncoderFromString(address[0]);
                var           witProg      = encoder.Decode(address[0], out var witVer);
                var           scriptPubkey = Scriptpubkey(witVer, witProg);
                var           hex          = string.Join("", scriptPubkey.Select(x => x.ToString("x2")));
                Assert.Equal(hex, address[1]);

                var addr = encoder.Encode(witVer, witProg);
                Assert.Equal(address[0].ToLowerInvariant(), addr);
            }
        }
示例#8
0
 public static T ToNetwork <T>(this T obj, Network network) where T : IBitcoinString
 {
     if (network == null)
     {
         throw new ArgumentNullException("network");
     }
     if (obj == null)
     {
         throw new ArgumentNullException("obj");
     }
     if (obj.Network == network)
     {
         return(obj);
     }
     if (obj is IBase58Data)
     {
         var b58 = (IBase58Data)obj;
         if (b58.Type != Base58Type.COLORED_ADDRESS)
         {
             byte[] version   = network.GetVersionBytes(b58.Type, true);
             byte[] inner     = Encoders.Base58Check.DecodeData(b58.ToString()).Skip(version.Length).ToArray();
             string newBase58 = Encoders.Base58Check.EncodeData(version.Concat(inner).ToArray());
             return(Network.Parse <T>(newBase58, network));
         }
         else
         {
             string         colored = BitcoinColoredAddress.GetWrappedBase58(obj.ToString(), obj.Network);
             BitcoinAddress address = Network.Parse <BitcoinAddress>(colored, obj.Network).ToNetwork(network);
             return((T)(object)address.ToColoredAddress());
         }
     }
     else if (obj is IBech32Data)
     {
         var           b32     = (IBech32Data)obj;
         Bech32Encoder encoder = b32.Network.GetBech32Encoder(b32.Type, true);
         byte          wit;
         byte[]        data = encoder.Decode(b32.ToString(), out wit);
         encoder = network.GetBech32Encoder(b32.Type, true);
         string str = encoder.Encode(wit, data);
         return((T)(object)Network.Parse <T>(str, network));
     }
     else
     {
         throw new NotSupportedException();
     }
 }
示例#9
0
        public static bool IsValid(string bech32, Network expectedNetwork, out Exception exception)
        {
            exception = null;

            if (bech32 == null)
            {
                exception = new ArgumentNullException("bech32");
                return(false);
            }

            Bech32Encoder encoder = expectedNetwork.GetBech32Encoder(Bech32Type.WITNESS_PUBKEY_ADDRESS, false);

            if (encoder == null)
            {
                return(false);
            }

            try
            {
                byte   witVersion;
                byte[] data = encoder.Decode(bech32, out witVersion);
                if (data.Length == 20 && witVersion == 0)
                {
                    return(true);
                }
            }
            catch (Bech32FormatException bech32FormatException)
            {
                exception = bech32FormatException;
                return(false);
            }
            catch (FormatException)
            {
                exception = new FormatException("Invalid BitcoinWitPubKeyAddress");
                return(false);
            }

            exception = new FormatException("Invalid BitcoinWitScriptAddress");
            return(false);
        }