当前位置: 首页 > 知识库问答 >
问题:

Corda持久性:未知实体:PersistentFungibleToken

巴宏恺
2023-03-14

日安!< br >我正在试用corda版令牌SDK 1.1版,并希望尝试发行/兑换自定义可替换令牌的各种方案。

我编写了一个简单的流程,描述了参与方自身的令牌颁发:< br >虽然非常基本的流程看起来工作得很好,但是在子流程(IssueTokensFlow)中,尝试将PersistentFungibleToken保存到数据库(下面是堆栈跟踪)。我试图实现自己的模式,但没有成功,因为函数supportedScema()只需要List。< br >我还尝试在不使用定制的FungilbeToken的情况下发行一些令牌,也没有成功。< br >如何解决这个问题?


import co.paralleluniverse.fibers.Suspendable
import com.maker.loyalty.states.NativeToken
import com.maker.loyalty.states.ParticipantNativeFungibleToken
import com.r3.corda.lib.tokens.contracts.states.FungibleToken
import com.r3.corda.lib.tokens.contracts.utilities.heldBy
import com.r3.corda.lib.tokens.contracts.utilities.of
import com.r3.corda.lib.tokens.workflows.flows.issue.IssueTokensFlow
import com.r3.corda.lib.tokens.workflows.utilities.getPreferredNotary
import net.corda.core.flows.*
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.ProgressTracker

object IssueTokenExperiment {
    private fun tracker() = ProgressTracker(
            NotaryInfo,
            CreateTransaction,
            Verify,
            Finalize,
            ExchangeValuesSingleParty.ExecuteExchange,
            SigningByOtherParty
    )

    private const val defaultAmount: Long = 2
    private val otherPartyDefaultName = CordaX500Name(organisation = "PartyA", locality = "London", country = "GB")

    //Scenario - issue token onto the ledger, verify it was issued

    @InitiatingFlow
    @StartableByRPC
    /**
     * Issues token to self an notifies the counter party about issuance
     * */
    class IssueNativeTokenToSelfInitializer(private val amount: Long = defaultAmount,
                                            private val otherPartyX500Name: CordaX500Name = otherPartyDefaultName) : FlowLogic<SignedTransaction>() {

        override val progressTracker: ProgressTracker = tracker()

        @Suspendable
        override fun call(): SignedTransaction {
            progressTracker.currentStep = NotaryInfo
            getPreferredNotary(serviceHub)

            val otherParty: Party = run {
                serviceHub.networkMapCache.getPeerByLegalName(otherPartyX500Name)
                        ?: throw FlowException("Other party not found")
            }
            val otherPartySession = initiateFlow(otherParty)
            progressTracker.currentStep = CreateTransaction

            val issuedSupplyAmount = NativeToken issuedBy ourIdentity
            val supplyAmount = amount of issuedSupplyAmount
//            val liability = supplyAmount heldBy ourIdentity
            val participantNativeAccountState = ParticipantNativeFungibleToken(
                    amount = supplyAmount,
                    issuer = ourIdentity,
                    participants = listOf(ourIdentity, otherParty),
                    observers = emptyList(),
                    owner = ourIdentity
            )
            return subFlow(IssueTokensFlow(
                    token = participantNativeAccountState as FungibleToken,
                    participantSessions = listOf(otherPartySession)
            ))

        }
    }

}

