-
Notifications
You must be signed in to change notification settings - Fork 2
/
parity.go
88 lines (75 loc) · 1.57 KB
/
parity.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package parity
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
"github.com/spf13/viper"
)
type jsonrpcResponse struct {
JSONRPC string
Result execTrace
ID int
}
type execTrace struct {
Trace []interface{}
StateDiff interface{}
Output string
VMTrace VMTrace
}
type VMTrace struct {
Ops []traceOperation
Code string
}
type traceOperation struct {
Cost int
PC int
Sub interface{}
Ex execTraceOpEx
}
type execTraceOpEx struct {
Push []string
Mem interface{}
Used int
Store interface{}
}
func GetExecTrace(txnHash string) (VMTrace, error) {
resp, err := http.Post(
viper.GetString("blockchain_client"),
"application/json",
strings.NewReader(
fmt.Sprintf(
`{
"jsonrpc": "2.0",
"method": "trace_replayTransaction",
"params": [
%q,
["vmTrace"]
],
"id": 1
}`,
txnHash,
),
),
)
if err != nil {
return VMTrace{}, err
}
defer resp.Body.Close()
var execTraceResponse jsonrpcResponse
err = json.NewDecoder(resp.Body).Decode(&execTraceResponse)
if err != nil {
return VMTrace{}, err
}
if execTraceResponse.Result.Output == "" {
return execTraceResponse.Result.VMTrace, errors.New("Transaction ID not found.")
}
if execTraceResponse.Result.VMTrace.Code == "0x" {
return execTraceResponse.Result.VMTrace, errors.New("Transaction has no associated bytecode.")
}
if len(execTraceResponse.Result.VMTrace.Ops) == 0 {
return execTraceResponse.Result.VMTrace, errors.New("Transaction has no execution trace steps.")
}
return execTraceResponse.Result.VMTrace, nil
}