fabric-gateway 0.0.1 → 0.3.0
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/.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
|