java.lang.IllegalArgumentException: Unknown entity: com.r3.corda.lib.tokens.contracts.internal.schemas.PersistentFungibleToken
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Unknown entity: com.r3.corda.lib.tokens.contracts.internal.schemas.PersistentFungibleToken
    at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
    at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1908)
    at net.corda.core.internal.concurrent.CordaFutureImpl.get(CordaFutureImpl.kt)
    at com.maker.loyalty.TwoPartyCoreTests.Create token test EXPERIMENT(TwoPartyCoreTests.kt:91)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
    at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: Unknown entity: com.r3.corda.lib.tokens.contracts.internal.schemas.PersistentFungibleToken
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:807)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:788)
    at net.corda.node.services.schema.PersistentStateService.persistStatesWithSchema$node(PersistentStateService.kt:48)
    at net.corda.node.services.schema.PersistentStateService.persist(PersistentStateService.kt:40)
    at net.corda.node.services.vault.NodeVaultService.processAndNotify(NodeVaultService.kt:393)
    at net.corda.node.services.vault.NodeVaultService.access$processAndNotify(NodeVaultService.kt:54)
    at net.corda.node.services.vault.NodeVaultService$notifyAll$1.invoke(NodeVaultService.kt:224)
    at net.corda.node.services.vault.NodeVaultService$notifyAll$2.invoke(NodeVaultService.kt:235)
    at net.corda.node.services.vault.NodeVaultService.notifyAll(NodeVaultService.kt:239)
    at net.corda.node.services.api.ServiceHubInternal$Companion$recordTransactions$1.invoke(ServiceHubInternal.kt:128)
    at net.corda.node.services.api.ServiceHubInternal$Companion$recordTransactions$1.invoke(ServiceHubInternal.kt:53)
    at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:235)
    at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:214)
    at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:220)
    at net.corda.node.services.api.ServiceHubInternal$Companion.recordTransactions(ServiceHubInternal.kt:72)
    at net.corda.node.services.api.ServiceHubInternal$DefaultImpls.recordTransactions(ServiceHubInternal.kt:158)
    at net.corda.node.internal.AbstractNode$ServiceHubInternalImpl.recordTransactions(AbstractNode.kt:1008)
    at net.corda.core.node.ServiceHub$DefaultImpls.recordTransactions(ServiceHub.kt:214)
    at net.corda.core.internal.ServiceHubCoreInternal$DefaultImpls.recordTransactions(ServiceHubCoreInternal.kt)
    at net.corda.node.services.api.ServiceHubInternal$DefaultImpls.recordTransactions(ServiceHubInternal.kt)
    at net.corda.node.internal.AbstractNode$ServiceHubInternalImpl.recordTransactions(AbstractNode.kt:1008)
    at net.corda.core.node.ServiceHub$DefaultImpls.recordTransactions(ServiceHub.kt:206)
    at net.corda.core.internal.ServiceHubCoreInternal$DefaultImpls.recordTransactions(ServiceHubCoreInternal.kt)
    at net.corda.node.services.api.ServiceHubInternal$DefaultImpls.recordTransactions(ServiceHubInternal.kt)
    at net.corda.node.internal.AbstractNode$ServiceHubInternalImpl.recordTransactions(AbstractNode.kt:1008)
    at net.corda.core.flows.FinalityFlow.notariseAndRecord(FinalityFlow.kt:205)
    at net.corda.core.flows.FinalityFlow.call(FinalityFlow.kt:147)
    at net.corda.core.flows.FinalityFlow.call(FinalityFlow.kt:39)
    at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:330)
    at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:326)
    at com.r3.corda.lib.tokens.workflows.internal.flows.finality.ObserverAwareFinalityFlow.call(ObserverAwareFinalityFlow.kt:75)
    at com.r3.corda.lib.tokens.workflows.internal.flows.finality.ObserverAwareFinalityFlow.call(ObserverAwareFinalityFlow.kt:35)
    at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:330)
    at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:326)
    at com.r3.corda.lib.tokens.workflows.flows.issue.IssueTokensFlow.call(IssueTokensFlow.kt:84)
    at com.r3.corda.lib.tokens.workflows.flows.issue.IssueTokensFlow.call(IssueTokensFlow.kt:46)
    at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:330)
    at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:326)
    at com.maker.loyalty.flows.IssueTokenExperiment$IssueNativeTokenToSelfInitializer.call(IssueTokenExperiment.kt:64)
    at com.maker.loyalty.flows.IssueTokenExperiment$IssueNativeTokenToSelfInitializer.call(IssueTokenExperiment.kt:37)
    at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:270)
    at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:46)
    at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
    at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
    at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
    at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63)
