2017-07-13 1 views
3

Actuellement, nous prévoyons d'avoir une version «Brouillon» du contrat qui ne sera pas envoyée à la contrepartie et l'initiateur peut apporter des modifications avant de l'envoyer au réseau, donc cela devrait être comme un "fait non partagé". Comme nous le savons Corda et le coffre-fort sont utilisés pour des faits partagés, je ne sais pas si nous pouvons toujours utiliser le coffre-fort pour stocker ce type de "non-partagé", mon idée ci-dessous et je peux déjà faire ce travail dans ma base locale. sur le tutoriel CorDapp, mais aimerait obtenir des contributions d'autres équipes/experts de Corda.Comment définir un fait non partagé dans Corda

Le principal changement est dans le flux initiateur:

  • Initier la seule de commande créer avec de clé
  • l'initiateur Ne pas invoquer la « CollectSignaturesFlow » donc ce ne sera pas envoyé à tous les autres
  • Appelez "FinalityFlow" après le verify(), donc ce sera engagé dans le ledger

Ci-dessous les codes pour les points mentionnés ci-dessus.

override fun call(): SignedTransaction { 
    // We create a transaction builder 
    val txBuilder = TransactionBuilder() 
    val notaryIdentity = serviceHub.networkMapCache.getAnyNotary() 
    txBuilder.notary = notaryIdentity 

    // We create the transaction's components. 
    val ourIdentity = serviceHub.myInfo.legalIdentity 
    val iou = TemplateState(iouValue, ourIdentity, ourIdentity) 
    val txCommand = Command(TemplateContract.Create(), listOf(ourIdentity.owningKey)) 

    // Adding the item's to the builder. 
    txBuilder.withItems(iou, txCommand) 

    // Verifying the transaction. 
    txBuilder.toWireTransaction().toLedgerTransaction(serviceHub).verify() 

    // Signing the transaction. 
    val partSignedTx = serviceHub.signInitialTransaction(txBuilder) 

    // Finalising the transaction. 
    return subFlow(FinalityFlow(partSignedTx)).single() 
} 

Répondre

3

Vous pouvez en effet créer un fait non partagé dans Corda! La clé ici est dans la liste participants de l'état. Ajoutez-vous simplement dans la liste des participants et seulement votre clé publique à la commande. Voici un exemple simple:

//Contract and State. 
class UnsharedFact: Contract { 
    override val legalContractReference: SecureHash = SecureHash.zeroHash 
    override fun verify(tx: TransactionForContract) = Unit // Stubbed out. 
    class Create: CommandData 

    data class State(val parties: Set<Party>): ContractState { 
     override val contract: Contract get() = UnsharedFact() 
     override val participants: List<AbstractParty> get() = parties.toList() 
     fun addParty(newParty: Party) = copy(parties = parties + newParty) 
    } 
} 

// Create flow. 
@InitiatingFlow 
@StartableByRPC 
class CreateUnsharedFact(): FlowLogic<SignedTransaction>() { 
    @Suspendable 
    override fun call(): SignedTransaction { 
     val me = serviceHub.myInfo.legalIdentity 
     val notary = serviceHub.networkMapCache.getAnyNotary() 
     val state = UnsharedFact.State(setOf(me)) 
     val command = Command(UnsharedFact.Create(), listOf(me.owningKey)) 
     val utx = TransactionBuilder(notary = notary).withItems(state, command) 
     val stx = serviceHub.signInitialTransaction(utx) 
     return subFlow(FinalityFlow(stx)).single() 
    } 
} 

Lorsque FinalityFlow est appelé, vous serez le seul nœud qui reçoit l'état de sortie.

Si vous souhaitez par la suite impliquer une autre partie, vous pouvez créer une nouvelle version de l'état à l'aide de la méthode addParty au UnsharedFact.State. Ensuite, créez une nouvelle transaction en ajoutant l'état d'origine comme entrée et la nouvelle version (avec la nouvelle partie) comme sortie. Lorsque cette transaction est finalisée (notariée), les deux parties en auront une copie dans leurs coffres respectifs. Maintenant, je suppose que le nom 'UnsharedFact' est inapproprié :)

Vous pouvez également supprimer des parties en utilisant une approche similaire.

+0

Merci Roger pour ce commentaire. Donc revenons à notre version "Brouillon" du contrat, même si ce n'est pas un fait partagé, mais c'est un fait qui est stocké dans le coffre-fort, donc pour le mettre à jour ou même le supprimer, nous devons toujours utiliser entrée et sortie ne devrait pas mettre à jour ou supprimer les données d'origine du coffre-fort, Corda lui-même ne fournit également aucune fonction pour mettre à jour/supprimer physiquement un état. Ai-je raison? –

+0

Et Roger, je viens de remarquer que dans le projet principal de Corda, le flux de démonstration de papier commercial, il a une fonction 'selfIssueSomeCommercialPaper' qui utilise' serviceHub.recordTransactions (listOf (tx)) 'pour enregistrer la transaction et son état de sortie vers Vault, au lieu de 'FinalityFlow', est-ce une autre approche que nous pouvons utiliser? –

+0

A votre premier commentaire - oui! Pour le mettre à jour et/ou le supprimer, vous utiliserez une transaction. A votre deuxième commentaire. Je recommande d'utiliser 'FinalityFlow' sur' recordTransactions'. 'FinalityFlow' attrape le notaire, si nécessaire, puis distribue le tx à toutes les parties requises en appelant' BroadcastTransactionFlow'. Les destinataires reçoivent 'NotifyTransactionHandler' (en réponse à' BroadcastTransactionFlow') qui résout ensuite les dépendances de tx et stocke la transaction. –