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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +3 -0
  3. data/.github/workflows/rspec.yml +37 -0
  4. data/.github/workflows/rubocop.yml +28 -0
  5. data/.gitignore +1 -0
  6. data/.rubocop.yml +23 -0
  7. data/.ruby-version +1 -0
  8. data/.vscode/settings.json +7 -0
  9. data/.yardopts +2 -0
  10. data/CODE_OF_CONDUCT.md +105 -46
  11. data/Gemfile +5 -3
  12. data/LICENSE.txt +1 -1
  13. data/README.md +105 -7
  14. data/Rakefile +7 -3
  15. data/bin/console +4 -3
  16. data/bin/regenerate +19 -0
  17. data/bin/release +5 -0
  18. data/fabric-gateway.gemspec +32 -17
  19. data/lib/common/common_pb.rb +113 -0
  20. data/lib/common/policies_pb.rb +61 -0
  21. data/lib/fabric/accessors/contract.rb +51 -0
  22. data/lib/fabric/accessors/gateway.rb +33 -0
  23. data/lib/fabric/accessors/network.rb +40 -0
  24. data/lib/fabric/client.rb +146 -0
  25. data/lib/fabric/constants.rb +8 -0
  26. data/lib/fabric/contract.rb +154 -0
  27. data/lib/fabric/ec_crypto_suite.rb +199 -0
  28. data/lib/fabric/entities/envelope.rb +153 -0
  29. data/lib/fabric/entities/identity.rb +87 -0
  30. data/lib/fabric/entities/proposal.rb +189 -0
  31. data/lib/fabric/entities/proposed_transaction.rb +163 -0
  32. data/lib/fabric/entities/status.rb +32 -0
  33. data/lib/fabric/entities/transaction.rb +247 -0
  34. data/lib/fabric/gateway.rb +31 -6
  35. data/lib/fabric/network.rb +56 -0
  36. data/lib/fabric/version.rb +5 -0
  37. data/lib/fabric.rb +57 -0
  38. data/lib/gossip/message_pb.rb +236 -0
  39. data/lib/gossip/message_services_pb.rb +31 -0
  40. data/lib/msp/identities_pb.rb +25 -0
  41. data/lib/msp/msp_principal_pb.rb +57 -0
  42. data/lib/orderer/ab_pb.rb +64 -0
  43. data/lib/orderer/ab_services_pb.rb +30 -0
  44. data/lib/peer/chaincode_event_pb.rb +19 -0
  45. data/lib/peer/chaincode_pb.rb +69 -0
  46. data/lib/peer/proposal_pb.rb +41 -0
  47. data/lib/peer/proposal_response_pb.rb +52 -0
  48. data/lib/peer/transaction_pb.rb +74 -0
  49. metadata +184 -10
  50. data/lib/fabric/gateway/version.rb +0 -5