import com.maker.loyalty.contracts.ParticipantNativeAccountContract
import com.maker.loyalty.schemas.ParticipantNativeTokenSchemaV1
import com.r3.corda.lib.tokens.contracts.internal.schemas.FungibleTokenSchema
import com.r3.corda.lib.tokens.contracts.internal.schemas.FungibleTokenSchemaV1
import com.r3.corda.lib.tokens.contracts.internal.schemas.PersistentFungibleToken
import com.r3.corda.lib.tokens.contracts.states.FungibleToken
import com.r3.corda.lib.tokens.contracts.types.IssuedTokenType
import com.r3.corda.lib.tokens.contracts.types.TokenType
import net.corda.core.contracts.Amount
import net.corda.core.contracts.BelongsToContract
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 net.corda.core.serialization.CordaSerializable
import java.util.*

@BelongsToContract(ParticipantNativeAccountContract::class)
data class ParticipantNativeFungibleToken(override val amount: Amount<IssuedTokenType>,
                                          override val issuer: Party,
                                          val owner: Party,
                                          val observers: List<AbstractParty> = listOf(),
                                          override val participants: List<AbstractParty> = (mutableListOf(owner, issuer) + observers)
) : FungibleToken(amount, issuer), QueryableState {
    override fun generateMappedObject(schema: MappedSchema): PersistentState {
        return when (schema) {
            is FungibleTokenSchemaV1 -> PersistentFungibleToken(
                    issuer = issuer,
                    tokenIdentifier = amount.token.tokenIdentifier,
                    holder = owner,
                    tokenClass = amount.token.tokenClass,
                    amount = amount.quantity
            )
//            is ParticipantNativeTokenSchemaV1 -> ParticipantNativeTokenSchemaV1.PersistentParticipantNativeToken(
//                    issuer = issuer,
//                    tokenIdentifier = amount.token.tokenIdentifier,
//                    holder = owner,
//                    tokenClass = amount.token.tokenClass,
//                    amount = amount.quantity
//            )
            else -> throw IllegalArgumentException("Unrecognised schema $schema")
        }
    }

    override fun supportedSchemas() = listOf(FungibleTokenSchemaV1)

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        other as ParticipantNativeFungibleToken
        if (amount != other.amount) return false
        if (holder != other.holder) return false
        if (tokenTypeJarHash != other.tokenTypeJarHash) return false
        return true
    }

    override fun hashCode(): Int {
        var result = amount.hashCode()
        result = 31 * result + holder.hashCode()
        result = 31 * result + (tokenTypeJarHash?.hashCode() ?: 0)
        return result
    }
}
    @Test
    fun `Issue token for self and notify the other party`() {
        val resultFuture = a.startFlow(IssueTokenExperiment.IssueNativeTokenToSelfInitializer(
                amount = 10L,
                otherPartyX500Name = bNodeName
        ))
        network.runNetwork()
        val res = resultFuture.get()
        assertNotNull(res)
    }

    @Before
    fun setup() {
        network.runNetwork()
        setupClients()
        addBonusToClientAccount()
    }

    @After
    fun tearDown() = network.stopNodes()

    private fun setupClients() {
        a.startFlow(ClientAccountFlows.InitiateClientAccountCreation(person = defaultPerson))
        b.startFlow(ClientAccountFlows.InitiateClientAccountCreation(person = defaultPerson))
        network.runNetwork()
    }

    private fun addBonusToClientAccount() {
        a.startFlow(ClientAccountFlows.AddBonusToClientAccount(person = defaultPerson, addedBonus = 100L))
        b.startFlow(ClientAccountFlows.AddBonusToClientAccount(person = defaultPerson, addedBonus = 100L))
        network.runNetwork()
    }
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.quasar-utils'

cordapp {
    targetPlatformVersion corda_platform_version
    minimumPlatformVersion corda_platform_version
    workflow {
        name "Loyalty Flows"
        versionId 1
    }
}

sourceSets {
    main {
        resources {
            srcDir rootProject.file("config/dev")
        }
    }
    test {
        resources {
            srcDir rootProject.file("config/test")
        }
    }
    integrationTest {
        kotlin {
            compileClasspath += main.output + test.output
            runtimeClasspath += main.output + test.output
            srcDir file('src/integrationTest/kotlin')
        }
    }
}

