mirror of
https://github.com/corda/corda.git
synced 2024-12-22 06:17:55 +00:00
Introduce a NamedByHash interface, for things that are identified via secure hash.
This commit is contained in:
parent
dfc15a6bab
commit
c24d991a7e
@ -12,9 +12,16 @@ import core.crypto.SecureHash
|
|||||||
import core.crypto.toStringShort
|
import core.crypto.toStringShort
|
||||||
import core.serialization.OpaqueBytes
|
import core.serialization.OpaqueBytes
|
||||||
import core.serialization.serialize
|
import core.serialization.serialize
|
||||||
|
import java.io.InputStream
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
import java.util.jar.JarInputStream
|
||||||
|
|
||||||
|
/** Implemented by anything that can be named by a secure hash value (e.g. transactions, attachments). */
|
||||||
|
interface NamedByHash {
|
||||||
|
val id: SecureHash
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A contract state (or just "state") contains opaque data used by a contract program. It can be thought of as a disk
|
* A contract state (or just "state") contains opaque data used by a contract program. It can be thought of as a disk
|
||||||
@ -147,3 +154,19 @@ interface ContractFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class UnknownContractException : Exception()
|
class UnknownContractException : Exception()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An attachment is a ZIP (or an optionally signed JAR) that contains one or more files. Attachments are meant to
|
||||||
|
* contain public static data which can be referenced from transactions and utilised from contracts. Good examples
|
||||||
|
* of how attachments are meant to be used include:
|
||||||
|
*
|
||||||
|
* - Calendar data
|
||||||
|
* - Fixes (e.g. LIBOR)
|
||||||
|
* - Smart contract code
|
||||||
|
* - Legal documents
|
||||||
|
* - Facts generated by oracles which might be reused a lot
|
||||||
|
*/
|
||||||
|
interface Attachment : NamedByHash {
|
||||||
|
fun open(): InputStream
|
||||||
|
fun openAsJAR() = JarInputStream(open())
|
||||||
|
}
|
@ -57,12 +57,13 @@ import java.util.*
|
|||||||
/** Transaction ready for serialisation, without any signatures attached. */
|
/** Transaction ready for serialisation, without any signatures attached. */
|
||||||
data class WireTransaction(val inputs: List<StateRef>,
|
data class WireTransaction(val inputs: List<StateRef>,
|
||||||
val outputs: List<ContractState>,
|
val outputs: List<ContractState>,
|
||||||
val commands: List<Command>) {
|
val commands: List<Command>) : NamedByHash {
|
||||||
|
|
||||||
// Cache the serialised form of the transaction and its hash to give us fast access to it.
|
// Cache the serialised form of the transaction and its hash to give us fast access to it.
|
||||||
@Volatile @Transient private var cachedBits: SerializedBytes<WireTransaction>? = null
|
@Volatile @Transient private var cachedBits: SerializedBytes<WireTransaction>? = null
|
||||||
val serialized: SerializedBytes<WireTransaction> get() = cachedBits ?: serialize().apply { cachedBits = this }
|
val serialized: SerializedBytes<WireTransaction> get() = cachedBits ?: serialize().apply { cachedBits = this }
|
||||||
val id: SecureHash get() = serialized.hash
|
override val id: SecureHash get() = serialized.hash
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun deserialize(bits: SerializedBytes<WireTransaction>): WireTransaction {
|
fun deserialize(bits: SerializedBytes<WireTransaction>): WireTransaction {
|
||||||
val wtx = bits.deserialize()
|
val wtx = bits.deserialize()
|
||||||
@ -98,14 +99,15 @@ data class WireTransaction(val inputs: List<StateRef>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Container for a [WireTransaction] and attached signatures. */
|
/** Container for a [WireTransaction] and attached signatures. */
|
||||||
data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>, val sigs: List<DigitalSignature.WithKey>) {
|
data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
|
||||||
|
val sigs: List<DigitalSignature.WithKey>) : NamedByHash {
|
||||||
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. */
|
||||||
val tx: WireTransaction by lazy { WireTransaction.deserialize(txBits) }
|
val tx: WireTransaction by lazy { WireTransaction.deserialize(txBits) }
|
||||||
|
|
||||||
/** A transaction ID is the hash of the [WireTransaction]. Thus adding or removing a signature does not change it. */
|
/** A transaction ID is the hash of the [WireTransaction]. Thus adding or removing a signature does not change it. */
|
||||||
val id: SecureHash get() = txBits.hash
|
override val id: SecureHash get() = txBits.hash
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies the given signatures against the serialized transaction data. Does NOT deserialise or check the contents
|
* Verifies the given signatures against the serialized transaction data. Does NOT deserialise or check the contents
|
||||||
|
Loading…
Reference in New Issue
Block a user