fabric-gateway 0.2.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -0,0 +1,247 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fabric
|
4
|
+
#
|
5
|
+
# Represents an endorsed transaction that can be submitted to the orderer for commit to the ledger,
|
6
|
+
# query the transaction results and its commit status.
|
7
|
+
#
|
8
|
+
class Transaction
|
9
|
+
attr_reader :network
|
10
|
+
|
11
|
+
include Fabric::Accessors::Network
|
12
|
+
|
13
|
+
# @return [Gateway::PreparedTransaction] Prepared Transaction
|
14
|
+
attr_reader :prepared_transaction
|
15
|
+
|
16
|
+
# @return [Fabric::Envelope]
|
17
|
+
attr_reader :envelope
|
18
|
+
|
19
|
+
#
|
20
|
+
# Creates a new Transaction instance.
|
21
|
+
#
|
22
|
+
# @param [Fabric::Network] network
|
23
|
+
# @param [Gateway::PreparedTransaction] prepared_transaction
|
24
|
+
#
|
25
|
+
def initialize(network, prepared_transaction)
|
26
|
+
@network = network
|
27
|
+
@prepared_transaction = prepared_transaction
|
28
|
+
@envelope = Envelope.new(prepared_transaction.envelope)
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Get the transaction result. This is obtained during the endorsement process when the transaction proposal is
|
33
|
+
# run on endorsing peers.
|
34
|
+
#
|
35
|
+
# @param [boolean] check_status set to true to raise exception if transaction has not yet been committed
|
36
|
+
#
|
37
|
+
# @return [String] Raw transaction result
|
38
|
+
#
|
39
|
+
def result(check_status: true)
|
40
|
+
raise Fabric::CommitError, status if check_status && !status.successful
|
41
|
+
|
42
|
+
envelope.result
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Returns the transaction ID from the prepared transaction.
|
47
|
+
#
|
48
|
+
# @return [String] transaction_id
|
49
|
+
#
|
50
|
+
def transaction_id
|
51
|
+
prepared_transaction.transaction_id
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Submit the transaction to the orderer to be committed to the ledger.
|
56
|
+
#
|
57
|
+
# @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
|
58
|
+
#
|
59
|
+
# @param [Hash] options gRPC call options
|
60
|
+
#
|
61
|
+
# @return [Fabric::Transaction] self
|
62
|
+
def submit(options = {})
|
63
|
+
sign_submit_request
|
64
|
+
|
65
|
+
client.submit(new_submit_request, options)
|
66
|
+
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Sign the transaction envelope.
|
72
|
+
#
|
73
|
+
# @return [void]
|
74
|
+
def sign_submit_request
|
75
|
+
return if submit_request_signed?
|
76
|
+
|
77
|
+
signature = signer.sign(envelope.payload_bytes)
|
78
|
+
self.submit_request_signature = signature
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Returns true if the transaction envelope has been signed.
|
83
|
+
#
|
84
|
+
# @return [Boolean] true if signed; false otherwise
|
85
|
+
#
|
86
|
+
def submit_request_signed?
|
87
|
+
@envelope.signed?
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Digest to be signed to support offline signing of the submit request
|
92
|
+
#
|
93
|
+
# @return [String] digest of the submit request
|
94
|
+
#
|
95
|
+
def submit_request_digest
|
96
|
+
envelope.payload_digest
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# Sets the submit request signature. This is used to support offline signing of the submit request.
|
101
|
+
#
|
102
|
+
# @param [String] signature
|
103
|
+
#
|
104
|
+
# @return [void]
|
105
|
+
#
|
106
|
+
def submit_request_signature=(signature)
|
107
|
+
envelope.signature = signature
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Get status of the committed transaction. If the transaction has not yet committed, this method blocks until the
|
112
|
+
# commit occurs. If status is already queried, this returns status from cache and does not make additional queries.
|
113
|
+
#
|
114
|
+
# @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
|
115
|
+
#
|
116
|
+
# @param [Hash] options gRPC call options
|
117
|
+
#
|
118
|
+
# @return [Fabric::Status] status of the committed transaction
|
119
|
+
#
|
120
|
+
def status(options = {})
|
121
|
+
@status ||= query_status(options)
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# Digest to be signed to support offline signing of the commit status request
|
126
|
+
#
|
127
|
+
# @return [String] digest of the commit status request
|
128
|
+
#
|
129
|
+
def status_request_digest
|
130
|
+
Fabric.crypto_suite.digest(signed_commit_status_request.request)
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Sets the status request signature. This is used to support offline signing of the commit status request.
|
135
|
+
#
|
136
|
+
# @param [String] signature
|
137
|
+
#
|
138
|
+
# @return [void]
|
139
|
+
#
|
140
|
+
def status_request_signature=(signature)
|
141
|
+
signed_commit_status_request.signature = signature
|
142
|
+
end
|
143
|
+
|
144
|
+
#
|
145
|
+
# Returns true if the signed commit status request has been signed.
|
146
|
+
#
|
147
|
+
# @return [Boolean] true if signed; false otherwise
|
148
|
+
#
|
149
|
+
def status_request_signed?
|
150
|
+
!signed_commit_status_request.signature.empty?
|
151
|
+
end
|
152
|
+
|
153
|
+
#
|
154
|
+
# Sign the signed commit status request
|
155
|
+
#
|
156
|
+
# @return [Fabric::Transaction] self
|
157
|
+
#
|
158
|
+
def sign_status_request
|
159
|
+
return if status_request_signed?
|
160
|
+
|
161
|
+
signature = signer.sign(signed_commit_status_request.request)
|
162
|
+
signed_commit_status_request.signature = signature
|
163
|
+
|
164
|
+
self
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
# Returns the current instance of the signed commit status request. Necessary so we can keep the state of the
|
169
|
+
# signature in the transaction object.
|
170
|
+
#
|
171
|
+
# @return [Gateway::SignedCommitStatusRequest] signed commit status request
|
172
|
+
#
|
173
|
+
def signed_commit_status_request
|
174
|
+
@signed_commit_status_request ||= new_signed_commit_status_request
|
175
|
+
end
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
#
|
180
|
+
# Actual status query call used by status method.
|
181
|
+
#
|
182
|
+
# @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
|
183
|
+
#
|
184
|
+
# @param [Hash] options gRPC call options
|
185
|
+
#
|
186
|
+
# @return [Fabric::Status] status of the committed transaction
|
187
|
+
#
|
188
|
+
def query_status(options = {})
|
189
|
+
sign_status_request
|
190
|
+
|
191
|
+
commit_status_response = client.commit_status(signed_commit_status_request, options)
|
192
|
+
new_status(commit_status_response)
|
193
|
+
end
|
194
|
+
|
195
|
+
#
|
196
|
+
# Generates a new signed commit status request
|
197
|
+
#
|
198
|
+
# @return [Gateway::SignedCommitStatusRequest] signed commit status request protobuf message
|
199
|
+
#
|
200
|
+
def new_signed_commit_status_request
|
201
|
+
::Gateway::SignedCommitStatusRequest.new(
|
202
|
+
request: new_commit_status_request.to_proto
|
203
|
+
)
|
204
|
+
end
|
205
|
+
|
206
|
+
#
|
207
|
+
# Generates a new commit status request
|
208
|
+
#
|
209
|
+
# @return [Gateway::CommitStatusRequest] commit status request protobuf message
|
210
|
+
#
|
211
|
+
def new_commit_status_request
|
212
|
+
::Gateway::CommitStatusRequest.new(
|
213
|
+
channel_id: network_name,
|
214
|
+
transaction_id: transaction_id,
|
215
|
+
identity: signer.to_proto
|
216
|
+
)
|
217
|
+
end
|
218
|
+
|
219
|
+
#
|
220
|
+
# Generates a new submit request.
|
221
|
+
#
|
222
|
+
# @return [Gateway::SubmitRequest] submit request protobuf message
|
223
|
+
#
|
224
|
+
def new_submit_request
|
225
|
+
::Gateway::SubmitRequest.new(
|
226
|
+
transaction_id: transaction_id,
|
227
|
+
channel_id: network_name,
|
228
|
+
prepared_transaction: envelope.envelope
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
#
|
233
|
+
# New Status from CommitStatusResponse
|
234
|
+
#
|
235
|
+
# @param [Gateway::CommitStatusResponse] response commit status response
|
236
|
+
#
|
237
|
+
# @return [Fabric::Status] transaction status
|
238
|
+
#
|
239
|
+
def new_status(response)
|
240
|
+
Fabric::Status.new(
|
241
|
+
transaction_id,
|
242
|
+
response.block_number,
|
243
|
+
Fabric::Status::TRANSACTION_STATUSES[response.result]
|
244
|
+
)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
data/lib/fabric/network.rb
CHANGED
@@ -11,19 +11,14 @@ module Fabric
|
|
11
11
|
class Network
|
12
12
|
attr_reader :gateway, :name
|
13
13
|
|
14
|
+
# @!parse include Fabric::Accessors::Gateway
|
15
|
+
include Fabric::Accessors::Gateway
|
16
|
+
|
14
17
|
def initialize(gateway, name)
|
15
18
|
@gateway = gateway
|
16
19
|
@name = name
|
17
20
|
end
|
18
21
|
|
19
|
-
def client
|
20
|
-
gateway.client
|
21
|
-
end
|
22
|
-
|
23
|
-
def signer
|
24
|
-
gateway.signer
|
25
|
-
end
|
26
|
-
|
27
22
|
#
|
28
23
|
# Creates a new contract instance
|
29
24
|
#
|
@@ -37,25 +32,39 @@ module Fabric
|
|
37
32
|
end
|
38
33
|
|
39
34
|
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
# @see
|
35
|
+
# Get chaincode events emitted by transaction functions of a specific chaincode.
|
36
|
+
#
|
37
|
+
# @see Fabric::Client#chaincode_events Fabric::Client#chaincode_events - explanation of the different return types
|
38
|
+
# and example usage.
|
39
|
+
# @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:server_streamer Call options for options parameter
|
43
40
|
#
|
44
|
-
# @
|
41
|
+
# @param [Fabric::Contract] contract the chaincode to listen for events on
|
42
|
+
# @param [Integer] start_block Block number at which to start reading chaincode events.
|
43
|
+
# @param [Hash] call_options gRPC call options (merged with default_call_options from initializer)
|
44
|
+
# @yield [chaincode_event] loops through the chaincode events
|
45
|
+
# @yieldparam chaincode_event [Gateway::ChaincodeEventsResponse] the chaincode event
|
45
46
|
#
|
46
|
-
|
47
|
-
|
47
|
+
# @return [Enumerator|GRPC::ActiveCall::Operation|nil] Dependent on parameters passed;
|
48
|
+
# please see Fabric::Client#get_chaincode_events
|
49
|
+
#
|
50
|
+
def chaincode_events(contract, start_block: nil, call_options: {}, &block)
|
51
|
+
new_chaincode_events_request(contract, start_block: start_block).get_events(call_options, &block)
|
48
52
|
end
|
49
53
|
|
50
54
|
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
55
|
+
# Create a request to receive chaincode events emitted by transaction functions of a specific chaincode. Supports
|
56
|
+
# off-line signing flow.
|
57
|
+
#
|
58
|
+
# @note I'm lying. I just copy and pasted the description from the node SDK. Offline signing should work, but it has
|
59
|
+
# not been explicitly tested.
|
60
|
+
# @todo Test off-line signing flow.
|
54
61
|
#
|
55
|
-
# @
|
62
|
+
# @param [Fabric::Contract] contract the chaincode to listen for events on
|
63
|
+
# @param [Integer] start_block Block number at which to start reading chaincode events.
|
64
|
+
# @return [Fabric::ChaincodeEventsRequest] Encapsulated ChaincodeEventsRequest
|
56
65
|
#
|
57
|
-
def new_chaincode_events_request
|
58
|
-
|
66
|
+
def new_chaincode_events_request(contract, start_block: nil)
|
67
|
+
ChaincodeEventsRequest.new(contract, start_block: start_block)
|
59
68
|
end
|
60
69
|
end
|
61
70
|
end
|
data/lib/fabric/version.rb
CHANGED
data/lib/fabric.rb
CHANGED
@@ -1,19 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'gateway/gateway_pb'
|
4
|
+
require 'gateway/gateway_services_pb'
|
5
|
+
|
6
|
+
require 'fabric/accessors/gateway'
|
7
|
+
require 'fabric/accessors/network'
|
8
|
+
require 'fabric/accessors/contract'
|
9
|
+
|
10
|
+
require 'fabric/entities/envelope'
|
11
|
+
require 'fabric/entities/identity'
|
12
|
+
require 'fabric/entities/proposal'
|
13
|
+
require 'fabric/entities/proposed_transaction'
|
14
|
+
require 'fabric/entities/status'
|
15
|
+
require 'fabric/entities/transaction'
|
16
|
+
require 'fabric/entities/chaincode_events_requests'
|
17
|
+
|
3
18
|
require 'fabric/constants'
|
4
19
|
require 'fabric/contract'
|
5
20
|
require 'fabric/client'
|
6
21
|
require 'fabric/ec_crypto_suite'
|
7
22
|
require 'fabric/gateway'
|
8
|
-
require 'fabric/identity'
|
9
23
|
require 'fabric/network'
|
10
|
-
require 'fabric/proposal'
|
11
|
-
require 'fabric/proposed_transaction'
|
12
24
|
require 'fabric/version'
|
13
25
|
|
14
|
-
require 'gateway/gateway_pb'
|
15
|
-
require 'gateway/gateway_services_pb'
|
16
|
-
|
17
26
|
#
|
18
27
|
# Hyperledger Fabric Gateway SDK
|
19
28
|
#
|
@@ -25,14 +34,20 @@ module Fabric
|
|
25
34
|
#
|
26
35
|
# CommitError
|
27
36
|
#
|
28
|
-
#
|
37
|
+
# TODO: Add RSpec Tests for CommitError
|
38
|
+
# @todo TEST ME!
|
29
39
|
#
|
30
40
|
class CommitError < Error
|
31
41
|
attr_reader :code, :transaction_id
|
32
42
|
|
43
|
+
#
|
44
|
+
# Creates a transaction commit error from the status
|
45
|
+
#
|
46
|
+
# @param [Fabric::Status] status transaction status
|
47
|
+
#
|
33
48
|
def initialize(status)
|
34
|
-
super("Transaction #{status.transaction_id} failed to commit with status code #{status.code} -" +
|
35
|
-
|
49
|
+
super("Transaction #{status.transaction_id} failed to commit with status code #{status.code} - " +
|
50
|
+
Status::TRANSACTION_STATUSES.key(status.code).to_s)
|
36
51
|
@code = code
|
37
52
|
@transaction_id = status.transaction_id
|
38
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fabric-gateway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Chan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-protobuf
|
@@ -72,14 +72,28 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 1.46.2
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 1.46.2
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake-notes
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.2.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.2.0
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rubocop
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,8 +150,21 @@ dependencies:
|
|
136
150
|
- - "~>"
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: 0.9.4
|
139
|
-
|
140
|
-
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: yard
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.9.27
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.9.27
|
167
|
+
description: Ruby port of the Hyperledger Fabric Gateway SDK
|
141
168
|
email:
|
142
169
|
- jonathan.chan@ethicalidentity.com
|
143
170
|
executables: []
|
@@ -145,8 +172,11 @@ extensions: []
|
|
145
172
|
extra_rdoc_files: []
|
146
173
|
files:
|
147
174
|
- ".editorconfig"
|
175
|
+
- ".github/workflows/codeql-analysis.yml"
|
148
176
|
- ".github/workflows/rspec.yml"
|
149
177
|
- ".github/workflows/rubocop.yml"
|
178
|
+
- ".github/workflows/todo.yml"
|
179
|
+
- ".github/workflows/yardoc.yml"
|
150
180
|
- ".gitignore"
|
151
181
|
- ".gitmodules"
|
152
182
|
- ".rspec"
|
@@ -154,6 +184,7 @@ files:
|
|
154
184
|
- ".ruby-version"
|
155
185
|
- ".travis.yml"
|
156
186
|
- ".vscode/settings.json"
|
187
|
+
- ".yardopts"
|
157
188
|
- CHANGELOG.md
|
158
189
|
- CODE_OF_CONDUCT.md
|
159
190
|
- Gemfile
|
@@ -171,15 +202,22 @@ files:
|
|
171
202
|
- lib/common/policies_pb.rb
|
172
203
|
- lib/fabric.rb
|
173
204
|
- lib/fabric/.DS_Store
|
205
|
+
- lib/fabric/accessors/contract.rb
|
206
|
+
- lib/fabric/accessors/gateway.rb
|
207
|
+
- lib/fabric/accessors/network.rb
|
174
208
|
- lib/fabric/client.rb
|
175
209
|
- lib/fabric/constants.rb
|
176
210
|
- lib/fabric/contract.rb
|
177
211
|
- lib/fabric/ec_crypto_suite.rb
|
212
|
+
- lib/fabric/entities/chaincode_events_requests.rb
|
213
|
+
- lib/fabric/entities/envelope.rb
|
214
|
+
- lib/fabric/entities/identity.rb
|
215
|
+
- lib/fabric/entities/proposal.rb
|
216
|
+
- lib/fabric/entities/proposed_transaction.rb
|
217
|
+
- lib/fabric/entities/status.rb
|
218
|
+
- lib/fabric/entities/transaction.rb
|
178
219
|
- lib/fabric/gateway.rb
|
179
|
-
- lib/fabric/identity.rb
|
180
220
|
- lib/fabric/network.rb
|
181
|
-
- lib/fabric/proposal.rb
|
182
|
-
- lib/fabric/proposed_transaction.rb
|
183
221
|
- lib/fabric/version.rb
|
184
222
|
- lib/gateway/gateway_pb.rb
|
185
223
|
- lib/gateway/gateway_services_pb.rb
|
@@ -217,5 +255,5 @@ requirements: []
|
|
217
255
|
rubygems_version: 3.1.6
|
218
256
|
signing_key:
|
219
257
|
specification_version: 4
|
220
|
-
summary: Hyperledger Fabric Gateway
|
258
|
+
summary: Hyperledger Fabric Gateway SDK
|
221
259
|
test_files: []
|