[refactor] add check in abi-spec decode and expect a hex string

Signed-off-by: yenda <eric@status.im>
This commit is contained in:
yenda 2019-03-28 08:59:48 +01:00
parent 9aea669da3
commit a6616033f4
No known key found for this signature in database
GPG Key ID: 0095623C0069DCE6
4 changed files with 43 additions and 30 deletions

View File

@ -26,11 +26,13 @@
(fn [_ [_ on-failure message]] (fn [_ [_ on-failure message]]
(when on-failure (on-failure {:value message})))) (when on-failure (on-failure {:value message}))))
(defn- wrap-with-resolution [db arguments address-keyword f] (defn- wrap-with-resolution
"function responsible to resolve ens taken from argument "function responsible to resolve ens taken from argument
and call the specified function with resolved address" and call the specified function with resolved address"
[db arguments address-keyword f]
(let [address (get arguments address-keyword) (let [address (get arguments address-keyword)
first-address (if (vector? address) ;; currently we only support one ens for address ;; currently we only support one ens for address
first-address (if (vector? address)
(first address) (first address)
address)] address)]
(if (ens/is-valid-eth-name? first-address) (if (ens/is-valid-eth-name? first-address)
@ -100,7 +102,7 @@
(cond (cond
(= "0x" result) nil (= "0x" result) nil
(and outputs result) (and outputs result)
(abi-spec/decode (string/replace result #"^0x" "") outputs) (abi-spec/decode result outputs)
:else result))) :else result)))
(defn- execute-ethcall [_ {:keys [to method params outputs on-success on-failure]}] (defn- execute-ethcall [_ {:keys [to method params outputs on-success on-failure]}]
@ -236,38 +238,47 @@
(let [eventid (str event "(" (string/join "," params) ")")] (let [eventid (str event "(" (string/join "," params) ")")]
(abi-spec/sha3 eventid))) (abi-spec/sha3 eventid)))
; Return a vector without indexed elements (defn- get-no-indexed
(defn- get-no-indexed [X indexed] "Return a vector without indexed elements"
[X indexed]
(as-> (into [] (take (count X) (range))) $ (as-> (into [] (take (count X) (range))) $
(zipmap $ X) (zipmap $ X)
(into [] (vals (apply dissoc $ indexed))))) (into [] (vals (apply dissoc $ indexed)))))
; Return a vector with indexed elements (defn- get-indexed
(defn- get-indexed [X indexed] "Return a vector with indexed elements"
[X indexed]
(let [keys (into [] (take (count X) (range)))] (let [keys (into [] (take (count X) (range)))]
(mapv #((zipmap keys X) %) indexed))) (mapv #((zipmap keys X) %) indexed)))
; Return the hint with the specified event (Topic0) from a vector of event hints given by the user (defn- get-hint
(defn- get-hint [hints first-topic] "Return the hint with the specified event (Topic0) from a vector of event hints given by the user"
[hints first-topic]
(as-> hints $ (as-> hints $
(mapv #(event-topic-enc (% :event) (% :params)) $) (mapv #(event-topic-enc (% :event) (% :params)) $)
(.indexOf $ first-topic) (.indexOf $ first-topic)
(get hints $))) (get hints $)))
; Return a map with all data params decoded (defn- decode-data
(defn- decode-data [data hint] "Return a map with all data params decoded"
[data hint]
(let [indexes (hint :indexed) (let [indexes (hint :indexed)
params (get-no-indexed (hint :params) indexes) params (get-no-indexed (hint :params) indexes)
names (mapv keyword (get-no-indexed (hint :names) indexes)) ; Exclude indexed params and names from decode in data, these are decoded in topics ;; Exclude indexed params and names from decode in data,
;; these are decoded in topics
names (mapv keyword (get-no-indexed (hint :names) indexes))
data-values (mapv (partial apply str) (partition 64 (string/replace-first data #"0x" "")))] data-values (mapv (partial apply str) (partition 64 (string/replace-first data #"0x" "")))]
(zipmap names (mapv abi-spec/hex-to-value data-values params)))) (zipmap names (mapv abi-spec/hex-to-value data-values params))))
; This assumes that Topic 0 is filtered and return a map with all topics decoded (defn- decode-topics
(defn- decode-topics [topics hint] "This assumes that Topic 0 is filtered and return a map with all topics decoded"
(zipmap [:topic1 :topic2 :topic3] (mapv abi-spec/hex-to-value topics (get-indexed (hint :params) (hint :indexed))))) ; Solidity indexed event params may number up to 3 (max 4 Topics) [topics hint]
;; Solidity indexed event params may number up to 3 (max 4 Topics)
(zipmap [:topic1 :topic2 :topic3] (mapv abi-spec/hex-to-value topics (get-indexed (hint :params) (hint :indexed)))))
; Flatten the input of event provided by an developer of extensions and return a 1 depth vector (defn- flatten-input
(defn- flatten-input [input] "Flatten the input of event provided by an developer of extensions and return a 1 depth vector"
[input]
(into [] (flatten input))) (into [] (flatten input)))
(defn parse-log [events-hints {:keys [address transactionHash blockHash transactionIndex topics blockNumber logIndex removed data]}] (defn parse-log [events-hints {:keys [address transactionHash blockHash transactionIndex topics blockNumber logIndex removed data]}]
@ -276,7 +287,7 @@
:address address :address address
:removed removed} :removed removed}
; filter useless topic 0 and decode topics ;; filter useless topic 0 and decode topics
(when (and topics (seq events-hints)) {:topics (decode-topics (filterv #(not (= (first topics) %)) topics) (get-hint events-hints (first topics)))}) (when (and topics (seq events-hints)) {:topics (decode-topics (filterv #(not (= (first topics) %)) topics) (get-hint events-hints (first topics)))})
(when (and data (seq events-hints)) {:data (decode-data data (get-hint events-hints (first topics)))}) (when (and data (seq events-hints)) {:data (decode-data data (get-hint events-hints (first topics)))})
(when logIndex {:log-index (abi-spec/hex-to-number logIndex)}) (when logIndex {:log-index (abi-spec/hex-to-number logIndex)})

View File

@ -386,6 +386,8 @@
(hex-to-value val type))))) (hex-to-value val type)))))
(defn decode [bytes types] (defn decode [bytes types]
(when-not (empty? bytes) (when bytes
(let [offsets (get-offsets types)] (let [bytes (subs bytes 2)]
(map (dec-type bytes) offsets types)))) (when-not (empty? bytes)
(let [offsets (get-offsets types)]
(map (dec-type bytes) offsets types))))))

View File

@ -20,7 +20,7 @@
(ethereum/call web3 (ethereum/call web3
(ethereum/call-params contract "getPackData(uint256)" (ethereum/int->hex pack-id)) (ethereum/call-params contract "getPackData(uint256)" (ethereum/int->hex pack-id))
(fn [_ data] (fn [_ data]
(cb (when data (abi-spec/decode (subs data 2) ["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"])))))) (cb (abi-spec/decode data ["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"])))))
(defn owned-tokens (defn owned-tokens
"Returns vector of owned tokens ids in the contract by address" "Returns vector of owned tokens ids in the contract by address"
@ -28,7 +28,7 @@
(ethereum/call web3 (ethereum/call web3
(ethereum/call-params contract "tokensOwnedBy(address)" (ethereum/normalized-address address)) (ethereum/call-params contract "tokensOwnedBy(address)" (ethereum/normalized-address address))
(fn [_ data] (fn [_ data]
(cb (when data (first (abi-spec/decode (subs data 2) ["uint256[]"]))))))) (cb (first (abi-spec/decode data ["uint256[]"]))))))
(defn token-pack-id (defn token-pack-id
"Returns pack id in the contract by token id" "Returns pack id in the contract by token id"

View File

@ -25,7 +25,7 @@
"0x809a9e55000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000003e8"))) "0x809a9e55000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000003e8")))
(deftest test-decode (deftest test-decode
(is (= (abi-spec/decode "000000000000000000000000000000000000000000000000000000005bc741cd00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000013b86dbf1a83c9e6a492914a0ee39e8a5b7eb60700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d533152484e4a57414b356e426f6f57454d34654d644268707a35666e325764557473457357754a4b79356147000000000000000000000000000000000000" (is (= (abi-spec/decode "0x000000000000000000000000000000000000000000000000000000005bc741cd00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000013b86dbf1a83c9e6a492914a0ee39e8a5b7eb60700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d533152484e4a57414b356e426f6f57454d34654d644268707a35666e325764557473457357754a4b79356147000000000000000000000000000000000000"
["uint256" "bytes" "address" "uint256" "uint256"]) ["uint256" "bytes" "address" "uint256" "uint256"])
'(1539785165 '(1539785165
"0x516d533152484e4a57414b356e426f6f57454d34654d644268707a35666e325764557473457357754a4b79356147" "0x516d533152484e4a57414b356e426f6f57454d34654d644268707a35666e325764557473457357754a4b79356147"
@ -33,27 +33,27 @@
0 0
0))) 0)))
(is (= (abi-spec/decode "0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000d7621dc58210000" (is (= (abi-spec/decode "0x0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000d7621dc58210000"
["uint256" "uint256"]) ["uint256" "uint256"])
'(1000000000000000000 970000000000000000))) '(1000000000000000000 970000000000000000)))
(is (= (abi-spec/decode "000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000003e8" (is (= (abi-spec/decode "0x000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000003e8"
["address" "address" "uint256"]) ["address" "address" "uint256"])
'("0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" 1000))) '("0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" 1000)))
(is (= (abi-spec/decode "00000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001" (is (= (abi-spec/decode "0x00000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001"
["uint32" "bool"]) ["uint32" "bool"])
'(69 true))) '(69 true)))
(is (= (map abi-spec/hex-to-utf8 (is (= (map abi-spec/hex-to-utf8
(first (abi-spec/decode "61626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000" (first (abi-spec/decode "0x61626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000"
["bytes3[2]"]))) ["bytes3[2]"])))
'("abc" "def"))) '("abc" "def")))
(is (= (abi-spec/decode "0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003" (is (= (abi-spec/decode "0x0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"
["string" "bool" "uint256[]"]) ["string" "bool" "uint256[]"])
'("dave" true [1 2 3]))) '("dave" true [1 2 3])))
(is (= (abi-spec/decode "00000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000" (is (= (abi-spec/decode "0x00000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000"
["uint" "uint32[]" "bytes10" "bytes"]) ["uint" "uint32[]" "bytes10" "bytes"])
'(291 [1110 1929] "31323334353637383930" "0x48656c6c6f2c20776f726c6421")))) '(291 [1110 1929] "31323334353637383930" "0x48656c6c6f2c20776f726c6421"))))