From ee4cafbbe3a3f4afc26e4cd4456ce85ffd4b7582 Mon Sep 17 00:00:00 2001 From: Julien Eluard Date: Tue, 20 Nov 2018 16:07:36 +0100 Subject: [PATCH] [Fixes #6784] Fixed some ABI codec issues Signed-off-by: Julien Eluard --- src/status_im/extensions/ethereum.cljs | 4 ++-- src/status_im/utils/ethereum/abi_spec.cljs | 19 +++++++++---------- .../test/utils/ethereum/abi_spec.cljs | 15 +++++++++++++-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/status_im/extensions/ethereum.cljs b/src/status_im/extensions/ethereum.cljs index e07a4bade4..dfcda4e650 100644 --- a/src/status_im/extensions/ethereum.cljs +++ b/src/status_im/extensions/ethereum.cljs @@ -51,7 +51,7 @@ (handlers/register-handler-fx :extensions/ethereum-send-transaction - (fn [{db :db} [_ {:keys [method params on-result] :as arguments}]] + (fn [{db :db} [_ _ {:keys [method params on-result] :as arguments}]] (let [tx-object (assoc (select-keys arguments [:to :gas :gas-price :value :nonce]) :data (when (and method params) (abi-spec/encode method params))) transaction (prepare-extension-transaction tx-object (:contacts/contacts db) on-result)] @@ -59,7 +59,7 @@ (handlers/register-handler-fx :extensions/ethereum-call - (fn [_ [_ {:keys [to method params outputs on-result]}]] + (fn [_ [_ _ {:keys [to method params outputs on-result]}]] (let [tx-object {:to to :data (when method (abi-spec/encode method params))}] {:browser/call-rpc [{"jsonrpc" "2.0" "method" "eth_call" diff --git a/src/status_im/utils/ethereum/abi_spec.cljs b/src/status_im/utils/ethereum/abi_spec.cljs index 874871d1ef..09365baa64 100644 --- a/src/status_im/utils/ethereum/abi_spec.cljs +++ b/src/status_im/utils/ethereum/abi_spec.cljs @@ -38,7 +38,7 @@ (.hexToUtf8 utils (str "0x" x))) (defn hex-to-number [x] - (.hexToNumber utils (str "0x" x))) + (.toNumber (dependencies/Web3.prototype.toBigNumber (str "0x" x) 16))) (defn sha3 [s] (.sha3 utils (str s))) @@ -59,21 +59,20 @@ ;; higher-order (left) side with 0xff for negative X and with zero bytes for ;; positive X such that the length is 32 bytes. (defmethod enc :int - [{:keys [value] - :or {size 256}}] + [{:keys [value]}] (to-two-complement value)) ;; uint: enc(X) is the big-endian encoding of X, padded on the ;; higher-order (left) side with zero-bytes such that the length is 32 bytes. (defmethod enc :uint - [{:keys [value] - :or {size 256}}] + [{:keys [value]}] (left-pad (number-to-hex value))) ;; address: as in the uint160 case (defmethod enc :address [{:keys [value]}] - (right-pad value)) + (when value + (left-pad (string/replace value "0x" "")))) ;; bytes, of length k (which is assumed to be of type uint256): ;; enc(X) = enc(k) pad_right(X), i.e. the number of bytes is encoded as a @@ -85,7 +84,7 @@ (defmethod enc :bytes [{:keys [value size dynamic?] :or {size 256}}] - ;; in the exemples of the abi specifications strings are passed for + ;; in the examples of the abi specifications strings are passed for ;; bytes parameters, in our ens resolver we pass encoded bytes directly ;; for namehash, this handles both cases by checking if the value is already ;; hex @@ -160,9 +159,9 @@ (defmethod enc :tuple [{:keys [value]}] (let [[len x] (reduce - (fn [[len acc] {:keys [type value] :as x}] + (fn [[len acc] {:keys [dynamic?] :as x}] (let [enc-x (enc x)] - (if (:dynamic? x) + (if dynamic? [(+ len 32) (conj acc (assoc x :tail enc-x))] [(+ len (/ (count enc-x) 2)) @@ -386,4 +385,4 @@ (defn decode [bytes types] (let [offsets (get-offsets types)] - (map (dec-type bytes) offsets types))) \ No newline at end of file + (map (dec-type bytes) offsets types))) diff --git a/test/cljs/status_im/test/utils/ethereum/abi_spec.cljs b/test/cljs/status_im/test/utils/ethereum/abi_spec.cljs index 873f14510b..65e46d90f2 100644 --- a/test/cljs/status_im/test/utils/ethereum/abi_spec.cljs +++ b/test/cljs/status_im/test/utils/ethereum/abi_spec.cljs @@ -16,7 +16,10 @@ "0x8be6524600000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000")) (is (= (abi-spec/encode "g(uint[][],string[])" [[[1 2] [3]] ["one" "two" "three"]]) - "0xad6a3446000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000036f6e650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000374776f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057468726565000000000000000000000000000000000000000000000000000000"))) + "0xad6a3446000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000036f6e650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000374776f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057468726565000000000000000000000000000000000000000000000000000000")) + + (is (= (abi-spec/encode "getExpectedRate(address,address,uint256)" ["0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" 1000]) + "0x809a9e55000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000003e8"))) (deftest test-decode (is (= (abi-spec/decode "000000000000000000000000000000000000000000000000000000005bc741cd00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000013b86dbf1a83c9e6a492914a0ee39e8a5b7eb60700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d533152484e4a57414b356e426f6f57454d34654d644268707a35666e325764557473457357754a4b79356147000000000000000000000000000000000000" @@ -27,6 +30,14 @@ 0 0))) + (is (= (abi-spec/decode "0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000d7621dc58210000" + ["uint256" "uint256"]) + '(1000000000000000000 970000000000000000))) + + (is (= (abi-spec/decode "000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000003e8" + ["address" "address" "uint256"]) + '("0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" 1000))) + (is (= (abi-spec/decode "00000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001" ["uint32" "bool"]) '(69 true))) @@ -42,4 +53,4 @@ (is (= (abi-spec/decode "00000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000" ["uint" "uint32[]" "bytes10" "bytes"]) - '(291 [1110 1929] "31323334353637383930" "0x48656c6c6f2c20776f726c6421")))) \ No newline at end of file + '(291 [1110 1929] "31323334353637383930" "0x48656c6c6f2c20776f726c6421"))))