Class: Fabric::Proposal

Inherits:
Object
  • Object
show all
Includes:
Accessors::Contract
Defined in:
lib/fabric/entities/proposal.rb

Overview

Proposal represents a transaction proposal that can be sent to peers for endorsement or evaluated as a query.

Combined ProposalBuilder with Proposal. Utilizing instance variables and functions in proposal seem adaquate enough to fully create the proposal. ProposalBuilder did not seem like a native ruby design pattern.

Instance Attribute Summary collapse

Attributes included from Accessors::Contract

#chaincode_name, #contract_name, #network

Attributes included from Accessors::Gateway

#client, #signer

Attributes included from Accessors::Network

#gateway, #network_name

Instance Method Summary collapse

Constructor Details

#initialize(proposed_transaction) ⇒ Proposal

Instantiates a new Proposal

Parameters:



17
18
19
# File 'lib/fabric/entities/proposal.rb', line 17

def initialize(proposed_transaction)
  @proposed_transaction = proposed_transaction
end

Instance Attribute Details

#proposed_transactionObject (readonly)

Returns the value of attribute proposed_transaction.



10
11
12
# File 'lib/fabric/entities/proposal.rb', line 10

def proposed_transaction
  @proposed_transaction
end

Instance Method Details

#contractObject



21
22
23
# File 'lib/fabric/entities/proposal.rb', line 21

def contract
  @proposed_transaction.contract
end

#digestString

Proposal digest which can be utilized for offline signing. If signing offline, call signature= to set signature once computed.

Returns:

  • (String)

    raw binary digest of the proposal message.



72
73
74
# File 'lib/fabric/entities/proposal.rb', line 72

def digest
  Fabric.crypto_suite.digest(proposal.to_proto)
end

#endorse(options = {}) ⇒ Fabric::Transaction

Obtain endorsement for the transaction proposal from sufficient peers to allow it to be committed to the ledger.

Parameters:

Returns:

Raises:



137
138
139
140
141
142
143
144
145
146
# File 'lib/fabric/entities/proposal.rb', line 137

def endorse(options = {})
  sign
  endorse_response = client.endorse(new_endorse_request, options)

  raise Fabric::Error, 'Missing transaction envelope' if endorse_response.prepared_transaction.nil?

  prepared_transaction = new_prepared_transaction(endorse_response.prepared_transaction)

  Fabric::Transaction.new(network, prepared_transaction)
end

#evaluate(options = {}) ⇒ String

Evaluate the transaction proposal and obtain its result, without updating the ledger. This runs the transaction on a peer to obtain a transaction result, but does not submit the endorsed transaction to the orderer to be committed to the ledger.

Parameters:

Returns:

  • (String)

    The result returned by the transaction function



123
124
125
126
127
128
# File 'lib/fabric/entities/proposal.rb', line 123

def evaluate(options = {})
  sign

  evaluate_response = client.evaluate(new_evaluate_request, options)
  evaluate_response.result.payload
end

#new_endorse_requestGateway::EndorseRequest

Creates a new endorse request from this proposal.

Returns:

  • (Gateway::EndorseRequest)

    EndorseRequest protobuf message



166
167
168
169
170
171
172
173
# File 'lib/fabric/entities/proposal.rb', line 166

def new_endorse_request
  ::Gateway::EndorseRequest.new(
    transaction_id: transaction_id,
    channel_id: network_name,
    proposed_transaction: signed_proposal,
    endorsing_organizations: proposed_transaction.endorsing_organizations
  )
end

#new_evaluate_requestGateway::EvaluateRequest

Generates an evaluate request from this proposal.

Returns:

  • (Gateway::EvaluateRequest)

    evaluation request with the current proposal



153
154
155
156
157
158
159
# File 'lib/fabric/entities/proposal.rb', line 153

def new_evaluate_request
  ::Gateway::EvaluateRequest.new(
    channel_id: network_name,
    proposed_transaction: signed_proposal,
    target_organizations: proposed_transaction.endorsing_organizations
  )
end

#new_prepared_transaction(envelope) ⇒ Gateway::PreparedTransaction

Creates a new prepared transaction from a transaction envelope.

Parameters:

  • envelope (Common::Envelope)

    transaction envelope

Returns:

  • (Gateway::PreparedTransaction)

    prepared transaction protobuf message



182
183
184
185
186
187
# File 'lib/fabric/entities/proposal.rb', line 182

def new_prepared_transaction(envelope)
  ::Gateway::PreparedTransaction.new(
    transaction_id: transaction_id,
    envelope: envelope
  )
end

#proposalProtos::Proposal|nil

Returns the proposal message as a protobuf Message object.

Returns:

  • (Protos::Proposal|nil)

    Proposal message



36
37
38
# File 'lib/fabric/entities/proposal.rb', line 36

def proposal
  proposed_transaction.proposal
end

#signObject

Utilizes the signer to sign the proposal message if it has not been signed yet.



108
109
110
111
112
# File 'lib/fabric/entities/proposal.rb', line 108

def sign
  return if signed?

  self.signature = signer.sign proposal.to_proto
end

#signatureString

Returns the signed proposal signature

Returns:

  • (String)

    Raw byte string signature



91
92
93
# File 'lib/fabric/entities/proposal.rb', line 91

def signature
  proposed_transaction.signed_proposal.signature
end

#signature=(signature) ⇒ Object

Sets the signature of the signed proposal in the proposed transaction

Parameters:

  • signature (String)

    raw byte string signature of the proposal message (should be the signature of the proposed message digest)



82
83
84
# File 'lib/fabric/entities/proposal.rb', line 82

def signature=(signature)
  proposed_transaction.signed_proposal.signature = signature
end

#signed?Boolean

Returns true if the signed proposal has a signature

Returns:

  • (Boolean)

    true|false



100
101
102
103
# File 'lib/fabric/entities/proposal.rb', line 100

def signed?
  # signature cannot be nil because google protobuf won't let it
  !proposed_transaction.signed_proposal.signature.empty?
end

#signed_proposalProtos::SignedProposal|nil

Returns the signed proposal

Fabric message naming scheme is a mess: ProposedTransaction has a Proposal which is a SignedProposal which has a Proposal which is a Proposal so.... which proposal do you want to access? Adding this function for clarity

Returns:

  • (Protos::SignedProposal|nil)

    SignedProposal message



52
53
54
# File 'lib/fabric/entities/proposal.rb', line 52

def signed_proposal
  proposed_transaction.proposed_transaction.proposal
end

#to_protoString

Serialized bytes of the proposal message in proto3 format.

Returns:

  • (String)

    Binary representation of the proposal message.



61
62
63
# File 'lib/fabric/entities/proposal.rb', line 61

def to_proto
  proposed_transaction.to_proto
end

#transaction_idObject



27
28
29
# File 'lib/fabric/entities/proposal.rb', line 27

def transaction_id
  proposed_transaction.transaction_id
end