Post
Topic
Board Development & Technical Discussion
Re: [Maybe Solved]More Wiki-fun, base58check encoding.
by
danneu
on 27/11/2013, 08:16:28 UTC
Here's my code. It's a function named `->address` that accepts `pubkey` data, concats together one sequence of `version+hash160+checksum` bytes, and base58 encodes it.

Code:
;; ByteArray -> String
(defn ->address [pubkey]
  (let [ver         (into-byte-array [0x00])
        hash160     (crypto/hash160 pubkey)  ;; (hash160 _) is (rmd160 (sha256 _))
        ver+hash160 (concat-bytes ver hash160)
        checksum    (crypto/calc-checksum ver+hash160)
        ver+hash160+checksum (concat-bytes ver+hash160 checksum)]
    (base58-encode ver+hash160+checksum)))

(->address "0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6")
;;=> "16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM"

The version-byte is actually determined by the network:

Code:
(def networks
  {:mainnet {:address/ver (byte 0x00)}
   :testnet3 {:address/ver (byte 0x6f)}})

Also, if you base58-encode a byte-array with leading 0-bytes, each 0-byte gets converted into a "1".

From bitcoin's test suite, "00000000000000000000" (hex) gets base58-encoded into "1111111111" (string).

In general, if the wiki doesn't help you, then check out any of the 50 partial bitcoin implementations and cross-examine them.