From 0471d5fd72cc94257bbf8da99a6cf50159d6348a Mon Sep 17 00:00:00 2001 From: mestorlx Date: Sat, 2 Feb 2019 14:49:24 +0100 Subject: [PATCH] Added utility function to test addresses according to EIP55. Added pop-up message when addres checksum fails in wallet/send/enter recipient address. Signed-off-by: Julien Eluard --- src/status_im/i18n.cljs | 2 +- .../wallet/choose_recipient/events.cljs | 7 ++++-- src/status_im/utils/ethereum/eip55.cljs | 22 +++++++++++++++++++ test/appium/tests/users.py | 2 +- test/cljs/status_im/test/runner.cljs | 2 ++ .../status_im/test/utils/ethereum/eip55.cljs | 16 ++++++++++++++ translations/en.json | 1 + 7 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 src/status_im/utils/ethereum/eip55.cljs create mode 100644 test/cljs/status_im/test/utils/ethereum/eip55.cljs diff --git a/src/status_im/i18n.cljs b/src/status_im/i18n.cljs index ee1d8a7b33..63dead05f5 100644 --- a/src/status_im/i18n.cljs +++ b/src/status_im/i18n.cljs @@ -63,7 +63,7 @@ :chat-settings :offline :update-status :invited :chat-send-eth :address :new-public-group-chat :datetime-hour :wallet-settings :datetime-ago-format :close-app-button :block :camera-access-error - :wallet-invalid-address :address-explication :remove + :wallet-invalid-address :wallet-invalid-address-checksum :address-explication :remove :transactions-delete-content :transactions-unsigned-empty :transaction-moved-text :add-members :sign-later-title :yes :dapps :popular-tags :network-settings :twelve-words-in-correct-order diff --git a/src/status_im/ui/screens/wallet/choose_recipient/events.cljs b/src/status_im/ui/screens/wallet/choose_recipient/events.cljs index d90a7d72d3..a055fcb1f8 100644 --- a/src/status_im/ui/screens/wallet/choose_recipient/events.cljs +++ b/src/status_im/ui/screens/wallet/choose_recipient/events.cljs @@ -4,6 +4,7 @@ [status-im.contact.db :as contact.db] [status-im.i18n :as i18n] [status-im.utils.ethereum.core :as ethereum] + [status-im.utils.ethereum.eip55 :as eip55] [status-im.utils.ethereum.eip681 :as eip681] [status-im.utils.ethereum.ens :as ens] [status-im.utils.handlers :as handlers] @@ -81,8 +82,10 @@ :ens-name recipient :cb #(re-frame/dispatch [:wallet.send/set-recipient %])}} (if (ethereum/address? recipient) - {:db (assoc-in db [:wallet :send-transaction :to] recipient) - :dispatch [:navigate-back]} + (if (eip55/valid-address-checksum? recipient) + {:db (assoc-in db [:wallet :send-transaction :to] recipient) + :dispatch [:navigate-back]} + {:ui/show-error (i18n/label :t/wallet-invalid-address-checksum {:data recipient})}) {:ui/show-error (i18n/label :t/wallet-invalid-address {:data recipient})}))))) (handlers/register-handler-fx diff --git a/src/status_im/utils/ethereum/eip55.cljs b/src/status_im/utils/ethereum/eip55.cljs new file mode 100644 index 0000000000..3faef9ed91 --- /dev/null +++ b/src/status_im/utils/ethereum/eip55.cljs @@ -0,0 +1,22 @@ +(ns status-im.utils.ethereum.eip55 + "Utility function related to [EIP55](https://eips.ethereum.org/EIPS/eip-55) + + This EIP standardize how ethereum addresses should be printed as strings to validate checksum. + + e.g. 0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed" + (:require [clojure.string :as string] + [status-im.utils.ethereum.core :as ethereum])) + +(defn valid-address-checksum? [address] + "verify address checksum according to EIP 55" + (let [adHash (ethereum/naked-address (ethereum/sha3 + (string/lower-case (ethereum/naked-address address))))] + (every? true? + (map-indexed (fn [idx char] + (if (> (compare char "9") 0) + (if (>= (js/parseInt (nth adHash idx) 16) 8) + ; If true should be upper case + (<= (compare char "Z") 0) + ; If not should be lower case + (> (compare char "Z") 0)) + true)) (ethereum/naked-address address))))) \ No newline at end of file diff --git a/test/appium/tests/users.py b/test/appium/tests/users.py index 0d96f7ddf1..107ceffac3 100644 --- a/test/appium/tests/users.py +++ b/test/appium/tests/users.py @@ -3,7 +3,7 @@ basic_user['passphrase'] = "tree weekend ceiling awkward universe pyramid glimps basic_user['username'] = "Little Weighty Iberianmole" basic_user['public_key'] = "0x040d3400f0ba80b2f6017a9021a66e042abc33cf7051ddf98a24a815c93d6c052ce2b7873d799f096325" \ "9f41c5a1bf08133dd4f3fe63ea1cceaa1e86ebc4bc42c9" -basic_user['address'] = "f184747445c3b85ceb147dfb136067cb93d95f1d" +basic_user['address'] = "f184747445c3B85CEb147DfB136067CB93d95F1D" wallet_users = dict() diff --git a/test/cljs/status_im/test/runner.cljs b/test/cljs/status_im/test/runner.cljs index 93ae7cf707..fd177b5016 100644 --- a/test/cljs/status_im/test/runner.cljs +++ b/test/cljs/status_im/test/runner.cljs @@ -37,6 +37,7 @@ [status-im.test.utils.utils] [status-im.test.utils.money] [status-im.test.utils.clocks] + [status-im.test.utils.ethereum.eip55] [status-im.test.utils.ethereum.eip681] [status-im.test.utils.ethereum.core] [status-im.test.utils.ethereum.abi-spec] @@ -107,6 +108,7 @@ 'status-im.test.utils.utils 'status-im.test.utils.money 'status-im.test.utils.clocks + 'status-im.test.utils.ethereum.eip55 'status-im.test.utils.ethereum.eip681 'status-im.test.utils.ethereum.core 'status-im.test.utils.ethereum.mnemonic diff --git a/test/cljs/status_im/test/utils/ethereum/eip55.cljs b/test/cljs/status_im/test/utils/ethereum/eip55.cljs new file mode 100644 index 0000000000..4b53068bed --- /dev/null +++ b/test/cljs/status_im/test/utils/ethereum/eip55.cljs @@ -0,0 +1,16 @@ +(ns status-im.test.utils.ethereum.eip55 + (:require [cljs.test :refer-macros [deftest is testing]] + [status-im.utils.ethereum.eip55 :as eip55])) + +(deftest valid-address-checksum? + (is (= true (eip55/valid-address-checksum? "0x52908400098527886E0F7030069857D2E4169EE7"))) + (is (= true (eip55/valid-address-checksum? "0x8617E340B3D01FA5F11F306F4090FD50E238070D"))) + (is (= true (eip55/valid-address-checksum? "0xde709f2102306220921060314715629080e2fb77"))) + (is (= true (eip55/valid-address-checksum? "0x27b1fdb04752bbc536007a920d24acb045561c26"))) + (is (= true (eip55/valid-address-checksum? "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"))) + (is (= true (eip55/valid-address-checksum? "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359"))) + (is (= true (eip55/valid-address-checksum? "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB"))) + (is (= true (eip55/valid-address-checksum? "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb"))) + (is (= false (eip55/valid-address-checksum? "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9adB"))) + (is (= false (eip55/valid-address-checksum? "0x8617e340b3d01fa5f11f306f4090fd50e238070d"))) + (is (= false (eip55/valid-address-checksum? "0xDE709F2102306220921060314715629080E2fB77")))) \ No newline at end of file diff --git a/translations/en.json b/translations/en.json index a03c0f57b6..8f83844b01 100644 --- a/translations/en.json +++ b/translations/en.json @@ -115,6 +115,7 @@ "empty-chat-description": "There are no messages \nin this chat yet", "camera-access-error": "To grant the required camera permission, please go to your system settings and make sure that Status > Camera is selected.", "wallet-invalid-address": "Invalid address: \n {{data}}", + "wallet-invalid-address-checksum": "Error in address: \n {{data}}", "welcome-to-status": "Welcome to Status", "cryptokitty-name": "CryptoKitty #{{id}}", "address-explication": "Your public key is used to generate your address on Ethereum and is a series of numbers and letters. You can find it easily in your profile",