mirror of
https://github.com/corda/corda.git
synced 2024-12-19 21:17:58 +00:00
Remove type-specific transaction builder. Normal transactions should use TransactionBuilder and notary change transactions are created directly.
This commit is contained in:
parent
59edd6f9ae
commit
4ca8b8d681
@ -80,7 +80,7 @@ interface ContractState {
|
||||
* A _participant_ is any party that is able to consume this state in a valid transaction.
|
||||
*
|
||||
* The list of participants is required for certain types of transactions. For example, when changing the notary
|
||||
* for this state ([TransactionType.NotaryChange]), every participant has to be involved and approve the transaction
|
||||
* for this state, every participant has to be involved and approve the transaction
|
||||
* so that they receive the updated state, and don't end up in a situation where they can no longer use a state
|
||||
* they possess, since someone consumed that state during the notary change process.
|
||||
*
|
||||
|
@ -1,17 +0,0 @@
|
||||
package net.corda.core.contracts
|
||||
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
|
||||
/** Defines transaction build & validation logic for a specific transaction type */
|
||||
@CordaSerializable
|
||||
// TODO: remove this concept
|
||||
sealed class TransactionType {
|
||||
/** A general transaction type where transaction validity is determined by custom contract code */
|
||||
object General : TransactionType() {
|
||||
/** Just uses the default [TransactionBuilder] with no special logic */
|
||||
@Deprecated("Use TransactionBuilder directly instead", ReplaceWith("TransactionBuilder()"))
|
||||
class Builder(notary: Party?) : TransactionBuilder(notary)
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ import java.security.PublicKey
|
||||
*
|
||||
* Example - issuing a multi-lateral agreement which requires N signatures:
|
||||
*
|
||||
* val builder = TransactionType.General.Builder(notaryRef)
|
||||
* val builder = TransactionBuilder(notaryRef)
|
||||
* val issueCommand = Command(Agreement.Commands.Issue(), state.participants)
|
||||
*
|
||||
* builder.withItems(state, issueCommand)
|
||||
|
@ -51,7 +51,7 @@ class ContractUpgradeFlow<OldState : ContractState, out NewState : ContractState
|
||||
privacySalt: PrivacySalt
|
||||
): TransactionBuilder {
|
||||
val contractUpgrade = upgradedContractClass.newInstance()
|
||||
return TransactionType.General.Builder(stateRef.state.notary)
|
||||
return TransactionBuilder(stateRef.state.notary)
|
||||
.withItems(
|
||||
stateRef,
|
||||
contractUpgrade.upgrade(stateRef.state.data),
|
||||
|
Binary file not shown.
@ -2,6 +2,7 @@ package net.corda.core.contracts
|
||||
|
||||
import net.corda.core.crypto.newSecureRandom
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
@ -32,14 +33,14 @@ class TransactionGraphSearchTests : TestDependencyInjectionBase() {
|
||||
val megaCorpServices = MockServices(MEGA_CORP_KEY)
|
||||
val notaryServices = MockServices(DUMMY_NOTARY_KEY)
|
||||
|
||||
val originBuilder = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val originBuilder = TransactionBuilder(DUMMY_NOTARY)
|
||||
originBuilder.addOutputState(DummyState(random31BitValue()))
|
||||
originBuilder.addCommand(command, MEGA_CORP_PUBKEY)
|
||||
|
||||
val originPtx = megaCorpServices.signInitialTransaction(originBuilder)
|
||||
val originTx = notaryServices.addSignature(originPtx)
|
||||
|
||||
val inputBuilder = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val inputBuilder = TransactionBuilder(DUMMY_NOTARY)
|
||||
inputBuilder.addInputState(originTx.tx.outRef<DummyState>(0))
|
||||
|
||||
val inputPtx = megaCorpServices.signInitialTransaction(inputBuilder)
|
||||
|
@ -2,11 +2,11 @@ package net.corda.core.flows
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.contracts.Command
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.contracts.requireThat
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.unwrap
|
||||
import net.corda.testing.MINI_CORP_KEY
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
@ -84,7 +84,7 @@ class CollectSignaturesFlowTests {
|
||||
val notary = serviceHub.networkMapCache.notaryNodes.single().notaryIdentity
|
||||
|
||||
val command = Command(DummyContract.Commands.Create(), state.participants.map { it.owningKey })
|
||||
val builder = TransactionType.General.Builder(notary = notary).withItems(state, command)
|
||||
val builder = TransactionBuilder(notary).withItems(state, command)
|
||||
val ptx = serviceHub.signInitialTransaction(builder)
|
||||
val stx = subFlow(CollectSignaturesFlow(ptx))
|
||||
val ftx = subFlow(FinalityFlow(stx)).single()
|
||||
@ -104,7 +104,7 @@ class CollectSignaturesFlowTests {
|
||||
override fun call(): SignedTransaction {
|
||||
val notary = serviceHub.networkMapCache.notaryNodes.single().notaryIdentity
|
||||
val command = Command(DummyContract.Commands.Create(), state.participants.map { it.owningKey })
|
||||
val builder = TransactionType.General.Builder(notary = notary).withItems(state, command)
|
||||
val builder = TransactionBuilder(notary).withItems(state, command)
|
||||
val ptx = serviceHub.signInitialTransaction(builder)
|
||||
val stx = subFlow(CollectSignaturesFlow(ptx))
|
||||
val ftx = subFlow(FinalityFlow(stx)).single()
|
||||
|
@ -4,7 +4,6 @@ import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.GBP
|
||||
import net.corda.core.contracts.Issued
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
|
@ -67,7 +67,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
|
||||
|
||||
fun generateInitial(owner: PartyAndReference, magicNumber: Int, notary: Party): TransactionBuilder {
|
||||
val state = State(magicNumber)
|
||||
return TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
return TransactionBuilder(notary).withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ class TransactionSerializationTests : TestDependencyInjectionBase() {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(
|
||||
tx = TransactionBuilder(DUMMY_NOTARY).withItems(
|
||||
inputState, outputState, changeState, Command(TestCash.Commands.Move(), arrayListOf(MEGA_CORP.owningKey))
|
||||
)
|
||||
}
|
||||
@ -86,7 +86,7 @@ class TransactionSerializationTests : TestDependencyInjectionBase() {
|
||||
|
||||
// If the signature was replaced in transit, we don't like it.
|
||||
assertFailsWith(SignatureException::class) {
|
||||
val tx2 = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState, outputState, changeState,
|
||||
val tx2 = TransactionBuilder(DUMMY_NOTARY).withItems(inputState, outputState, changeState,
|
||||
Command(TestCash.Commands.Move(), DUMMY_KEY_2.public))
|
||||
|
||||
val ptx2 = notaryServices.signInitialTransaction(tx2)
|
||||
|
@ -96,7 +96,6 @@ Where:
|
||||
* ``id`` is the transaction's merkle root hash'
|
||||
* ``notary`` is the transaction's notary. If there are inputs these must have the same notary on their source transactions.
|
||||
* ``timeWindow`` is the transaction's timestamp and defines the acceptable delay for notarisation.
|
||||
* ``type`` is the class of Transaction. Normal ledger data transactions are ``TransactionType.General``, but migration of states to a new notary uses ``TransactionType.NotaryChange``.
|
||||
|
||||
requireThat()
|
||||
^^^^^^^^^^^^^
|
||||
|
@ -9,36 +9,6 @@ API: Transactions
|
||||
|
||||
.. note:: Before reading this page, you should be familiar with the key concepts of :doc:`key-concepts-transactions`.
|
||||
|
||||
Transaction types
|
||||
-----------------
|
||||
There are two types of transaction in Corda:
|
||||
|
||||
* ``TransactionType.NotaryChange``, used to change the notary for a set of states
|
||||
* ``TransactionType.General``, for transactions other than notary-change transactions
|
||||
|
||||
Notary-change transactions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
A single Corda network will usually have multiple notary services. To commit a transaction, we require a signature
|
||||
from the notary service associated with each input state. If we tried to commit a transaction where the input
|
||||
states were associated with different notary services, the transaction would require a signature from multiple notary
|
||||
services, creating a complicated multi-phase commit scenario. To prevent this, every input state in a transaction
|
||||
must be associated the same notary.
|
||||
|
||||
However, we will often need to create a transaction involving input states associated with different notaries. Before
|
||||
we can create this transaction, we will need to change the notary service associated with each state by:
|
||||
|
||||
* Deciding which notary service we want to notarise the transaction
|
||||
* For each set of inputs states that point to the same notary service that isn't the desired notary service, creating a
|
||||
``TransactionType.NotaryChange`` transaction that:
|
||||
|
||||
* Consumes the input states pointing to the old notary
|
||||
* Outputs the same states, but that now point to the new notary
|
||||
|
||||
* Using the outputs of the notary-change transactions as inputs to a standard ``TransactionType.General`` transaction
|
||||
|
||||
In practice, this process is handled automatically by a built-in flow called ``NotaryChangeFlow``. See
|
||||
:doc:`api-flows` for more details.
|
||||
|
||||
Transaction workflow
|
||||
--------------------
|
||||
There are four states the transaction can occupy:
|
||||
@ -590,3 +560,22 @@ Notarising and recording
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Notarising and recording a transaction is handled by a built-in flow called ``FinalityFlow``. See
|
||||
:doc:`api-flows` for more details.
|
||||
|
||||
Notary-change transactions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
A single Corda network will usually have multiple notary services. To commit a transaction, we require a signature
|
||||
from the notary service associated with each input state. If we tried to commit a transaction where the input
|
||||
states were associated with different notary services, the transaction would require a signature from multiple notary
|
||||
services, creating a complicated multi-phase commit scenario. To prevent this, every input state in a transaction
|
||||
must be associated with the same notary.
|
||||
|
||||
However, we will often need to create a transaction involving input states associated with different notaries. Before
|
||||
we can create this transaction, we will need to change the notary service associated with each state by:
|
||||
|
||||
* Deciding which notary service we want to notarise the transaction
|
||||
* Creating a special ``NotaryChangeWireTransaction`` that consumes the input states pointing to the old notary and
|
||||
produces outputs which are identical but point to the new notary service
|
||||
* Using the outputs of the notary-change transactions as inputs to a standard transaction
|
||||
|
||||
In practice, this process is handled automatically by a built-in flow called ``NotaryChangeFlow``. See
|
||||
:doc:`api-flows` for more details.
|
@ -7,6 +7,9 @@ from the previous milestone release.
|
||||
UNRELEASED
|
||||
----------
|
||||
|
||||
* The concept of ``TransactionType`` has been removed. Transactions no longer carry a `type` property. All usages of
|
||||
``TransactionType.General.Builder()`` have to be replaced with ``TransactionBuilder()``.
|
||||
|
||||
* Changes in ``NodeInfo``:
|
||||
|
||||
* ``PhysicalLocation`` was renamed to ``WorldMapLocation`` to emphasise that it doesn't need to map to a truly physical
|
||||
|
@ -5,7 +5,6 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.corda.contracts.asset.Cash;
|
||||
import net.corda.core.contracts.*;
|
||||
import net.corda.core.contracts.TransactionType.General;
|
||||
import net.corda.core.crypto.DigitalSignature;
|
||||
import net.corda.core.crypto.SecureHash;
|
||||
import net.corda.core.flows.*;
|
||||
|
@ -3,7 +3,6 @@ package net.corda.docs
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.contracts.TransactionType.General
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.flows.*
|
||||
|
@ -5,7 +5,6 @@ import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.Issued
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.flows.*
|
||||
@ -16,6 +15,7 @@ import net.corda.core.node.services.queryBy
|
||||
import net.corda.core.node.services.vault.QueryCriteria
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.unwrap
|
||||
import java.util.*
|
||||
|
||||
@ -180,7 +180,7 @@ class ForeignExchangeFlow(val tradeId: String,
|
||||
// This is the correct way to create a TransactionBuilder,
|
||||
// do not construct directly.
|
||||
// We also set the notary to match the input notary
|
||||
val builder = TransactionType.General.Builder(ourStates.inputs.first().state.notary)
|
||||
val builder = TransactionBuilder(ourStates.inputs.first().state.notary)
|
||||
|
||||
// Add the move commands and key to indicate all the respective owners and need to sign
|
||||
val ourSigners = ourStates.inputs.map { it.state.data.owner.owningKey }.toSet()
|
||||
|
@ -16,6 +16,7 @@ import net.corda.core.node.services.linearHeadsOfType
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.core.utilities.unwrap
|
||||
import java.security.PublicKey
|
||||
@ -122,7 +123,7 @@ class SubmitTradeApprovalFlow(val tradeId: String,
|
||||
// identify a notary. This might also be done external to the flow
|
||||
val notary = serviceHub.networkMapCache.getAnyNotary()
|
||||
// Create the TransactionBuilder and populate with the new state.
|
||||
val tx = TransactionType.General.Builder(notary)
|
||||
val tx = TransactionBuilder(notary)
|
||||
.withItems(tradeProposal, Command(TradeApprovalContract.Commands.Issue(), listOf(tradeProposal.source.owningKey)))
|
||||
tx.setTimeWindow(serviceHub.clock.instant(), 60.seconds)
|
||||
// We can automatically sign as there is no untrusted data.
|
||||
@ -177,9 +178,7 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow
|
||||
// To destroy the old proposal state and replace with the new completion state.
|
||||
// Also add the Completed command with keys of all parties to signal the Tx purpose
|
||||
// to the Contract verify method.
|
||||
val tx = TransactionType.
|
||||
General.
|
||||
Builder(notary).
|
||||
val tx = TransactionBuilder(notary).
|
||||
withItems(
|
||||
latestRecord,
|
||||
newState,
|
||||
|
@ -104,7 +104,7 @@ transaction and send it to the recipient node:
|
||||
|
||||
// Create a trivial transaction that just passes across the attachment - in normal cases there would be
|
||||
// inputs, outputs and commands that refer to this attachment.
|
||||
val ptx = TransactionType.General.Builder(notary = null)
|
||||
val ptx = TransactionBuilder(notary = null)
|
||||
require(rpc.attachmentExists(PROSPECTUS_HASH))
|
||||
ptx.addAttachment(PROSPECTUS_HASH)
|
||||
// TODO: Add a dummy state and specify a notary, so that the tx hash is randomised each time and the demo can be repeated.
|
||||
|
@ -4,102 +4,102 @@ Building transactions
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Understanding and implementing transactions in Corda is key to building
|
||||
and implementing real world smart contracts. It is only through
|
||||
construction of valid Corda transactions containing appropriate data
|
||||
that nodes on the ledger can map real world business objects into a
|
||||
shared digital view of the data in the Corda ledger. More importantly as
|
||||
the developer of new smart contracts it is the code which determines
|
||||
what data is well formed and what data should be rejected as mistakes,
|
||||
or to prevent malicious activity. This document details some of the
|
||||
considerations and APIs used to when constructing transactions as part
|
||||
of a flow.
|
||||
Understanding and implementing transactions in Corda is key to building
|
||||
and implementing real world smart contracts. It is only through
|
||||
construction of valid Corda transactions containing appropriate data
|
||||
that nodes on the ledger can map real world business objects into a
|
||||
shared digital view of the data in the Corda ledger. More importantly as
|
||||
the developer of new smart contracts it is the code which determines
|
||||
what data is well formed and what data should be rejected as mistakes,
|
||||
or to prevent malicious activity. This document details some of the
|
||||
considerations and APIs used to when constructing transactions as part
|
||||
of a flow.
|
||||
|
||||
The Basic Lifecycle Of Transactions
|
||||
-----------------------------------
|
||||
|
||||
Transactions in Corda are constructed in stages and contain a number of
|
||||
elements. In particular a transaction’s core data structure is the
|
||||
``net.corda.core.transactions.WireTransaction``, which is usually
|
||||
manipulated via a
|
||||
``net.corda.core.contracts.General.TransactionBuilder`` and contains:
|
||||
Transactions in Corda are constructed in stages and contain a number of
|
||||
elements. In particular a transaction’s core data structure is the
|
||||
``net.corda.core.transactions.WireTransaction``, which is usually
|
||||
manipulated via a
|
||||
``net.corda.core.transactions.TransactionBuilder`` and contains:
|
||||
|
||||
1. A set of Input state references that will be consumed by the final
|
||||
accepted transaction.
|
||||
1. A set of Input state references that will be consumed by the final
|
||||
accepted transaction.
|
||||
|
||||
2. A set of Output states to create/replace the consumed states and thus
|
||||
become the new latest versions of data on the ledger.
|
||||
2. A set of Output states to create/replace the consumed states and thus
|
||||
become the new latest versions of data on the ledger.
|
||||
|
||||
3. A set of ``Attachment`` items which can contain legal documents, contract
|
||||
code, or private encrypted sections as an extension beyond the native
|
||||
contract states.
|
||||
3. A set of ``Attachment`` items which can contain legal documents, contract
|
||||
code, or private encrypted sections as an extension beyond the native
|
||||
contract states.
|
||||
|
||||
4. A set of ``Command`` items which give a context to the type of ledger
|
||||
transition that is encoded in the transaction. Also each command has an
|
||||
associated set of signer keys, which will be required to sign the
|
||||
transaction.
|
||||
4. A set of ``Command`` items which give a context to the type of ledger
|
||||
transition that is encoded in the transaction. Also each command has an
|
||||
associated set of signer keys, which will be required to sign the
|
||||
transaction.
|
||||
|
||||
5. A signers list, which is populated by the ``TransactionBuilder`` to
|
||||
be the union of the signers on the individual Command objects.
|
||||
5. A signers list, which is populated by the ``TransactionBuilder`` to
|
||||
be the union of the signers on the individual Command objects.
|
||||
|
||||
6. A notary identity to specify the Notary node which is tracking the
|
||||
state consumption. (If the input states are registered with different
|
||||
notary nodes the flow will have to insert additional ``NotaryChange``
|
||||
transactions to migrate the states across to a consistent notary node,
|
||||
before being allowed to mutate any states.)
|
||||
6. A notary identity to specify the Notary node which is tracking the
|
||||
state consumption. (If the input states are registered with different
|
||||
notary nodes the flow will have to insert additional ``NotaryChange``
|
||||
transactions to migrate the states across to a consistent notary node,
|
||||
before being allowed to mutate any states.)
|
||||
|
||||
7. Optionally a timestamp that can used in the Notary to time bound the
|
||||
period in which the proposed transaction stays valid.
|
||||
7. Optionally a timestamp that can used in the Notary to time bound the
|
||||
period in which the proposed transaction stays valid.
|
||||
|
||||
Typically, the ``WireTransaction`` should be regarded as a proposal and
|
||||
may need to be exchanged back and forth between parties before it can be
|
||||
fully populated. This is an immediate consequence of the Corda privacy
|
||||
model, which means that the input states are likely to be unknown to the
|
||||
other node.
|
||||
Typically, the ``WireTransaction`` should be regarded as a proposal and
|
||||
may need to be exchanged back and forth between parties before it can be
|
||||
fully populated. This is an immediate consequence of the Corda privacy
|
||||
model, which means that the input states are likely to be unknown to the
|
||||
other node.
|
||||
|
||||
Once the proposed data is fully populated the flow code should freeze
|
||||
the ``WireTransaction`` and form a ``SignedTransaction``. This is key to
|
||||
the ledger agreement process, as once a flow has attached a node’s
|
||||
signature it has stated that all details of the transaction are
|
||||
acceptable to it. A flow should take care not to attach signatures to
|
||||
intermediate data, which might be maliciously used to construct a
|
||||
different ``SignedTransaction``. For instance in a foreign exchange
|
||||
scenario we shouldn't send a ``SignedTransaction`` with only our sell
|
||||
side populated as that could be used to take the money without the
|
||||
expected return of the other currency. Also, it is best practice for
|
||||
flows to receive back the ``DigitalSignature.WithKey`` of other parties
|
||||
rather than a full ``SignedTransaction`` objects, because otherwise we
|
||||
have to separately check that this is still the same
|
||||
``SignedTransaction`` and not a malicious substitute.
|
||||
Once the proposed data is fully populated the flow code should freeze
|
||||
the ``WireTransaction`` and form a ``SignedTransaction``. This is key to
|
||||
the ledger agreement process, as once a flow has attached a node’s
|
||||
signature it has stated that all details of the transaction are
|
||||
acceptable to it. A flow should take care not to attach signatures to
|
||||
intermediate data, which might be maliciously used to construct a
|
||||
different ``SignedTransaction``. For instance in a foreign exchange
|
||||
scenario we shouldn't send a ``SignedTransaction`` with only our sell
|
||||
side populated as that could be used to take the money without the
|
||||
expected return of the other currency. Also, it is best practice for
|
||||
flows to receive back the ``DigitalSignature.WithKey`` of other parties
|
||||
rather than a full ``SignedTransaction`` objects, because otherwise we
|
||||
have to separately check that this is still the same
|
||||
``SignedTransaction`` and not a malicious substitute.
|
||||
|
||||
The final stage of committing the transaction to the ledger is to
|
||||
notarise the ``SignedTransaction``, distribute this to all appropriate
|
||||
parties and record the data into the ledger. These actions are best
|
||||
delegated to the ``FinalityFlow``, rather than calling the individual
|
||||
steps manually. However, do note that the final broadcast to the other
|
||||
nodes is asynchronous, so care must be used in unit testing to
|
||||
correctly await the Vault updates.
|
||||
The final stage of committing the transaction to the ledger is to
|
||||
notarise the ``SignedTransaction``, distribute this to all appropriate
|
||||
parties and record the data into the ledger. These actions are best
|
||||
delegated to the ``FinalityFlow``, rather than calling the individual
|
||||
steps manually. However, do note that the final broadcast to the other
|
||||
nodes is asynchronous, so care must be used in unit testing to
|
||||
correctly await the Vault updates.
|
||||
|
||||
Gathering Inputs
|
||||
----------------
|
||||
|
||||
One of the first steps to forming a transaction is gathering the set of
|
||||
input references. This process will clearly vary according to the nature
|
||||
of the business process being captured by the smart contract and the
|
||||
parameterised details of the request. However, it will generally involve
|
||||
searching the Vault via the ``VaultService`` interface on the
|
||||
One of the first steps to forming a transaction is gathering the set of
|
||||
input references. This process will clearly vary according to the nature
|
||||
of the business process being captured by the smart contract and the
|
||||
parameterised details of the request. However, it will generally involve
|
||||
searching the Vault via the ``VaultService`` interface on the
|
||||
``ServiceHub`` to locate the input states.
|
||||
|
||||
To give a few more specific details consider two simplified real world
|
||||
scenarios. First, a basic foreign exchange Cash transaction. This
|
||||
transaction needs to locate a set of funds to exchange. A flow
|
||||
modelling this is implemented in ``FxTransactionBuildTutorial.kt``.
|
||||
Second, a simple business model in which parties manually accept, or
|
||||
reject each other's trade proposals which is implemented in
|
||||
``WorkflowTransactionBuildTutorial.kt``. To run and explore these
|
||||
examples using the IntelliJ IDE one can run/step the respective unit
|
||||
tests in ``FxTransactionBuildTutorialTest.kt`` and
|
||||
``WorkflowTransactionBuildTutorialTest.kt``, which drive the flows as
|
||||
To give a few more specific details consider two simplified real world
|
||||
scenarios. First, a basic foreign exchange Cash transaction. This
|
||||
transaction needs to locate a set of funds to exchange. A flow
|
||||
modelling this is implemented in ``FxTransactionBuildTutorial.kt``.
|
||||
Second, a simple business model in which parties manually accept, or
|
||||
reject each other's trade proposals which is implemented in
|
||||
``WorkflowTransactionBuildTutorial.kt``. To run and explore these
|
||||
examples using the IntelliJ IDE one can run/step the respective unit
|
||||
tests in ``FxTransactionBuildTutorialTest.kt`` and
|
||||
``WorkflowTransactionBuildTutorialTest.kt``, which drive the flows as
|
||||
part of a simulated in-memory network of nodes.
|
||||
|
||||
.. |nbsp| unicode:: 0xA0
|
||||
@ -111,53 +111,53 @@ part of a simulated in-memory network of nodes.
|
||||
to the VM options, and set Working directory to ``$PROJECT_DIR$``
|
||||
so that the ``Quasar`` instrumentation is correctly configured.
|
||||
|
||||
For the Cash transaction let’s assume the cash resources are using the
|
||||
standard ``CashState`` in the ``:financial`` Gradle module. The Cash
|
||||
contract uses ``FungibleAsset`` states to model holdings of
|
||||
interchangeable assets and allow the split/merge and summing of
|
||||
states to meet a contractual obligation. We would normally use the
|
||||
``generateSpend`` method on the ``VaultService`` to gather the required
|
||||
amount of cash into a ``TransactionBuilder``, set the outputs and move
|
||||
command. However, to elucidate more clearly example flow code is shown
|
||||
here that will manually carry out the inputs queries using the lower
|
||||
level ``VaultService``.
|
||||
For the Cash transaction let’s assume the cash resources are using the
|
||||
standard ``CashState`` in the ``:financial`` Gradle module. The Cash
|
||||
contract uses ``FungibleAsset`` states to model holdings of
|
||||
interchangeable assets and allow the split/merge and summing of
|
||||
states to meet a contractual obligation. We would normally use the
|
||||
``generateSpend`` method on the ``VaultService`` to gather the required
|
||||
amount of cash into a ``TransactionBuilder``, set the outputs and move
|
||||
command. However, to elucidate more clearly example flow code is shown
|
||||
here that will manually carry out the inputs queries using the lower
|
||||
level ``VaultService``.
|
||||
|
||||
.. literalinclude:: example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt
|
||||
:language: kotlin
|
||||
:start-after: DOCSTART 1
|
||||
:end-before: DOCEND 1
|
||||
|
||||
As a foreign exchange transaction we expect an exchange of two
|
||||
currencies, so we will also require a set of input states from the other
|
||||
counterparty. However, the Corda privacy model means we do not know the
|
||||
other node’s states. Our flow must therefore negotiate with the other
|
||||
node for them to carry out a similar query and populate the inputs (See
|
||||
the ``ForeignExchangeFlow`` for more details of the exchange). Having
|
||||
identified a set of Input ``StateRef`` items we can then create the
|
||||
output as discussed below.
|
||||
As a foreign exchange transaction we expect an exchange of two
|
||||
currencies, so we will also require a set of input states from the other
|
||||
counterparty. However, the Corda privacy model means we do not know the
|
||||
other node’s states. Our flow must therefore negotiate with the other
|
||||
node for them to carry out a similar query and populate the inputs (See
|
||||
the ``ForeignExchangeFlow`` for more details of the exchange). Having
|
||||
identified a set of Input ``StateRef`` items we can then create the
|
||||
output as discussed below.
|
||||
|
||||
For the trade approval flow we need to implement a simple workflow
|
||||
pattern. We start by recording the unconfirmed trade details in a state
|
||||
object implementing the ``LinearState`` interface. One field of this
|
||||
record is used to map the business workflow to an enumerated state.
|
||||
Initially the initiator creates a new state object which receives a new
|
||||
``UniqueIdentifier`` in its ``linearId`` property and a starting
|
||||
workflow state of ``NEW``. The ``Contract.verify`` method is written to
|
||||
allow the initiator to sign this initial transaction and send it to the
|
||||
other party. This pattern ensures that a permanent copy is recorded on
|
||||
both ledgers for audit purposes, but the state is prevented from being
|
||||
maliciously put in an approved state. The subsequent workflow steps then
|
||||
follow with transactions that consume the state as inputs on one side
|
||||
and output a new version with whatever state updates, or amendments
|
||||
match to the business process, the ``linearId`` being preserved across
|
||||
the changes. Attached ``Command`` objects help the verify method
|
||||
restrict changes to appropriate fields and signers at each step in the
|
||||
workflow. In this it is typical to have both parties sign the change
|
||||
transactions, but it can be valid to allow unilateral signing, if for instance
|
||||
one side could block a rejection. Commonly the manual initiator of these
|
||||
workflows will query the Vault for states of the right contract type and
|
||||
in the right workflow state over the RPC interface. The RPC will then
|
||||
initiate the relevant flow using ``StateRef``, or ``linearId`` values as
|
||||
For the trade approval flow we need to implement a simple workflow
|
||||
pattern. We start by recording the unconfirmed trade details in a state
|
||||
object implementing the ``LinearState`` interface. One field of this
|
||||
record is used to map the business workflow to an enumerated state.
|
||||
Initially the initiator creates a new state object which receives a new
|
||||
``UniqueIdentifier`` in its ``linearId`` property and a starting
|
||||
workflow state of ``NEW``. The ``Contract.verify`` method is written to
|
||||
allow the initiator to sign this initial transaction and send it to the
|
||||
other party. This pattern ensures that a permanent copy is recorded on
|
||||
both ledgers for audit purposes, but the state is prevented from being
|
||||
maliciously put in an approved state. The subsequent workflow steps then
|
||||
follow with transactions that consume the state as inputs on one side
|
||||
and output a new version with whatever state updates, or amendments
|
||||
match to the business process, the ``linearId`` being preserved across
|
||||
the changes. Attached ``Command`` objects help the verify method
|
||||
restrict changes to appropriate fields and signers at each step in the
|
||||
workflow. In this it is typical to have both parties sign the change
|
||||
transactions, but it can be valid to allow unilateral signing, if for instance
|
||||
one side could block a rejection. Commonly the manual initiator of these
|
||||
workflows will query the Vault for states of the right contract type and
|
||||
in the right workflow state over the RPC interface. The RPC will then
|
||||
initiate the relevant flow using ``StateRef``, or ``linearId`` values as
|
||||
parameters to the flow to identify the states being operated upon. Thus
|
||||
code to gather the latest input state would be:
|
||||
|
||||
@ -177,51 +177,51 @@ code to gather the latest input state would be:
|
||||
Generating Commands
|
||||
-------------------
|
||||
|
||||
For the commands that will be added to the transaction, these will need
|
||||
to correctly reflect the task at hand. These must match because inside
|
||||
the ``Contract.verify`` method the command will be used to select the
|
||||
validation code path. The ``Contract.verify`` method will then restrict
|
||||
the allowed contents of the transaction to reflect this context. Typical
|
||||
restrictions might include that the input cash amount must equal the
|
||||
output cash amount, or that a workflow step is only allowed to change
|
||||
the status field. Sometimes, the command may capture some data too e.g.
|
||||
the foreign exchange rate, or the identity of one party, or the StateRef
|
||||
of the specific input that originates the command in a bulk operation.
|
||||
This data will be used to further aid the ``Contract.verify``, because
|
||||
to ensure consistent, secure and reproducible behaviour in a distributed
|
||||
environment the ``Contract.verify``, transaction is the only allowed to
|
||||
use the content of the transaction to decide validity.
|
||||
For the commands that will be added to the transaction, these will need
|
||||
to correctly reflect the task at hand. These must match because inside
|
||||
the ``Contract.verify`` method the command will be used to select the
|
||||
validation code path. The ``Contract.verify`` method will then restrict
|
||||
the allowed contents of the transaction to reflect this context. Typical
|
||||
restrictions might include that the input cash amount must equal the
|
||||
output cash amount, or that a workflow step is only allowed to change
|
||||
the status field. Sometimes, the command may capture some data too e.g.
|
||||
the foreign exchange rate, or the identity of one party, or the StateRef
|
||||
of the specific input that originates the command in a bulk operation.
|
||||
This data will be used to further aid the ``Contract.verify``, because
|
||||
to ensure consistent, secure and reproducible behaviour in a distributed
|
||||
environment the ``Contract.verify``, transaction is the only allowed to
|
||||
use the content of the transaction to decide validity.
|
||||
|
||||
Another essential requirement for commands is that the correct set of
|
||||
``CompositeKeys`` are added to the Command on the builder, which will be
|
||||
used to form the set of required signers on the final validated
|
||||
transaction. These must correctly align with the expectations of the
|
||||
``Contract.verify`` method, which should be written to defensively check
|
||||
this. In particular, it is expected that at minimum the owner of an
|
||||
asset would have to be signing to permission transfer of that asset. In
|
||||
addition, other signatories will often be required e.g. an Oracle
|
||||
identity for an Oracle command, or both parties when there is an
|
||||
exchange of assets.
|
||||
Another essential requirement for commands is that the correct set of
|
||||
``CompositeKeys`` are added to the Command on the builder, which will be
|
||||
used to form the set of required signers on the final validated
|
||||
transaction. These must correctly align with the expectations of the
|
||||
``Contract.verify`` method, which should be written to defensively check
|
||||
this. In particular, it is expected that at minimum the owner of an
|
||||
asset would have to be signing to permission transfer of that asset. In
|
||||
addition, other signatories will often be required e.g. an Oracle
|
||||
identity for an Oracle command, or both parties when there is an
|
||||
exchange of assets.
|
||||
|
||||
Generating Outputs
|
||||
------------------
|
||||
|
||||
Having located a set of ``StateAndRefs`` as the transaction inputs, the
|
||||
flow has to generate the output states. Typically, this is a simple call
|
||||
to the Kotlin ``copy`` method to modify the few fields that will
|
||||
transitioned in the transaction. The contract code may provide a
|
||||
``generateXXX`` method to help with this process if the task is more
|
||||
complicated. With a workflow state a slightly modified copy state is
|
||||
usually sufficient, especially as it is expected that we wish to preserve
|
||||
the ``linearId`` between state revisions, so that Vault queries can find
|
||||
Having located a set of ``StateAndRefs`` as the transaction inputs, the
|
||||
flow has to generate the output states. Typically, this is a simple call
|
||||
to the Kotlin ``copy`` method to modify the few fields that will
|
||||
transitioned in the transaction. The contract code may provide a
|
||||
``generateXXX`` method to help with this process if the task is more
|
||||
complicated. With a workflow state a slightly modified copy state is
|
||||
usually sufficient, especially as it is expected that we wish to preserve
|
||||
the ``linearId`` between state revisions, so that Vault queries can find
|
||||
the latest revision.
|
||||
|
||||
For fungible contract states such as ``Cash`` it is common to distribute
|
||||
and split the total amount e.g. to produce a remaining balance output
|
||||
state for the original owner when breaking up a large amount input
|
||||
state. Remember that the result of a successful transaction is always to
|
||||
fully consume/spend the input states, so this is required to conserve
|
||||
the total cash. For example from the demo code:
|
||||
For fungible contract states such as ``Cash`` it is common to distribute
|
||||
and split the total amount e.g. to produce a remaining balance output
|
||||
state for the original owner when breaking up a large amount input
|
||||
state. Remember that the result of a successful transaction is always to
|
||||
fully consume/spend the input states, so this is required to conserve
|
||||
the total cash. For example from the demo code:
|
||||
|
||||
.. literalinclude:: example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt
|
||||
:language: kotlin
|
||||
@ -231,15 +231,13 @@ the total cash. For example from the demo code:
|
||||
Building the WireTransaction
|
||||
----------------------------
|
||||
|
||||
Having gathered all the ingredients for the transaction we now need to
|
||||
use a ``TransactionBuilder`` to construct the full ``WireTransaction``.
|
||||
The initial ``TransactionBuilder`` should be created by calling the
|
||||
``TransactionType.General.Builder`` method. (The other
|
||||
``TransactionBuilder`` implementation is only used for the ``NotaryChange`` flow where
|
||||
``ContractStates`` need moving to a different Notary.) At this point the
|
||||
Notary to associate with the states should be recorded. Then we keep
|
||||
adding inputs, outputs, commands and attachments to fill the
|
||||
transaction. Examples of this process are:
|
||||
Having gathered all the ingredients for the transaction we now need to
|
||||
use a ``TransactionBuilder`` to construct the full ``WireTransaction``.
|
||||
The initial ``TransactionBuilder`` should be created by calling the
|
||||
``TransactionBuilder`` method. At this point the
|
||||
Notary to associate with the states should be recorded. Then we keep
|
||||
adding inputs, outputs, commands and attachments to fill the
|
||||
transaction. Examples of this process are:
|
||||
|
||||
.. literalinclude:: example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt
|
||||
:language: kotlin
|
||||
@ -254,51 +252,51 @@ transaction. Examples of this process are:
|
||||
Completing the SignedTransaction
|
||||
--------------------------------
|
||||
|
||||
Having created an initial ``WireTransaction`` and converted this to an
|
||||
initial ``SignedTransaction`` the process of verifying and forming a
|
||||
full ``SignedTransaction`` begins and then completes with the
|
||||
notarisation. In practice this is a relatively stereotypical process,
|
||||
because assuming the ``WireTransaction`` is correctly constructed the
|
||||
verification should be immediate. However, it is also important to
|
||||
recheck the business details of any data received back from an external
|
||||
node, because a malicious party could always modify the contents before
|
||||
returning the transaction. Each remote flow should therefore check as
|
||||
much as possible of the initial ``SignedTransaction`` inside the ``unwrap`` of
|
||||
the receive before agreeing to sign. Any issues should immediately throw
|
||||
an exception to abort the flow. Similarly the originator, should always
|
||||
apply any new signatures to its original proposal to ensure the contents
|
||||
Having created an initial ``WireTransaction`` and converted this to an
|
||||
initial ``SignedTransaction`` the process of verifying and forming a
|
||||
full ``SignedTransaction`` begins and then completes with the
|
||||
notarisation. In practice this is a relatively stereotypical process,
|
||||
because assuming the ``WireTransaction`` is correctly constructed the
|
||||
verification should be immediate. However, it is also important to
|
||||
recheck the business details of any data received back from an external
|
||||
node, because a malicious party could always modify the contents before
|
||||
returning the transaction. Each remote flow should therefore check as
|
||||
much as possible of the initial ``SignedTransaction`` inside the ``unwrap`` of
|
||||
the receive before agreeing to sign. Any issues should immediately throw
|
||||
an exception to abort the flow. Similarly the originator, should always
|
||||
apply any new signatures to its original proposal to ensure the contents
|
||||
of the transaction has not been altered by the remote parties.
|
||||
|
||||
The typical code therefore checks the received ``SignedTransaction``
|
||||
The typical code therefore checks the received ``SignedTransaction``
|
||||
using the ``verifySignaturesExcept`` method, excluding itself, the
|
||||
notary and any other parties yet to apply their signature. The contents of the
|
||||
``WireTransaction`` inside the ``SignedTransaction`` should be fully
|
||||
verified further by expanding with ``toLedgerTransaction`` and calling
|
||||
``verify``. Further context specific and business checks should then be
|
||||
made, because the ``Contract.verify`` is not allowed to access external
|
||||
context. For example the flow may need to check that the parties are the
|
||||
right ones, or that the ``Command`` present on the transaction is as
|
||||
expected for this specific flow. An example of this from the demo code is:
|
||||
``WireTransaction`` inside the ``SignedTransaction`` should be fully
|
||||
verified further by expanding with ``toLedgerTransaction`` and calling
|
||||
``verify``. Further context specific and business checks should then be
|
||||
made, because the ``Contract.verify`` is not allowed to access external
|
||||
context. For example the flow may need to check that the parties are the
|
||||
right ones, or that the ``Command`` present on the transaction is as
|
||||
expected for this specific flow. An example of this from the demo code is:
|
||||
|
||||
.. literalinclude:: example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt
|
||||
:language: kotlin
|
||||
:start-after: DOCSTART 3
|
||||
:end-before: DOCEND 3
|
||||
|
||||
After verification the remote flow will return its signature to the
|
||||
originator. The originator should apply that signature to the starting
|
||||
After verification the remote flow will return its signature to the
|
||||
originator. The originator should apply that signature to the starting
|
||||
``SignedTransaction`` and recheck the signatures match.
|
||||
|
||||
Committing the Transaction
|
||||
--------------------------
|
||||
|
||||
Once all the party signatures are applied to the SignedTransaction the
|
||||
final step is notarisation. This involves calling ``NotaryFlow.Client``
|
||||
to confirm the transaction, consume the inputs and return its confirming
|
||||
signature. Then the flow should ensure that all nodes end with all
|
||||
signatures and that they call ``ServiceHub.recordTransactions``. The
|
||||
code for this is standardised in the ``FinalityFlow``, or more explicitly
|
||||
an example is:
|
||||
Once all the party signatures are applied to the SignedTransaction the
|
||||
final step is notarisation. This involves calling ``NotaryFlow.Client``
|
||||
to confirm the transaction, consume the inputs and return its confirming
|
||||
signature. Then the flow should ensure that all nodes end with all
|
||||
signatures and that they call ``ServiceHub.recordTransactions``. The
|
||||
code for this is standardised in the ``FinalityFlow``, or more explicitly
|
||||
an example is:
|
||||
|
||||
.. literalinclude:: example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt
|
||||
:language: kotlin
|
||||
@ -308,19 +306,19 @@ an example is:
|
||||
Partially Visible Transactions
|
||||
------------------------------
|
||||
|
||||
The discussion so far has assumed that the parties need full visibility
|
||||
of the transaction to sign. However, there may be situations where each
|
||||
party needs to store private data for audit purposes, or for evidence to
|
||||
a regulator, but does not wish to share that with the other trading
|
||||
partner. The tear-off/Merkle tree support in Corda allows flows to send
|
||||
portions of the full transaction to restrict visibility to remote
|
||||
parties. To do this one can use the
|
||||
``WireTransaction.buildFilteredTransaction`` extension method to produce
|
||||
a ``FilteredTransaction``. The elements of the ``SignedTransaction``
|
||||
which we wish to be hide will be replaced with their secure hash. The
|
||||
overall transaction txid is still provable from the
|
||||
``FilteredTransaction`` preventing change of the private data, but we do
|
||||
not expose that data to the other node directly. A full example of this
|
||||
can be found in the ``NodeInterestRates`` Oracle code from the
|
||||
``irs-demo`` project which interacts with the ``RatesFixFlow`` flow.
|
||||
Also, refer to the :doc:`merkle-trees` documentation.
|
||||
The discussion so far has assumed that the parties need full visibility
|
||||
of the transaction to sign. However, there may be situations where each
|
||||
party needs to store private data for audit purposes, or for evidence to
|
||||
a regulator, but does not wish to share that with the other trading
|
||||
partner. The tear-off/Merkle tree support in Corda allows flows to send
|
||||
portions of the full transaction to restrict visibility to remote
|
||||
parties. To do this one can use the
|
||||
``WireTransaction.buildFilteredTransaction`` extension method to produce
|
||||
a ``FilteredTransaction``. The elements of the ``SignedTransaction``
|
||||
which we wish to be hide will be replaced with their secure hash. The
|
||||
overall transaction txid is still provable from the
|
||||
``FilteredTransaction`` preventing change of the private data, but we do
|
||||
not expose that data to the other node directly. A full example of this
|
||||
can be found in the ``NodeInterestRates`` Oracle code from the
|
||||
``irs-demo`` project which interacts with the ``RatesFixFlow`` flow.
|
||||
Also, refer to the :doc:`merkle-trees` documentation.
|
||||
|
@ -39,7 +39,7 @@ Then we initialise the transaction builder:
|
||||
|
||||
.. sourcecode:: kotlin
|
||||
|
||||
val builder: TransactionBuilder = TransactionType.General.Builder(notary = ourNotary)
|
||||
val builder: TransactionBuilder = TransactionBuilder(notary = ourNotary)
|
||||
|
||||
For any output state we add to this transaction builder, ``ourNotary`` will be assigned as its notary.
|
||||
Next we create a state object and assign ourselves as the owner. For this example we'll use a
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.corda.contracts
|
||||
package net.corda.contracts.isolated
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.SecureHash
|
||||
@ -31,7 +31,7 @@ class AnotherDummyContract : Contract, net.corda.core.node.DummyContractBackdoor
|
||||
|
||||
override fun generateInitial(owner: PartyAndReference, magicNumber: Int, notary: Party): TransactionBuilder {
|
||||
val state = State(magicNumber)
|
||||
return TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
return TransactionBuilder(notary).withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
}
|
||||
|
||||
override fun inspectState(state: ContractState): Int = (state as State).magicNumber
|
@ -316,7 +316,7 @@ public class JavaCommercialPaper implements Contract {
|
||||
public TransactionBuilder generateIssue(@NotNull PartyAndReference issuance, @NotNull Amount<Issued<Currency>> faceValue, @Nullable Instant maturityDate, @NotNull Party notary, Integer encumbrance) {
|
||||
State state = new State(issuance, issuance.getParty(), faceValue, maturityDate);
|
||||
TransactionState output = new TransactionState<>(state, notary, encumbrance);
|
||||
return new TransactionType.General.Builder(notary).withItems(output, new Command(new Commands.Issue(), issuance.getParty().getOwningKey()));
|
||||
return new TransactionBuilder(notary).withItems(output, new Command(new Commands.Issue(), issuance.getParty().getOwningKey()));
|
||||
}
|
||||
|
||||
public TransactionBuilder generateIssue(@NotNull PartyAndReference issuance, @NotNull Amount<Issued<Currency>> faceValue, @Nullable Instant maturityDate, @NotNull Party notary) {
|
||||
|
@ -200,7 +200,7 @@ class CommercialPaper : Contract {
|
||||
*/
|
||||
fun generateIssue(issuance: PartyAndReference, faceValue: Amount<Issued<Currency>>, maturityDate: Instant, notary: Party): TransactionBuilder {
|
||||
val state = TransactionState(State(issuance, issuance.party, faceValue, maturityDate), notary)
|
||||
return TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Issue(), issuance.party.owningKey))
|
||||
return TransactionBuilder(notary).withItems(state, Command(Commands.Issue(), issuance.party.owningKey))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,6 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.InsufficientBalanceException
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.contracts.issuedBy
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.identity.Party
|
||||
@ -36,7 +35,7 @@ class CashExitFlow(val amount: Amount<Currency>, val issueRef: OpaqueBytes, prog
|
||||
@Throws(CashException::class)
|
||||
override fun call(): AbstractCashFlow.Result {
|
||||
progressTracker.currentStep = GENERATING_TX
|
||||
val builder: TransactionBuilder = TransactionType.General.Builder(notary = null as Party?)
|
||||
val builder: TransactionBuilder = TransactionBuilder(notary = null as Party?)
|
||||
val issuer = serviceHub.myInfo.legalIdentity.ref(issueRef)
|
||||
val exitStates = serviceHub.vaultService.unconsumedStatesForSpending<Cash.State>(amount, setOf(issuer.party), builder.notary, builder.lockId, setOf(issuer.reference))
|
||||
val signers = try {
|
||||
|
@ -3,7 +3,6 @@ package net.corda.flows
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.contracts.issuedBy
|
||||
import net.corda.core.flows.FinalityFlow
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
@ -50,7 +49,7 @@ class CashIssueFlow(val amount: Amount<Currency>,
|
||||
}
|
||||
val anonymousRecipient = txIdentities[recipient]?.party ?: recipient
|
||||
progressTracker.currentStep = GENERATING_TX
|
||||
val builder: TransactionBuilder = TransactionType.General.Builder(notary = notary)
|
||||
val builder: TransactionBuilder = TransactionBuilder(notary)
|
||||
val issuer = serviceHub.myInfo.legalIdentity.ref(issueRef)
|
||||
val signers = Cash().generateIssue(builder, amount.issuedBy(issuer), anonymousRecipient, notary)
|
||||
progressTracker.currentStep = SIGNING_TX
|
||||
|
@ -3,7 +3,6 @@ package net.corda.flows
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.InsufficientBalanceException
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.flows.TransactionKeyFlow
|
||||
import net.corda.core.identity.AnonymousPartyAndPath
|
||||
@ -43,7 +42,7 @@ open class CashPaymentFlow(
|
||||
}
|
||||
val anonymousRecipient = txIdentities.get(recipient)?.party ?: recipient
|
||||
progressTracker.currentStep = GENERATING_TX
|
||||
val builder: TransactionBuilder = TransactionType.General.Builder(null as Party?)
|
||||
val builder: TransactionBuilder = TransactionBuilder(null as Party?)
|
||||
// TODO: Have some way of restricting this to states the caller controls
|
||||
val (spendTX, keysForSigning) = try {
|
||||
serviceHub.vaultService.generateSpend(
|
||||
|
@ -178,7 +178,7 @@ object TwoPartyTradeFlow {
|
||||
|
||||
@Suspendable
|
||||
private fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair<TransactionBuilder, List<PublicKey>> {
|
||||
val ptx = TransactionType.General.Builder(notary)
|
||||
val ptx = TransactionBuilder(notary)
|
||||
|
||||
// Add input and output states for the movement of cash, by using the Cash contract to generate the states
|
||||
val (tx, cashSigningPubKeys) = serviceHub.vaultService.generateSpend(ptx, tradeRequest.price, tradeRequest.sellerOwner)
|
||||
|
@ -10,6 +10,7 @@ import net.corda.core.node.services.Vault
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MockServices
|
||||
@ -263,7 +264,7 @@ class CommercialPaperTestsGeneric {
|
||||
databaseAlice.transaction {
|
||||
// Alice pays $9000 to BigCorp to own some of their debt.
|
||||
moveTX = run {
|
||||
val builder = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val builder = TransactionBuilder(DUMMY_NOTARY)
|
||||
aliceVaultService.generateSpend(builder, 9000.DOLLARS, AnonymousParty(bigCorpServices.key.public))
|
||||
CommercialPaper().generateMove(builder, issueTx.tx.outRef(0), AnonymousParty(aliceServices.key.public))
|
||||
val ptx = aliceServices.signInitialTransaction(builder)
|
||||
@ -284,7 +285,7 @@ class CommercialPaperTestsGeneric {
|
||||
|
||||
databaseBigCorp.transaction {
|
||||
fun makeRedeemTX(time: Instant): Pair<SignedTransaction, UUID> {
|
||||
val builder = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val builder = TransactionBuilder(DUMMY_NOTARY)
|
||||
builder.setTimeWindow(time, 30.seconds)
|
||||
CommercialPaper().generateRedeem(builder, moveTX.tx.outRef(1), bigCorpVaultService)
|
||||
val ptx = aliceServices.signInitialTransaction(builder)
|
||||
|
@ -9,6 +9,7 @@ import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.node.services.unconsumedStates
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.node.services.vault.NodeVaultService
|
||||
@ -155,7 +156,7 @@ class CashTests : TestDependencyInjectionBase() {
|
||||
fun generateIssueRaw() {
|
||||
initialiseTestSerialization()
|
||||
// Test generation works.
|
||||
val tx: WireTransaction = TransactionType.General.Builder(notary = null).apply {
|
||||
val tx: WireTransaction = TransactionBuilder(notary = null).apply {
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` MINI_CORP.ref(12, 34), owner = AnonymousParty(DUMMY_PUBKEY_1), notary = DUMMY_NOTARY)
|
||||
}.toWireTransaction()
|
||||
assertTrue(tx.inputs.isEmpty())
|
||||
@ -172,7 +173,7 @@ class CashTests : TestDependencyInjectionBase() {
|
||||
initialiseTestSerialization()
|
||||
// Test issuance from an issued amount
|
||||
val amount = 100.DOLLARS `issued by` MINI_CORP.ref(12, 34)
|
||||
val tx: WireTransaction = TransactionType.General.Builder(notary = null).apply {
|
||||
val tx: WireTransaction = TransactionBuilder(notary = null).apply {
|
||||
Cash().generateIssue(this, amount, owner = AnonymousParty(DUMMY_PUBKEY_1), notary = DUMMY_NOTARY)
|
||||
}.toWireTransaction()
|
||||
assertTrue(tx.inputs.isEmpty())
|
||||
@ -244,13 +245,13 @@ class CashTests : TestDependencyInjectionBase() {
|
||||
fun `reject issuance with inputs`() {
|
||||
initialiseTestSerialization()
|
||||
// Issue some cash
|
||||
var ptx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
var ptx = TransactionBuilder(DUMMY_NOTARY)
|
||||
|
||||
Cash().generateIssue(ptx, 100.DOLLARS `issued by` MINI_CORP.ref(12, 34), owner = MINI_CORP, notary = DUMMY_NOTARY)
|
||||
val tx = miniCorpServices.signInitialTransaction(ptx)
|
||||
|
||||
// Include the previously issued cash in a new issuance command
|
||||
ptx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
ptx = TransactionBuilder(DUMMY_NOTARY)
|
||||
ptx.addInputState(tx.tx.outRef<Cash.State>(0))
|
||||
Cash().generateIssue(ptx, 100.DOLLARS `issued by` MINI_CORP.ref(12, 34), owner = MINI_CORP, notary = DUMMY_NOTARY)
|
||||
}
|
||||
@ -476,13 +477,13 @@ class CashTests : TestDependencyInjectionBase() {
|
||||
* Generate an exit transaction, removing some amount of cash from the ledger.
|
||||
*/
|
||||
fun makeExit(amount: Amount<Currency>, corp: Party, depositRef: Byte = 1): WireTransaction {
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val tx = TransactionBuilder(DUMMY_NOTARY)
|
||||
Cash().generateExit(tx, Amount(amount.quantity, Issued(corp.ref(depositRef), amount.token)), WALLET)
|
||||
return tx.toWireTransaction()
|
||||
}
|
||||
|
||||
fun makeSpend(amount: Amount<Currency>, dest: AbstractParty): WireTransaction {
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val tx = TransactionBuilder(DUMMY_NOTARY)
|
||||
database.transaction {
|
||||
vault.generateSpend(tx, amount, dest)
|
||||
}
|
||||
@ -560,7 +561,7 @@ class CashTests : TestDependencyInjectionBase() {
|
||||
fun generateExitWithEmptyVault() {
|
||||
initialiseTestSerialization()
|
||||
assertFailsWith<InsufficientBalanceException> {
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val tx = TransactionBuilder(DUMMY_NOTARY)
|
||||
Cash().generateExit(tx, Amount(100, Issued(CHARLIE.ref(1), GBP)), emptyList())
|
||||
}
|
||||
}
|
||||
@ -584,7 +585,7 @@ class CashTests : TestDependencyInjectionBase() {
|
||||
initialiseTestSerialization()
|
||||
database.transaction {
|
||||
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val tx = TransactionBuilder(DUMMY_NOTARY)
|
||||
vault.generateSpend(tx, 80.DOLLARS, ALICE, setOf(MINI_CORP))
|
||||
|
||||
assertEquals(vaultStatesUnconsumed.elementAt(2).ref, tx.inputStates()[0])
|
||||
|
@ -8,6 +8,7 @@ import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.testing.NULL_PARTY
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.NonEmptySet
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.core.utilities.days
|
||||
@ -135,7 +136,7 @@ class ObligationTests {
|
||||
|
||||
initialiseTestSerialization()
|
||||
// Test generation works.
|
||||
val tx = TransactionType.General.Builder(notary = null).apply {
|
||||
val tx = TransactionBuilder(notary = null).apply {
|
||||
Obligation<Currency>().generateIssue(this, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity,
|
||||
beneficiary = CHARLIE, notary = DUMMY_NOTARY)
|
||||
}.toWireTransaction()
|
||||
@ -214,14 +215,14 @@ class ObligationTests {
|
||||
fun `reject issuance with inputs`() {
|
||||
initialiseTestSerialization()
|
||||
// Issue some obligation
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY).apply {
|
||||
val tx = TransactionBuilder(DUMMY_NOTARY).apply {
|
||||
Obligation<Currency>().generateIssue(this, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity,
|
||||
beneficiary = MINI_CORP, notary = DUMMY_NOTARY)
|
||||
}.toWireTransaction()
|
||||
|
||||
|
||||
// Include the previously issued obligation in a new issuance command
|
||||
val ptx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val ptx = TransactionBuilder(DUMMY_NOTARY)
|
||||
ptx.addInputState(tx.outRef<Obligation.State<Currency>>(0))
|
||||
Obligation<Currency>().generateIssue(ptx, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity,
|
||||
beneficiary = MINI_CORP, notary = DUMMY_NOTARY)
|
||||
@ -233,7 +234,7 @@ class ObligationTests {
|
||||
initialiseTestSerialization()
|
||||
val obligationAliceToBob = oneMillionDollars.OBLIGATION between Pair(ALICE, BOB)
|
||||
val obligationBobToAlice = oneMillionDollars.OBLIGATION between Pair(BOB, ALICE)
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY).apply {
|
||||
val tx = TransactionBuilder(DUMMY_NOTARY).apply {
|
||||
Obligation<Currency>().generateCloseOutNetting(this, ALICE, obligationAliceToBob, obligationBobToAlice)
|
||||
}.toWireTransaction()
|
||||
assertEquals(0, tx.outputs.size)
|
||||
@ -245,7 +246,7 @@ class ObligationTests {
|
||||
initialiseTestSerialization()
|
||||
val obligationAliceToBob = (2000000.DOLLARS `issued by` defaultIssuer).OBLIGATION between Pair(ALICE, BOB)
|
||||
val obligationBobToAlice = oneMillionDollars.OBLIGATION between Pair(BOB, ALICE)
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY).apply {
|
||||
val tx = TransactionBuilder(DUMMY_NOTARY).apply {
|
||||
Obligation<Currency>().generateCloseOutNetting(this, ALICE, obligationAliceToBob, obligationBobToAlice)
|
||||
}.toWireTransaction()
|
||||
assertEquals(1, tx.outputs.size)
|
||||
@ -260,7 +261,7 @@ class ObligationTests {
|
||||
initialiseTestSerialization()
|
||||
val obligationAliceToBob = oneMillionDollars.OBLIGATION between Pair(ALICE, BOB)
|
||||
val obligationBobToAlice = oneMillionDollars.OBLIGATION between Pair(BOB, ALICE)
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY).apply {
|
||||
val tx = TransactionBuilder(DUMMY_NOTARY).apply {
|
||||
Obligation<Currency>().generatePaymentNetting(this, obligationAliceToBob.amount.token, DUMMY_NOTARY, obligationAliceToBob, obligationBobToAlice)
|
||||
}.toWireTransaction()
|
||||
assertEquals(0, tx.outputs.size)
|
||||
@ -272,7 +273,7 @@ class ObligationTests {
|
||||
initialiseTestSerialization()
|
||||
val obligationAliceToBob = oneMillionDollars.OBLIGATION between Pair(ALICE, BOB)
|
||||
val obligationBobToAlice = (2000000.DOLLARS `issued by` defaultIssuer).OBLIGATION between Pair(BOB, ALICE)
|
||||
val tx = TransactionType.General.Builder(null).apply {
|
||||
val tx = TransactionBuilder(null).apply {
|
||||
Obligation<Currency>().generatePaymentNetting(this, obligationAliceToBob.amount.token, DUMMY_NOTARY, obligationAliceToBob, obligationBobToAlice)
|
||||
}.toWireTransaction()
|
||||
assertEquals(1, tx.outputs.size)
|
||||
@ -289,7 +290,7 @@ class ObligationTests {
|
||||
val dueBefore = TEST_TX_TIME - 7.days
|
||||
|
||||
// Generate a transaction issuing the obligation.
|
||||
var tx = TransactionType.General.Builder(null).apply {
|
||||
var tx = TransactionBuilder(null).apply {
|
||||
val amount = Amount(100, Issued(defaultIssuer, USD))
|
||||
Obligation<Currency>().generateCashIssue(this, ALICE, amount, dueBefore,
|
||||
beneficiary = MINI_CORP, notary = DUMMY_NOTARY)
|
||||
@ -298,7 +299,7 @@ class ObligationTests {
|
||||
var stateAndRef = stx.tx.outRef<Obligation.State<Currency>>(0)
|
||||
|
||||
// Now generate a transaction marking the obligation as having defaulted
|
||||
tx = TransactionType.General.Builder(DUMMY_NOTARY).apply {
|
||||
tx = TransactionBuilder(DUMMY_NOTARY).apply {
|
||||
Obligation<Currency>().generateSetLifecycle(this, listOf(stateAndRef), Lifecycle.DEFAULTED, DUMMY_NOTARY)
|
||||
}
|
||||
var ptx = miniCorpServices.signInitialTransaction(tx, MINI_CORP_PUBKEY)
|
||||
@ -310,7 +311,7 @@ class ObligationTests {
|
||||
|
||||
// And set it back
|
||||
stateAndRef = stx.tx.outRef<Obligation.State<Currency>>(0)
|
||||
tx = TransactionType.General.Builder(DUMMY_NOTARY).apply {
|
||||
tx = TransactionBuilder(DUMMY_NOTARY).apply {
|
||||
Obligation<Currency>().generateSetLifecycle(this, listOf(stateAndRef), Lifecycle.NORMAL, DUMMY_NOTARY)
|
||||
}
|
||||
ptx = miniCorpServices.signInitialTransaction(tx)
|
||||
@ -324,18 +325,18 @@ class ObligationTests {
|
||||
@Test
|
||||
fun `generate settlement transaction`() {
|
||||
initialiseTestSerialization()
|
||||
val cashTx = TransactionType.General.Builder(null).apply {
|
||||
val cashTx = TransactionBuilder(null).apply {
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` defaultIssuer, MINI_CORP, DUMMY_NOTARY)
|
||||
}.toWireTransaction()
|
||||
|
||||
// Generate a transaction issuing the obligation
|
||||
val obligationTx = TransactionType.General.Builder(null).apply {
|
||||
val obligationTx = TransactionBuilder(null).apply {
|
||||
Obligation<Currency>().generateIssue(this, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity,
|
||||
beneficiary = MINI_CORP, notary = DUMMY_NOTARY)
|
||||
}.toWireTransaction()
|
||||
|
||||
// Now generate a transaction settling the obligation
|
||||
val settleTx = TransactionType.General.Builder(DUMMY_NOTARY).apply {
|
||||
val settleTx = TransactionBuilder(DUMMY_NOTARY).apply {
|
||||
Obligation<Currency>().generateSettle(this, listOf(obligationTx.outRef(0)), listOf(cashTx.outRef(0)), Cash.Commands.Move(), DUMMY_NOTARY)
|
||||
}.toWireTransaction()
|
||||
assertEquals(2, settleTx.inputs.size)
|
||||
|
@ -8,7 +8,6 @@ import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.contracts.Command
|
||||
import net.corda.core.contracts.CommandData
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.testing.NullSignature
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.testing.*
|
||||
|
@ -3,7 +3,6 @@ package net.corda.node.services
|
||||
import com.nhaarman.mockito_kotlin.whenever
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.composite.CompositeKey
|
||||
import net.corda.core.internal.div
|
||||
@ -13,6 +12,7 @@ import net.corda.core.flows.NotaryFlow
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.core.utilities.Try
|
||||
import net.corda.node.internal.AbstractNode
|
||||
@ -138,8 +138,8 @@ class BFTNotaryServiceTests {
|
||||
private fun AbstractNode.signInitialTransaction(
|
||||
notary: Party,
|
||||
makeUnique: Boolean = false,
|
||||
block: TransactionType.General.Builder.() -> Any?
|
||||
) = services.signInitialTransaction(TransactionType.General.Builder(notary).apply {
|
||||
block: TransactionBuilder.() -> Any?
|
||||
) = services.signInitialTransaction(TransactionBuilder(notary).apply {
|
||||
block()
|
||||
if (makeUnique) {
|
||||
addAttachment(SecureHash.randomSHA256())
|
||||
|
@ -3,13 +3,13 @@ package net.corda.node.services
|
||||
import com.google.common.util.concurrent.Futures
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.flows.NotaryError
|
||||
import net.corda.core.flows.NotaryException
|
||||
import net.corda.core.flows.NotaryFlow
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.map
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.node.internal.AbstractNode
|
||||
import net.corda.testing.DUMMY_BANK_A
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
@ -34,13 +34,13 @@ class RaftNotaryServiceTests : NodeBasedTest() {
|
||||
|
||||
val inputState = issueState(bankA, notaryParty)
|
||||
|
||||
val firstTxBuilder = TransactionType.General.Builder(notaryParty).withItems(inputState)
|
||||
val firstTxBuilder = TransactionBuilder(notaryParty).withItems(inputState)
|
||||
val firstSpendTx = bankA.services.signInitialTransaction(firstTxBuilder)
|
||||
|
||||
val firstSpend = bankA.services.startFlow(NotaryFlow.Client(firstSpendTx))
|
||||
firstSpend.resultFuture.getOrThrow()
|
||||
|
||||
val secondSpendBuilder = TransactionType.General.Builder(notaryParty).withItems(inputState).run {
|
||||
val secondSpendBuilder = TransactionBuilder(notaryParty).withItems(inputState).run {
|
||||
val dummyState = DummyContract.SingleOwnerState(0, bankA.info.legalIdentity)
|
||||
addOutputState(dummyState)
|
||||
this
|
||||
|
@ -137,7 +137,7 @@ class NotaryChangeTests {
|
||||
val stateB = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
|
||||
val stateC = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
|
||||
|
||||
val tx = TransactionType.General.Builder(null).apply {
|
||||
val tx = TransactionBuilder(null).apply {
|
||||
addCommand(Command(DummyContract.Commands.Create(), owner.party.owningKey))
|
||||
addOutputState(stateA, notary, encumbrance = 2) // Encumbered by stateB
|
||||
addOutputState(stateC, notary)
|
||||
|
@ -4,7 +4,6 @@ import io.requery.Persistable
|
||||
import io.requery.kotlin.eq
|
||||
import io.requery.sql.KotlinEntityDataStore
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.testing.NullPublicKey
|
||||
|
@ -9,6 +9,7 @@ import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.testing.ALICE_KEY
|
||||
import net.corda.testing.DUMMY_CA
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
@ -280,7 +281,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
apply {
|
||||
val freshKey = services.keyManagementService.freshKey()
|
||||
val state = TestState(FlowLogicRefFactoryImpl.createForRPC(TestFlowLogic::class.java, increment), instant)
|
||||
val builder = TransactionType.General.Builder(null).apply {
|
||||
val builder = TransactionBuilder(null).apply {
|
||||
addOutputState(state, DUMMY_NOTARY)
|
||||
addCommand(Command(), freshKey)
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.node.services.linearHeadsOfType
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.node.services.network.NetworkMapService
|
||||
import net.corda.node.services.statemachine.StateMachineManager
|
||||
import net.corda.node.services.transactions.ValidatingNotaryService
|
||||
@ -57,7 +58,7 @@ class ScheduledFlowTests {
|
||||
serviceHub.myInfo.legalIdentity, destination)
|
||||
|
||||
val notary = serviceHub.networkMapCache.getAnyNotary()
|
||||
val builder = TransactionType.General.Builder(notary)
|
||||
val builder = TransactionBuilder(notary)
|
||||
builder.withItems(scheduledState)
|
||||
val tx = serviceHub.signInitialTransaction(builder)
|
||||
subFlow(FinalityFlow(tx, setOf(serviceHub.myInfo.legalIdentity)))
|
||||
@ -77,7 +78,7 @@ class ScheduledFlowTests {
|
||||
require(!scheduledState.processed) { "State should not have been previously processed" }
|
||||
val notary = state.state.notary
|
||||
val newStateOutput = scheduledState.copy(processed = true)
|
||||
val builder = TransactionType.General.Builder(notary)
|
||||
val builder = TransactionBuilder(notary)
|
||||
builder.withItems(state, newStateOutput)
|
||||
val tx = serviceHub.signInitialTransaction(builder)
|
||||
subFlow(FinalityFlow(tx, setOf(scheduledState.source, scheduledState.destination)))
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.corda.node.services.persistence
|
||||
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.testing.NullPublicKey
|
||||
|
@ -4,7 +4,6 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.Issued
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.contracts.USD
|
||||
import net.corda.core.flows.BroadcastTransactionFlow.NotifyTxRequest
|
||||
import net.corda.core.flows.FlowLogic
|
||||
@ -13,6 +12,7 @@ import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.unconsumedStates
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.node.services.NotifyTransactionHandler
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.MEGA_CORP
|
||||
@ -50,7 +50,7 @@ class DataVendingServiceTests {
|
||||
mockNet.runNetwork()
|
||||
|
||||
// Generate an issuance transaction
|
||||
val ptx = TransactionType.General.Builder(null)
|
||||
val ptx = TransactionBuilder(null)
|
||||
Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY)
|
||||
|
||||
// Complete the cash transaction, and then manually relay it
|
||||
@ -80,7 +80,7 @@ class DataVendingServiceTests {
|
||||
mockNet.runNetwork()
|
||||
|
||||
// Generate an issuance transaction
|
||||
val ptx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val ptx = TransactionBuilder(DUMMY_NOTARY)
|
||||
Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY)
|
||||
|
||||
// The transaction tries issuing MEGA_CORP cash, but we aren't the issuer, so it's invalid
|
||||
|
@ -3,7 +3,6 @@ package net.corda.node.services.transactions
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.flows.NotaryError
|
||||
import net.corda.core.flows.NotaryException
|
||||
@ -12,6 +11,7 @@ import net.corda.core.getOrThrow
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.node.internal.AbstractNode
|
||||
import net.corda.node.services.network.NetworkMapService
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
@ -50,7 +50,7 @@ class NotaryServiceTests {
|
||||
fun `should sign a unique transaction with a valid time-window`() {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
val tx = TransactionBuilder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.setTimeWindow(Instant.now(), 30.seconds)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
@ -64,7 +64,7 @@ class NotaryServiceTests {
|
||||
fun `should sign a unique transaction without a time-window`() {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
val tx = TransactionBuilder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ class NotaryServiceTests {
|
||||
fun `should report error for transaction with an invalid time-window`() {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
val tx = TransactionBuilder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.setTimeWindow(Instant.now().plusSeconds(3600), 30.seconds)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
@ -92,7 +92,7 @@ class NotaryServiceTests {
|
||||
fun `should sign identical transaction multiple times (signing is idempotent)`() {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
val tx = TransactionBuilder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
|
||||
@ -110,11 +110,11 @@ class NotaryServiceTests {
|
||||
fun `should report conflict when inputs are reused across transactions`() {
|
||||
val inputState = issueState(clientNode)
|
||||
val stx = run {
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
val tx = TransactionBuilder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
val stx2 = run {
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
val tx = TransactionBuilder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.addInputState(issueState(clientNode))
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import com.google.common.util.concurrent.ListenableFuture
|
||||
import net.corda.core.contracts.Command
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.flows.NotaryError
|
||||
import net.corda.core.flows.NotaryException
|
||||
@ -12,6 +11,7 @@ import net.corda.core.flows.NotaryFlow
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.node.internal.AbstractNode
|
||||
import net.corda.node.services.issueInvalidState
|
||||
import net.corda.node.services.network.NetworkMapService
|
||||
@ -52,7 +52,7 @@ class ValidatingNotaryServiceTests {
|
||||
fun `should report error for invalid transaction dependency`() {
|
||||
val stx = run {
|
||||
val inputState = issueInvalidState(clientNode, notaryNode.info.notaryIdentity)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
val tx = TransactionBuilder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ class ValidatingNotaryServiceTests {
|
||||
val inputState = issueState(clientNode)
|
||||
|
||||
val command = Command(DummyContract.Commands.Move(), expectedMissingKey)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState, command)
|
||||
val tx = TransactionBuilder(notaryNode.info.notaryIdentity).withItems(inputState, command)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
|
||||
|
@ -403,7 +403,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
||||
val freshKey = services.legalIdentityKey
|
||||
|
||||
// Issue a txn to Send us some Money
|
||||
val usefulBuilder = TransactionType.General.Builder(null).apply {
|
||||
val usefulBuilder = TransactionBuilder(null).apply {
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshKey), DUMMY_NOTARY)
|
||||
}
|
||||
val usefulTX = megaCorpServices.signInitialTransaction(usefulBuilder)
|
||||
@ -416,7 +416,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
||||
assertEquals(3, vaultSvc.getTransactionNotes(usefulTX.id).count())
|
||||
|
||||
// Issue more Money (GBP)
|
||||
val anotherBuilder = TransactionType.General.Builder(null).apply {
|
||||
val anotherBuilder = TransactionBuilder(null).apply {
|
||||
Cash().generateIssue(this, 200.POUNDS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshKey), DUMMY_NOTARY)
|
||||
}
|
||||
val anotherTX = megaCorpServices.signInitialTransaction(anotherBuilder)
|
||||
|
@ -10,6 +10,7 @@ import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.node.services.consumedStates
|
||||
import net.corda.core.node.services.unconsumedStates
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.node.services.database.HibernateConfiguration
|
||||
import net.corda.node.services.schema.NodeSchemaService
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
@ -93,7 +94,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
database.transaction {
|
||||
// A tx that sends us money.
|
||||
val freshKey = services.keyManagementService.freshKey()
|
||||
val usefulBuilder = TransactionType.General.Builder(null)
|
||||
val usefulBuilder = TransactionBuilder(null)
|
||||
Cash().generateIssue(usefulBuilder, 100.DOLLARS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshKey), DUMMY_NOTARY)
|
||||
val usefulTX = megaCorpServices.signInitialTransaction(usefulBuilder)
|
||||
|
||||
@ -101,7 +102,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
services.recordTransactions(usefulTX)
|
||||
|
||||
// A tx that spends our money.
|
||||
val spendTXBuilder = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val spendTXBuilder = TransactionBuilder(DUMMY_NOTARY)
|
||||
vault.generateSpend(spendTXBuilder, 80.DOLLARS, BOB)
|
||||
val spendPTX = services.signInitialTransaction(spendTXBuilder, freshKey)
|
||||
val spendTX = notaryServices.addSignature(spendPTX)
|
||||
@ -109,7 +110,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
assertEquals(100.DOLLARS, services.getCashBalance(USD))
|
||||
|
||||
// A tx that doesn't send us anything.
|
||||
val irrelevantBuilder = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val irrelevantBuilder = TransactionBuilder(DUMMY_NOTARY)
|
||||
Cash().generateIssue(irrelevantBuilder, 100.DOLLARS `issued by` MEGA_CORP.ref(1), BOB, DUMMY_NOTARY)
|
||||
|
||||
val irrelevantPTX = megaCorpServices.signInitialTransaction(irrelevantBuilder)
|
||||
@ -147,7 +148,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
backgroundExecutor.submit {
|
||||
database.transaction {
|
||||
try {
|
||||
val txn1Builder = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val txn1Builder = TransactionBuilder(DUMMY_NOTARY)
|
||||
vault.generateSpend(txn1Builder, 60.DOLLARS, BOB)
|
||||
val ptxn1 = notaryServices.signInitialTransaction(txn1Builder)
|
||||
val txn1 = services.addSignature(ptxn1, freshKey)
|
||||
@ -177,7 +178,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
backgroundExecutor.submit {
|
||||
database.transaction {
|
||||
try {
|
||||
val txn2Builder = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val txn2Builder = TransactionBuilder(DUMMY_NOTARY)
|
||||
vault.generateSpend(txn2Builder, 80.DOLLARS, BOB)
|
||||
val ptxn2 = notaryServices.signInitialTransaction(txn2Builder)
|
||||
val txn2 = services.addSignature(ptxn2, freshKey)
|
||||
@ -219,7 +220,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
val linearId = UniqueIdentifier()
|
||||
|
||||
// Issue a linear state
|
||||
val dummyIssueBuilder = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY).apply {
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
|
||||
}
|
||||
@ -240,7 +241,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
val linearId = UniqueIdentifier()
|
||||
|
||||
// Issue a linear state
|
||||
val dummyIssueBuilder = TransactionType.General.Builder(notary = DUMMY_NOTARY)
|
||||
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
|
||||
dummyIssueBuilder.addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
|
||||
val dummyIssuePtx = notaryServices.signInitialTransaction(dummyIssueBuilder)
|
||||
val dummyIssue = services.addSignature(dummyIssuePtx)
|
||||
@ -251,7 +252,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
assertThat(vault.unconsumedStates<DummyLinearContract.State>()).hasSize(1)
|
||||
|
||||
// Move the same state
|
||||
val dummyMoveBuilder = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
val dummyMoveBuilder = TransactionBuilder(notary = DUMMY_NOTARY).apply {
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
|
||||
addInputState(dummyIssue.tx.outRef<LinearState>(0))
|
||||
}
|
||||
@ -283,7 +284,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
|
||||
database.transaction {
|
||||
// A tx that spends our money.
|
||||
val spendTXBuilder = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val spendTXBuilder = TransactionBuilder(DUMMY_NOTARY)
|
||||
vault.generateSpend(spendTXBuilder, 80.DOLLARS, BOB)
|
||||
val spendPTX = notaryServices.signInitialTransaction(spendTXBuilder)
|
||||
val spendTX = services.addSignature(spendPTX, freshKey)
|
||||
@ -313,7 +314,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() {
|
||||
linearStates.forEach { println(it.state.data.linearId) }
|
||||
|
||||
// Create a txn consuming different contract types
|
||||
val dummyMoveBuilder = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
val dummyMoveBuilder = TransactionBuilder(notary = DUMMY_NOTARY).apply {
|
||||
addOutputState(DummyLinearContract.State(participants = listOf(freshIdentity)))
|
||||
addOutputState(DummyDealContract.State(ref = "999", participants = listOf(freshIdentity)))
|
||||
addInputState(linearStates.first())
|
||||
|
@ -5,7 +5,6 @@ import joptsimple.OptionParser
|
||||
import net.corda.client.rpc.CordaRPCClient
|
||||
import net.corda.core.contracts.Contract
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.flows.FinalityFlow
|
||||
import net.corda.core.flows.FlowLogic
|
||||
@ -19,6 +18,7 @@ import net.corda.core.messaging.CordaRPCOps
|
||||
import net.corda.core.messaging.startTrackedFlow
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
import net.corda.testing.DUMMY_BANK_B
|
||||
@ -106,7 +106,7 @@ class AttachmentDemoFlow(val otherSide: Party, val hash: SecureHash.SHA256) : Fl
|
||||
@Suspendable
|
||||
override fun call(): SignedTransaction {
|
||||
// Create a trivial transaction with an output that describes the attachment, and the attachment itself
|
||||
val ptx = TransactionType.General.Builder(notary = DUMMY_NOTARY)
|
||||
val ptx = TransactionBuilder(notary = DUMMY_NOTARY)
|
||||
ptx.addOutputState(AttachmentContract.State(hash))
|
||||
ptx.addAttachment(hash)
|
||||
|
||||
|
@ -783,7 +783,7 @@ class InterestRateSwap : Contract {
|
||||
|
||||
// Put all the above into a new State object.
|
||||
val state = State(fixedLeg, floatingLeg, newCalculation, common)
|
||||
return TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Agree(), listOf(state.floatingLeg.floatingRatePayer.owningKey, state.fixedLeg.fixedRatePayer.owningKey)))
|
||||
return TransactionBuilder(notary).withItems(state, Command(Commands.Agree(), listOf(state.floatingLeg.floatingRatePayer.owningKey, state.fixedLeg.fixedRatePayer.owningKey)))
|
||||
}
|
||||
|
||||
private fun calcFixingDate(date: LocalDate, fixingPeriodOffset: Int, calendar: BusinessCalendar): LocalDate {
|
||||
|
@ -61,7 +61,7 @@ object FixingFlow {
|
||||
|
||||
val newDeal = deal
|
||||
|
||||
val ptx = TransactionType.General.Builder(txState.notary)
|
||||
val ptx = TransactionBuilder(txState.notary)
|
||||
|
||||
val oracle = serviceHub.networkMapCache.getNodesWithService(handshake.payload.oracleType).first()
|
||||
val oracleParty = oracle.serviceIdentities(handshake.payload.oracleType).first()
|
||||
|
@ -208,7 +208,7 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() {
|
||||
n2.database.transaction {
|
||||
n2.installCordaService(NodeInterestRates.Oracle::class.java).knownFixes = TEST_DATA
|
||||
}
|
||||
val tx = TransactionType.General.Builder(null)
|
||||
val tx = TransactionBuilder(null)
|
||||
val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M")
|
||||
val oracle = n2.info.serviceIdentities(NodeInterestRates.Oracle.type).first()
|
||||
val flow = FilteredRatesFlow(tx, oracle, fixOf, BigDecimal("0.675"), BigDecimal("0.1"))
|
||||
@ -239,6 +239,6 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeTX() = TransactionType.General.Builder(DUMMY_NOTARY).withItems(
|
||||
private fun makeTX() = TransactionBuilder(DUMMY_NOTARY).withItems(
|
||||
1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE `with notary` DUMMY_NOTARY)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package net.corda.irs.contract
|
||||
import net.corda.contracts.*
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MockServices
|
||||
@ -305,7 +306,7 @@ class IRSTests : TestDependencyInjectionBase() {
|
||||
while (true) {
|
||||
val nextFix: FixOf = currentIRS().nextFixingOf() ?: break
|
||||
val fixTX: SignedTransaction = run {
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val tx = TransactionBuilder(DUMMY_NOTARY)
|
||||
val fixing = Fix(nextFix, "0.052".percent.value)
|
||||
InterestRateSwap().generateFix(tx, previousTXN.tx.outRef(0), fixing)
|
||||
tx.setTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
|
@ -2,7 +2,6 @@ package net.corda.vega.contracts
|
||||
|
||||
import net.corda.contracts.DealState
|
||||
import net.corda.core.contracts.Command
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.contracts.UniqueIdentifier
|
||||
import net.corda.core.crypto.keys
|
||||
import net.corda.core.identity.AbstractParty
|
||||
@ -29,6 +28,6 @@ data class IRSState(val swap: SwapData,
|
||||
|
||||
override fun generateAgreement(notary: Party): TransactionBuilder {
|
||||
val state = IRSState(swap, buyer, seller, OGTrade())
|
||||
return TransactionType.General.Builder(notary).withItems(state, Command(OGTrade.Commands.Agree(), participants.map { it.owningKey }))
|
||||
return TransactionBuilder(notary).withItems(state, Command(OGTrade.Commands.Agree(), participants.map { it.owningKey }))
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ data class PortfolioState(val portfolio: List<StateRef>,
|
||||
}
|
||||
|
||||
override fun generateAgreement(notary: Party): TransactionBuilder {
|
||||
return TransactionType.General.Builder(notary).withItems(copy(), Command(PortfolioSwap.Commands.Agree(), participants.map { it.owningKey }))
|
||||
return TransactionBuilder(notary).withItems(copy(), Command(PortfolioSwap.Commands.Agree(), participants.map { it.owningKey }))
|
||||
}
|
||||
|
||||
override fun generateRevision(notary: Party, oldState: StateAndRef<*>, updatedValue: Update): TransactionBuilder {
|
||||
@ -50,7 +50,7 @@ data class PortfolioState(val portfolio: List<StateRef>,
|
||||
val portfolio = updatedValue.portfolio ?: portfolio
|
||||
val valuation = updatedValue.valuation ?: valuation
|
||||
|
||||
val tx = TransactionType.General.Builder(notary)
|
||||
val tx = TransactionBuilder(notary)
|
||||
tx.addInputState(oldState)
|
||||
tx.addOutputState(copy(portfolio = portfolio, valuation = valuation))
|
||||
tx.addCommand(PortfolioSwap.Commands.Update(), participants.map { it.owningKey })
|
||||
|
@ -16,6 +16,7 @@ import net.corda.core.identity.Party
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
import net.corda.flows.TwoPartyTradeFlow
|
||||
import net.corda.testing.BOC
|
||||
@ -91,7 +92,7 @@ class SellerFlow(val otherParty: Party,
|
||||
|
||||
// Now make a dummy transaction that moves it to a new key, just to show that resolving dependencies works.
|
||||
val move: SignedTransaction = run {
|
||||
val builder = TransactionType.General.Builder(notaryNode.notaryIdentity)
|
||||
val builder = TransactionBuilder(notaryNode.notaryIdentity)
|
||||
CommercialPaper().generateMove(builder, issuance.tx.outRef(0), ownedBy)
|
||||
val stx = serviceHub.signInitialTransaction(builder)
|
||||
subFlow(FinalityFlow(stx)).single()
|
||||
|
@ -50,10 +50,10 @@ data class DummyContract(override val legalContractReference: SecureHash = Secur
|
||||
val owners = listOf(owner) + otherOwners
|
||||
return if (owners.size == 1) {
|
||||
val state = SingleOwnerState(magicNumber, owners.first().party)
|
||||
TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Create(), owners.first().party.owningKey))
|
||||
TransactionBuilder(notary).withItems(state, Command(Commands.Create(), owners.first().party.owningKey))
|
||||
} else {
|
||||
val state = MultiOwnerState(magicNumber, owners.map { it.party })
|
||||
TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Create(), owners.map { it.party.owningKey }))
|
||||
TransactionBuilder(notary).withItems(state, Command(Commands.Create(), owners.map { it.party.owningKey }))
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ data class DummyContract(override val legalContractReference: SecureHash = Secur
|
||||
require(priors.isNotEmpty())
|
||||
val priorState = priors[0].state.data
|
||||
val (cmd, state) = priorState.withNewOwner(newOwner)
|
||||
return TransactionType.General.Builder(notary = priors[0].state.notary).withItems(
|
||||
return TransactionBuilder(notary = priors[0].state.notary).withItems(
|
||||
/* INPUTS */ *priors.toTypedArray(),
|
||||
/* COMMAND */ Command(cmd, priorState.owner.owningKey),
|
||||
/* OUTPUT */ state
|
||||
|
@ -5,6 +5,7 @@ import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.flows.ContractUpgradeFlow
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
|
||||
// The dummy contract doesn't do anything useful. It exists for testing purposes.
|
||||
@ -51,7 +52,7 @@ class DummyContractV2 : UpgradedContract<DummyContract.State, DummyContractV2.St
|
||||
require(states.isNotEmpty())
|
||||
|
||||
val signees: Set<AbstractParty> = states.flatMap { it.state.data.participants }.distinct().toSet()
|
||||
return Pair(TransactionType.General.Builder(notary).apply {
|
||||
return Pair(TransactionBuilder(notary).apply {
|
||||
states.forEach {
|
||||
addInputState(it)
|
||||
addOutputState(upgrade(it.state.data))
|
||||
|
@ -13,6 +13,7 @@ import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.services.Vault
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.testing.CHARLIE
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.DUMMY_NOTARY_KEY
|
||||
@ -30,7 +31,7 @@ fun ServiceHub.fillWithSomeTestDeals(dealIds: List<String>,
|
||||
|
||||
val transactions: List<SignedTransaction> = dealIds.map {
|
||||
// Issue a deal state
|
||||
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
val dummyIssue = TransactionBuilder(notary = DUMMY_NOTARY).apply {
|
||||
addOutputState(DummyDealContract.State(ref = it, participants = participants.plus(me)))
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}
|
||||
@ -60,7 +61,7 @@ fun ServiceHub.fillWithSomeTestLinearStates(numberToCreate: Int,
|
||||
|
||||
val transactions: List<SignedTransaction> = (1..numberToCreate).map {
|
||||
// Issue a Linear state
|
||||
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
val dummyIssue = TransactionBuilder(notary = DUMMY_NOTARY).apply {
|
||||
addOutputState(DummyLinearContract.State(
|
||||
linearId = UniqueIdentifier(externalId),
|
||||
participants = participants.plus(me),
|
||||
@ -111,7 +112,7 @@ fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>,
|
||||
// We will allocate one state to one transaction, for simplicities sake.
|
||||
val cash = Cash()
|
||||
val transactions: List<SignedTransaction> = amounts.map { pennies ->
|
||||
val issuance = TransactionType.General.Builder(null as Party?)
|
||||
val issuance = TransactionBuilder(null as Party?)
|
||||
cash.generateIssue(issuance, Amount(pennies, Issued(issuedBy.copy(reference = ref), howMuch.token)), me, outputNotary)
|
||||
issuance.signWith(issuerKey)
|
||||
|
||||
@ -139,7 +140,7 @@ fun ServiceHub.fillWithSomeTestCommodity(amount: Amount<Commodity>,
|
||||
val me = AnonymousParty(myKey)
|
||||
|
||||
val commodity = CommodityContract()
|
||||
val issuance = TransactionType.General.Builder(null as Party?)
|
||||
val issuance = TransactionBuilder(null as Party?)
|
||||
commodity.generateIssue(issuance, Amount(amount.quantity, Issued(issuedBy.copy(reference = ref), amount.token)), me, outputNotary)
|
||||
issuance.signWith(issuerKey)
|
||||
val transaction = issuance.toSignedTransaction(true)
|
||||
@ -180,7 +181,7 @@ fun calculateRandomlySizedAmounts(howMuch: Amount<Currency>, min: Int, max: Int,
|
||||
fun <T : LinearState> ServiceHub.consume(states: List<StateAndRef<T>>) {
|
||||
// Create a txn consuming different contract types
|
||||
states.forEach {
|
||||
val consumedTx = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
val consumedTx = TransactionBuilder(notary = DUMMY_NOTARY).apply {
|
||||
addInputState(it)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
@ -191,7 +192,7 @@ fun <T : LinearState> ServiceHub.consume(states: List<StateAndRef<T>>) {
|
||||
|
||||
fun <T : LinearState> ServiceHub.consumeAndProduce(stateAndRef: StateAndRef<T>): StateAndRef<T> {
|
||||
// Create a txn consuming different contract types
|
||||
val consumedTx = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
val consumedTx = TransactionBuilder(notary = DUMMY_NOTARY).apply {
|
||||
addInputState(stateAndRef)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
@ -199,7 +200,7 @@ fun <T : LinearState> ServiceHub.consumeAndProduce(stateAndRef: StateAndRef<T>):
|
||||
recordTransactions(consumedTx)
|
||||
|
||||
// Create a txn consuming different contract types
|
||||
val producedTx = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
val producedTx = TransactionBuilder(notary = DUMMY_NOTARY).apply {
|
||||
addOutputState(DummyLinearContract.State(linearId = stateAndRef.state.data.linearId,
|
||||
participants = stateAndRef.state.data.participants))
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
@ -224,7 +225,7 @@ fun ServiceHub.evolveLinearState(linearState: StateAndRef<LinearState>) : StateA
|
||||
@JvmOverloads
|
||||
fun ServiceHub.consumeCash(amount: Amount<Currency>, to: Party = CHARLIE): Vault<Cash.State> {
|
||||
// A tx that spends our money.
|
||||
val spendTX = TransactionType.General.Builder(DUMMY_NOTARY).apply {
|
||||
val spendTX = TransactionBuilder(DUMMY_NOTARY).apply {
|
||||
vaultService.generateSpend(this, amount, to)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction(checkSufficientSignatures = false)
|
||||
|
Loading…
Reference in New Issue
Block a user