从git下载了可工作的cordapp。 添加了我自己的自定义状态,流程和合同。 但是事务无法正常工作,并且无法为节点创建dab表。
MobileServiceState.java:
package com.example.Mobile;
import com.google.common.collect.ImmutableList;
import net.corda.core.contracts.LinearState;
import net.corda.core.contracts.UniqueIdentifier;
import net.corda.core.identity.AbstractParty;
import net.corda.core.identity.Party;
import net.corda.core.schemas.MappedSchema;
import net.corda.core.schemas.PersistentState;
import net.corda.core.schemas.QueryableState;
import java.util.List;
import java.util.Arrays;
public class MobileServiceState implements LinearState, QueryableState {
private final Party provider;
private final Party customer;
private final int plan;
private final String type;
private final boolean paymentStatus;
private final UniqueIdentifier linearId;
public MobileServiceState(Party provider, Party customer, int plan, String type, boolean paymentStatus, UniqueIdentifier linearId) {
this.provider = provider;
this.customer = customer;
this.plan = plan;
this.type = type;
this.paymentStatus = paymentStatus;
this.linearId = linearId;
}
public Party getProvider() {
return provider;
}
public Party getCustomer() {
return customer;
}
public int getPlan() {
return plan;
}
public String getType() {
return type;
}
public boolean isPaymentStatus() {
return paymentStatus;
}
@Override
public UniqueIdentifier getLinearId() {
return linearId;
}
@Override
public List<AbstractParty> getParticipants(){
//return null;
return Arrays.asList(provider, customer);
}
@Override public PersistentState generateMappedObject(MappedSchema schema) {
if (schema instanceof MobileSchemaDev) {
return new MobileSchemaDev.PersistentMobileDev(
this.provider.getName().toString(),
this.customer.getName().toString(),
this.plan,
this.type,
this.paymentStatus,
this.linearId.getId()
);
} else {
throw new IllegalArgumentException("Unrecognised schema $schema");
}
}
@Override
public Iterable<MappedSchema> supportedSchemas() {
return ImmutableList.of(new MobileSchemaDev());
}
public String toString(){
return " provider:"+this.provider+"" +
"\n Customer:"+this.customer+"" +
"\n Plan:"+ this.plan+"" +
"\n Type:"+this.type+"" +
"\nPayment Status:"+paymentStatus+"\n tx ID:"+this.linearId;
}
public static void main(String [] args){
Party customer= null;
Party provider= null;
MobileServiceState mSS= new MobileServiceState(provider, customer, 499, "postpaid", true, null);
System.out.println(mSS.toString());
}
}
MobileContract.java:
package com.example.Mobile;
import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.CommandWithParties;
import net.corda.core.contracts.Contract;
import net.corda.core.transactions.LedgerTransaction;
import static net.corda.core.contracts.ContractsDSL.requireSingleCommand;
public class MobileContract implements Contract {
public static final String IOU_CONTRACT_ID = "com.example.Mobile.MobileContract";
@Override
public void verify(LedgerTransaction tx) throws IllegalArgumentException {
final CommandWithParties<Commands.BillGenerate> command= requireSingleCommand(tx.getCommands(), Commands.BillGenerate.class);
}
public interface Commands extends CommandData {
class BillGenerate implements MobileContract.Commands {}
}
}
MobileFlow.java:
package com.example.Mobile;
import co.paralleluniverse.fibers.Suspendable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import net.corda.core.contracts.ContractState;
import net.corda.core.contracts.UniqueIdentifier;
import net.corda.core.flows.*;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
import net.corda.core.utilities.ProgressTracker;
import net.corda.core.contracts.Command;
import org.jetbrains.annotations.NotNull;
import static com.example.Mobile.MobileContract.IOU_CONTRACT_ID;
import static net.corda.core.contracts.ContractsDSL.requireThat;
import java.util.Date;
public class MobileFlow {
@InitiatingFlow
@StartableByRPC
public static class Provider extends FlowLogic<SignedTransaction> {
private Party customer;
private int plan;
private boolean paymentStatus;
private String type;
// private Date dueDate;
public Provider(Party customer, int plan, String type, boolean paymentStatus) {
this.customer = customer;
this.plan = plan;
this.type = type;
this.paymentStatus = paymentStatus;
}
private final ProgressTracker progressTracker = new ProgressTracker();
@Override
public ProgressTracker getProgressTracker() {
return progressTracker;
}
@Suspendable
@Override
public SignedTransaction call() throws FlowException {
final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
Party provider = getOurIdentity();
MobileServiceState mobileServiceState =
new MobileServiceState(provider, customer, plan, type,
paymentStatus, new UniqueIdentifier());
final Command<MobileContract.Commands.BillGenerate> billCommand = new Command<>
(new MobileContract.Commands.BillGenerate(), ImmutableList.of(mobileServiceState.getCustomer().getOwningKey(),
mobileServiceState.getProvider().getOwningKey()));
final TransactionBuilder billTxBuilder = new TransactionBuilder(notary)
.addOutputState(mobileServiceState, IOU_CONTRACT_ID)
.addCommand(billCommand);
billTxBuilder.verify(getServiceHub());
final SignedTransaction providerSignedTx = getServiceHub().signInitialTransaction(billTxBuilder);
FlowSession customerSession = initiateFlow(customer);
final SignedTransaction fullySignedTx = subFlow(
new CollectSignaturesFlow(providerSignedTx, ImmutableSet.of(customerSession), CollectSignaturesFlow.Companion.tracker()));
return subFlow(new FinalityFlow(fullySignedTx));
}
}
@InitiatedBy(Provider.class)
public static class Customer extends FlowLogic<SignedTransaction> {
private final FlowSession provider;
public Customer(FlowSession provider) {
this.provider = provider;
}
@Override
public SignedTransaction call() throws FlowException {
class SignTxFlow extends SignTransactionFlow {
private SignTxFlow(FlowSession otherPartyFlow, ProgressTracker progressTracker) {
super(otherPartyFlow, progressTracker);
}
@Override
protected void checkTransaction(@NotNull SignedTransaction stx) {
requireThat(require -> {
ContractState output = stx.getTx().getOutputs().get(0).getData();
require.using("This should be a mobile bill", output instanceof MobileServiceState);
MobileServiceState out = (MobileServiceState) output;
require.using("Customer should be of Post Paid type", out.getType() == "PostPaid");
return null;
});
}
}
return subFlow(new SignTxFlow(provider, SignTransactionFlow.Companion.tracker()));
}
}
}
MobileSchemaDev.java:
package com.example.Mobile;
import com.google.common.collect.ImmutableList;
import net.corda.core.schemas.MappedSchema;
import net.corda.core.schemas.PersistentState;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.UUID;
public class MobileSchemaDev extends MappedSchema {
public MobileSchemaDev() {
super(FakeSchema.class, 1, ImmutableList.of(FakeSchema.class));
}
@Entity
@Table(name="Mobile_payment_state")
public static class PersistentMobileDev extends PersistentState {
@Column(name = "provider") private final String provider;
@Column(name = "customer") private final String customer;
@Column(name = "plan") private final int plan;
@Column(name="type") private final String type;
@Column(name="paymentStatus") private final boolean paymentStatus;
@Column(name = "linear_id") private final UUID linearId;
public PersistentMobileDev(String provider, String customer, int plan, String type, boolean paymentStatus, UUID linearId) {
this.provider = provider;
this.customer = customer;
this.plan = plan;
this.type = type;
this.paymentStatus = paymentStatus;
this.linearId = linearId;
}
// Default constructor required by hibernate.
public PersistentMobileDev() {
this.provider = null;
this.customer = null;
this.plan = 0;
this.type = null;
this.paymentStatus = false;
this.linearId = null;
}
public String getProvider() {
return provider;
}
public String getCustomer() {
return customer;
}
public int getPlan() {
return plan;
}
public String getType() {
return type;
}
public boolean isPaymentStatus() {
return paymentStatus;
}
public UUID getLinearId() {
return linearId;
}
}
}
FakeSchema.java:
package com.example.Mobile;
public class FakeSchema {
}
build.gradle:
repositories {
mavenLocal()
jcenter()
mavenCentral()
maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda' }
maven { url 'https://jitpack.io' }
}
apply plugin: 'java'
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.cordformation'
apply plugin: 'net.corda.plugins.quasar-utils'
jar.baseName = "cordapp-example"
sourceSets {
main {
resources {
srcDir "../config/dev"
}
}
test {
resources {
srcDir "../config/test"
}
}
integrationTest {
java {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integration-test/java')
}
}
}
configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
}
dependencies {
testCompile "junit:junit:$junit_version"
// Corda integration dependencies
cordaCompile "$corda_release_group:corda-core:$corda_release_version"
cordaCompile "$corda_release_group:corda-finance:$corda_release_version"
cordaCompile "$corda_release_group:corda-jackson:$corda_release_version"
cordaCompile "$corda_release_group:corda-rpc:$corda_release_version"
cordaCompile "$corda_release_group:corda-webserver-impl:$corda_release_version"
cordaRuntime "$corda_release_group:corda:$corda_release_version"
cordaRuntime "$corda_release_group:corda-webserver:$corda_release_version"
testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
// CorDapp dependencies
// Specify your cordapp's dependencies below, including dependent CorDapps
cordapp "$corda_release_group:corda-finance:$corda_release_version"
}
task integrationTest(type: Test, dependsOn: []) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
tasks.withType(JavaCompile) {
options.compilerArgs << "-parameters" // Required for shell commands.
}
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
directory "./build/nodes"
node {
name "O=Notary,L=London,C=GB"
notary = [validating : false]
p2pPort 10006
cordapps = ["$corda_release_group:corda-finance:$corda_release_version"]
}
node {
name "O=PartyA,L=London,C=GB"
p2pPort 10007
rpcSettings {
address("localhost:10008")
adminAddress("localhost:10048")
}
webPort 10009
cordapps = ["$corda_release_group:corda-finance:$corda_release_version"]
rpcUsers = [[user: "user1", "password": "test", "permissions": ["ALL"]]]
}
node {
name "O=PartyB,L=New York,C=US"
p2pPort 10010
rpcSettings {
address("localhost:10011")
adminAddress("localhost:10051")
}
webPort 10012
cordapps = ["$corda_release_group:corda-finance:$corda_release_version"]
rpcUsers = [[user: "user1", "password": "test", "permissions": ["ALL"]]]
}
node {
name "O=PartyC,L=Paris,C=FR"
p2pPort 10013
rpcSettings {
address("localhost:10014")
adminAddress("localhost:10054")
}
webPort 10015
cordapps = ["$corda_release_group:corda-finance:$corda_release_version"]
rpcUsers = [[user: "user1", "password": "test", "permissions": ["ALL"]]]
}
}
task runExampleClientRPCJava(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'com.example.client.ExampleClientRPC'
args 'localhost:10008'
}
请帮助成功完成此交易。
答案 0 :(得分:0)
这是由于MobileSchemaDev
的构造函数配置错误而缺少的ProgressTracker
。