How to use contracts in attachments - corda

I uploaded contract jar from rpc shell. And then used the hash in the transaction builder
val txBuilder = TransactionBuilder(notary)
.addOutputState(
TransactionState(
dummyState,
"com.example.contract.SampleContract",
notary,
null,
HashAttachmentConstraint(SecureHash.parse(hashId))
)
)
.addCommand(txCommand)
On running this flow, I see the below error in the notary log:
net.corda.core.contracts.TransactionVerificationException$ContractConstraintRejection:
Contract constraints failed for com.example.contract.SampleContract,
transaction:
781CC5C14E9DC7642B3C7F12177CB79C5EADE0D7F2033F56DB6909E1F2199C42
The SecureHash of my uploaded jar is "05A2B667D5DDE42A632EF0A9810D5CE90B3F31BFF62E0539C11C9DEB0FAC2430". This is different from the one seen in the error message.

CordaRPCOps.uploadAttachment should not be used for contract JARs. Contract JARs should be added to the node by adding the JAR files to the node's cordapps folder and restarting the node. If the notary is a validating notary, they will also require a copy of the contract JAR.
CordaRPCOps.uploadAttachment should only be used for attachments containing supporting information for a transaction. These attachments are propagated automatically and are added to transactions using the TransactionBuilder.addAttachment method.

Related

Corda Network-Map is up and running, but Notary is not in whitelist

I have a Corda Infrastructure with some nodes and a (not validating) notary. They're all using a Network Map for the compatibility zone, and all the corda nodes, including the notary, download the same network-parameters file.
When executing a flow, Corda gives me an Exception because the Notary is not on the network parameters whitelist. I cannot find anything anything about that on R3 Documentation.
java.lang.IllegalStateException: Notary [O=Notary, L=Cosenza, C=IT (owningKey = DLAdtNkbnrjn6FGwzE4sCaiDS3tRgMw3KhZfA7bD3icYK1)] specified by the transaction is not on the network parameter whitelist: []
at net.corda.core.internal.TransactionUtilsKt.checkNotaryWhitelisted(TransactionUtils.kt:257) ~[corda-core-4.8.jar:?]
Note that I'm using a fixed Notary X500 Name in the Flow code instead of "preferredNotary" because it won't be found. I think it is because of the same problem.
Do I have to do something explicit to add Notary in network parameters whitelist?
Do I have to do something explicit to add Notary in network parameters whitelist?
Yeah you do. Since you are using a network-map-service your node will get its network-parameters from there.
What you'll have to do then is
delete your current network-parameters for every Node.
whitelist your Notary Node into your network-map-service
restart all your Nodes so they can retrieve the new network-parameters from the network-map-service where the new Notary is assigned as such
I don't know which network-map-service exactly you use but i assume its nms by cordite. You can read up on how to whitelist a Notary here: https://gitlab.com/cordite/network-map-service/-/blob/master/FAQ.md#14-start-the-notary-node

Corda - Validating notaries and custom objects in states

In relation to this post: Corda - java.lang.IllegalArgumentException being thrown from a validating notary
I've identified a case in Corda where states sometimes need to store a custom data type, however validating transactions using these states fails when using a validating notary.
Consider the following types to be implemented in the same package, in the same jar file:
Example Custom Type
package com.example.statescontracts
#CordaSerializable
data class Foo(
val bar: Int,
val baz: String
)
Example State
package com.example.statescontracts
data class FooState(
override val linearId: UniqueIdentifier,
val obligor: AbstractParty,
val obligee: AbstractParty,
val foos: Set<Foo>
) : LinearState {
override val participants get() = listOf(obligor, obligee)
}
Issuing a new FooState instance to the ledger probably isn't affected as it's not consuming a previous FooState instance, but subsequent consumption of FooState instances seem to fail for validating notaries.
Exception
java.lang.IllegalArgumentException: Not a valid Java name:
java.util.Set<com.example.statescontracts.Foo>
Assumptions
Validation can occur for all participants of the state who have the states/contracts JAR file, and therefore can access the Foo type, however this doesn't work for the notary because it doesn't have a copy of the states/contracts JAR file locally.
As I understand it, the states/contracts JAR file should be kept small as it's attached to the transaction when proposed, therefore validating notaries should be able to validate using classes found in the JAR attached to the transaction.
Question
Can anyone verify whether my assumptions are correct, and if so, why this issue occurs for validating notaries, and how to correct this issue?
As described in the tech white paper, the intended end design is that the contract JARs are taken from attachments and run inside the deterministic JVM, where they're sandboxed and resource monitored.
A standalone DJVM preview is shipping in Corda 4, but is not integrated. We will continue to work on this over time, which will allow nodes that don't have the contracts JAR to validate transactions. For now, validating notaries do need to have every version of every app they may encounter installed. Non-validating notaries don't suffer this problem.
As of Corda 3, validating notaries need the states/contracts JAR file for each transaction they are notarising.

