mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
Minor: rename SignedWireTransaction to just SignedTransaction
This commit is contained in:
parent
a42d7e64ef
commit
6deef5b598
@ -86,10 +86,10 @@ Our protocol has two parties (B and S for buyer and seller) and will proceed as
|
|||||||
|
|
||||||
1. S sends a ``StateAndRef`` pointing to the state they want to sell to B, along with info about the price they require
|
1. S sends a ``StateAndRef`` pointing to the state they want to sell to B, along with info about the price they require
|
||||||
B to pay.
|
B to pay.
|
||||||
2. B sends to S a ``SignedWireTransaction`` that includes the state as input, B's cash as input, the state with the new
|
2. B sends to S a ``SignedTransaction`` that includes the state as input, B's cash as input, the state with the new
|
||||||
owner key as output, and any change cash as output. It contains a single signature from B but isn't valid because
|
owner key as output, and any change cash as output. It contains a single signature from B but isn't valid because
|
||||||
it lacks a signature from S authorising movement of the asset.
|
it lacks a signature from S authorising movement of the asset.
|
||||||
3. S signs it and hands the now finalised ``SignedWireTransaction`` back to B.
|
3. S signs it and hands the now finalised ``SignedTransaction`` back to B.
|
||||||
|
|
||||||
You can find the implementation of this protocol in the file ``contracts/protocols/TwoPartyTradeProtocol.kt``.
|
You can find the implementation of this protocol in the file ``contracts/protocols/TwoPartyTradeProtocol.kt``.
|
||||||
|
|
||||||
@ -245,7 +245,7 @@ Let's implement the ``Seller.call`` method. This will be invoked by the platform
|
|||||||
|
|
||||||
.. sourcecode:: kotlin
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
val partialTX: SignedWireTransaction = receiveAndCheckProposedTransaction()
|
val partialTX: SignedTransaction = receiveAndCheckProposedTransaction()
|
||||||
|
|
||||||
// These two steps could be done in parallel, in theory. Our framework doesn't support that yet though.
|
// These two steps could be done in parallel, in theory. Our framework doesn't support that yet though.
|
||||||
val ourSignature = signWithOurKey(partialTX)
|
val ourSignature = signWithOurKey(partialTX)
|
||||||
@ -267,13 +267,13 @@ Let's fill out the ``receiveAndCheckProposedTransaction()`` method.
|
|||||||
.. sourcecode:: kotlin
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
open fun receiveAndCheckProposedTransaction(): SignedWireTransaction {
|
open fun receiveAndCheckProposedTransaction(): SignedTransaction {
|
||||||
val sessionID = random63BitValue()
|
val sessionID = random63BitValue()
|
||||||
|
|
||||||
// Make the first message we'll send to kick off the protocol.
|
// Make the first message we'll send to kick off the protocol.
|
||||||
val hello = SellerTradeInfo(assetToSell, price, myKeyPair.public, sessionID)
|
val hello = SellerTradeInfo(assetToSell, price, myKeyPair.public, sessionID)
|
||||||
|
|
||||||
val maybePartialTX = sendAndReceive(TRADE_TOPIC, buyerSessionID, sessionID, hello, SignedWireTransaction::class.java)
|
val maybePartialTX = sendAndReceive(TRADE_TOPIC, buyerSessionID, sessionID, hello, SignedTransaction::class.java)
|
||||||
val partialTX = maybePartialTX.validate {
|
val partialTX = maybePartialTX.validate {
|
||||||
it.verifySignatures()
|
it.verifySignatures()
|
||||||
logger.trace { "Received partially signed transaction" }
|
logger.trace { "Received partially signed transaction" }
|
||||||
@ -305,7 +305,7 @@ the initial protocol message, and then call ``sendAndReceive``. This function ta
|
|||||||
- The thing to send. It'll be serialised and sent automatically.
|
- The thing to send. It'll be serialised and sent automatically.
|
||||||
- Finally a type argument, which is the kind of object we're expecting to receive from the other side.
|
- Finally a type argument, which is the kind of object we're expecting to receive from the other side.
|
||||||
|
|
||||||
It returns a simple wrapper class, ``UntrustworthyData<SignedWireTransaction>``, which is just a marker class that reminds
|
It returns a simple wrapper class, ``UntrustworthyData<SignedTransaction>``, which is just a marker class that reminds
|
||||||
us that the data came from a potentially malicious external source and may have been tampered with or be unexpected in
|
us that the data came from a potentially malicious external source and may have been tampered with or be unexpected in
|
||||||
other ways. It doesn't add any functionality, but acts as a reminder to "scrub" the data before use. Here, our scrubbing
|
other ways. It doesn't add any functionality, but acts as a reminder to "scrub" the data before use. Here, our scrubbing
|
||||||
simply involves checking the signatures on it. Then we could go ahead and do some more involved checks.
|
simply involves checking the signatures on it. Then we could go ahead and do some more involved checks.
|
||||||
@ -329,15 +329,15 @@ Here's the rest of the code:
|
|||||||
|
|
||||||
.. sourcecode:: kotlin
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
open fun signWithOurKey(partialTX: SignedWireTransaction) = myKeyPair.signWithECDSA(partialTX.txBits)
|
open fun signWithOurKey(partialTX: SignedTransaction) = myKeyPair.signWithECDSA(partialTX.txBits)
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
open fun timestamp(partialTX: SignedWireTransaction): DigitalSignature.LegallyIdentifiable {
|
open fun timestamp(partialTX: SignedTransaction): DigitalSignature.LegallyIdentifiable {
|
||||||
return TimestamperClient(this, timestampingAuthority).timestamp(partialTX.txBits)
|
return TimestamperClient(this, timestampingAuthority).timestamp(partialTX.txBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
open fun sendSignatures(partialTX: SignedWireTransaction, ourSignature: DigitalSignature.WithKey,
|
open fun sendSignatures(partialTX: SignedTransaction, ourSignature: DigitalSignature.WithKey,
|
||||||
tsaSig: DigitalSignature.LegallyIdentifiable): LedgerTransaction {
|
tsaSig: DigitalSignature.LegallyIdentifiable): LedgerTransaction {
|
||||||
val fullySigned = partialTX + tsaSig + ourSignature
|
val fullySigned = partialTX + tsaSig + ourSignature
|
||||||
val ltx = fullySigned.verifyToLedgerTransaction(serviceHub.identityService)
|
val ltx = fullySigned.verifyToLedgerTransaction(serviceHub.identityService)
|
||||||
@ -411,7 +411,7 @@ OK, let's do the same for the buyer side:
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
open fun swapSignaturesWithSeller(stx: SignedWireTransaction, theirSessionID: Long): SignaturesFromSeller {
|
open fun swapSignaturesWithSeller(stx: SignedTransaction, theirSessionID: Long): SignaturesFromSeller {
|
||||||
logger.trace { "Sending partially signed transaction to seller" }
|
logger.trace { "Sending partially signed transaction to seller" }
|
||||||
|
|
||||||
// TODO: Protect against the seller terminating here and leaving us in the lurch without the final tx.
|
// TODO: Protect against the seller terminating here and leaving us in the lurch without the final tx.
|
||||||
@ -419,7 +419,7 @@ OK, let's do the same for the buyer side:
|
|||||||
return sendAndReceive(TRADE_TOPIC, otherSide, theirSessionID, sessionID, stx, SignaturesFromSeller::class.java).validate {}
|
return sendAndReceive(TRADE_TOPIC, otherSide, theirSessionID, sessionID, stx, SignaturesFromSeller::class.java).validate {}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun signWithOurKeys(cashSigningPubKeys: List<PublicKey>, ptx: TransactionBuilder): SignedWireTransaction {
|
open fun signWithOurKeys(cashSigningPubKeys: List<PublicKey>, ptx: TransactionBuilder): SignedTransaction {
|
||||||
// Now sign the transaction with whatever keys we need to move the cash.
|
// Now sign the transaction with whatever keys we need to move the cash.
|
||||||
for (k in cashSigningPubKeys) {
|
for (k in cashSigningPubKeys) {
|
||||||
val priv = serviceHub.keyManagementService.toPrivate(k)
|
val priv = serviceHub.keyManagementService.toPrivate(k)
|
||||||
|
@ -744,7 +744,7 @@ A ``TransactionBuilder`` is not by itself ready to be used anywhere, so first, w
|
|||||||
is recognised by the network. The most important next step is for the participating entities to sign it using the
|
is recognised by the network. The most important next step is for the participating entities to sign it using the
|
||||||
``signWith()`` method. This takes a keypair, serialises the transaction, signs the serialised form and then stores the
|
``signWith()`` method. This takes a keypair, serialises the transaction, signs the serialised form and then stores the
|
||||||
signature inside the ``TransactionBuilder``. Once all parties have signed, you can call ``TransactionBuilder.toSignedTransaction()``
|
signature inside the ``TransactionBuilder``. Once all parties have signed, you can call ``TransactionBuilder.toSignedTransaction()``
|
||||||
to get a ``SignedWireTransaction`` object. This is an immutable form of the transaction that's ready for *timestamping*,
|
to get a ``SignedTransaction`` object. This is an immutable form of the transaction that's ready for *timestamping*,
|
||||||
which can be done using a ``TimestamperClient``. To learn more about that, please refer to the
|
which can be done using a ``TimestamperClient``. To learn more about that, please refer to the
|
||||||
:doc:`protocol-state-machines` document.
|
:doc:`protocol-state-machines` document.
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ import java.time.Instant
|
|||||||
*
|
*
|
||||||
* 1. S sends the [StateAndRef] pointing to what they want to sell to B, along with info about the price they require
|
* 1. S sends the [StateAndRef] pointing to what they want to sell to B, along with info about the price they require
|
||||||
* B to pay. For example this has probably been agreed on an exchange.
|
* B to pay. For example this has probably been agreed on an exchange.
|
||||||
* 2. B sends to S a [SignedWireTransaction] that includes the state as input, B's cash as input, the state with the new
|
* 2. B sends to S a [SignedTransaction] that includes the state as input, B's cash as input, the state with the new
|
||||||
* owner key as output, and any change cash as output. It contains a single signature from B but isn't valid because
|
* owner key as output, and any change cash as output. It contains a single signature from B but isn't valid because
|
||||||
* it lacks a signature from S authorising movement of the asset.
|
* it lacks a signature from S authorising movement of the asset.
|
||||||
* 3. S signs it and hands the now finalised SignedWireTransaction back to B.
|
* 3. S signs it and hands the now finalised SignedWireTransaction back to B.
|
||||||
@ -85,7 +85,7 @@ object TwoPartyTradeProtocol {
|
|||||||
val buyerSessionID: Long) : ProtocolStateMachine<Pair<WireTransaction, LedgerTransaction>>() {
|
val buyerSessionID: Long) : ProtocolStateMachine<Pair<WireTransaction, LedgerTransaction>>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): Pair<WireTransaction, LedgerTransaction> {
|
override fun call(): Pair<WireTransaction, LedgerTransaction> {
|
||||||
val partialTX: SignedWireTransaction = receiveAndCheckProposedTransaction()
|
val partialTX: SignedTransaction = receiveAndCheckProposedTransaction()
|
||||||
|
|
||||||
// These two steps could be done in parallel, in theory. Our framework doesn't support that yet though.
|
// These two steps could be done in parallel, in theory. Our framework doesn't support that yet though.
|
||||||
val ourSignature = signWithOurKey(partialTX)
|
val ourSignature = signWithOurKey(partialTX)
|
||||||
@ -97,13 +97,13 @@ object TwoPartyTradeProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
open fun receiveAndCheckProposedTransaction(): SignedWireTransaction {
|
open fun receiveAndCheckProposedTransaction(): SignedTransaction {
|
||||||
val sessionID = random63BitValue()
|
val sessionID = random63BitValue()
|
||||||
|
|
||||||
// Make the first message we'll send to kick off the protocol.
|
// Make the first message we'll send to kick off the protocol.
|
||||||
val hello = SellerTradeInfo(assetToSell, price, myKeyPair.public, sessionID)
|
val hello = SellerTradeInfo(assetToSell, price, myKeyPair.public, sessionID)
|
||||||
|
|
||||||
val maybePartialTX = sendAndReceive(TRADE_TOPIC, otherSide, buyerSessionID, sessionID, hello, SignedWireTransaction::class.java)
|
val maybePartialTX = sendAndReceive(TRADE_TOPIC, otherSide, buyerSessionID, sessionID, hello, SignedTransaction::class.java)
|
||||||
val partialTX = maybePartialTX.validate {
|
val partialTX = maybePartialTX.validate {
|
||||||
it.verifySignatures()
|
it.verifySignatures()
|
||||||
logger.trace { "Received partially signed transaction" }
|
logger.trace { "Received partially signed transaction" }
|
||||||
@ -127,15 +127,15 @@ object TwoPartyTradeProtocol {
|
|||||||
return partialTX
|
return partialTX
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun signWithOurKey(partialTX: SignedWireTransaction) = myKeyPair.signWithECDSA(partialTX.txBits)
|
open fun signWithOurKey(partialTX: SignedTransaction) = myKeyPair.signWithECDSA(partialTX.txBits)
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
open fun timestamp(partialTX: SignedWireTransaction): DigitalSignature.LegallyIdentifiable {
|
open fun timestamp(partialTX: SignedTransaction): DigitalSignature.LegallyIdentifiable {
|
||||||
return TimestamperClient(this, timestampingAuthority).timestamp(partialTX.txBits)
|
return TimestamperClient(this, timestampingAuthority).timestamp(partialTX.txBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
open fun sendSignatures(partialTX: SignedWireTransaction, ourSignature: DigitalSignature.WithKey,
|
open fun sendSignatures(partialTX: SignedTransaction, ourSignature: DigitalSignature.WithKey,
|
||||||
tsaSig: DigitalSignature.LegallyIdentifiable): LedgerTransaction {
|
tsaSig: DigitalSignature.LegallyIdentifiable): LedgerTransaction {
|
||||||
val fullySigned = partialTX + tsaSig + ourSignature
|
val fullySigned = partialTX + tsaSig + ourSignature
|
||||||
val ltx = fullySigned.verifyToLedgerTransaction(serviceHub.identityService)
|
val ltx = fullySigned.verifyToLedgerTransaction(serviceHub.identityService)
|
||||||
@ -199,7 +199,7 @@ object TwoPartyTradeProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
open fun swapSignaturesWithSeller(stx: SignedWireTransaction, theirSessionID: Long): SignaturesFromSeller {
|
open fun swapSignaturesWithSeller(stx: SignedTransaction, theirSessionID: Long): SignaturesFromSeller {
|
||||||
logger.trace { "Sending partially signed transaction to seller" }
|
logger.trace { "Sending partially signed transaction to seller" }
|
||||||
|
|
||||||
// TODO: Protect against the seller terminating here and leaving us in the lurch without the final tx.
|
// TODO: Protect against the seller terminating here and leaving us in the lurch without the final tx.
|
||||||
@ -207,7 +207,7 @@ object TwoPartyTradeProtocol {
|
|||||||
return sendAndReceive(TRADE_TOPIC, otherSide, theirSessionID, sessionID, stx, SignaturesFromSeller::class.java).validate {}
|
return sendAndReceive(TRADE_TOPIC, otherSide, theirSessionID, sessionID, stx, SignaturesFromSeller::class.java).validate {}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun signWithOurKeys(cashSigningPubKeys: List<PublicKey>, ptx: TransactionBuilder): SignedWireTransaction {
|
open fun signWithOurKeys(cashSigningPubKeys: List<PublicKey>, ptx: TransactionBuilder): SignedTransaction {
|
||||||
// Now sign the transaction with whatever keys we need to move the cash.
|
// Now sign the transaction with whatever keys we need to move the cash.
|
||||||
for (k in cashSigningPubKeys) {
|
for (k in cashSigningPubKeys) {
|
||||||
val priv = serviceHub.keyManagementService.toPrivate(k)
|
val priv = serviceHub.keyManagementService.toPrivate(k)
|
||||||
|
@ -78,9 +78,9 @@ data class WireTransaction(val inputs: List<StateRef>,
|
|||||||
return LedgerTransaction(inputs, outputs, authenticatedArgs, id)
|
return LedgerTransaction(inputs, outputs, authenticatedArgs, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Serialises and returns this transaction as a [SignedWireTransaction] with no signatures attached. */
|
/** Serialises and returns this transaction as a [SignedTransaction] with no signatures attached. */
|
||||||
fun toSignedTransaction(withSigs: List<DigitalSignature.WithKey>): SignedWireTransaction {
|
fun toSignedTransaction(withSigs: List<DigitalSignature.WithKey>): SignedTransaction {
|
||||||
return SignedWireTransaction(serialized, withSigs)
|
return SignedTransaction(serialized, withSigs)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
@ -94,7 +94,7 @@ data class WireTransaction(val inputs: List<StateRef>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Container for a [WireTransaction] and attached signatures. */
|
/** Container for a [WireTransaction] and attached signatures. */
|
||||||
data class SignedWireTransaction(val txBits: SerializedBytes<WireTransaction>, val sigs: List<DigitalSignature.WithKey>) {
|
data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>, val sigs: List<DigitalSignature.WithKey>) {
|
||||||
init { check(sigs.isNotEmpty()) }
|
init { check(sigs.isNotEmpty()) }
|
||||||
|
|
||||||
/** Lazily calculated access to the deserialised/hashed transaction data. */
|
/** Lazily calculated access to the deserialised/hashed transaction data. */
|
||||||
@ -237,7 +237,7 @@ class TransactionBuilder(private val inputs: MutableList<StateRef> = arrayListOf
|
|||||||
|
|
||||||
fun toWireTransaction() = WireTransaction(ArrayList(inputs), ArrayList(outputs), ArrayList(commands))
|
fun toWireTransaction() = WireTransaction(ArrayList(inputs), ArrayList(outputs), ArrayList(commands))
|
||||||
|
|
||||||
fun toSignedTransaction(checkSufficientSignatures: Boolean = true): SignedWireTransaction {
|
fun toSignedTransaction(checkSufficientSignatures: Boolean = true): SignedTransaction {
|
||||||
if (checkSufficientSignatures) {
|
if (checkSufficientSignatures) {
|
||||||
val gotKeys = currentSigs.map { it.by }.toSet()
|
val gotKeys = currentSigs.map { it.by }.toSet()
|
||||||
for (command in commands) {
|
for (command in commands) {
|
||||||
@ -245,7 +245,7 @@ class TransactionBuilder(private val inputs: MutableList<StateRef> = arrayListOf
|
|||||||
throw IllegalStateException("Missing signatures on the transaction for a ${command.data.javaClass.canonicalName} command")
|
throw IllegalStateException("Missing signatures on the transaction for a ${command.data.javaClass.canonicalName} command")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SignedWireTransaction(toWireTransaction().serialize(), ArrayList(currentSigs))
|
return SignedTransaction(toWireTransaction().serialize(), ArrayList(currentSigs))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addInputState(ref: StateRef) {
|
fun addInputState(ref: StateRef) {
|
||||||
@ -299,13 +299,13 @@ data class LedgerTransaction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts this transaction to [SignedWireTransaction] form, optionally using the provided keys to sign. There is
|
* Converts this transaction to [SignedTransaction] form, optionally using the provided keys to sign. There is
|
||||||
* no requirement that [andSignWithKeys] include all required keys.
|
* no requirement that [andSignWithKeys] include all required keys.
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if a key is provided that isn't listed in any command and [allowUnusedKeys]
|
* @throws IllegalArgumentException if a key is provided that isn't listed in any command and [allowUnusedKeys]
|
||||||
* is false.
|
* is false.
|
||||||
*/
|
*/
|
||||||
fun toSignedTransaction(andSignWithKeys: List<KeyPair> = emptyList(), allowUnusedKeys: Boolean = false): SignedWireTransaction {
|
fun toSignedTransaction(andSignWithKeys: List<KeyPair> = emptyList(), allowUnusedKeys: Boolean = false): SignedTransaction {
|
||||||
val allPubKeys = commands.flatMap { it.signers }.toSet()
|
val allPubKeys = commands.flatMap { it.signers }.toSet()
|
||||||
val wtx = toWireTransaction()
|
val wtx = toWireTransaction()
|
||||||
val bits = wtx.serialize()
|
val bits = wtx.serialize()
|
||||||
|
@ -16,7 +16,7 @@ import com.esotericsoftware.kryo.Serializer
|
|||||||
import com.esotericsoftware.kryo.io.Input
|
import com.esotericsoftware.kryo.io.Input
|
||||||
import com.esotericsoftware.kryo.io.Output
|
import com.esotericsoftware.kryo.io.Output
|
||||||
import com.esotericsoftware.kryo.serializers.JavaSerializer
|
import com.esotericsoftware.kryo.serializers.JavaSerializer
|
||||||
import core.SignedWireTransaction
|
import core.SignedTransaction
|
||||||
import core.crypto.SecureHash
|
import core.crypto.SecureHash
|
||||||
import core.crypto.generateKeyPair
|
import core.crypto.generateKeyPair
|
||||||
import core.crypto.sha256
|
import core.crypto.sha256
|
||||||
@ -206,7 +206,7 @@ fun createKryo(k: Kryo = Kryo()): Kryo {
|
|||||||
// Some classes have to be handled with the ImmutableClassSerializer because they need to have their
|
// Some classes have to be handled with the ImmutableClassSerializer because they need to have their
|
||||||
// constructors be invoked (typically for lazy members).
|
// constructors be invoked (typically for lazy members).
|
||||||
val immutables = listOf(
|
val immutables = listOf(
|
||||||
SignedWireTransaction::class,
|
SignedTransaction::class,
|
||||||
SerializedBytes::class
|
SerializedBytes::class
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ class TransactionGroupTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun signGroup() {
|
fun signGroup() {
|
||||||
val signedTxns: List<SignedWireTransaction> = transactionGroup {
|
val signedTxns: List<SignedTransaction> = transactionGroup {
|
||||||
transaction {
|
transaction {
|
||||||
output("£1000") { A_THOUSAND_POUNDS }
|
output("£1000") { A_THOUSAND_POUNDS }
|
||||||
arg(MINI_CORP_PUBKEY) { Cash.Commands.Issue() }
|
arg(MINI_CORP_PUBKEY) { Cash.Commands.Issue() }
|
||||||
|
@ -315,7 +315,7 @@ class TransactionGroupDSL<T : ContractState>(private val stateType: Class<T>) {
|
|||||||
GraphVisualiser(this as TransactionGroupDSL<ContractState>).display()
|
GraphVisualiser(this as TransactionGroupDSL<ContractState>).display()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun signAll(): List<SignedWireTransaction> {
|
fun signAll(): List<SignedTransaction> {
|
||||||
return txns.map { wtx ->
|
return txns.map { wtx ->
|
||||||
val allPubKeys = wtx.commands.flatMap { it.pubkeys }.toSet()
|
val allPubKeys = wtx.commands.flatMap { it.pubkeys }.toSet()
|
||||||
val bits = wtx.serialize()
|
val bits = wtx.serialize()
|
||||||
|
Loading…
Reference in New Issue
Block a user