@@ -0,0 +1,113 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: common/common.proto
3
+
4
+ require 'google/protobuf/timestamp_pb'
5
+ require 'google/protobuf'
6
+
7
+ Google::Protobuf::DescriptorPool.generated_pool.build do
8
+ add_file("common/common.proto", :syntax => :proto3) do
9
+ add_message "common.LastConfig" do
10
+ optional :index, :uint64, 1
11
+ end
12
+ add_message "common.Metadata" do
13
+ optional :value, :bytes, 1
14
+ repeated :signatures, :message, 2, "common.MetadataSignature"
15
+ end
16
+ add_message "common.MetadataSignature" do
17
+ optional :signature_header, :bytes, 1
18
+ optional :signature, :bytes, 2
19
+ end
20
+ add_message "common.Header" do
21
+ optional :channel_header, :bytes, 1
22
+ optional :signature_header, :bytes, 2
23
+ end
24
+ add_message "common.ChannelHeader" do
25
+ optional :type, :int32, 1
26
+ optional :version, :int32, 2
27
+ optional :timestamp, :message, 3, "google.protobuf.Timestamp"
28
+ optional :channel_id, :string, 4
29
+ optional :tx_id, :string, 5
30
+ optional :epoch, :uint64, 6
31
+ optional :extension, :bytes, 7
32
+ optional :tls_cert_hash, :bytes, 8
33
+ end
34
+ add_message "common.SignatureHeader" do
35
+ optional :creator, :bytes, 1
36
+ optional :nonce, :bytes, 2
37
+ end
38
+ add_message "common.Payload" do
39
+ optional :header, :message, 1, "common.Header"
40
+ optional :data, :bytes, 2
41
+ end
42
+ add_message "common.Envelope" do
43
+ optional :payload, :bytes, 1
44
+ optional :signature, :bytes, 2
45
+ end
46
+ add_message "common.Block" do
47
+ optional :header, :message, 1, "common.BlockHeader"
48
+ optional :data, :message, 2, "common.BlockData"
49
+ optional :metadata, :message, 3, "common.BlockMetadata"
50
+ end
51
+ add_message "common.BlockHeader" do
52
+ optional :number, :uint64, 1
53
+ optional :previous_hash, :bytes, 2
54
+ optional :data_hash, :bytes, 3
55
+ end
56
+ add_message "common.BlockData" do
57
+ repeated :data, :bytes, 1
58
+ end
59
+ add_message "common.BlockMetadata" do
60
+ repeated :metadata, :bytes, 1
61
+ end
62
+ add_message "common.OrdererBlockMetadata" do
63
+ optional :last_config, :message, 1, "common.LastConfig"
64
+ optional :consenter_metadata, :bytes, 2
65
+ end
66
+ add_enum "common.Status" do
67
+ value :UNKNOWN, 0
68
+ value :SUCCESS, 200
69
+ value :BAD_REQUEST, 400
70
+ value :FORBIDDEN, 403
71
+ value :NOT_FOUND, 404
72
+ value :REQUEST_ENTITY_TOO_LARGE, 413
73
+ value :INTERNAL_SERVER_ERROR, 500
74
+ value :NOT_IMPLEMENTED, 501
75
+ value :SERVICE_UNAVAILABLE, 503
76
+ end
77
+ add_enum "common.HeaderType" do
78
+ value :MESSAGE, 0
79
+ value :CONFIG, 1
80
+ value :CONFIG_UPDATE, 2
81
+ value :ENDORSER_TRANSACTION, 3
82
+ value :ORDERER_TRANSACTION, 4
83
+ value :DELIVER_SEEK_INFO, 5
84
+ value :CHAINCODE_PACKAGE, 6
85
+ end
86
+ add_enum "common.BlockMetadataIndex" do
87
+ value :SIGNATURES, 0
88
+ value :LAST_CONFIG, 1
89
+ value :TRANSACTIONS_FILTER, 2
90
+ value :ORDERER, 3
91
+ value :COMMIT_HASH, 4
92
+ end
93
+ end
94
+ end
95
+
96
+ module Common
97
+ LastConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.LastConfig").msgclass
98
+ Metadata = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.Metadata").msgclass
99
+ MetadataSignature = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.MetadataSignature").msgclass
100
+ Header = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.Header").msgclass
101
+ ChannelHeader = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.ChannelHeader").msgclass
102
+ SignatureHeader = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.SignatureHeader").msgclass
103
+ Payload = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.Payload").msgclass
104
+ Envelope = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.Envelope").msgclass
105
+ Block = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.Block").msgclass
106
+ BlockHeader = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.BlockHeader").msgclass
107
+ BlockData = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.BlockData").msgclass
108
+ BlockMetadata = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.BlockMetadata").msgclass
109
+ OrdererBlockMetadata = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.OrdererBlockMetadata").msgclass
110
+ Status = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.Status").enummodule
111
+ HeaderType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.HeaderType").enummodule
112
+ BlockMetadataIndex = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.BlockMetadataIndex").enummodule
113
+ end
@@ -0,0 +1,61 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: common/policies.proto
3
+
4
+ require 'msp/msp_principal_pb'
5
+ require 'google/protobuf'
6
+
7
+ Google::Protobuf::DescriptorPool.generated_pool.build do
8
+ add_file("common/policies.proto", :syntax => :proto3) do
9
+ add_message "common.Policy" do
10
+ optional :type, :int32, 1
11
+ optional :value, :bytes, 2
12
+ end
13
+ add_enum "common.Policy.PolicyType" do
14
+ value :UNKNOWN, 0
15
+ value :SIGNATURE, 1
16
+ value :MSP, 2
17
+ value :IMPLICIT_META, 3
18
+ end
19
+ add_message "common.SignaturePolicyEnvelope" do
20
+ optional :version, :int32, 1
21
+ optional :rule, :message, 2, "common.SignaturePolicy"
22
+ repeated :identities, :message, 3, "common.MSPPrincipal"
23
+ end
24
+ add_message "common.SignaturePolicy" do
25
+ oneof :Type do
26
+ optional :signed_by, :int32, 1
27
+ optional :n_out_of, :message, 2, "common.SignaturePolicy.NOutOf"
28
+ end
29
+ end
30
+ add_message "common.SignaturePolicy.NOutOf" do
31
+ optional :n, :int32, 1
32
+ repeated :rules, :message, 2, "common.SignaturePolicy"
33
+ end
34
+ add_message "common.ImplicitMetaPolicy" do
35
+ optional :sub_policy, :string, 1
36
+ optional :rule, :enum, 2, "common.ImplicitMetaPolicy.Rule"
37
+ end
38
+ add_enum "common.ImplicitMetaPolicy.Rule" do
39
+ value :ANY, 0
40
+ value :ALL, 1
41
+ value :MAJORITY, 2
42
+ end
43
+ add_message "common.ApplicationPolicy" do
44
+ oneof :Type do
45
+ optional :signature_policy, :message, 1, "common.SignaturePolicyEnvelope"
46
+ optional :channel_config_policy_reference, :string, 2
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ module Common
53
+ Policy = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.Policy").msgclass
54
+ Policy::PolicyType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.Policy.PolicyType").enummodule
55
+ SignaturePolicyEnvelope = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.SignaturePolicyEnvelope").msgclass
56
+ SignaturePolicy = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.SignaturePolicy").msgclass
57
+ SignaturePolicy::NOutOf = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.SignaturePolicy.NOutOf").msgclass
58
+ ImplicitMetaPolicy = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.ImplicitMetaPolicy").msgclass
59
+ ImplicitMetaPolicy::Rule = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.ImplicitMetaPolicy.Rule").enummodule
60
+ ApplicationPolicy = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("common.ApplicationPolicy").msgclass
61
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fabric
4
+ module Accessors
5
+ #
6
+ # Add accessor methods to the given class.
7
+ #
8
+ # Usage: make sure the class has a contract accessor method
9
+ # and then `include Fabric::Accessors::Contract`
10
+ #
11
+ module Contract
12
+ # @!visibility private
13
+ def self.included(base)
14
+ base.send :include, Fabric::Accessors::Network
15
+ end
16
+
17
+ # @!parse include Fabric::Accessors::Network
18
+ # @!parse include Fabric::Accessors::Gateway
19
+
20
+ #
21
+ # Returns the network instance
22
+ #
23
+ # @return [Fabric::Network] network
24
+ # @!parse attr_reader :network
25
+ #
26
+ def network
27
+ contract.network
28
+ end
29
+
30
+ #
31
+ # Returns the contract name
32
+ #
33
+ # @return [String] contract name
34
+ # @!parse attr_reader :contract_name
35
+ #
36
+ def contract_name
37
+ contract.contract_name
38
+ end
39
+
40
+ #
41
+ # Returns the chaincode name
42
+ #
43
+ # @return [String] chaincode name
44
+ # @!parse attr_reader :chaincode_name
45
+ #
46
+ def chaincode_name
47
+ contract.chaincode_name
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fabric
4
+ module Accessors
5
+ #
6
+ # Add accessor methods to the given class.
7
+ #
8
+ # Usage: make sure the class has a gateway accessor method
9
+ # and then `include Fabric::Accessors::Gateway`
10
+ #
11
+ module Gateway
12
+ #
13
+ # Returns the client instance
14
+ #
15
+ # @return [Fabric::Client] client
16
+ # @!parse attr_reader :client
17
+ #
18
+ def client
19
+ gateway.client
20
+ end
21
+
22
+ #
23
+ # Returns the signer identity instance
24
+ #
25
+ # @return [Fabric::Identity] signer
26
+ # @!parse attr_reader :signer
27
+ #
28
+ def signer
29
+ gateway.signer
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fabric
4
+ module Accessors
5
+ #
6
+ # Add accessor methods to the given class.
7
+ #
8
+ # Usage: make sure the class has a network accessor method
9
+ # and then `include Fabric::Accessors::Network`
10
+ #
11
+ module Network
12
+ # @!visibility private
13
+ def self.included(base)
14
+ base.send :include, Fabric::Accessors::Gateway
15
+ end
16
+
17
+ # @!parse include Fabric::Accessors::Gateway
18
+
19
+ #
20
+ # Returns the gateway instance
21
+ #
22
+ # @return [Fabric::Gateway] gateway
23
+ # @!parse attr_reader :gateway
24
+ #
25
+ def gateway
26
+ network.gateway
27
+ end
28
+
29
+ #
30
+ # Network name or the channel name or channel id
31
+ #
32
+ # @return [String] network name
33
+ # @!parse attr_reader :network_name
34
+ #
35
+ def network_name
36
+ network.name
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fabric
4
+ #
5
+ # Gateway Client represents the connection to a Hyperledger Fabric Gateway.
6
+ #
7
+ class Client
8
+ attr_reader :grpc_client, :default_call_options
9
+
10
+ #
11
+ # Initializes a client
12
+ #
13
+ #
14
+ # @overload initialize(grpc_client: client, default_call_options: {}, **client_opts)
15
+ # Initializes a client from a gRPC Gateway client stub
16
+ # @param [Gateway::Gateway::Stub] grpc_client grpc gateway client stub
17
+ # @param [Hash] default_call_options call options to use by default for different operations
18
+ # @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response Keyword Argument call options for
19
+ # *_options default_call_options
20
+ # @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:initialize Keyword arguments for **client_opts
21
+ # @option default_call_options [Hash] :endorse_options default options for endorse call
22
+ # @option default_call_options [Hash] :evaluate_options default options for evaluate call
23
+ # @option default_call_options [Hash] :submit_options default options for submit call
24
+ # @option default_call_options [Hash] :commit_status_options default options for commit_status call
25
+ # @option default_call_options [Hash] :chaincode_events_options default options for chaincode_events call
26
+ # @param [Hash] **client_opts client initialization options
27
+ # @overload initialize(host: host, creds: creds, default_call_options: {}, **client_opts)
28
+ # Instantiates a new gRPC Gateway client stub from the parameters
29
+ # @param [string] host hostname and port of the gateway
30
+ # @param [GRPC::Core::ChannelCredentials|GRPC::Core::XdsChannelCredentials|Symbol] creds channel credentials
31
+ # (usually the CA certificate)
32
+ # @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response Keyword Argument call options for
33
+ # *_options default_call_options
34
+ # @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:initialize Keyword arguments for **client_opts
35
+ # @option default_call_options [Hash] :endorse_options default options for endorse call
36
+ # @option default_call_options [Hash] :evaluate_options default options for evaluate call
37
+ # @option default_call_options [Hash] :submit_options default options for submit call
38
+ # @option default_call_options [Hash] :commit_status_options default options for commit_status call
39
+ # @option default_call_options [Hash] :chaincode_events_options default options for chaincode_events call
40
+ # @param [Hash] **client_opts client initialization options
41
+ #
42
+ def initialize(grpc_client: nil, host: nil, creds: nil, default_call_options: {}, **client_opts)
43
+ if grpc_client
44
+ init_stub grpc_client
45
+ elsif host && creds
46
+ init_grpc_args(host, creds, **client_opts)
47
+ else
48
+ raise InvalidArgument, 'Must pass a Gateway::Gateway::Stub or <host>, <creds>, <client_opts>'
49
+ end
50
+ init_call_options(default_call_options)
51
+ end
52
+
53
+ #
54
+ # Submits an evaluate_request to the gateway to be evaluted.
55
+ #
56
+ # @param [Gateway::EvaluateRequest] evaluate_request
57
+ # @param [Hash] options gRPC call options (merged with default options) @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
58
+ #
59
+ # @return [Gateway::EvaluateResponse] evaluate_response
60
+ #
61
+ def evaluate(evaluate_request, options = {})
62
+ @grpc_client.evaluate(evaluate_request, @default_call_options[:evaluate_options].merge(options))
63
+ end
64
+
65
+ #
66
+ # Submits an endorse_request to the gateway to be evaluted.
67
+ #
68
+ # @param [Gateway::EndorseRequest] endorse_request
69
+ # @param [Hash] options gRPC call options (merged with default options) @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
70
+ #
71
+ # @return [Gateway::EndorseResponse] endorse_response
72
+ #
73
+ def endorse(endorse_request, options = {})
74
+ @grpc_client.endorse(endorse_request, @default_call_options[:endorse_options].merge(options))
75
+ end
76
+
77
+ #
78
+ # Submits an submit_request to the gateway to be evaluted.
79
+ #
80
+ # @param [Gateway::SubmitRequest] submit_request
81
+ # @param [Hash] options gRPC call options (merged with default options) @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
82
+ #
83
+ # @return [Gateway::SubmitResponse] submit_response
84
+ #
85
+ def submit(submit_request, options = {})
86
+ @grpc_client.submit(submit_request, @default_call_options[:submit_options].merge(options))
87
+ end
88
+
89
+ #
90
+ # Submits an commit_status_request to the gateway to be evaluted.
91
+ #
92
+ # @param [Gateway::CommitStatusRequest] commit_status_request
93
+ # @param [Hash] options gRPC call options (merged with default options) @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
94
+ #
95
+ # @return [Gateway::CommitStatusResponse] commit_status_response
96
+ #
97
+ def commit_status(commit_status_request, options = {})
98
+ @grpc_client.commit_status(commit_status_request, @default_call_options[:commit_status_options].merge(options))
99
+ end
100
+
101
+ #
102
+ # Subscribe to chaincode events
103
+ #
104
+ # @note This function has never been utilized or tested. This function is probably wrong, missing a block.
105
+ # @todo add testing!
106
+ #
107
+ # @param [Gateway::ChaincodeEventsRequest] chaincode_events_request
108
+ # @param [Hash] options gRPC call options (merged with default options) @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:server_streamer
109
+ #
110
+ # @return [Gateway::ChaincodeEventsResponse] commit_status_response (probably wrong, this is a stream.)
111
+ #
112
+ def chaincode_events(chaincode_events_request, options = {}, &block)
113
+ @grpc_client.chaincode_events(chaincode_events_request,
114
+ @default_call_options[:chaincode_events_options].merge(options), &block)
115
+ end
116
+
117
+ private
118
+
119
+ def init_stub(stub)
120
+ unless stub.is_a? ::Gateway::Gateway::Stub
121
+ raise InvalidArgument, 'Must pass a Gateway::Gateway::Stub or <host>, <creds>, <client_opts>'
122
+ end
123
+
124
+ @grpc_client = stub
125
+ end
126
+
127
+ def init_grpc_args(host, creds, **client_opts)
128
+ unless creds.is_a?(GRPC::Core::ChannelCredentials) ||
129
+ creds.is_a?(GRPC::Core::XdsChannelCredentials) ||
130
+ creds.is_a?(Symbol)
131
+ raise InvalidArgument, 'creds is not a ChannelCredentials, XdsChannelCredentials, or Symbol'
132
+ end
133
+
134
+ @grpc_client = ::Gateway::Gateway::Stub.new(host, creds, **client_opts)
135
+ end
136
+
137
+ def init_call_options(call_options)
138
+ @default_call_options = call_options
139
+ @default_call_options[:endorse_options] ||= {}
140
+ @default_call_options[:evaluate_options] ||= {}
141
+ @default_call_options[:submit_options] ||= {}
142
+ @default_call_options[:commit_status_options] ||= {}
143
+ @default_call_options[:chaincode_events_options] ||= {}
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fabric
4
+ module Constants
5
+ ## Variables
6
+ CHANNEL_HEADER_VERSION = 1
7
+ end
8
+ end
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fabric
4
+ #
5
+ # Contract represents a smart contract, and allows applications to:
6
+ #
7
+ # - Evaluate transactions that query state from the ledger using the EvaluateTransaction() method.
8
+ #
9
+ # - Submit transactions that store state to the ledger using the SubmitTransaction() method.
10
+ #
11
+ # For more complex transaction invocations, such as including transient data, transactions can be evaluated or
12
+ # submitted using the Evaluate() or Submit() methods respectively. The result of a submitted transaction can be
13
+ # accessed prior to its commit to the ledger using SubmitAsync().
14
+ #
15
+ # By default, proposal, transaction and commit status messages will be signed using the signing implementation
16
+ # specified when connecting the Gateway. In cases where an external client holds the signing credentials, a signing
17
+ # implementation can be omitted when connecting the Gateway and off-line signing can be carried out by:
18
+ #
19
+ # 1. Returning the serialized proposal, transaction or commit status along with its digest to the client for
20
+ # them to generate a signature.
21
+ #
22
+ # 2. With the serialized message and signature received from the client to create a signed proposal, transaction or
23
+ # commit using the Gateway's NewSignedProposal(), NewSignedTransaction() or NewSignedCommit() methods respectively.
24
+ #
25
+ class Contract
26
+ attr_reader :network, :chaincode_name, :contract_name
27
+
28
+ # @!parse include Fabric::Accessors::Network
29
+ # @!parse include Fabric::Accessors::Gateway
30
+ include Fabric::Accessors::Network
31
+
32
+ def initialize(network, chaincode_name, contract_name = '')
33
+ @network = network
34
+ @chaincode_name = chaincode_name
35
+ @contract_name = contract_name
36
+ end
37
+
38
+ #
39
+ # Evaluate a transaction function and return its results. A transaction proposal will be evaluated on endorsing
40
+ # peers but the transaction will not be sent to the ordering service and so will not be committed to the ledger.
41
+ # This can be used for querying the world state.
42
+ #
43
+ # @param [String] transaction_name
44
+ # @param [Array] arguments array of arguments to pass to the transaction
45
+ #
46
+ # @return [String] raw payload of the transaction response
47
+ #
48
+ def evaluate_transaction(transaction_name, arguments = [])
49
+ evaluate(transaction_name, { arguments: arguments })
50
+ end
51
+
52
+ #
53
+ # Submit a transaction to the ledger and return its result only after it is committed to the ledger. The
54
+ # transaction function will be evaluated on endorsing peers and then submitted to the ordering service to be
55
+ # committed to the ledger.
56
+ #
57
+ #
58
+ # @param [String] transaction_name
59
+ # @param [Array] arguments array of arguments to pass to the transaction
60
+ #
61
+ # @return [String] raw payload of the transaction response
62
+ #
63
+ def submit_transaction(transaction_name, arguments = [])
64
+ submit(transaction_name, { arguments: arguments })
65
+ end
66
+
67
+ #
68
+ # Evaluate a transaction function and return its result. This method provides greater control over the transaction
69
+ # proposal content and the endorsing peers on which it is evaluated. This allows transaction functions to be
70
+ # evaluated where the proposal must include transient data, or that will access ledger data with key-based
71
+ # endorsement policies.
72
+ #
73
+ # @param [String] transaction_name
74
+ # @param [Hash] proposal_options
75
+ # @option proposal_options [Array] :arguments array of arguments to pass to the transaction
76
+ # @option proposal_options [Hash] :transient_data Private data passed to the transaction function but not recorded
77
+ # on the ledger.
78
+ # @option proposal_options [Array] :endorsing_organizations Specifies the set of organizations that will attempt to
79
+ # endorse the proposal.
80
+ #
81
+ # @return [String] Raw evaluation response payload
82
+ #
83
+ def evaluate(transaction_name, proposal_options = {})
84
+ new_proposal(transaction_name, **proposal_options).evaluate
85
+ end
86
+
87
+ #
88
+ # Submit a transaction to the ledger and return its result only after it is committed to the ledger. The
89
+ # transaction function will be evaluated on endorsing peers and then submitted to the ordering service to be
90
+ # committed to the ledger.
91
+ #
92
+ # @param [String] transaction_name
93
+ # @param [Hash] proposal_options
94
+ # @option proposal_options [Array] :arguments array of arguments to pass to the transaction
95
+ # @option proposal_options [Hash] :transient_data Private data passed to the transaction function but not recorded
96
+ # on the ledger.
97
+ # @option proposal_options [Array] :endorsing_organizations Specifies the set of organizations that will attempt to
98
+ # endorse the proposal.
99
+ #
100
+ # @return [String] Raw evaluation response payload
101
+ #
102
+ def submit(transaction_name, proposal_options = {})
103
+ transaction = new_proposal(transaction_name, **proposal_options).endorse
104
+ transaction.submit
105
+
106
+ transaction.result
107
+ end
108
+
109
+ #
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)
113
+ #
114
+ # not 100% sure if grpc support is necessary for this.
115
+ #
116
+ def submit_async
117
+ raise NotYetImplemented
118
+ end
119
+
120
+ #
121
+ # Creates a transaction proposal that can be evaluated or endorsed. Supports off-line signing flow.
122
+ #
123
+ # @param [String] transaction_name transaction name (first argument unshifted into the argument array)
124
+ # @param [Array<String>] arguments array of arguments to pass to the transaction
125
+ # @param [Hash] transient_data Private data passed to the transaction function but not recorded on the ledger.
126
+ # @param [Array] endorsing_organizations Specifies the set of organizations that will attempt to endorse the
127
+ # proposal.
128
+ #
129
+ # @return [Fabric::Proposal] signed unexecuted proposal
130
+ #
131
+ def new_proposal(transaction_name, arguments: [], transient_data: {}, endorsing_organizations: [])
132
+ proposed_transaction = ProposedTransaction.new(
133
+ self,
134
+ qualified_transaction_name(transaction_name),
135
+ arguments: arguments,
136
+ transient_data: transient_data,
137
+ endorsing_organizations: endorsing_organizations
138
+ )
139
+ Proposal.new(proposed_transaction)
140
+ end
141
+
142
+ #
143
+ # Generates the qualified transaction name for the contract. (prepends the contract name to the transaction name if
144
+ # contract name is set)
145
+ #
146
+ # @param [string] transaction_name
147
+ #
148
+ # @return [string] qualified transaction name
149
+ #
150
+ def qualified_transaction_name(transaction_name)
151
+ contract_name.nil? || contract_name.empty? ? transaction_name : "#{contract_name}:#{transaction_name}"
152
+ end
153
+ end
154
+ end