Ethereum address validation + unit test

* utility function for validate Ethereum addresses
* unit test
This commit is contained in:
Teemu Patja 2017-02-21 21:41:39 +02:00
parent d5ebf3b0bc
commit 1663669163
No known key found for this signature in database
GPG Key ID: F5B7035E6580FD4C
3 changed files with 62 additions and 5 deletions

View File

@ -40,7 +40,8 @@
[crypto-random "1.2.0"]
[crypto-equality "1.0.0"]
[cheshire "5.7.0"]
[mpg "1.3.0"]]
[mpg "1.3.0"]
[pandect "0.6.1"]]
:min-lein-version "2.0.0"
:source-paths ["src/clj" "src/cljc"]

View File

@ -5,7 +5,8 @@
[commiteth.config :refer [env]]
[clojure.string :refer [join]]
[clojure.tools.logging :as log]
[clojure.string :as str]))
[clojure.string :as str]
[pandect.core :as pandect]))
(def eth-rpc-url "http://localhost:8545")
(defn eth-account [] (:eth-account env))
@ -65,9 +66,9 @@
(eth-rpc
"personal_sendTransaction"
[(if (not (nil? to))
(merge args {:to to})
args)
(eth-password)])))
(merge args {:to to})
args)
(eth-password)])))
(defn get-transaction-receipt
[hash]
@ -104,3 +105,44 @@
(let [data (apply format-call-params method-id params)
value (format "0x%x" 1)]
(send-transaction from contract value {:data data})))
(defn hex-ch->num
[ch]
(read-string (str "0x" ch)))
(defn strip-0x
[x]
(str/replace x #"(?i)^0x" ""))
(defn upper-ch [ch]
(first (str/upper-case ch)))
(defn lower-ch [ch]
(first (str/lower-case ch)))
(defn valid-address?
"Validate given ethereum address. Checksum validation is performed
and input is case-sensitive"
[address]
(log/debug "valid-address?" address)
;; logic based on
;; https://github.com/cilphex/ethereum-address/blob/master/index.js
(and (boolean (re-matches #"(?i)^(0x)?[0-9a-f]{40}$" address))
(let [addr (strip-0x address)
hash (pandect/keccak-256 (str/lower-case addr))]
(log/debug "address hash" hash "addr" addr)
(->>
(map-indexed (fn [idx _]
(let [hash-ch-int (-> (nth hash idx)
(hex-ch->num))
ch (nth addr idx)
ch-lower (lower-ch ch)
ch-upper (upper-ch ch)]
(or (and (> hash-ch-int 7)
(not= ch-upper ch))
(and (<= hash-ch-int 7)
(not= ch-lower ch)))))
addr)
(filter true?)
(empty?)))))

View File

@ -0,0 +1,14 @@
(ns commiteth.test.eth
(:require [clojure.test :refer :all]
[commiteth.eth.core :as eth]))
(deftest test-address-validation
(testing "Short address is invalid"
(let [addr "0x34264362346364326423"]
(is (false? (eth/valid-address? addr)))))
(testing "Valid address is valid"
(let [addr "0xA1cab91b36bea34487c5670Bbd00a1Aa8196aeD8"]
(is (true? (eth/valid-address? addr)))))
(testing "Case sensitivity matters"
(let [addr "0xa1cab91b36bea34487c5670bbd00a1aa8196aed8"]
(is (false? (eth/valid-address? addr))))))