Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: Vort3x.Layers on August 19, 2021, 09:52:36 PM



Title: C# Bitcoin Address Validation [Legacy, Nested SegWit, Native SegWit] | OFFLINE
Post by: Vort3x.Layers on August 19, 2021, 09:52:36 PM
I am looking for a class or method in c# language to validate bitcoin address.(OFFLINE)
I want to validate [Legacy, Nested SegWit, Native SegWit] address types (https://help.crypto.com/en/articles/4056348-send-and-receive-btc-ltc-difference-between-segwit-and-legacy-address).

For this purpose i found this :  
determine-if-a-bitcoin-wallet-address-is-valid (https://stackoverflow.com/questions/25343204/determine-if-a-bitcoin-wallet-address-is-valid)
But it validates Legacy addresses only.

I also found this :  
bitcoin-address-validation (https://github.com/ruigomeseu/bitcoin-address-validation)
But i think it is using an api for this purpose & language is not c#.

I also found this :  
bitcoin-address-validator (https://github.com/kielabokkie/bitcoin-address-validator)
This is not in c# language. It's php & i am not familiar with php.

I also found this :
address_validation (http://rosettacode.org/wiki/Bitcoin/address_validation)
Too old and only for Legacy addresses.

Please give me a solution on this.


Title: Re: C# Bitcoin Address Validation [Legacy, Nested SegWit, Native SegWit] | OFFLINE
Post by: Coding Enthusiast on August 20, 2021, 02:07:50 AM
I have a library called Bitcoin.Net (https://www.nuget.org/packages/Autarkysoft.Bitcoin/) that has a static address class (https://github.com/Autarkysoft/Denovo/blob/master/Src/Autarkysoft.Bitcoin/Encoders/Address.cs) that does validation like this.
You have to use the GetAddressType method with 2 overloads
AddressType GetAddressType(string address, NetworkType netType)
AddressType GetAddressType(string address, NetworkType netType, out byte[] data)

This both checks the address and return its type and it can decode and return the data (hash) encoded by that address.

If you want to check the address against a certain pubkey script type you can use bool VerifyType(string address, PubkeyScriptType scrType, out byte[] hash) method.

BTW "nested SegWit" address type is P2SH, there is no way of having any additional information by only seeing the address.


Title: Re: C# Bitcoin Address Validation [Legacy, Nested SegWit, Native SegWit] | OFFLINE
Post by: Vort3x.Layers on August 20, 2021, 05:33:18 AM
Thanks for the answer,
But in this link bitcoin-address-validator (https://github.com/kielabokkie/bitcoin-address-validator)
They are validating legacy, segwit and native segwit (bech32) Bitcoin addresses.
It's in php language.
So there should be a way for Nested SegWit (P2SH) too.


Title: Re: C# Bitcoin Address Validation [Legacy, Nested SegWit, Native SegWit] | OFFLINE
Post by: Coding Enthusiast on August 20, 2021, 07:07:21 AM
So there should be a way for Nested SegWit (P2SH) too.
The point I was making is that you can't know the script type that was hashed by seeing the address alone. In other words you can validate a P2SH address and get the 20-byte hash out but there is no way to tell from the address if the script type which is hashed is P2WPKH or P2WSH or a legacy redeem script or something else entirely (eg. P2TR-P2SH).


Title: Re: C# Bitcoin Address Validation [Legacy, Nested SegWit, Native SegWit] | OFFLINE
Post by: Vort3x.Layers on August 20, 2021, 08:46:14 AM
My goal is recognize that a string is bitcoin address or not.(Offline Mode)
So for this purpose introduce a good library.

Would you please show some examples of usage these methods :
Quote
AddressType GetAddressType(string address, NetworkType netType)
AddressType GetAddressType(string address, NetworkType netType, out byte[] data)
bool VerifyType(string address, PubkeyScriptType scrType, out byte[] hash)

What is NetworkType netType? Is this method working offline?
I need a method that returns TRUE or FALSE.


Title: Re: C# Bitcoin Address Validation [Legacy, Nested SegWit, Native SegWit] | OFFLINE
Post by: Vort3x.Layers on August 20, 2021, 10:47:24 AM
This link solved my issue.
regex-bitcoin-addresses (https://regexland.com/regex-bitcoin-addresses/)


Title: Re: C# Bitcoin Address Validation [Legacy, Nested SegWit, Native SegWit] | OFFLINE
Post by: Coding Enthusiast on August 20, 2021, 01:06:55 PM
For future reference:
My goal is recognize that a string is bitcoin address or not.(Offline Mode)
I need a method that returns TRUE or FALSE.
You just have to check if the returned type is not Invalid (eg. wrong checksum, wrong length, etc.) or Unknown (eg. Bech32m with witness version 2+).
Code:
AddressType t = GetAddressType(...);
bool result = (t != AddressType.Invalid && t != AddressType.Unknown);

Would you please show some examples of usage these methods :
Bitcoin.Net has a huge number of tests that you could use as examples. Each test file is in the Test project with the same namespace name.
/Tests/Bitcoin/Encoders/AddressTests.cs (https://github.com/Autarkysoft/Denovo/blob/232efbae9285a558d805cc31c7adb0c5c27104da/Src/Tests/Bitcoin/Encoders/AddressTests.cs#L199)

What is NetworkType netType?
3 different network types are defined in Bitcoin: MainNet, TestNet and RegTest and some of the prefixes used when encoding addresses (and other variables elsewhere) are different for these networks.

Is this method working offline?
There is no reason not to!

This link solved my issue.
regex-bitcoin-addresses (https://regexland.com/regex-bitcoin-addresses/)
This is a very bad approach and will have a lot of false positives and false negatives.
  • Address length in Base58 is not fixed. It may be as small as 26 and as big as 35 (the article uses wrong values).
  • First character being 1 or 3 doesn't mean the address's first byte was correct. Eg. 3R2cuiTJNvFDn18H7i7h7pvwYuvaRTNaJq is an invalid address because it uses 6 as the first byte instead of 5
  • Regex doesn't validate the address checksum for either legacy or Bech32
  • Due to lack of checksum validation there is no way to reject Bech32 addresses for version 1+ witness programs
  • Certain edge cases aren't considered such as "bc1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqyqskt8xg" being an invalid Bech32 address


Title: Re: C# Bitcoin Address Validation [Legacy, Nested SegWit, Native SegWit] | OFFLINE
Post by: Vort3x.Layers on August 20, 2021, 01:49:05 PM
Coding Enthusiast (https://bitcointalk.org/index.php?action=profile;u=879277)
Thanks a lot brother


Title: Re: C# Bitcoin Address Validation [Legacy, Nested SegWit, Native SegWit] | OFFLINE
Post by: BlackHatCoiner on August 20, 2021, 01:49:38 PM
Even if your issue is resolved, I'll try to clear out some things to you that you possibly don't know. Giving you a bunch of coding lines will only assist you temporarily.

I need a method that returns TRUE or FALSE.
Alright, maybe you aren't familiar that much with coding yet and Coding Enthusiast's scripts may be an overstatement to understand.

First off, it is required for you to know what's the background of a Bitcoin address, how it is structured etc. In this case, I'll explain you a legacy address' structure, but it works similarly for Native SegWit and Nested SegWit. This bitcoin wiki article (https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses) is useful. Briefly, a Bitcoin address is a base58 encoding of a string that contains these stuff in the following order: [version prefix][160-bit hash][checksum]

The checksum is the first 4 bytes of the prefix plus a 160-bit hash that is hashed two times with SHA256. For instance, if someone gave you this 160-bit hash:

Code:
e01f8922bb5bbfac8d02e77b023f2561fd2fa26b

You could get the checksum as following:

Code:
SHA256("00e01f8922bb5bbfac8d02e77b023f2561fd2fa26b") = 5088bf915b5880a5423a4064266ff534b28d74d4e1dce6e68f3fbf35e4481e32
SHA256("5088bf915b5880a5423a4064266ff534b28d74d4e1dce6e68f3fbf35e4481e32") = 351ca7c467a8c5f19dfb8472f5d4c1f8ee1ed38e2e9254ed1b0f04fec79a19d4
Checksum = 351ca7c4

So, to be able to detect an address, you have to decode it and check if it has the above requirements; if the twice hashed prefix along with the next 40 hexadecimal characters begin with the last 4 bytes of the decoded address. You can google (https://www.google.com/search?q=base58+decode+c%23) for a base58 decoder script in C#, but it shouldn't be hard to write it yourself if you firstly understand how it works (https://learnmeabitcoin.com/technical/base58).

In Bitcoin, you should never hash a message as a text, but rather as a byte array.


Title: Re: C# Bitcoin Address Validation [Legacy, Nested SegWit, Native SegWit] | OFFLINE
Post by: Vort3x.Layers on August 20, 2021, 02:20:26 PM
BlackHatCoiner (https://bitcointalk.org/index.php?action=profile;u=2775483)
Thanks for the assist in this topic