Reputation: 8106
I have a simple flow that creates a state between a buyer and seller and obviously each side can see everything on the state.
However, I now have a requirement that the buyer wants to store the user that processed the transaction for auditing and reporting purposes.
The user in this case is not a node or an account but a user that has logged in to the application and been authorised via Active Directory.
I could just add the user name to the state as a String but that would expose private data to the seller.
An alternative would be to obfuscate the name in some way but I would rather store the information in a separate table outside the state and only in the buyers vault.
How do I do this and is there a sample that demonstrates it?
Upvotes: 0
Views: 63
Reputation: 1138
You can create a second output state, which is used in the same transaction, but has only the token issuer as participant. Then of course, it is up to you to make the link between the "issued state" and the "recorder state", it depends on what you will store inside the latter.
Let's make an example of a fungible token issuance from Node1 to Node2. You could create a "issuance recorder state" that aims at recording something on Node1's vault only, like so (note the list of participants):
// the "recorder" state visible only in Node1's vault
@BelongsToContract(IssuanceRecordContract::class)
class IssuanceRecord(
val holder: AbstractParty,
val amount: Amount<IssuedTokenType>
) : ContractState {
override val participants: List<AbstractParty>
get() = listOf(amount.token.issuer)
}
and then you could pass it to the same TransactionBuilder
that you are using to issue the fungible token (which instead has both parties in the list of participants), like so:
// This is from the Issuanflow launched from Node1
@Suspendable
override fun call(): String {
...
...
// Create the FungibleToken (issuedToken is an IssuedTokenType created before)
val tokenCoin = FungibleToken(Amount(volume.toLong(), issuedToken), holderAnonymousParty)
// create the "recorder" output state visible only to Node1
val issuanceRecord = IssuanceRecord(holderAnonymousParty, tokenCoin.amount)
// create the Transaction Builder passing the "recorder" output state
val transactionBuilder = TransactionBuilder(notary).apply {
addOutputState(issuanceRecord, IssuanceRecordContract.ID)
addCommand(Command(IssuanceRecordContract.Commands.Issue(), ourIdentity.owningKey))
}
// Issue the token passing the transactionBuilder and the fungible token
addIssueTokens(transactionBuilder, tokenCoin)
// collect signatures
// verify transaction
// FinalityFlow (fundamental to make this work in Node1)
}
This way, I think, the recorder states will be atomically stored in Node1's vault. If something happens, the transaction will be not successful for both output states.
Upvotes: 1