jaswdr / faker

:rocket: Ultimate fake data generator for Go with zero dependencies
https://pkg.go.dev/github.com/jaswdr/faker
MIT License
566 stars 59 forks source link

[FEATURE] Bitcoin Address Support #78

Closed fzn0x closed 2 years ago

fzn0x commented 2 years ago

Is your feature request related to a problem? Please describe. Bitcoin Address Support with available standard implementation

xlanor commented 2 years ago

@jaswdr, I would like to work on this too, but would like to have some clarification:

jaswdr commented 2 years ago

Hey @xlanor, awesome to hear that, I was thinking about it too, I believe that the best way is to have one separate method for each standard, I'm not a crypto specialist but considering what I've found there are three main formats: P2PKH (Legacy), P2SH and Bech32, so I believe that we should have methods for those directly and one generic one that randomly pick one of those three, see some scratched code:

file: crypto.go

type Crypto struct {
    Faker *Faker
}

func (c Crypto) Address() string {
  // Any from P2PKH(), P2SH() and Bech32()
}

func (c Crypto) P2PKH() string {
  // Example: 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2
}

func (c Crypto) P2SH() string {
  // Example: 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy
}

func (c Crypto) Bech32() string {
  Example: bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq
}
xlanor commented 2 years ago

Yep! That's actually the line of thought I was going down. However, these are Bitcoin specific addresses in nature. Ethereum addresses, for example, would be different

Even for each type, the length of the address, for example, which is a fairly important factor to note when generating the address, does not seem to have an official source/paper describing the maximum or minimum length.

For example, this wiki fixes it at 30ish, whereas BitcoinTalk says that for Bech32, it can go up to 62 characters.

fzn0x commented 2 years ago

@jaswdr, I would like to work on this too, but would like to have some clarification:

  • Currently, there are four types of Bitcoin addresses avaliable (from what I can tell). However, I am unable to find a fixed spec sheet anywhere pertaining to the length. Should we fix a length at maybe say, 60, and subsequently tweak it as need be? it may be incorrect at the start, but I do not have the specific knowledge on Bitcoin addresses, apart from their prefixes and non-allowed characters or digits, but the discussion on maximum and minimum allowed lengths seems to have conflicting information and no official source. Unless @bl0cknumber can provide more concrete details?
  • I was thinking of structuring this under a Crypto generator so that we could have further extensions in the future, such as f.Crypto().Bitcoin().Address() and f.Crypto().Ethereum().Address(), what do you think?

Bitcoin address would take up 26-35, see here for the information from Bitcoin wiki

A Bitcoin invoice address, or simply invoice, is an identifier of 26-35 alphanumeric characters, beginning with the number 1, 3 or bc1 that represents a possible destination for a bitcoin payment. Invoices can be generated at no cost by any user of Bitcoin. It is also possible to get a Bitcoin invoice address using an account at an exchange or online wallet service.

There are currently three invoice address formats in use:

P2PKH which begin with the number 1, eg: 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2. P2SH type starting with the number 3, eg: 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy. Bech32 type starting with bc1, eg: bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq.


Ethereum address would take up 42 characters long for the prefixed address, see here for the information from Ethereum documentation glossary

An Ethereum address represents an account. For EOA, the address is derived as the last 20 bytes of the public key controlling the account, e.g., cd2a3d9f938e13cd947ec05abc7fe734df8dd826. This is a hexadecimal format (base 16 notation), which is often indicated explicitly by appending 0x to the address. Web3.js and console functions accept addresses with or without this prefix but for transparency we encourage their use. Since each byte of the address is represented by 2 hex characters, a prefixed address is 42 characters long. Several apps and APIs are also meant to implement the new checksum-enabled address scheme introduced in the Mist Ethereum wallet as of version 0.5.0.

xlanor commented 2 years ago

Cool. In that case, what I will probably do is to do a variable length function signature where the user would have to specify the signature length. This allows for the use case whereby in future, if new address standards are implemented (like increasing length) it will not result in a backward breaking change for existing users of the library.

Can I confirm for the prefix - is the count inclusive of the prefix? @bl0cknumber

ccing @jaswdr to comment on the above proposal

jaswdr commented 2 years ago

@xlanor LGTM, the only thing that maybe is interesting to change is to not require that the user specifies the length, but instead generate a random length (with IntBetween) and use that to generate the value, and if the user want to have a specific length you can create some WithLength variants.

xlanor commented 2 years ago

Sounds good. I'll get started on it and should have a PR ready in the next few days

jaswdr commented 2 years ago

Both PRs were merged, I'm closing this for now

fzn0x commented 2 years ago

Both PRs were merged, I'm closing this for now

Thanks!