Is the contract handling code essentially just Java and run by the server ?.
If I want to edit a contract's functionality do I have to release code to be installed across the network ?.
Great question. The Corda technical whitepaper talks about this. See e.g. section 5.9: https://docs.corda.net/_static/corda-technical-whitepaper.pdf
The short answer is that some of this infrastructure still needs to be built out but the key idea is that a State doesn't just say "the Java class with this name governs my evolution"; it says: "the Java class with this name, living in a JAR with this hash governs my evolution". So there will be no room for games caused by people trying to substitute malicious/compromised implementations.
As for how the code gets distributed: today, it is installed in each node locally. Very soon, it will be able to migrate around the network using the Attachments functionality.
And I should add: the contract verification logic will run in a very strict sandbox: both to limit what it can do and to ensure it is 100% deterministic... we can't have one node thinking a transaction is valid and another one thinking it is invalid!
As Richard notes, states reference contracts. Indeed, there is a contract property in the base ContractState interface:
#CordaSerializable
interface ContractState {
val contract: Contract
val participants: List<AbstractParty>
}
A Corda transaction is required to change any state property. Therefore, if one party wishes to novate/update the contract code then they must propose a transaction which changes the contract reference then ask all required participants to assent to this change.
Related
I'm trying to write contract tests for an object that contains a dictionary of objects. I want to verify the entries respect my contract. The keys are changing between the consumer and provider. Right now, the matching rules of my contract are trying to find specific keys in the body of my message such as "$.properties.desired.deploymentsRemovals['4JgEA5GCeqwVsu6Qada9XS'].appId"
Is it possible to write contract tests in my situation?
I'm using the PactNet nuget version 4.0.0-beta.3.
Using a matcher on the key such as
deployments = new Dictionary<object, object> {
{Match.Type("6XKISmGMWynbwM52mxov6S"),
new {...
produces a contract searching for "pactNet.Matchers.TypeMatcher" as the key
"deployments": {
"pactNet.Matchers.TypeMatcher": {
I'm Yousaf, A developer advocate here at Pact https://pact.io/ and Pactflow - https://pactflow.io/
We have an open forum about contract testing in our Pact Foundation Slack, you can join over at https://slack.pact.io
You may find the pact-net channel of particular interest.
.NET isn't my forte, and I haven't spend much time on StackOverflow in past, I hope to now!
You should be able to use matchers in your pact-net library, they were designed in V2 Pact specification onwards to solve that exact problem
Which particular version and library are you using, there are various implementations, both official and community supported.
There should be examples of their implementation in your respective libraries readme, but let me know if there isn't, and we can look to resolve.
We plan to display these matcher implementations across the various languages very soon
I am going through this documentation and I have several uncertainties.
Performing explicit contract and state upgrades
Preserve the existing state and contract definitions
Write the new state and contract definitions
Create the new CorDapp JAR
Distribute the new CorDapp JAR
Stop the nodes
Re-run the network bootstrapper (only if you want to whitelist the
new contract)
Restart the nodes
Authorise the upgrade
Perform the upgrade
Migrate the new upgraded state to the Signature Constraint from the
zone constraint
Questions:
1. Preserve the existing state and contract definitions
2. Write the new state and contract definitions
3. Create the new CorDapp JAR
How do I do that? is it meant only to preserve jars with contracts and states on nodes, not preserving them in source code? If I do not preserve them in source code then how can I create the upgrade method?
interface UpgradedContract<in OldState : ContractState, out NewState : ContractState> : Contract {
val legacyContract: ContractClassName
fun upgrade(state: OldState): NewState
}
If I do not preserve old state in source code, then shoud I name the jar differently each time I need to do an upgrade?
Can old jars be reoved from the node when the upgrade was completed?
6. Re-run the network bootstrapper (only if you want to whitelist the
new contract)
8. Authorise the upgrade
Am I right that only those 2 steps are related to Explicit contact upgrades? And If I use implicit flow with signature, then I need to skip only those two steps, while the others are still aplicable and must be performed?
9. Perform the upgrade
Should this be done for each state separately by the owner of the state? In that case should I run it on each node for specific contrcats where the node is the participant of the state? (In doc it is mentioned to be run on single node - but what id=f a single node is not participant of some state)
Other questions
This section describes explicit contracts and states update.
https://docs.corda.net/upgrading-cordapps.html#performing-explicit-contract-and-state-upgrades while signature constraint section (https://docs.corda.net/api-contract-constraints.html#signature-constraints) does not describe an update process for states.
is it the same as for explicit upgrades with the difference only in steps 6,8 or it is somewhat completely different?
Do I need to create the function transforming old states to new states in that case? if not , then how the old states will be handled by new flows?
I see you have many some great questions about contract upgrades. Here is an article that is written by one of our dev-relation engineers. https://medium.com/corda/contract-upgrades-and-constraints-in-corda-425055a9a47f
Feel free to follow up any additional questions that you have.
If you are new to Corda, feel free to join the Corda community channels #http://slack.corda.net/
While performing legacy contract upgrades, you need both the old and new contract jars installed on your node. (present in the cordapps folder).
You can create a new Gradle module say v2-contract and write the new contract in this. This is where you will write your UpgradedContract. You will need to refer to the old v1-conract jar as well as it needs to know what the old state was. To do this add a gradle dependency in v2-contract like below.
dependencies {
// Corda dependencies.
cordapp project(v1_contract)
}
The old jar can be removed from the cordapps folder, once all the states have been upgraded to new v2-contract.
a. For HashConstraints there is no need to run the bootstrapper again. You will write the new contract by implementing UpgradedContractWithLegacyConstraint,run the jar task to build this new jar, add it to the cordapps folder, run the Authorise Flow from all nodes, run the Initiate flow from one of he node's terminal. This is the explicit way of upgrading.
b. However if you are using Whitelistzoneconstraint, you want to make sure to add the new v2-contract jar's hash to whitelist param in network param. You will need to run the network Bootstrapper to whitelist this new v2-contracts jar hash. https://docs.corda.net/network-bootstrapper.html#whitelisting-contracts.
Once you do that you can either go for an explicit upgrade by implementing UpgradedContract, or you can use implicit upgrade.
c. If you are using Signature Constraints, no need to run the network Bootstrapper for the new jar, write the new v2-contract, build it using gradle jar task, replace old jar with new jar. This is the implicit way of upgrading.
You should run the Authorise Flow for all the participants only.
Other questions
There is no explicit upgrade in Signature constraints. You need to make sure you write your state in a backward compatible way, build new jar, replace old jar with new jar. The states will refer to the new contract then.
Hope that helps. Feel free to post more questions on the above answer or ping on Slack.
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.
How to get information about the party that started transaction in contract code (verify)? That would be useful for implement checks like "only owner of the input state can do some action" in contract instead of flow.
Thanks. Sorry for my bad English.
This information is not contained in a Corda transaction, and therefore cannot be checked by the verify method.
Instead, you should make the owner of the state a required signer, and they should only sign if they are willing to authorise the transfer.
Additionally, you may want to put a check like the following in your flow to prevent human error:
check(ourIdentity == lenderIdentity) {
"Obligation transfer can only be initiated by the lender."
}
I would like to add a new Notary/Regulatory node in my Cordapp application ,
which should perform some extra validation checks when transaction
is completed between two parties.
so that notary/regulatory will be finally checks for some things and stamp the transaction.
There are two options here:
Instead of using the default FinalityFlow to notarise, broadcast and record transactions, you can implement your own flow that performs some additional validation before the notarisation step. The limitation here is that the checks are not part of the notary service.
Create your own custom notary. Here, the custom validation checks happen within the notary service. The ability to do this is a recent change to the codebase, as such the documentation has not been updated to reflect the changes, however the source docs can be found on github:
Instructions for creating a custom notary service: https://github.com/corda/corda/blob/9e563f9b98b79a308d68ecb01c80ce61df048310/docs/source/tutorial-custom-notary.rst
Sample custom notary service code: https://github.com/corda/corda/blob/9e563f9b98b79a308d68ecb01c80ce61df048310/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt
As Roger notes, you could customise FinalityFlow/implement your own notary.
An alternative would be:
Add a new node to the network representing some regulator
Write the contract rules so that the regulator is a required signer on transactions
Have the regulator do additional checking of the transaction in their flow before signing