issue in consuming existing data after re-build and deploy nodes

i created one transaction using . After that i made some changes in code and build and deploy the nodes successfully. I tried to consume previously created data to create new data. But it led to Contract constraints failed error. But i didn’t get any error at the time of creating new data and consuming the same to create another transaction at that instance.
TransactionVerificationException.ContractConstraintRejection
This exception is thrown when you have existing states in the vault and you updated the contract code and redeployed.
Every time at the node startup CorDapp Jar are scanned and Jar which has Contract classes are uploaded to attachment storage, and the hash of the Jar used as Attachment ID to attach the contract to a transaction.
Now, consider, you have a first fresh version of CorDapp - Attachment ID is: 3B6CA18330500C738455444115C49769D54074CE3CFFB194D8943F34494DB0A4
To create State on vault, you build the transaction, Corda auto-attach the contract using Attachment ID given above.
Then, consider, you changed the code and re-ployed the CorDapp, now jar hash changed, new Attachment ID is: F054BA8C1A67BAABF58539F8718B8A62DC770157D9F1D01434B86E73AD2A9217
My finding, when you create any new the transaction, Corda uses new/recent Attachment ID to attach specified contract.
For example, You want to update State already present on vault.
a. You created a transaction which has one input and it's output state.
b. You sent this transaction for verification.
c. There is check verifies that input state contract Attachment Id and current transaction Attachment Id must be same.
d. But right now input state pointing to old Attachment ID and transaction pointing new Attachment ID. Here check fails and throws a TransactionVerificationException.ContractConstraintRejection exception.

Can I create Corda Custom Data Tables?

Reference code :-
GIT clone url :- git clone https://github.com/corda/cordapp-tutorial
Release M14 :- git checkout -b release-M14.0
I am little bit confused about how the data flows in Corda. I have some database releated queries:
Whether the database structure is fixed or we can add our custom tables in it?
Where can I see the data flowing in tables, when I do a cash transaction which I can see in VAULT_CASH_BALANCES
table in my H2 database client but apart from cash I am unable to see any details of my other transactiosn i.e. if I
save a string then I am unable to get the information, I only get the transaction Id for that.
Is it possible to get entire data flow diagram?
Do the Node and Vault tables created every time when I build a code?
You can define how each state type is stored in the node by implementing the QueryableState interface. Each state type that implements QueryableState will have its own custom database table.
See https://github.com/corda/cordapp-tutorial/blob/master/kotlin-source/src/main/kotlin/com/example/state/IOUState.kt for an example. Since the IOU state implements a schema (in the Kotlin version of the CorDapp), you can see the sender, recipient and value from the H2 interface for each IOU state.
In the current implementation, the node's data is stored in the persistence.mv.db file of the deployed node. This will be wiped whenever you run gradlew deployNodes. However, if you simply create an updated CorDapp jar by running gradlew jar, you can then copy the updated CorDapp jar from build/libs into each node's plugins folder, and the node will use the new plugin.

How to create Corda Custom Data Tables

Reference code:
Git clone URL: git clone https://github.com/corda/cordapp-tutorial
Release M14: git checkout -b release-M14.0
I am little bit confused about how the data flows in Corda. I have some database related queries:
Is the database structure fixed or can we add our custom tables in it?
Where can I see the data flowing in tables? When I do a cash transaction, I can see it in the AULT_CASH_BALANCES table in my H2 database client, but apart from cash I am unable to see any details of my other transactions, i.e., if I save a string then I am unable to get the information, I only get the transaction ID for that.
Is it possible to get entire data flow diagram?
Are the Node and Vault tables created every time when I build a code?
You can define how each state type is stored in the node by implementing the QueryableState interface. Each state type that implements QueryableState will have its own custom database table.
See https://github.com/corda/cordapp-tutorial/blob/master/kotlin-source/src/main/kotlin/com/example/state/IOUState.kt for an example. Since the IOU state implements a schema (in the Kotlin version of the CorDapp), you can see the sender, recipient and value from the H2 interface for each IOU state.
In the current implementation, the node's data is stored in the persistence.mv.db file of the deployed node. This will be wiped whenever you run gradlew deployNodes. However, if you simply create an updated CorDapp jar by running gradlew jar, you can then copy the updated CorDapp jar from build/libs into each node's plugins folder, and the node will use the new plugin.

Resources