[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]]
(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
and call the specified function with resolved address"
[db arguments address-keyword f]
(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)
address)]
(if (ens/is-valid-eth-name? first-address)
@ -100,7 +102,7 @@
(cond
(= "0x" result) nil
(and outputs result)
(abi-spec/decode (string/replace result #"^0x" "") outputs)
(abi-spec/decode result outputs)
:else result)))
(defn- execute-ethcall [_ {:keys [to method params outputs on-success on-failure]}]
@ -236,38 +238,47 @@
(let [eventid (str event "(" (string/join "," params) ")")]
(abi-spec/sha3 eventid)))
; Return a vector without indexed elements
(defn- get-no-indexed [X indexed]
(defn- get-no-indexed
"Return a vector without indexed elements"
[X indexed]
(as-> (into [] (take (count X) (range))) $
(zipmap $ X)
(into [] (vals (apply dissoc $ indexed)))))
; Return a vector with indexed elements
(defn- get-indexed [X indexed]
(defn- get-indexed
"Return a vector with indexed elements"
[X indexed]
(let [keys (into [] (take (count X) (range)))]
(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 [hints first-topic]
(defn- get-hint
"Return the hint with the specified event (Topic0) from a vector of event hints given by the user"
[hints first-topic]
(as-> hints $
(mapv #(event-topic-enc (% :event) (% :params)) $)
(.indexOf $ first-topic)
(get hints $)))
; Return a map with all data params decoded
(defn- decode-data [data hint]
(defn- decode-data
"Return a map with all data params decoded"
[data hint]
(let [indexes (hint :indexed)
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" "")))]
(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 [topics hint]
(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)
(defn- decode-topics
"This assumes that Topic 0 is filtered and return a map with all topics decoded"
[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 [input]
(defn- flatten-input
"Flatten the input of event provided by an developer of extensions and return a 1 depth vector"
[input]
(into [] (flatten input)))
(defn parse-log [events-hints {:keys [address transactionHash blockHash transactionIndex topics blockNumber logIndex removed data]}]
@ -276,7 +287,7 @@
:address address
: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 data (seq events-hints)) {:data (decode-data data (get-hint events-hints (first topics)))})
(when logIndex {:log-index (abi-spec/hex-to-number logIndex)})

View File

@ -386,6 +386,8 @@
(hex-to-value val type)))))
(defn decode [bytes types]
(when-not (empty? bytes)
(let [offsets (get-offsets types)]
(map (dec-type bytes) offsets types))))
(when bytes
(let [bytes (subs bytes 2)]
(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-params contract "getPackData(uint256)" (ethereum/int->hex pack-id))
(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
"Returns vector of owned tokens ids in the contract by address"
@ -28,7 +28,7 @@
(ethereum/call web3
(ethereum/call-params contract "tokensOwnedBy(address)" (ethereum/normalized-address address))
(fn [_ data]
(cb (when data (first (abi-spec/decode (subs data 2) ["uint256[]"])))))))
(cb (first (abi-spec/decode data ["uint256[]"]))))))
(defn token-pack-id
"Returns pack id in the contract by token id"

View File

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