repositories {
    maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib' }
    maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib-dev' }
}

configurations {
    integrationTestCompile.extendsFrom testCompile
    integrationTestRuntime.extendsFrom testRuntime
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
    testCompile "junit:junit:$junit_version"

    // Corda dependencies.
    cordaCompile "$corda_release_group:corda-core:$corda_release_version"
    cordaRuntime "$corda_release_group:corda:$corda_release_version"
    cordaCompile "$tokens_release_group:tokens-workflows:$tokens_release_version"
    testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
    //tokens sdk
    cordaCompile "$tokens_release_group:tokens-workflows:$tokens_release_version"
    cordaCompile "$tokens_release_group:tokens-money:$tokens_release_version"
    cordapp "$tokens_release_group:tokens-selection:$tokens_release_version"

    // CorDapp dependencies.
    cordapp project(":contracts")
}

task integrationTest(type: Test, dependsOn: []) {
    testClassesDirs = sourceSets.integrationTest.output.classesDirs
    classpath = sourceSets.integrationTest.runtimeClasspath
}

共有1个答案

阎宾实
2023-03-14

您可能忘记在节点定义中(即在根 build.gradle 文件中的 deployNodes 任务内部)包含令牌合约依赖项(错误消息中提到的缺少自定义架构类)。

添加这一行:

cordapp("$tokens_release_group:tokens-contracts:$tokens_release_version")

请记住,在契约测试的MockService和流测试MockNetwork中也要包括这种依赖关系:

// Contract tests.
private final MockServices ledgerServices = new MockServices(
            Collections.singletonList("com.r3.corda.lib.tokens.contracts"));    

// Flow tests.
private final MockNetwork network = new MockNetwork(new MockNetworkParameters()
            .withCordappsForAllNodes(ImmutableList.of(                
                TestCordapp.findCordapp("com.r3.corda.lib.tokens.contracts"),



 类似资料:
  • 我试图集成Spring和JSF,我坚持使用对象。我不想处理事务(begin-commit等) 经过一些谷歌,我可以找到一个答案,给我需要在这个链接 我使用eclipselink作为ORM和Oracle 11g数据库,并使用带有Maven的Glassfish Server3.1。我更喜欢Spring配置的注释。我用 相关类中的注释。我的名称是E_DefterManagementPU,我的事务类型是J

  • 我正在引用另一个实体类中的实体,并出现此错误。下面是示例代码。我有这些课程在坚持。还有xml。 是什么导致了这个问题?我正在使用Spring数据JPA和Hibernate。

  • 我需要一个EAR java应用程序,在其中我可以定义一个持久性单元,并在不同的组件中使用该持久性单元。例如:我在我的application.xml中定义了两个JAR:my-product . JAR和my-product-module . JAR——这两个JAR文件应该能够使用同一个PersistenceUnit。这个PersistenceUnit是在一个单独的jar中定义的,这个jar是我的EA

  • 问题内容: 我正在尝试入门Hibernate 2nd Edition,而我一直试图将简单的工作示例与HSQLDB结合在一起。 当我跑步时,我得到 这是我得到的: Message.java PopulateMessages.java build.properties hibernate.cfg.xml build.xml 问题答案: 您的实体注释不正确, 必须 使用注释。您可以使用Hibernate

  • 问题内容: 我真的很想了解我的代码发生了什么。 我有一个独立的应用程序,它使用spring和Hibernate作为JPA,我正在尝试使用单个主类运行测试 我的主班 我的应用程序上下文是: 我的用户模型是: 我的DAO是: 这是我运行程序时出现的我的stacktrace错误: 问题答案: 您必须在会话工厂配置中列出您的类。如果使用,则可以自动发现实体。 为了在hibernate和spring中使用注

  • 我有一个测试车, 而applicatin.xml是 但它报告异常 java.lang.IllegalArgumentException:未知实体:com.chinalbs.entity.conductor(位于org.hibernate.ejb.abstractentyManagerImpl.persist(abstractentyManagerImpl.java:842)(位于sun.refle