Class: Fabric::ProposedTransaction

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

Overview

Manages the instantiation and creation of the Gateway::ProposedTransaction Protobuf Message.

Adapted from official fabric-gateway SDK ProposalBuilder and hyperledger-fabric-sdk: https://github.com/hyperledger/fabric-gateway/blob/1518e03ed3d6db1b6809e23e61a92744fd18e724/node/src/proposalbuilder.ts https://github.com/kirshin/hyperledger-fabric-sdk/blob/95a5a1a37001852312df25946e960a9ff149207e/lib/fabric/proposal.rb

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(contract, transaction_name, arguments: [], transient_data: {}, endorsing_organizations: []) ⇒ ProposedTransaction

Returns a new instance of ProposedTransaction.



26
27
28
29
30
31
32
33
34
# File 'lib/fabric/entities/proposed_transaction.rb', line 26

def initialize(contract, transaction_name, arguments: [], transient_data: {}, endorsing_organizations: [])
  @contract = contract
  @transaction_name = transaction_name
  @arguments = arguments
  @transient_data = transient_data
  @endorsing_organizations = endorsing_organizations

  generate_proposed_transaction
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments.



11
12
13
# File 'lib/fabric/entities/proposed_transaction.rb', line 11

def arguments
  @arguments
end

#contractObject (readonly)

Returns the value of attribute contract.



11
12
13
# File 'lib/fabric/entities/proposed_transaction.rb', line 11

def contract
  @contract
end

#endorsing_organizationsObject (readonly)

Specifies the set of organizations that will attempt to endorse the proposal. No other organizations' peers will be sent this proposal. This is usually used in conjunction with transientData for private data scenarios.



20
21
22
# File 'lib/fabric/entities/proposed_transaction.rb', line 20

def endorsing_organizations
  @endorsing_organizations
end

#proposed_transactionObject (readonly)

Returns the value of attribute proposed_transaction.



11
12
13
# File 'lib/fabric/entities/proposed_transaction.rb', line 11

def proposed_transaction
  @proposed_transaction
end

#transaction_nameObject (readonly)

Returns the value of attribute transaction_name.



11
12
13
# File 'lib/fabric/entities/proposed_transaction.rb', line 11

def transaction_name
  @transaction_name
end

#transient_dataObject (readonly)

Returns the value of attribute transient_data.



11
12
13
# File 'lib/fabric/entities/proposed_transaction.rb', line 11

def transient_data
  @transient_data
end

Instance Method Details

#as_protoGateway::ProposedTransaction

Returns the protobuf message instance

Returns:

  • (Gateway::ProposedTransaction)

    protobuf message instance



139
140
141
# File 'lib/fabric/entities/proposed_transaction.rb', line 139

def as_proto
  proposed_transaction
end

#chaincode_idObject



77
78
79
# File 'lib/fabric/entities/proposed_transaction.rb', line 77

def chaincode_id
  Protos::ChaincodeID.new name: chaincode_name
end

#chaincode_proposal_payloadObject



81
82
83
84
85
86
87
88
89
# File 'lib/fabric/entities/proposed_transaction.rb', line 81

def chaincode_proposal_payload
  chaincode_input = Protos::ChaincodeInput.new args: [transaction_name] + arguments
  chaincode_spec = Protos::ChaincodeSpec.new type: Protos::ChaincodeSpec::Type::NODE,
                                             chaincode_id: chaincode_id,
                                             input: chaincode_input
  input = Protos::ChaincodeInvocationSpec.new chaincode_spec: chaincode_spec

  Protos::ChaincodeProposalPayload.new input: input.to_proto, TransientMap: transient_data
end

#channel_headerObject



65
66
67
68
69
70
71
# File 'lib/fabric/entities/proposed_transaction.rb', line 65

def channel_header
  Common::ChannelHeader.new type: Common::HeaderType::ENDORSER_TRANSACTION,
                            channel_id: network_name, tx_id: transaction_id,
                            extension: channel_header_extension.to_proto,
                            timestamp: timestamp, epoch: 0
  # version: Constants::CHANNEL_HEADER_VERSION # official SDK does not send this.
end

#channel_header_extensionObject



73
74
75
# File 'lib/fabric/entities/proposed_transaction.rb', line 73

def channel_header_extension
  Protos::ChaincodeHeaderExtension.new chaincode_id: chaincode_id
end

#generate_proposed_transactionGateway::ProposedTransaction

Builds the proposed transaction protobuf message

Returns:

  • (Gateway::ProposedTransaction)


41
42
43
44
45
46
47
# File 'lib/fabric/entities/proposed_transaction.rb', line 41

def generate_proposed_transaction
  @proposed_transaction = ::Gateway::ProposedTransaction.new(
    transaction_id: transaction_id,
    proposal: signed_proposal,
    endorsing_organizations: endorsing_organizations
  )
end

#headerObject



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

def header
  Common::Header.new channel_header: channel_header.to_proto,
                     signature_header: signature_header.to_proto
end

#nonceString

Generates a random nonce

Returns:

  • (String)

    random nonce



107
108
109
# File 'lib/fabric/entities/proposed_transaction.rb', line 107

def nonce
  @nonce ||= signer.crypto_suite.generate_nonce
end

#proposalObject



55
56
57
58
# File 'lib/fabric/entities/proposed_transaction.rb', line 55

def proposal
  @proposal ||= Protos::Proposal.new header: header.to_proto,
                                     payload: chaincode_proposal_payload.to_proto
end

#signature_headerCommon::SignatureHeader

Generates a SignatureHeader protobuf message from the signer and nonce

Returns:

  • (Common::SignatureHeader)

    signature header protobuf message instance



126
127
128
# File 'lib/fabric/entities/proposed_transaction.rb', line 126

def signature_header
  Common::SignatureHeader.new creator: signer.to_proto, nonce: nonce
end

#signed_proposalObject



49
50
51
52
53
# File 'lib/fabric/entities/proposed_transaction.rb', line 49

def signed_proposal
  @signed_proposal ||= Protos::SignedProposal.new(
    proposal_bytes: proposal.to_proto
  )
end

#timestampGoogle::Protobuf::Timestamp

Returns the current timestamp

Returns:

  • (Google::Protobuf::Timestamp)

    gRPC timestamp



96
97
98
99
100
# File 'lib/fabric/entities/proposed_transaction.rb', line 96

def timestamp
  now = Time.now

  @timestamp ||= Google::Protobuf::Timestamp.new seconds: now.to_i, nanos: now.nsec
end

#to_json(options = {}) ⇒ String

Returns the serialized JSON form of the proposed transaction

Parameters:

Returns:

  • (String)

    serialized JSON form of the proposed transaction



159
160
161
# File 'lib/fabric/entities/proposed_transaction.rb', line 159

def to_json(options = {})
  proposed_transaction.to_json(options)
end

#to_protoString

Returns the serialized Protobuf binary form of the proposed transaction

Returns:

  • (String)

    serialized Protobuf binary form of the proposed transaction



148
149
150
# File 'lib/fabric/entities/proposed_transaction.rb', line 148

def to_proto
  proposed_transaction.to_proto
end

#transaction_idString

Generates a unique transaction ID for the transaction based on a random number and the signer or returns the existing transaction ID if it has already been generated.

Returns:

  • (String)

    transaction ID



117
118
119
# File 'lib/fabric/entities/proposed_transaction.rb', line 117

def transaction_id
  @transaction_id ||= signer.crypto_suite.hexdigest(nonce + signer.to_proto)
end