- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试实现一些逻辑来赎回可替代 token ,我的场景如下:
我有一个发行方甲发行可替代的代币,这些将由乙方持有。我需要实现一个场景,甲方将赎回乙方持有的代币。
我的流程是这样的:
addMoveFungibleTokens() //Move tokens own by Party B back to the issuer Party A
addFungibleTokensToRedeem() //Party A redeems the tokens that were received from the Party B
addMoveFungibleTokens(transactionBuilder, serviceHub, amountToRedeem, PartyB, PartyA)
java.lang.IllegalStateException: Insufficient spendable states identified for 50 TokenPointer(class com.template.states.TypeX, e4842e04-5ff2-4eb8-936e-ea3fee82c2fd).
run vaultQuery contractStateType: com.r3.corda.lib.tokens.contracts.states.FungibleToken
PartyA acts central bank and emits money for PartyB. PartyA and B share a group of states which allows them to track how much money was issued. Besides this, whenever new money is emited, PartA also issues a token with the amount of money issued, this money is held by partyB (I am representing money as a fungible token here). For some reason CountryX where PartyA and B operate is changing currency, due > to this the transactions in the old currency need to be converted into a newCurrency. Initially Party A has two currency types oldCurrency and one newCurrency Since oldCurrency is disappearing all the previous transaction have to be converted to new currency.
@InitiatingFlow()
@StartableByRPC
class PartyAAskTokens(val oldCurrency: String, val newCurrency: String, val partyB: Party): FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
val counterPartySession = initiateFlow(partyB)
// Get the type that represents old currency - This can be improved with QueryCriterias
val oldCurrencyTypeStateRef = serviceHub.vaultService.queryBy<CurrencyType>().states.filter { stateAndRef -> stateAndRef.state.data.currency == oldCurrency }.single()
val oldCurrencyTypePointer = oldCurrencyTypeStateRef.state.data.toPointer<CurrencyType>()
// Get the type that represents new currency - This can be improved with QueryCriterias
val newCurrencyTypeStateRef = serviceHub.vaultService.queryBy<CurrencyType>().states.filter { stateAndRef -> stateAndRef.state.data.currency == newCurrency }.single()
val newCurrencyTypePointer = newCurrencyTypeStateRef.state.data.toPointer<CurrencyType>()
// Get state of the user
// This state allows to keep track on the quantity of tokens issued at a given time
// For each puchase I am creating a new state (e.g. Date of the operation matters for historical reasons)
val userOperationState = serviceHub.vaultService.queryBy<UserOperationState>().states
// Keys of each one of the participants in the transaction
val ownSignerKey = ourIdentity.owningKey
val otherPartyKey = partyB.owningKey
// Propose a currency conversion transaction
val transactionBuilder = TransactionBuilder(serviceHub.networkMapCache.notaryIdentities.first())
// Command identifies that this transaction is an exchange of tokens from an old type into a new type.
val exchangeOldCurrencyForNewCommand = Command(UserOperationContract.Commands.exchangeOldCurrencyForNew(), listOf(ownSignerKey, otherPartyKey))
transactionBuilder.addCommand(exchangeOldCurrencyForNewCommand)
// Hold the amount that needs to redeem from the old currency
var amountToRedeemFromOldCurrencyType:Long = 0
// Propose new states for the state current state
userOperationState.forEach { userOperation ->
run {
transactionBuilder.addInputState(userOperation)
transactionBuilder.addOutputState(userOperation.state.data.copy(currency = newCurrency))
// Generate a new token with new currency, this should match the units of the new state
val amountOfToken: Amount<TokenType> = userOperation.state.data.amountOfCurrency of newCurrencyTypePointer
val issueToken: Amount<IssuedTokenType> = amountOfToken issuedBy ourIdentity
val fungibleToken: FungibleToken = issueToken heldBy counterPartySession.counterparty
addIssueTokens(transactionBuilder, listOf(fungibleToken))
// Keep track of the untis that need to be deleted
amountToRedeemFromOldCurrencyType += userOperation.state.data.amountOfCurrency
}
}
// Generate the amount to redeem
val redeemQuantity = amountToRedeemFromOldCurrencyType of oldCurrencyTypePointer
// Notify PartyB that you are requiring this amount of token
counterPartySession.send(AmountRedeemRequest(redeemQuantity))
// Get the token from CounterParty (PartyB)
val fungibleTokenToRedeemStateRef = subFlow(ReceiveStateAndRefFlow<FungibleToken>(counterPartySession))
//val fungibleTokens = counterPartySession.receive<List<FungibleToken>>().unwrap { it }
// TODO: How to improve this code if there is an exception here I will loose all my old tokens that need to be redeemed.
// ############## EXCEPTION_HERE ##############
// Redeem the token in transaction
addTokensToRedeem(transactionBuilder, fungibleTokenToRedeemStateRef)
// Sign the transaction using the your own key
val iSignedTransaction = serviceHub.signInitialTransaction(transactionBuilder)
// Ask others participants to sign
val signedTransaction = subFlow(CollectSignaturesFlow(iSignedTransaction, listOf(counterPartySession)))
return subFlow(FinalityFlow(signedTransaction, listOf(counterPartySession)))
}
}
@InitiatedBy(PartyAAskTokens::class)
class PartyBGiveTokenBack(val counterPartySession: FlowSession): FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
val tokenAmountToRedeem = counterPartySession.receive<AmountRedeemRequest>().unwrap { it }
val (inputs, outputs) = TokenSelection(serviceHub).generateMove(
lockId = runId.uuid,
partyAndAmounts = listOf(PartyAndAmount(counterPartySession.counterparty, tokenAmountToRedeem.amountOfTokenToSendBack)),
changeHolder = ourIdentity
)
// Send the token states.
subFlow(SendStateAndRefFlow(counterPartySession, inputs))
// Send the tokens
// Not needed because through the state I can get to the data.
//counterPartySession.send(outputs)
// validate data
val stx = subFlow(object: SignTransactionFlow(counterPartySession) {
override fun checkTransaction(stx: SignedTransaction) {
// TODO: Check quantity of tokens to be redeemed is the same as the tokens to be issued
// TODO: Check if the states point to new token type.
}
})
return subFlow(ReceiveFinalityFlow(counterPartySession, stx.id))
}
}
val fungibleStates = tokenSelection.attemptSpend(amount, transactionBuilder.lockId, queryCriteria)
最佳答案
在我看来,您所描述的几乎与 token SDK 中当前存在的内容相同。与其编写一个全新的流程,不如将现有的赎回代币流程与以发行者指定应该赎回哪些代币开始的附加流程包装起来?我想你可能只需要几行额外的代码就可以做到这一点。
关于您为什么会遇到异常,除非我看到代码,否则我不知道。我建议你重新开始包装 RedeemFungibleTokensFlow
和 RedeemTokensFlowHandler
处理与发行人而不是赎回方开始赎回过程的流程。
关于kotlin - 发行人赎回另一方持有的可替代代币,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57323633/
我正在查看Kotlin Github page我注意到 Kotlin 语言本身大部分是用 Kotlin 编写的:我只是想知道,一种语言怎么可能大部分都是用它自己的语言编写的?在您可以使用正在创建的语言
我有以下非常简单的 kotlin 代码来演示中缀函数 com.lopushen.demo.presentation 包 fun main(args: Array) { print("Hello
我在 Java 中有 2 个模型类,其中一个扩展了另一个 @UseStag public class GenericMessages extends NavigationLocalizationMap
Kotlin 代码 runBlocking { flow { for (i in 0..4) { println("Emit $i")
这三个 Kotlin 插件和它们的实际作用有什么区别? plugins { id 'kotlin-android' id 'org.jetbrains.kotlin.android'
我正在为某些现有库添加 Kotlin 原生 linuxX64 目标支持。库已成功编译,但在运行测试用例时,出现以下运行时错误: kotlin.native.concurrent.InvalidMuta
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 2 年前。 Improve t
我创建了一个类并向其添加了一个与成员函数具有相同签名的扩展,并执行了这个方法,它总是执行成员方法。 class Worker { fun work() = "...working" } fun
我知道传递给函数的参数将被视为“val”,即使变量被初始化为“var”。但这对我来说一直是个问题。在下面的示例代码中,我想通过使用函数“changeNum”修改变量“num”的值。但当然,Kotlin
现在,我正在尝试用 Kotlin 重写我的 Java 应用程序。然后,我遇到了日志语句,比如 log.info("do the print thing for {}", arg); 所以我有两种方法可
有点出名article关于许多语言的异步编程模型的状态,指出它们存在“颜色”问题,特别是将生态系统分为两个独立的世界:异步和非异步。以下是这种语言的属性: 每个函数都有一种颜色,红色或蓝色(例如asy
因为 KDoc 文档生成引擎是 abandoned in favor of Dokka , Kotlin 文档应该称为“KDoc 注释”,还是“Dokka 注释”? 最佳答案 如所述here , KD
我想在可空对象上传递函数引用。以 Android 为例,假设我想使用 Activity#onBackPressed来自作为该事件的子级的片段。 如果我想调用这个函数,我可以很容易地做到 activit
我有一个列表 (x, y)其中y只能是 0 或 1 这样 例如: [(3, 0), (3, 1), (5, 1)] [(5, 0), (3, 1), (5, 1)] [(1, 1), (3, 1),
从强类型语言的定义来看: A strongly-typed programming language is one in which each type of data (such as intege
这不能编译的事实是否意味着它们不是一流的类型? fun foo(s: String): Int = s.length // This won't compile. val bar = foo 有没有办
如果在 Java i++是一个表达式和 i++;是一个表达式语句,分号(;) 在 Kotlin 中是可选的,是 i++ Kotlin 中的表达式或表达式语句? 最佳答案 i++是一个表达式,因为它有一
代码(如下所示)是否正确?它取自 Kotlin-docs.pdf 的第 63 页,这也是 https://kotlinlang.org/docs/reference/generics.html 的最后
我正在尝试使用 Kotlin 为 Android 的一些全局 API 解析器(检查网络连接、调用 API 并通过来自源的单个调用返回格式化数据),并且在某些时候我不得不创建一个通用类型 object就
kotlinlang 中的任务: 使用月份变量重写此模式,使其与格式 13 JUN 1992(两位数字、一个空格、一个月份缩写、一个空格、四位数字)中的日期相匹配。 答案是:val month = "
我是一名优秀的程序员,十分优秀!