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,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,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
|