在Corda中,响应者如何向事务添加组件?
我有一个Corda流程,其中响应方<代码>方代码>需要向交易中添加组件(例如,响应方可能必须向交易中添加自己的现金以支付交易中的资产)在Corda中,响应者如何向事务添加组件?,corda,Corda,我有一个Corda流程,其中响应方方需要向交易中添加组件(例如,响应方可能必须向交易中添加自己的现金以支付交易中的资产) 如何允许响应者添加这些输入?下面是一个示例。总之: 启动器使用send向响应程序发送要添加的状态参数 响应者使用receive接收这些参数并创建状态 响应者使用send将创建的状态发送回启动器 启动器将状态添加到事务生成器中,并像往常一样继续处理流 当要求响应者作为CollectSignaturesFlow的一部分对交易进行签名时,响应者会检查他们提供的状态和交易是否与预期
如何允许响应者添加这些输入?下面是一个示例。总之:
- 启动器使用
向响应程序发送要添加的状态参数send
- 响应者使用
接收这些参数并创建状态receive
- 响应者使用
将创建的状态发送回启动器send
- 启动器将状态添加到事务生成器中,并像往常一样继续处理流
- 当要求响应者作为
的一部分对交易进行签名时,响应者会检查他们提供的状态和交易是否与预期一致CollectSignaturesFlow
@InitiatingFlow
@StartableByRPC
public class IOUFlowInitiator extends FlowLogic<SignedTransaction> {
private final int iouValue;
private final Party otherParty;
private final ProgressTracker progressTracker = new ProgressTracker();
public IOUFlowInitiator(int iouValue, Party otherParty) {
this.iouValue = iouValue;
this.otherParty = otherParty;
}
@Override
public ProgressTracker getProgressTracker() {
return progressTracker;
}
@Suspendable
@Override
public SignedTransaction call() throws FlowException {
// Get the counterparty to create the output IOUState.
final FlowSession otherPartySession = initiateFlow(otherParty);
final IOUState iouState = otherPartySession.sendAndReceive(IOUState.class, iouValue).unwrap(wrappedIOU -> wrappedIOU);
// Create the command.
final List<PublicKey> requiredSigners = Arrays.asList(iouState.getLender().getOwningKey(), iouState.getBorrower().getOwningKey());
final Command<IOUContract.Commands.Create> txCommand = new Command<>(
new IOUContract.Commands.Create(), requiredSigners);
// Build the transaction.
final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
final TransactionBuilder txBuilder = new TransactionBuilder(notary)
.addOutputState(iouState, IOU_CONTRACT_ID)
.addCommand(txCommand);
// Verify, sign and finalise.
txBuilder.verify(getServiceHub());
final SignedTransaction partSignedTx = getServiceHub().signInitialTransaction(txBuilder);
final SignedTransaction fullySignedTx = subFlow(new CollectSignaturesFlow(partSignedTx, ImmutableSet.of(otherPartySession), CollectSignaturesFlow.Companion.tracker()));
return subFlow(new FinalityFlow(fullySignedTx));
}
}
@InitiatedBy(IOUFlowInitiator.class)
public class IOUFlowResponder extends FlowLogic<SignedTransaction> {
private final FlowSession counterpartySession;
public IOUFlowResponder(FlowSession counterpartySession) {
this.counterpartySession = counterpartySession;
}
@Suspendable
@Override
public SignedTransaction call() throws FlowException {
// Receive the IOU's value from the counterparty.
Integer iouValue = counterpartySession.receive(Integer.class).unwrap(wrappedInt -> wrappedInt);
// Create the output IOUState.
Party otherParty = counterpartySession.getCounterparty();
IOUState iouState = new IOUState(iouValue, getOurIdentity(), otherParty, new UniqueIdentifier());
// Send the output IOUState to the counterparty.
counterpartySession.send(iouState);
// Sign the resulting transaction if it meets expectations.
return subFlow(new CheckIOUAndSignFlow(iouState, counterpartySession, SignTransactionFlow.Companion.tracker()));
}
}
class CheckIOUAndSignFlow extends SignTransactionFlow {
private final IOUState expectedIOU;
CheckIOUAndSignFlow(IOUState expectedIOU, FlowSession otherPartyFlow, ProgressTracker progressTracker) {
super(otherPartyFlow, progressTracker);
this.expectedIOU = expectedIOU;
}
@Override
protected void checkTransaction(SignedTransaction stx) throws FlowException {
LedgerTransaction ltx = null;
try {
ltx = stx.toLedgerTransaction(getServiceHub(), false);
} catch (SignatureException e) {
throw new FlowException("Transaction had invalid signature.");
}
// Check that the resulting transaction meets expectations.
List<IOUState> outputs = ltx.outputsOfType(IOUState.class);
List<Command<IOUContract.Commands.Create>> commands = ltx.commandsOfType(IOUContract.Commands.Create.class);
if (outputs.size() != 1) throw new FlowException("Expected single IOU output in the transaction.");
if (commands.size() != 1) throw new FlowException("Expected single IOU Create command in the transaction.");
IOUState outputState = outputs.get(0);
if (!outputState.equals(expectedIOU)) throw new FlowException("IOU does not match expected IOU..");
}
}
@InitiatingFlow
@星表
公共类IOUFlowInitiator扩展了FlowLogic{
私人最终国际价值;
私人最终一方或另一方;
private final ProgressTracker ProgressTracker=新ProgressTracker();
公共IOUFlowInitiator(int iouValue,一方或另一方){
this.iouValue=iouValue;
this.otherParty=另一方;
}
@凌驾
公共ProgressTracker getProgressTracker(){
返回进程跟踪器;
}
@暂停
@凌驾
public SignedTransaction调用()引发流异常{
//让交易对手创建输出。
最终FlowSession otherPartySession=initiateFlow(另一方);
最终Ioutate Ioutate=otherPartySession.sendAndReceive(Ioutate.class,iouValue).展开(wrappedIOU->wrappedIOU);
//创建命令。
最终列表requiredSigners=Arrays.asList(ioState.getLender().getOwningKey(),ioState.GetFrooder().getOwningKey());
最终命令txCommand=新命令(
新建IOUContract.Commands.Create(),requiredSigners);
//构建事务。
最终参与方公证人=getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
最终TransactionBuilder txBuilder=新TransactionBuilder(公证人)
.addOutputState(IOU状态、IOU合同ID)
.addCommand(txCommand);
//核实、签署并最终确定。
验证(getServiceHub());
最终签名的Transaction partSignedTx=getServiceHub()。签名初始Transaction(txBuilder);
final SignedTransaction fullySignedTx=子流(新CollectSignaturesFlow(partSignedTx,ImmutableSet.of(otherPartySession),CollectSignaturesFlow.Companion.tracker());
返回子流(新最终流(fullySignedTx));
}
}
应答器代码
@InitiatingFlow
@StartableByRPC
public class IOUFlowInitiator extends FlowLogic<SignedTransaction> {
private final int iouValue;
private final Party otherParty;
private final ProgressTracker progressTracker = new ProgressTracker();
public IOUFlowInitiator(int iouValue, Party otherParty) {
this.iouValue = iouValue;
this.otherParty = otherParty;
}
@Override
public ProgressTracker getProgressTracker() {
return progressTracker;
}
@Suspendable
@Override
public SignedTransaction call() throws FlowException {
// Get the counterparty to create the output IOUState.
final FlowSession otherPartySession = initiateFlow(otherParty);
final IOUState iouState = otherPartySession.sendAndReceive(IOUState.class, iouValue).unwrap(wrappedIOU -> wrappedIOU);
// Create the command.
final List<PublicKey> requiredSigners = Arrays.asList(iouState.getLender().getOwningKey(), iouState.getBorrower().getOwningKey());
final Command<IOUContract.Commands.Create> txCommand = new Command<>(
new IOUContract.Commands.Create(), requiredSigners);
// Build the transaction.
final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
final TransactionBuilder txBuilder = new TransactionBuilder(notary)
.addOutputState(iouState, IOU_CONTRACT_ID)
.addCommand(txCommand);
// Verify, sign and finalise.
txBuilder.verify(getServiceHub());
final SignedTransaction partSignedTx = getServiceHub().signInitialTransaction(txBuilder);
final SignedTransaction fullySignedTx = subFlow(new CollectSignaturesFlow(partSignedTx, ImmutableSet.of(otherPartySession), CollectSignaturesFlow.Companion.tracker()));
return subFlow(new FinalityFlow(fullySignedTx));
}
}
@InitiatedBy(IOUFlowInitiator.class)
public class IOUFlowResponder extends FlowLogic<SignedTransaction> {
private final FlowSession counterpartySession;
public IOUFlowResponder(FlowSession counterpartySession) {
this.counterpartySession = counterpartySession;
}
@Suspendable
@Override
public SignedTransaction call() throws FlowException {
// Receive the IOU's value from the counterparty.
Integer iouValue = counterpartySession.receive(Integer.class).unwrap(wrappedInt -> wrappedInt);
// Create the output IOUState.
Party otherParty = counterpartySession.getCounterparty();
IOUState iouState = new IOUState(iouValue, getOurIdentity(), otherParty, new UniqueIdentifier());
// Send the output IOUState to the counterparty.
counterpartySession.send(iouState);
// Sign the resulting transaction if it meets expectations.
return subFlow(new CheckIOUAndSignFlow(iouState, counterpartySession, SignTransactionFlow.Companion.tracker()));
}
}
class CheckIOUAndSignFlow extends SignTransactionFlow {
private final IOUState expectedIOU;
CheckIOUAndSignFlow(IOUState expectedIOU, FlowSession otherPartyFlow, ProgressTracker progressTracker) {
super(otherPartyFlow, progressTracker);
this.expectedIOU = expectedIOU;
}
@Override
protected void checkTransaction(SignedTransaction stx) throws FlowException {
LedgerTransaction ltx = null;
try {
ltx = stx.toLedgerTransaction(getServiceHub(), false);
} catch (SignatureException e) {
throw new FlowException("Transaction had invalid signature.");
}
// Check that the resulting transaction meets expectations.
List<IOUState> outputs = ltx.outputsOfType(IOUState.class);
List<Command<IOUContract.Commands.Create>> commands = ltx.commandsOfType(IOUContract.Commands.Create.class);
if (outputs.size() != 1) throw new FlowException("Expected single IOU output in the transaction.");
if (commands.size() != 1) throw new FlowException("Expected single IOU Create command in the transaction.");
IOUState outputState = outputs.get(0);
if (!outputState.equals(expectedIOU)) throw new FlowException("IOU does not match expected IOU..");
}
}
@InitiatedBy(IOUFlowInitiator.class)
公共类IOUFlowResponder扩展了FlowLogic{
非公开的最终流程交易对手;
公共IOUFlowResponder(FlowSession对方会话){
this.counterpartySession=counterpartySession;
}
@暂停
@凌驾
public SignedTransaction调用()引发流异常{
//从交易对手处获得借据价值。
Integer iouValue=counterpartySession.receive(Integer.class).unwrap(wrappedInt->wrappedInt);
//创建输出。
Party otherParty=对方会话。GetCountery();
IOUState IOUState=新IOUState(iouValue,getOurIdentity(),otherParty,new UniqueIdentifier());
//将输出发送给交易对手。
交易对手发送(IuteState);
//如果结果交易符合预期,则对其进行签名。
返回子流(新的CheckIOUAndSignFlow(ioState、counterpartySession、SignTransactionFlow.Companion.tracker());
}
}
类CheckIOUAndSignFlow扩展了SignTransactionFlow{
私人终审法院;
检查IOUAN和Signflow(IOUATE预期用户、FlowSession其他方流、ProgressTracker ProgressTracker){
超级(其他方流量、进度跟踪);
this.expectedou=expectedou;
}
@凌驾
受保护的无效检查事务(SignedTransaction stx)引发FlowException{
账本交易ltx=null;
试一试{
ltx=stx.toLedgerTransaction(getServiceHub(),false);
}捕获(签名例外e){
抛出新的FlowException(“事务具有无效签名”);
}
//检查生成的事务是否符合预期。
列表输出=ltx.outputsOfType(iostate.class);
List commands=ltx.commandsOfType(IOUContract.commands.Create.class);
if(outputs.size()!=1)抛出新的FlowException(“事务中预期的单个IOU输出”);
if(commands.size()!=1)抛出新的FlowException(“事务中预期的单个IOU创建命令”);
IOUState outputState=outputs.get(0);
如果(!outputState.equals(ExpectedYou))抛出新的FlowException(“IOU与预期IOU不匹配”);
}
}