没有使用Cordapp

时间:2018-12-20 07:31:36

标签: java corda

从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'
}

请帮助成功完成此交易。

1 个答案:

答案 0 :(得分:0)

这是由于MobileSchemaDev的构造函数配置错误而缺少的ProgressTracker