fabric-gateway 0.2.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/codeql-analysis.yml +71 -0
- data/.github/workflows/rubocop.yml +1 -1
- data/.github/workflows/todo.yml +10 -0
- data/.github/workflows/yardoc.yml +28 -0
- data/.yardopts +8 -0
- data/README.md +45 -20
- data/Rakefile +1 -0
- data/fabric-gateway.gemspec +5 -3
- data/lib/fabric/accessors/contract.rb +51 -0
- data/lib/fabric/accessors/gateway.rb +33 -0
- data/lib/fabric/accessors/network.rb +40 -0
- data/lib/fabric/client.rb +89 -24
- data/lib/fabric/contract.rb +41 -26
- data/lib/fabric/ec_crypto_suite.rb +1 -1
- data/lib/fabric/entities/chaincode_events_requests.rb +166 -0
- data/lib/fabric/entities/envelope.rb +158 -0
- data/lib/fabric/{identity.rb → entities/identity.rb} +2 -2
- data/lib/fabric/{proposal.rb → entities/proposal.rb} +41 -34
- data/lib/fabric/{proposed_transaction.rb → entities/proposed_transaction.rb} +4 -28
- data/lib/fabric/entities/status.rb +32 -0
- data/lib/fabric/entities/transaction.rb +247 -0
- data/lib/fabric/network.rb +29 -20
- data/lib/fabric/version.rb +1 -1
- data/lib/fabric.rb +24 -9
- metadata +48 -10
data/lib/fabric/contract.rb
CHANGED
@@ -25,28 +25,16 @@ module Fabric
|
|
25
25
|
class Contract
|
26
26
|
attr_reader :network, :chaincode_name, :contract_name
|
27
27
|
|
28
|
+
# @!parse include Fabric::Accessors::Network
|
29
|
+
# @!parse include Fabric::Accessors::Gateway
|
30
|
+
include Fabric::Accessors::Network
|
31
|
+
|
28
32
|
def initialize(network, chaincode_name, contract_name = '')
|
29
33
|
@network = network
|
30
34
|
@chaincode_name = chaincode_name
|
31
35
|
@contract_name = contract_name
|
32
36
|
end
|
33
37
|
|
34
|
-
def client
|
35
|
-
network.client
|
36
|
-
end
|
37
|
-
|
38
|
-
def signer
|
39
|
-
network.signer
|
40
|
-
end
|
41
|
-
|
42
|
-
def gateway
|
43
|
-
network.gateway
|
44
|
-
end
|
45
|
-
|
46
|
-
def network_name
|
47
|
-
network.name
|
48
|
-
end
|
49
|
-
|
50
38
|
#
|
51
39
|
# Evaluate a transaction function and return its results. A transaction proposal will be evaluated on endorsing
|
52
40
|
# peers but the transaction will not be sent to the ordering service and so will not be committed to the ledger.
|
@@ -66,7 +54,6 @@ module Fabric
|
|
66
54
|
# transaction function will be evaluated on endorsing peers and then submitted to the ordering service to be
|
67
55
|
# committed to the ledger.
|
68
56
|
#
|
69
|
-
# @TODO: Not yet complete
|
70
57
|
#
|
71
58
|
# @param [String] transaction_name
|
72
59
|
# @param [Array] arguments array of arguments to pass to the transaction
|
@@ -102,8 +89,6 @@ module Fabric
|
|
102
89
|
# transaction function will be evaluated on endorsing peers and then submitted to the ordering service to be
|
103
90
|
# committed to the ledger.
|
104
91
|
#
|
105
|
-
# @TODO: Implement Me! - LEFT OFF HERE!
|
106
|
-
#
|
107
92
|
# @param [String] transaction_name
|
108
93
|
# @param [Hash] proposal_options
|
109
94
|
# @option proposal_options [Array] :arguments array of arguments to pass to the transaction
|
@@ -116,17 +101,15 @@ module Fabric
|
|
116
101
|
#
|
117
102
|
def submit(transaction_name, proposal_options = {})
|
118
103
|
transaction = new_proposal(transaction_name, **proposal_options).endorse
|
119
|
-
|
120
|
-
|
121
|
-
status = submitted.get_status
|
104
|
+
transaction.submit
|
122
105
|
|
123
|
-
|
106
|
+
transaction.result
|
124
107
|
end
|
125
108
|
|
126
109
|
#
|
127
|
-
# @
|
128
|
-
#
|
129
|
-
#
|
110
|
+
# @todo unimplemented, not sure if this can be implemented because
|
111
|
+
# the official grpc ruby client does not support non-blocking async
|
112
|
+
# calls (https://github.com/grpc/grpc/issues/10973)
|
130
113
|
#
|
131
114
|
# not 100% sure if grpc support is necessary for this.
|
132
115
|
#
|
@@ -134,6 +117,30 @@ module Fabric
|
|
134
117
|
raise NotYetImplemented
|
135
118
|
end
|
136
119
|
|
120
|
+
#
|
121
|
+
# Get chaincode events emitted by transaction functions of the chaincode.
|
122
|
+
#
|
123
|
+
# @see Fabric::Client#chaincode_events Fabric::Client#chaincode_events - explanation of the different return types
|
124
|
+
# and example usage.
|
125
|
+
# @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:server_streamer Call options for options parameter
|
126
|
+
#
|
127
|
+
# @param [Integer] start_block Block number at which to start reading chaincode events.
|
128
|
+
# @param [Hash] call_options gRPC call options (merged with default_call_options from initializer)
|
129
|
+
# @yield [chaincode_event] loops through the chaincode events
|
130
|
+
# @yieldparam [Gateway::ChaincodeEventsResponse] chaincode_event the chaincode event
|
131
|
+
#
|
132
|
+
# @return [Enumerator|GRPC::ActiveCall::Operation|nil] Dependent on parameters passed;
|
133
|
+
# please see Fabric::Client#get_chaincode_events
|
134
|
+
#
|
135
|
+
def chaincode_events(start_block: nil, call_options: {}, &block)
|
136
|
+
network.chaincode_events(
|
137
|
+
self,
|
138
|
+
start_block: start_block,
|
139
|
+
call_options: call_options,
|
140
|
+
&block
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
137
144
|
#
|
138
145
|
# Creates a transaction proposal that can be evaluated or endorsed. Supports off-line signing flow.
|
139
146
|
#
|
@@ -156,6 +163,14 @@ module Fabric
|
|
156
163
|
Proposal.new(proposed_transaction)
|
157
164
|
end
|
158
165
|
|
166
|
+
#
|
167
|
+
# Generates the qualified transaction name for the contract. (prepends the contract name to the transaction name if
|
168
|
+
# contract name is set)
|
169
|
+
#
|
170
|
+
# @param [string] transaction_name
|
171
|
+
#
|
172
|
+
# @return [string] qualified transaction name
|
173
|
+
#
|
159
174
|
def qualified_transaction_name(transaction_name)
|
160
175
|
contract_name.nil? || contract_name.empty? ? transaction_name : "#{contract_name}:#{transaction_name}"
|
161
176
|
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fabric
|
4
|
+
#
|
5
|
+
# Encapsulates a Chaincode Events Request protobuf message
|
6
|
+
#
|
7
|
+
class ChaincodeEventsRequest
|
8
|
+
attr_reader :contract,
|
9
|
+
:start_block
|
10
|
+
|
11
|
+
# @!parse include Fabric::Accessors::Network
|
12
|
+
# @!parse include Fabric::Accessors::Gateway
|
13
|
+
include Fabric::Accessors::Contract
|
14
|
+
|
15
|
+
#
|
16
|
+
# Creates a new ChaincodeEventsRequest
|
17
|
+
#
|
18
|
+
# @param [Fabric::Contract] contract an instance of a contract
|
19
|
+
# @param [Integer] start_block Block number at which to start reading chaincode events.
|
20
|
+
#
|
21
|
+
def initialize(contract, start_block: nil)
|
22
|
+
@contract = contract
|
23
|
+
@start_block = start_block
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Returns the signed request
|
28
|
+
#
|
29
|
+
# @return [Gateway::SignedChaincodeEventsRequest] generated signed request
|
30
|
+
#
|
31
|
+
def signed_request
|
32
|
+
@signed_request ||= ::Gateway::SignedChaincodeEventsRequest.new(request: chaincode_events_request.to_proto)
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Returns the chaincode events request
|
37
|
+
#
|
38
|
+
# @return [Gateway::ChaincodeEventsRequest] chaincode events request - controls what events are returned
|
39
|
+
# from a chaincode events request
|
40
|
+
#
|
41
|
+
def chaincode_events_request
|
42
|
+
@chaincode_events_request ||= new_chaincode_events_request
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Get the serialized chaincode events request protobuffer message.
|
47
|
+
#
|
48
|
+
# @return [String] protobuffer serialized chaincode events request
|
49
|
+
#
|
50
|
+
def request_bytes
|
51
|
+
signed_request.request
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Get the digest of the chaincode events request. This is used to generate a digital signature.
|
56
|
+
#
|
57
|
+
# @return [String] chaincode events request digest
|
58
|
+
#
|
59
|
+
def request_digest
|
60
|
+
Fabric.crypto_suite.digest(request_bytes)
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Sets the signed request signature.
|
65
|
+
#
|
66
|
+
# @param [String] signature
|
67
|
+
#
|
68
|
+
# @return [void]
|
69
|
+
#
|
70
|
+
def signature=(signature)
|
71
|
+
signed_request.signature = signature
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Returns the signed_request signature
|
76
|
+
#
|
77
|
+
# @return [String] Raw byte string signature
|
78
|
+
#
|
79
|
+
def signature
|
80
|
+
signed_request.signature
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Sign the chaincode events request; Noop if request already signed.
|
85
|
+
#
|
86
|
+
# @return [void]
|
87
|
+
#
|
88
|
+
def sign
|
89
|
+
return if signed?
|
90
|
+
|
91
|
+
self.signature = signer.sign(request_bytes)
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Checks if the signed chaincode events has been signed.
|
96
|
+
#
|
97
|
+
# @return [Boolean] true if the signed chaincode events has been signed; otherwise false.
|
98
|
+
#
|
99
|
+
def signed?
|
100
|
+
!signed_request.signature.empty?
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Get chaincode events emitted by transaction functions of a specific chaincode.
|
105
|
+
#
|
106
|
+
# @see Fabric::Client#chaincode_events Fabric::Client#chaincode_events - explanation of the different return types
|
107
|
+
# and example usage.
|
108
|
+
# @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:server_streamer Call options for options parameter
|
109
|
+
#
|
110
|
+
# @param [Hash] options gRPC call options (merged with default_call_options from initializer)
|
111
|
+
# @yield [chaincode_event] loops through the chaincode events
|
112
|
+
# @yieldparam [Gateway::ChaincodeEventsResponse] chaincode_event the chaincode event
|
113
|
+
#
|
114
|
+
# @return [Enumerator|GRPC::ActiveCall::Operation|nil] Dependent on parameters passed;
|
115
|
+
# please see Fabric::Client#get_chaincode_events
|
116
|
+
#
|
117
|
+
def get_events(options = {}, &block)
|
118
|
+
sign
|
119
|
+
|
120
|
+
client.chaincode_events(signed_request, options, &block)
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
#
|
126
|
+
# Generates a new chaincode events request
|
127
|
+
#
|
128
|
+
# @return [Gateway::ChaincodeEventsRequest] chaincode events request - controls what events are returned
|
129
|
+
#
|
130
|
+
def new_chaincode_events_request
|
131
|
+
::Gateway::ChaincodeEventsRequest.new(
|
132
|
+
channel_id: network_name,
|
133
|
+
chaincode_id: chaincode_name,
|
134
|
+
identity: signer.to_proto,
|
135
|
+
start_position: start_position
|
136
|
+
)
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Generates the start_position for the chaincode events request or returns the cached start_position
|
141
|
+
#
|
142
|
+
# @return [Orderer::SeekPosition] start position for the chaincode events request
|
143
|
+
#
|
144
|
+
def start_position
|
145
|
+
@start_position ||= new_start_position
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Generates the start position for the chaincode events request; if no start_block is specified,
|
150
|
+
# generates a seek next commit start position, otherwise generates a start_position to the start_block
|
151
|
+
#
|
152
|
+
# @return [Orderer::SeekPosition] start position for the chaincode events request
|
153
|
+
#
|
154
|
+
def new_start_position
|
155
|
+
specified = nil
|
156
|
+
next_commit = nil
|
157
|
+
|
158
|
+
if start_block
|
159
|
+
specified = ::Orderer::SeekSpecified.new(number: start_block)
|
160
|
+
else
|
161
|
+
next_commit = ::Orderer::SeekNextCommit.new
|
162
|
+
end
|
163
|
+
Orderer::SeekPosition.new(specified: specified, next_commit: next_commit)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fabric
|
4
|
+
#
|
5
|
+
# Encapsulates an Envelop protobuf message
|
6
|
+
#
|
7
|
+
class Envelope
|
8
|
+
# @return [Common::Envelope] transaction envelope
|
9
|
+
attr_reader :envelope
|
10
|
+
|
11
|
+
#
|
12
|
+
# Creates a new Envelope instance.
|
13
|
+
#
|
14
|
+
# @param [Common::Envelope] envelope
|
15
|
+
#
|
16
|
+
def initialize(envelope)
|
17
|
+
@envelope = envelope
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Checks if the envelope has been signed.
|
22
|
+
#
|
23
|
+
# @return [Boolean] true if the envelope has been signed; otherwise false.
|
24
|
+
#
|
25
|
+
def signed?
|
26
|
+
!envelope.signature.empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# The protobuffer serialized form of the envelope payload.
|
31
|
+
#
|
32
|
+
# @return [String] serialized payload
|
33
|
+
#
|
34
|
+
def payload_bytes
|
35
|
+
envelope.payload
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# The digest of the payload.
|
40
|
+
#
|
41
|
+
# @return [String] payload digest
|
42
|
+
#
|
43
|
+
def payload_digest
|
44
|
+
Fabric.crypto_suite.digest(envelope.payload)
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Sets the envelope signature.
|
49
|
+
#
|
50
|
+
# @param [String] signature
|
51
|
+
#
|
52
|
+
# @return [void]
|
53
|
+
#
|
54
|
+
def signature=(signature)
|
55
|
+
envelope.signature = signature
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Returns the results from the transaction result payload.
|
60
|
+
#
|
61
|
+
# @return [Payload] transaction result payload
|
62
|
+
#
|
63
|
+
def result
|
64
|
+
@result ||= parse_result_from_payload
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Returns the deserialized payload.
|
69
|
+
#
|
70
|
+
# @return [Common::Payload] Envelope payload
|
71
|
+
#
|
72
|
+
def payload
|
73
|
+
@payload ||= Common::Payload.decode(envelope.payload)
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Returns the envelope payload header.
|
78
|
+
#
|
79
|
+
# Envelope => Payload => Header
|
80
|
+
#
|
81
|
+
# @return [Common::Header] Envelope Payload Header
|
82
|
+
#
|
83
|
+
def header
|
84
|
+
raise Fabric::Error, 'Missing header' if payload.header.nil?
|
85
|
+
|
86
|
+
@header ||= payload.header
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# Returns the deserialized transaction channel header
|
91
|
+
#
|
92
|
+
# Envelope => Payload => Header => ChannelHeader
|
93
|
+
#
|
94
|
+
# @return [Common::ChannelHeader] envelop payload header channel header
|
95
|
+
#
|
96
|
+
def channel_header
|
97
|
+
@channel_header ||= Common::ChannelHeader.decode(header.channel_header)
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# Grabs the channel_name frmo the depths of the envelope.
|
102
|
+
#
|
103
|
+
# @return [String] channel name
|
104
|
+
#
|
105
|
+
def channel_name
|
106
|
+
channel_header.channel_id
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Returns the deserialized transaction
|
111
|
+
#
|
112
|
+
# @return [Protos::Transaction] transaction
|
113
|
+
#
|
114
|
+
def transaction
|
115
|
+
@transaction ||= Protos::Transaction.decode(payload.data)
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
#
|
121
|
+
# Parse the transaction actions from the payload looking for the transaction result payload.
|
122
|
+
#
|
123
|
+
# @return [String] result payload
|
124
|
+
# @raise [Fabric::Error] if the transaction result payload is not found
|
125
|
+
#
|
126
|
+
def parse_result_from_payload
|
127
|
+
errors = []
|
128
|
+
transaction.actions.each do |action|
|
129
|
+
return parse_result_from_transaction_action(action)
|
130
|
+
rescue Fabric::Error => e
|
131
|
+
errors << e
|
132
|
+
end
|
133
|
+
|
134
|
+
raise Fabric::Error, "No proposal response found: #{errors.inspect}"
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# Parse a single transaction action looking for the transaction result payload.
|
139
|
+
#
|
140
|
+
# @param [Protos::TransactionAction] transaction_action
|
141
|
+
#
|
142
|
+
# @return [Payload] transaction result payload
|
143
|
+
# @raise [Fabric::Error] if the endorsed_action is missing or the chaincode response is missing
|
144
|
+
#
|
145
|
+
def parse_result_from_transaction_action(transaction_action)
|
146
|
+
action_payload = Protos::ChaincodeActionPayload.decode(transaction_action.payload)
|
147
|
+
endorsed_action = action_payload.action
|
148
|
+
raise Fabric::Error, 'Missing endorsed action' if endorsed_action.nil?
|
149
|
+
|
150
|
+
response_payload = Protos::ProposalResponsePayload.decode(endorsed_action.proposal_response_payload)
|
151
|
+
chaincode_action = Protos::ChaincodeAction.decode(response_payload.extension)
|
152
|
+
chaincode_response = chaincode_action.response
|
153
|
+
raise Fabric::Error, 'Missing chaincode response' if chaincode_response.nil?
|
154
|
+
|
155
|
+
chaincode_response.payload
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -76,9 +76,9 @@ module Fabric
|
|
76
76
|
#
|
77
77
|
# Creates a new gateway passing in the current identity
|
78
78
|
#
|
79
|
-
# @param [
|
79
|
+
# @param [Fabric::Client] client
|
80
80
|
#
|
81
|
-
# @return [Fabric::Gateway]
|
81
|
+
# @return [Fabric::Gateway] gateway
|
82
82
|
#
|
83
83
|
def new_gateway(client)
|
84
84
|
Fabric::Gateway.new(self, client)
|
@@ -22,33 +22,7 @@ module Fabric
|
|
22
22
|
@proposed_transaction.contract
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
contract.network
|
27
|
-
end
|
28
|
-
|
29
|
-
def client
|
30
|
-
network.client
|
31
|
-
end
|
32
|
-
|
33
|
-
def signer
|
34
|
-
network.signer
|
35
|
-
end
|
36
|
-
|
37
|
-
def gateway
|
38
|
-
network.gateway
|
39
|
-
end
|
40
|
-
|
41
|
-
def network_name
|
42
|
-
network.name
|
43
|
-
end
|
44
|
-
|
45
|
-
def contract_name
|
46
|
-
contract.contract_name
|
47
|
-
end
|
48
|
-
|
49
|
-
def chaincode_name
|
50
|
-
contract.chaincode_name
|
51
|
-
end
|
25
|
+
include Fabric::Accessors::Contract
|
52
26
|
|
53
27
|
def transaction_id
|
54
28
|
proposed_transaction.transaction_id
|
@@ -96,7 +70,7 @@ module Fabric
|
|
96
70
|
# @return [String] raw binary digest of the proposal message.
|
97
71
|
#
|
98
72
|
def digest
|
99
|
-
|
73
|
+
Fabric.crypto_suite.digest(proposal.to_proto)
|
100
74
|
end
|
101
75
|
|
102
76
|
#
|
@@ -153,8 +127,22 @@ module Fabric
|
|
153
127
|
evaluate_response.result.payload
|
154
128
|
end
|
155
129
|
|
156
|
-
|
157
|
-
|
130
|
+
#
|
131
|
+
# Obtain endorsement for the transaction proposal from sufficient peers to allow it to be committed to the ledger.
|
132
|
+
#
|
133
|
+
# @param [Hash] options gRPC call options @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
|
134
|
+
#
|
135
|
+
# @return [Fabric::Transaction] An endorsed transaction that can be submitted to the ledger.
|
136
|
+
#
|
137
|
+
def endorse(options = {})
|
138
|
+
sign
|
139
|
+
endorse_response = client.endorse(new_endorse_request, options)
|
140
|
+
|
141
|
+
raise Fabric::Error, 'Missing transaction envelope' if endorse_response.prepared_transaction.nil?
|
142
|
+
|
143
|
+
prepared_transaction = new_prepared_transaction(endorse_response.prepared_transaction)
|
144
|
+
|
145
|
+
Fabric::Transaction.new(network, prepared_transaction)
|
158
146
|
end
|
159
147
|
|
160
148
|
#
|
@@ -170,13 +158,32 @@ module Fabric
|
|
170
158
|
)
|
171
159
|
end
|
172
160
|
|
161
|
+
#
|
162
|
+
# Creates a new endorse request from this proposal.
|
163
|
+
#
|
164
|
+
# @return [Gateway::EndorseRequest] EndorseRequest protobuf message
|
165
|
+
#
|
173
166
|
def new_endorse_request
|
174
|
-
|
167
|
+
::Gateway::EndorseRequest.new(
|
168
|
+
transaction_id: transaction_id,
|
169
|
+
channel_id: network_name,
|
170
|
+
proposed_transaction: signed_proposal,
|
171
|
+
endorsing_organizations: proposed_transaction.endorsing_organizations
|
172
|
+
)
|
175
173
|
end
|
176
174
|
|
177
|
-
|
178
|
-
|
179
|
-
|
175
|
+
#
|
176
|
+
# Creates a new prepared transaction from a transaction envelope.
|
177
|
+
#
|
178
|
+
# @param [Common::Envelope] envelope transaction envelope
|
179
|
+
#
|
180
|
+
# @return [Gateway::PreparedTransaction] prepared transaction protobuf message
|
181
|
+
#
|
182
|
+
def new_prepared_transaction(envelope)
|
183
|
+
::Gateway::PreparedTransaction.new(
|
184
|
+
transaction_id: transaction_id,
|
185
|
+
envelope: envelope
|
186
|
+
)
|
180
187
|
end
|
181
188
|
end
|
182
189
|
end
|
@@ -19,6 +19,10 @@ module Fabric
|
|
19
19
|
# This is usually used in conjunction with transientData for private data scenarios.
|
20
20
|
attr_reader :endorsing_organizations
|
21
21
|
|
22
|
+
# @!parse include Fabric::Accessors::Network
|
23
|
+
# @!parse include Fabric::Accessors::Gateway
|
24
|
+
include Fabric::Accessors::Contract
|
25
|
+
|
22
26
|
def initialize(contract, transaction_name, arguments: [], transient_data: {}, endorsing_organizations: [])
|
23
27
|
@contract = contract
|
24
28
|
@transaction_name = transaction_name
|
@@ -29,34 +33,6 @@ module Fabric
|
|
29
33
|
generate_proposed_transaction
|
30
34
|
end
|
31
35
|
|
32
|
-
def network
|
33
|
-
contract.network
|
34
|
-
end
|
35
|
-
|
36
|
-
def client
|
37
|
-
network.client
|
38
|
-
end
|
39
|
-
|
40
|
-
def signer
|
41
|
-
network.signer
|
42
|
-
end
|
43
|
-
|
44
|
-
def gateway
|
45
|
-
network.gateway
|
46
|
-
end
|
47
|
-
|
48
|
-
def network_name
|
49
|
-
network.name
|
50
|
-
end
|
51
|
-
|
52
|
-
def contract_name
|
53
|
-
contract.contract_name
|
54
|
-
end
|
55
|
-
|
56
|
-
def chaincode_name
|
57
|
-
contract.chaincode_name
|
58
|
-
end
|
59
|
-
|
60
36
|
#
|
61
37
|
# Builds the proposed transaction protobuf message
|
62
38
|
#
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fabric
|
4
|
+
#
|
5
|
+
# Status of a transaction that is to be committed to the ledger.
|
6
|
+
#
|
7
|
+
class Status
|
8
|
+
TRANSACTION_STATUSES = ::Protos::TxValidationCode.constants.map(&::Protos::TxValidationCode.method(:const_get))
|
9
|
+
.collect do |i|
|
10
|
+
[::Protos::TxValidationCode.lookup(i), i]
|
11
|
+
end.to_h
|
12
|
+
|
13
|
+
# @return [Integer] Block number in which the transaction committed.
|
14
|
+
attr_reader :block_number
|
15
|
+
|
16
|
+
# @return [Integer] Transaction status
|
17
|
+
attr_reader :code
|
18
|
+
|
19
|
+
# @return [Boolean] `true` if the transaction committed successfully; otherwise `false`.
|
20
|
+
attr_reader :successful
|
21
|
+
|
22
|
+
# @return [String] The ID of the transaction.
|
23
|
+
attr_reader :transaction_id
|
24
|
+
|
25
|
+
def initialize(transaction_id, block_number, code)
|
26
|
+
@transaction_id = transaction_id
|
27
|
+
@block_number = block_number
|
28
|
+
@code = code
|
29
|
+
@successful = @code == TRANSACTION_STATUSES[:VALID]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|