mirror of
https://github.com/corda/corda.git
synced 2024-12-21 13:57:54 +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.serialization.OpaqueBytes
|
||||
import core.serialization.serialize
|
||||
import java.io.InputStream
|
||||
import java.security.PublicKey
|
||||
import java.time.Duration
|
||||
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
|
||||
@ -146,4 +153,20 @@ interface ContractFactory {
|
||||
operator fun <T : Contract> get(hash: SecureHash): T
|
||||
}
|
||||
|
||||
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. */
|
||||
data class WireTransaction(val inputs: List<StateRef>,
|
||||
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.
|
||||
@Volatile @Transient private var cachedBits: SerializedBytes<WireTransaction>? = null
|
||||
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 {
|
||||
fun deserialize(bits: SerializedBytes<WireTransaction>): WireTransaction {
|
||||
val wtx = bits.deserialize()
|
||||
@ -98,14 +99,15 @@ data class WireTransaction(val inputs: List<StateRef>,
|
||||
}
|
||||
|
||||
/** 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()) }
|
||||
|
||||
/** Lazily calculated access to the deserialised/hashed transaction data. */
|
||||
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. */
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user