Background:
We learned that corda is not tamper-proof but tamper-evident. So, if one of the node manipulated a state directly in the database, other nodes will be able to detect and flag it if that state was used in subsequent transactions. However, our test results were not as per our expectation. Corda did not flag the state that was tampered and in fact it recorded the new state with tampered data in all participant nodes.
Prerequisites:
Comment Out Contract Validations: We commented contract code to check if the data tampering is detected in Corda without the check being explicitly done at command level.
Steps to replicate:
Start obligation Cordapp.
Create 3 obligations between Party A and Party B (100 THB, 256 THB and 100 THB)
Edit the VAULT_STATES table in the database of Party B, by looking at the differences between the hexs.
Obligations with different amount is on the left and the two obligations with the same amount is on the right. From the editor when they are at same amount there are 2 differences (presumably linear-id & timestamp related) and when they are at different amount the 3rd discrepancy is showed on the left.
Overwrite the specific portion with the lower value amount, update vault using SQL on Party B’s vault:
After this update, check Party B’s vault and the amounts are changed to 100 THB on all 3 obligations.
However, Party A’s vault will show original amounts (100, 256, 100) as the data was not tampered in Party A’s vault.
Transfer ALL obligations from Party B to Party C
Transfer obligations result: Party B have no more obligations
Transfer obligations result: Party C will get all Party B’s Obligations (100 THB for all, i.e. tampered data was passed on to the new party)
Transfer obligations result: Party A’s vault will also be updated with tampered data. It couldn’t identify or flag tampered data.
How to get Corda participant nodes to detect tampered states? have i missed some config while setting up the node?
I'm afraid this discussion may take a while because most of us are off on holiday from this afternoon.
We'll have a go at replicating what you did here. However it's not clear to me that this is a bug.
You say you commented out the contract validation logic. It sounds like what may have happened is this:
Edit the states table to hold a corrupted state.
Build a transaction with INPUT=pointer to previous correct state. OUTPUT=(corrupted state)+edit to hold new owner field.
This transaction is now signed and transferred.
This transaction would have been considered invalid and rejected when the transfer to Party C is attempted, because it'd be an illegal state transition: the numbers do not balance. But you commented out the code that checks for that! So nothing anywhere is saying you aren't allowed to simply change the size of an obligation whenever you like ... Corda doesn't know that implicitly if you comment out the code that contains this knowledge. Thus from the IOU app's perspective changing the size as you transfer it is now a perfectly legitimate thing to do.
Here's the question - if you leave the app alone and don't modify its source code, is the tampering detected? If the answer is still "no" then we have some more investigation to do.
Related
Is there any way a CorDapp can ask a Notary if a state has been consumed prior to using it in a Transaction?
Background:
I am testing FungibleToken’s that point to EvolvableTokenType’s. Eventually the EvolvableTokenType changes and holders of the tokens that are not Participants of the EvolvableTokenType end up with states in their vault that have been unknowingly consumed. When they try to execute a transaction involving these states the Notary will refuse to sign because it knows the states have been consumed.
I have written flows that will contact a Participant and request the missing state(s). However it would be more efficient if I could first ask the Notary if I need to do that (i.e. if the state hasn’t been consumed I don’t need to ask a participant for an update).
You could do this a couple ways.
For example, in your vault query, you could simply make sure to filter on StateStatus = UNCONSUMED. That's one way you can ensure this works the way you expect and you never get a state that won't fit your criteria.
check out this section of the docs on vaultQuery : https://docs.corda.net/docs/corda-os/4.7/api-vault-query.html#querycriteria-interface
The other way I'd recommend that might also work is just to include this filter in your contract verification for the transaction, but doing it at the flow level just catches the problem sooner rather than later.
I have a transaction system in my web service. Basically you can send (fake) currency back and forth between accounts.
This requires a strongly consistent write model. This is the scenario i'm worried about. A has 0$ B has 0$ and C has 100$. C sends A 100$ Cs balance is currently being updated. Before the update is propagated across all dynamoDB nodes, C sends 100$ to B, since on another instance, his balance is still 100$. Now C has a balance of -100$ and A and B both have 100$. This would be an invalid state.
Since this scenario would require both consistent reads and writes (to check and update balances), are dynamoDB writes suited for this?
I'm not a DynamoDB expert, but I'm almost certain you can pull this off.
To make this work, make sure to use the ConditionExpression feature on the UpdateItem request. That way you can protect against what you're talking about.
Reads in DynamoDB are "eventually consistent", so it is possible, as you stated, that a reader could think that "C has $100" just after you've changed C's balance. However, I'm pretty sure using the condition expression you can fully guarantee that you never get into this bad state. You can structure your update request as a totally atomic operation that doesn't execute unless a condition is met: "Decrement C's balance by $100 only if C's balance >= $100". DynamoDB can execute that update atomically for you, and thus prevent the issue.
P.S. check out this talk. If I remember correctly the speaker covers some topics adjacent to this.
So I've been tasked with developing a POC for my company and have been learning about Corda. I think I understand the overview of Corda and a few details but I came across something that I don't quite understand. To illustrate, let's use the IOU example that the tutorial uses.
In that case, let's say I have two parties: Alice and Bob. Alice borrows $20 from Bob. This is correctly recorded in both their vaults and DB.
Now, let's say Bob is a bad actor and manually updates the information on his side (including associated hashes for the transaction) so that the transaction states that Alice borrowed $30 instead of $20.
So here are my questions:
Are there any safeguards built into Corda to prevent Bob from arbitrarily changing the data on his end?
If he is successful in mutating the facts on his end, how does the network decide who is correct in the future when Alice and Bob both present mutually exclusive transaction histories?
In a similar use case, imagine there is a fact that is initially shared between multiple parties, then is legitimately marked as only concerning one party, and then is again shared multiple (potentially different) parties. In this case, what would happen if the fact were to be illegitimately mutated during the single party access phase of the fact's lifespan?
Thanks in advance to all the people that help clear this up!
This will be specified in the smart contract you setup with the counterparty when instigating the trade. Cobra will not settle your distributes since this defeats the whole purpose of the platform.
I am using Corda and in one of our use-cases, we need to limit the transaction information shared among the nodes (e.g. 4 parties) in the network.
The transaction state will contain sensitive data of other nodes but we need to limit this data to be accessed by authorised parties only. e.g. party A should not see data of Party B in the transaction state.
I looked at the Corda documentation and tumbled upon Transaction tear-off but I could not find any concrete implementation of this.
I would be really grateful, if someone can give me an examples of transaction tear-off implementation or point me to right direction if there is better approach to limit transaction state sharing among parties than using transaction tear-off.
Thanks in advance
Transaction tear-offs are typically used in the use case where you're using an oracle to attest to a fact within your transaction.
The idea being, you want to strictly limit the oracle to viewing only what is required in order for it to attest, so you filter out all other parts of the transaction.
Take a look at the following tutorial https://docs.corda.net/tutorial-tear-offs.html it contains the steps required to create a filtered transaction.
You can also take a look at the samples on https://www.corda.net/samples that make use of an oracle. In particular, if you look at the Options sample, the OptionIssueFlow creates a filtered transaction for the oracle to sign.
One other approach - would it matter if Party A could see the data of Party B if it didn't know it was Party B? If not, you could look at using confidential identities https://docs.corda.net/api-identity.html#confidential-identities
I would like to ask your help and suggestion about below use case what are related to our new business case, a CorDapp which will be used to manage software license usage and management.
Does Corda has a pre-defined structure or approach to define the parent and child relationship between different states, for example, one contract state(main contract) has two child contract states(two types of license contracts)
If we want to track the license usage on blockchain, is that a good direction to ownable state for licenses? Our current thought is Party A(License Provider) and Party B(License consumer) has one agreed contract that Party A will provide Party B 100 licenses to be used, but charge will only happen after one license is activated by Party B. So from Corda’s backend process, Party A will issue 100 licenses initially which owner is PartyA, and this shared fact will be initialized as a transaction and will be added to both party’s ledger. Then periodically license usage data will be extracted from Party A’s system and updated the ledger by initializing a transaction, we will use “Move” flow to transfer the license state’s amount and owner. For example, if Party B activated 40 licenses, then Party A’s license state amount will become to 60, and there is another new state which owner is Party B and amount is 40. I thought I should use ownable state for this use case after reading some Corda documentation about linear state and ownable state, but not sure whether my understanding is correct
What is the best practice from Corda about how to design a dynamical contract terms which can be used in smart contract(verify menthod conditions). For example, in the initial version of license management process, two types of licenses and their price will be defined as contract terms, and we plan to define them as the state’s properties(meta data). If later there are one new type need to be added, how should we best handle this situation. Is there any dynamical approach to define the state’s properties/meta data? Our ideal approach is initially there is no any terms defined(no license type pre-defined), and allow user to add different type of license with their price information dynamically on UI, then these dynamically defined contract terms will be stored in CorDapp and can be used in later phase, and this approach can be easily to be “copied” to different providers. Is this possible to do?
Very interesting use case and scenarios. We have not formalized best practices for parent child states in api wrappers, but you can treat the collection of states using the same relational database model as long as your transactions also keep pointers updated.
Our thinking for state representation covers 3 hierarchical scenarios:
1 - portfolio of assets - like an etf or index grouping multiple assets. This can be moved as a new portfolio asset representing a tether to the existing asset data or a grouping function
2 - asset itself - this is a linear state that has a life cycle of events that influence it. Think of this like the company ref data behind the equity
3 - fungible asset representation - cash flow fungible staye that can reference the asset's linear id - think of issued shares for the equity
In this case, the 2 & 3 scenarios have the ref data to fungible state relationship. The fungible state can store the reference to the asset's linear ID and the asset can store an array of owners of the equity. Depending on your queries, you can also store another relational table for mapping different foreign and primary keys. The careful part is taking into account this logic linking when executing transactions that change issuance or ownership
For the standard Ethereum factory pattern, cordapps can be broken up into multiple functions. For example, the obligation cordapp uses the corda-finance-1.0.jar package to share different library functions and definitions on self issuing cash and cash properties.
Coming back to the asset example, we have an interest rate swap example cordapp that has contract code defining the known fields in a standard irs ISDA contract. From this template, you can deploy any irs type of state by defining the field properties like maturity date and interest rate.
I imagine the license use case can create similar fields for types for how the business logic or contract code would see it evolve. This also brings to light a tool gap for wrapping a workflow management tool or interface above the corda fundamentals.