forked from Deeptiman/blockreader
/
get_transaction.go
199 lines (161 loc) · 5.43 KB
/
get_transaction.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package blockreader
import (
"crypto/sha256"
"encoding/hex"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/pkg/errors"
)
func GetTransactionJson(chaincodeActionPayload *peer.ChaincodeActionPayload) (Transaction, error) {
/*
type TransactionAction struct {
Header []byte
Payload []byte
}
*/
// Payload field is marshalled object of ChaincodeActionPayload
/*
type ChaincodeActionPayload struct {
ChaincodeProposalPayload []byte
Action *ChaincodeEndorsedAction
}
*/
// 1. ChaincodeProposalPayload
chaincodeProposalPayloadJson, err := GetChainCodeProposalPayload(chaincodeActionPayload)
if err != nil {
return Transaction{}, errors.WithMessage(err, "chaincode proposal payload error: ")
}
// 2. ChaincodeEndorsedAction
chaincodeEndorsedActionJson, err := GetChainCodeEndorsedAction(chaincodeActionPayload)
if err != nil {
return Transaction{}, errors.WithMessage(err, "chaincode endorse action error: ")
}
transactionJson := Transaction{
ChaincodeProposalPayload: chaincodeProposalPayloadJson,
ChaincodeEndorsedAction: chaincodeEndorsedActionJson,
}
return transactionJson, nil
}
func GetChainCodeProposalPayload(chaincodeActionPayload *peer.ChaincodeActionPayload) (ChaincodeProposalPayload, error) {
/*
type ChaincodeProposalPayload struct {
Input []byte
TransientMap map[string][]byte
}
*/
chaincodeProposalPayload := &peer.ChaincodeProposalPayload{}
err := proto.Unmarshal(chaincodeActionPayload.ChaincodeProposalPayload, chaincodeProposalPayload)
if err != nil {
return ChaincodeProposalPayload{}, errors.WithMessage(err, "unmarshaling Chaincode Proposal Payload error: ")
}
// The Input field is marshalled object of ChaincodeInvocationSpec
input := &peer.ChaincodeInvocationSpec{}
err = proto.Unmarshal(chaincodeProposalPayload.Input, input)
if err != nil {
return ChaincodeProposalPayload{}, errors.WithMessage(err, "unmarshaling Chaincode Proposal Payload Input error: ")
}
/*
type ChaincodeInvocationSpec struct {
ChaincodeSpec *ChaincodeSpec
}
type ChaincodeSpec struct {
Type ChaincodeSpec_Type
ChaincodeId *ChaincodeID
Input *ChaincodeInput
Timeout int32
}
type ChaincodeInput struct {
Args [][]byte
Decorations map[string][]byte
}
*/
if input.ChaincodeSpec == nil || input.ChaincodeSpec.Input == nil {
return ChaincodeProposalPayload{
ChaincodeInvocationSpec: ChaincodeInvocationSpec{
ChaincodeSpec: ChaincodeSpec{
ChaincodeId: "",
ChaincodeType: "",
ChaincodeArgs: []string{},
},
},
}, nil
}
chaincodeArgs := make([]string, len(input.ChaincodeSpec.Input.Args))
for i, c := range input.ChaincodeSpec.Input.Args {
args := CToGoString(c[:])
chaincodeArgs[i] = args
}
ChaincodeType := [5]string{"UNDEFINED", "GOLANG", "NODE", "CAR", "JAVA"}
chaincodeSpecJson := ChaincodeSpec{
ChaincodeId: input.ChaincodeSpec.ChaincodeId.Name,
ChaincodeType: ChaincodeType[input.ChaincodeSpec.Type],
ChaincodeArgs: chaincodeArgs,
}
chaincodeInvocationSpecJson := ChaincodeInvocationSpec{
ChaincodeSpec: chaincodeSpecJson,
}
chaincodeProposalPayloadJson := ChaincodeProposalPayload{
ChaincodeInvocationSpec: chaincodeInvocationSpecJson,
}
return chaincodeProposalPayloadJson, nil
}
func GetChainCodeEndorsedAction(chaincodeActionPayload *peer.ChaincodeActionPayload) (ChaincodeEndorsedAction, error) {
/*
type ChaincodeEndorsedAction struct {
ProposalResponsePayload []byte
Endorsements []*Endorsement
}
*/
// ProposalResponsePayload field is the marshalled object of ProposalResponsePayload
/*
type ProposalResponsePayload struct {
ProposalHash []byte
Extension []byte
}
*/
proposalResponsePayload := &peer.ProposalResponsePayload{}
err := proto.Unmarshal(chaincodeActionPayload.Action.ProposalResponsePayload, proposalResponsePayload)
if err != nil {
return ChaincodeEndorsedAction{}, errors.WithMessage(err, "unmarshaling Proposal Response Payload error: ")
}
proposalHash := sha256.Sum256(proposalResponsePayload.ProposalHash)
// Extension is the marshalled object of ChaincodeAction
/*
type ChaincodeAction struct {
Results []byte
Events []byte
Response *Response
}
*/
chaincodeAction := &peer.ChaincodeAction{}
err = proto.Unmarshal(proposalResponsePayload.Extension, chaincodeAction)
if err != nil {
return ChaincodeEndorsedAction{}, errors.WithMessage(err, "unmarshaling Extension error: ")
}
chaincodeKVRWSetJson, err := GetKVRWSetJson(chaincodeAction)
if err != nil {
return ChaincodeEndorsedAction{}, errors.WithMessage(err, "failed to get KVRWSet Json error: ")
}
//Events
chaincodeEvent := &peer.ChaincodeEvent{}
err = proto.Unmarshal(chaincodeAction.Events, chaincodeEvent)
if err != nil {
return ChaincodeEndorsedAction{}, errors.WithMessage(err, "unmarshaling Chaincode Events error: ")
}
eventPayload := CToGoString(chaincodeEvent.Payload[:])
chaincodeEventJson := ChaincodeEvents{
ChaincodeId: chaincodeEvent.ChaincodeId,
TxId: chaincodeEvent.TxId,
EventName: chaincodeEvent.EventName,
Payload: eventPayload,
}
proposalResponsePayloadJson := ProposalResponsePayload{
ProposalHash: hex.EncodeToString(proposalHash[:]),
ChaincodeKVRWSet: chaincodeKVRWSetJson,
ChaincodeEvents: chaincodeEventJson,
}
chaincodeEndorsedActionJson := ChaincodeEndorsedAction{
ProposalResponsePayload: proposalResponsePayloadJson,
}
return chaincodeEndorsedActionJson, nil
}