fabric-gateway 0.0.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +3 -0
- data/.github/workflows/rspec.yml +37 -0
- data/.github/workflows/rubocop.yml +28 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +23 -0
- data/.ruby-version +1 -0
- data/.vscode/settings.json +7 -0
- data/.yardopts +2 -0
- data/CODE_OF_CONDUCT.md +105 -46
- data/Gemfile +5 -3
- data/LICENSE.txt +1 -1
- data/README.md +105 -7
- data/Rakefile +7 -3
- data/bin/console +4 -3
- data/bin/regenerate +19 -0
- data/bin/release +5 -0
- data/fabric-gateway.gemspec +32 -17
- data/lib/common/common_pb.rb +113 -0
- data/lib/common/policies_pb.rb +61 -0
- 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 +146 -0
- data/lib/fabric/constants.rb +8 -0
- data/lib/fabric/contract.rb +154 -0
- data/lib/fabric/ec_crypto_suite.rb +199 -0
- data/lib/fabric/entities/envelope.rb +153 -0
- data/lib/fabric/entities/identity.rb +87 -0
- data/lib/fabric/entities/proposal.rb +189 -0
- data/lib/fabric/entities/proposed_transaction.rb +163 -0
- data/lib/fabric/entities/status.rb +32 -0
- data/lib/fabric/entities/transaction.rb +247 -0
- data/lib/fabric/gateway.rb +31 -6
- data/lib/fabric/network.rb +56 -0
- data/lib/fabric/version.rb +5 -0
- data/lib/fabric.rb +57 -0
- data/lib/gossip/message_pb.rb +236 -0
- data/lib/gossip/message_services_pb.rb +31 -0
- data/lib/msp/identities_pb.rb +25 -0
- data/lib/msp/msp_principal_pb.rb +57 -0
- data/lib/orderer/ab_pb.rb +64 -0
- data/lib/orderer/ab_services_pb.rb +30 -0
- data/lib/peer/chaincode_event_pb.rb +19 -0
- data/lib/peer/chaincode_pb.rb +69 -0
- data/lib/peer/proposal_pb.rb +41 -0
- data/lib/peer/proposal_response_pb.rb +52 -0
- data/lib/peer/transaction_pb.rb +74 -0
- metadata +184 -10
- data/lib/fabric/gateway/version.rb +0 -5
@@ -0,0 +1,163 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fabric
|
4
|
+
#
|
5
|
+
# Manages the instantiation and creation of the Gateway::ProposedTransaction Protobuf Message.
|
6
|
+
#
|
7
|
+
# Adapted from official fabric-gateway SDK ProposalBuilder and hyperledger-fabric-sdk:
|
8
|
+
# https://github.com/hyperledger/fabric-gateway/blob/1518e03ed3d6db1b6809e23e61a92744fd18e724/node/src/proposalbuilder.ts
|
9
|
+
# https://github.com/kirshin/hyperledger-fabric-sdk/blob/95a5a1a37001852312df25946e960a9ff149207e/lib/fabric/proposal.rb
|
10
|
+
class ProposedTransaction
|
11
|
+
attr_reader :contract,
|
12
|
+
:transaction_name,
|
13
|
+
:transient_data,
|
14
|
+
:arguments,
|
15
|
+
:proposed_transaction
|
16
|
+
|
17
|
+
# Specifies the set of organizations that will attempt to endorse the proposal.
|
18
|
+
# No other organizations' peers will be sent this proposal.
|
19
|
+
# This is usually used in conjunction with transientData for private data scenarios.
|
20
|
+
attr_reader :endorsing_organizations
|
21
|
+
|
22
|
+
# @!parse include Fabric::Accessors::Network
|
23
|
+
# @!parse include Fabric::Accessors::Gateway
|
24
|
+
include Fabric::Accessors::Contract
|
25
|
+
|
26
|
+
def initialize(contract, transaction_name, arguments: [], transient_data: {}, endorsing_organizations: [])
|
27
|
+
@contract = contract
|
28
|
+
@transaction_name = transaction_name
|
29
|
+
@arguments = arguments
|
30
|
+
@transient_data = transient_data
|
31
|
+
@endorsing_organizations = endorsing_organizations
|
32
|
+
|
33
|
+
generate_proposed_transaction
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Builds the proposed transaction protobuf message
|
38
|
+
#
|
39
|
+
# @return [Gateway::ProposedTransaction]
|
40
|
+
#
|
41
|
+
def generate_proposed_transaction
|
42
|
+
@proposed_transaction = ::Gateway::ProposedTransaction.new(
|
43
|
+
transaction_id: transaction_id,
|
44
|
+
proposal: signed_proposal,
|
45
|
+
endorsing_organizations: endorsing_organizations
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def signed_proposal
|
50
|
+
@signed_proposal ||= Protos::SignedProposal.new(
|
51
|
+
proposal_bytes: proposal.to_proto
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def proposal
|
56
|
+
@proposal ||= Protos::Proposal.new header: header.to_proto,
|
57
|
+
payload: chaincode_proposal_payload.to_proto
|
58
|
+
end
|
59
|
+
|
60
|
+
def header
|
61
|
+
Common::Header.new channel_header: channel_header.to_proto,
|
62
|
+
signature_header: signature_header.to_proto
|
63
|
+
end
|
64
|
+
|
65
|
+
def channel_header
|
66
|
+
Common::ChannelHeader.new type: Common::HeaderType::ENDORSER_TRANSACTION,
|
67
|
+
channel_id: network_name, tx_id: transaction_id,
|
68
|
+
extension: channel_header_extension.to_proto,
|
69
|
+
timestamp: timestamp, epoch: 0
|
70
|
+
# version: Constants::CHANNEL_HEADER_VERSION # official SDK does not send this.
|
71
|
+
end
|
72
|
+
|
73
|
+
def channel_header_extension
|
74
|
+
Protos::ChaincodeHeaderExtension.new chaincode_id: chaincode_id
|
75
|
+
end
|
76
|
+
|
77
|
+
def chaincode_id
|
78
|
+
Protos::ChaincodeID.new name: chaincode_name
|
79
|
+
end
|
80
|
+
|
81
|
+
def chaincode_proposal_payload
|
82
|
+
chaincode_input = Protos::ChaincodeInput.new args: [transaction_name] + arguments
|
83
|
+
chaincode_spec = Protos::ChaincodeSpec.new type: Protos::ChaincodeSpec::Type::NODE,
|
84
|
+
chaincode_id: chaincode_id,
|
85
|
+
input: chaincode_input
|
86
|
+
input = Protos::ChaincodeInvocationSpec.new chaincode_spec: chaincode_spec
|
87
|
+
|
88
|
+
Protos::ChaincodeProposalPayload.new input: input.to_proto, TransientMap: transient_data
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Returns the current timestamp
|
93
|
+
#
|
94
|
+
# @return [Google::Protobuf::Timestamp] gRPC timestamp
|
95
|
+
#
|
96
|
+
def timestamp
|
97
|
+
now = Time.now
|
98
|
+
|
99
|
+
@timestamp ||= Google::Protobuf::Timestamp.new seconds: now.to_i, nanos: now.nsec
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Generates a random nonce
|
104
|
+
#
|
105
|
+
# @return [String] random nonce
|
106
|
+
#
|
107
|
+
def nonce
|
108
|
+
@nonce ||= signer.crypto_suite.generate_nonce
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Generates a unique transaction ID for the transaction based on a random number and the signer
|
113
|
+
# or returns the existing transaction ID if it has already been generated.
|
114
|
+
#
|
115
|
+
# @return [String] transaction ID
|
116
|
+
#
|
117
|
+
def transaction_id
|
118
|
+
@transaction_id ||= signer.crypto_suite.hexdigest(nonce + signer.to_proto)
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
# Generates a SignatureHeader protobuf message from the signer and nonce
|
123
|
+
#
|
124
|
+
# @return [Common::SignatureHeader] signature header protobuf message instance
|
125
|
+
#
|
126
|
+
def signature_header
|
127
|
+
Common::SignatureHeader.new creator: signer.to_proto, nonce: nonce
|
128
|
+
end
|
129
|
+
|
130
|
+
# Dev note: if we have more classes that encapsulate protobuffer messages, consider
|
131
|
+
# creating an EncapsulatedPBMessage to hold the message and expose the following methods
|
132
|
+
# as common interface.
|
133
|
+
|
134
|
+
#
|
135
|
+
# Returns the protobuf message instance
|
136
|
+
#
|
137
|
+
# @return [Gateway::ProposedTransaction] protobuf message instance
|
138
|
+
#
|
139
|
+
def as_proto
|
140
|
+
proposed_transaction
|
141
|
+
end
|
142
|
+
|
143
|
+
#
|
144
|
+
# Returns the serialized Protobuf binary form of the proposed transaction
|
145
|
+
#
|
146
|
+
# @return [String] serialized Protobuf binary form of the proposed transaction
|
147
|
+
#
|
148
|
+
def to_proto
|
149
|
+
proposed_transaction.to_proto
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# Returns the serialized JSON form of the proposed transaction
|
154
|
+
#
|
155
|
+
# @param [Hash] options JSON serialization options @see https://ruby-doc.org/stdlib-2.6.3/libdoc/json/rdoc/JSON.html#method-i-generate
|
156
|
+
#
|
157
|
+
# @return [String] serialized JSON form of the proposed transaction
|
158
|
+
#
|
159
|
+
def to_json(options = {})
|
160
|
+
proposed_transaction.to_json(options)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -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
|
@@ -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/gateway.rb
CHANGED
@@ -1,10 +1,35 @@
|
|
1
|
-
|
2
|
-
require "gateway/gateway_pb"
|
3
|
-
require "gateway/gateway_services_pb"
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
3
|
module Fabric
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
#
|
5
|
+
# Gateway represents the connection of a specific client identity to a Fabric Gateway.
|
6
|
+
#
|
7
|
+
class Gateway
|
8
|
+
attr_reader :signer, :client
|
9
|
+
|
10
|
+
#
|
11
|
+
# Initialize a new Gateway
|
12
|
+
#
|
13
|
+
# @param [Fabric::Identity] signer identity utilized to sign transactions
|
14
|
+
# @param [Fabric::Client] client Gateway Client
|
15
|
+
#
|
16
|
+
def initialize(signer, client)
|
17
|
+
raise InvalidArgument, 'signer must be Fabric::Identity' unless signer.is_a? Fabric::Identity
|
18
|
+
raise InvalidArgument, 'client must be Fabric::Client' unless client.is_a? Fabric::Client
|
19
|
+
|
20
|
+
@signer = signer
|
21
|
+
@client = client
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Initialize new network from the Gateway
|
26
|
+
#
|
27
|
+
# @param [string] name channel name
|
28
|
+
#
|
29
|
+
# @return [Fabric::Network] returns a new network
|
30
|
+
#
|
31
|
+
def new_network(name)
|
32
|
+
Network.new(self, name)
|
33
|
+
end
|
9
34
|
end
|
10
35
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fabric
|
4
|
+
#
|
5
|
+
# Network represents a blockchain network, or Fabric channel. The Network can be used to access deployed smart
|
6
|
+
# contracts, and to listen for events emitted when blocks are committed to the ledger.
|
7
|
+
#
|
8
|
+
# JChan & THowe believe this should be called a Channel, however Hyperledger Fabric has decided upon the terminology
|
9
|
+
# network - https://github.com/hyperledger/fabric-gateway/issues/355#issuecomment-997888071
|
10
|
+
#
|
11
|
+
class Network
|
12
|
+
attr_reader :gateway, :name
|
13
|
+
|
14
|
+
# @!parse include Fabric::Accessors::Gateway
|
15
|
+
include Fabric::Accessors::Gateway
|
16
|
+
|
17
|
+
def initialize(gateway, name)
|
18
|
+
@gateway = gateway
|
19
|
+
@name = name
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Creates a new contract instance
|
24
|
+
#
|
25
|
+
# @param [string] chaincode_name name of the chaincode
|
26
|
+
# @param [string] contract_name optional name of the contract
|
27
|
+
#
|
28
|
+
# @return [Fabric::Contract] new contract instance
|
29
|
+
#
|
30
|
+
def new_contract(chaincode_name, contract_name = '')
|
31
|
+
Contract.new(self, chaincode_name, contract_name)
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# @todo original SDK has getChaincodeEvents and newChaincodeEventsRequest methods
|
36
|
+
# @see https://github.com/hyperledger/fabric-gateway/blob/08118cf0a792898925d0b2710b0a9e7c5ec23228/node/src/network.ts
|
37
|
+
# @see https://github.com/hyperledger/fabric-gateway/blob/main/pkg/client/network.go
|
38
|
+
#
|
39
|
+
# @return [?] ?
|
40
|
+
#
|
41
|
+
def new_chaincode_events
|
42
|
+
raise NotYetImplemented
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# @todo original SDK has getChaincodeEvents and newChaincodeEventsRequest methods
|
47
|
+
# @see https://github.com/hyperledger/fabric-gateway/blob/08118cf0a792898925d0b2710b0a9e7c5ec23228/node/src/network.ts
|
48
|
+
# @see https://github.com/hyperledger/fabric-gateway/blob/main/pkg/client/network.go
|
49
|
+
#
|
50
|
+
# @return [?] ?
|
51
|
+
#
|
52
|
+
def new_chaincode_events_request
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/fabric.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
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
|
+
|
17
|
+
require 'fabric/constants'
|
18
|
+
require 'fabric/contract'
|
19
|
+
require 'fabric/client'
|
20
|
+
require 'fabric/ec_crypto_suite'
|
21
|
+
require 'fabric/gateway'
|
22
|
+
require 'fabric/network'
|
23
|
+
require 'fabric/version'
|
24
|
+
|
25
|
+
#
|
26
|
+
# Hyperledger Fabric Gateway SDK
|
27
|
+
#
|
28
|
+
module Fabric
|
29
|
+
class Error < StandardError; end
|
30
|
+
class InvalidArgument < Error; end
|
31
|
+
class NotYetImplemented < Error; end
|
32
|
+
|
33
|
+
#
|
34
|
+
# CommitError
|
35
|
+
#
|
36
|
+
# @todo TEST ME!
|
37
|
+
#
|
38
|
+
class CommitError < Error
|
39
|
+
attr_reader :code, :transaction_id
|
40
|
+
|
41
|
+
#
|
42
|
+
# Creates a transaction commit error from the status
|
43
|
+
#
|
44
|
+
# @param [Fabric::Status] status transaction status
|
45
|
+
#
|
46
|
+
def initialize(status)
|
47
|
+
super("Transaction #{status.transaction_id} failed to commit with status code #{status.code} - " +
|
48
|
+
Status::TRANSACTION_STATUSES.key(status.code).to_s)
|
49
|
+
@code = code
|
50
|
+
@transaction_id = status.transaction_id
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.crypto_suite(opts = {})
|
55
|
+
@crypto_suite ||= Fabric::ECCryptoSuite.new opts
|
56
|
+
end
|
57
|
+
end
|