mirror of
https://github.com/corda/corda.git
synced 2025-03-11 06:54:04 +00:00
Merged in rg_work_in_progress (pull request #16)
Updated as comments per previous pull request, now generic tests run both Kotlin and Java CommercialPaper class tests.
This commit is contained in:
commit
ea2b18eb41
25
src/main/java/contracts/ICommercialPaperState.java
Normal file
25
src/main/java/contracts/ICommercialPaperState.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
|
||||||
|
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
|
||||||
|
* set forth therein.
|
||||||
|
*
|
||||||
|
* All other rights reserved.
|
||||||
|
*/
|
||||||
|
package contracts;
|
||||||
|
|
||||||
|
import core.*;
|
||||||
|
|
||||||
|
import java.security.*;
|
||||||
|
import java.time.*;
|
||||||
|
|
||||||
|
/* This is an interface solely created to demonstrate that the same kotlin tests can be run against
|
||||||
|
* either a Java implementation of the CommercialPaper or a kotlin implementation.
|
||||||
|
* Normally one would not duplicate an implementation in different languages for obvious reasons, but it demonstrates that
|
||||||
|
* ultimately either language can be used against a common test framework (and therefore can be used for real).
|
||||||
|
*/
|
||||||
|
public interface ICommercialPaperState extends ContractState {
|
||||||
|
ICommercialPaperState withOwner(PublicKey newOwner);
|
||||||
|
ICommercialPaperState withIssuance(PartyReference newIssuance);
|
||||||
|
ICommercialPaperState withFaceValue(Amount newFaceValue);
|
||||||
|
ICommercialPaperState withMaturityDate(Instant newMaturityDate);
|
||||||
|
}
|
@ -47,12 +47,18 @@ class CommercialPaper : Contract {
|
|||||||
override val owner: PublicKey,
|
override val owner: PublicKey,
|
||||||
val faceValue: Amount,
|
val faceValue: Amount,
|
||||||
val maturityDate: Instant
|
val maturityDate: Instant
|
||||||
) : OwnableState {
|
) : OwnableState, ICommercialPaperState {
|
||||||
override val programRef = CP_PROGRAM_ID
|
override val programRef = CP_PROGRAM_ID
|
||||||
|
|
||||||
fun withoutOwner() = copy(owner = NullPublicKey)
|
fun withoutOwner() = copy(owner = NullPublicKey)
|
||||||
override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner))
|
override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||||
override fun toString() = "${Emoji.newspaper}CommercialPaper(of $faceValue redeemable on $maturityDate by '$issuance', owned by ${owner.toStringShort()})"
|
override fun toString() = "${Emoji.newspaper}CommercialPaper(of $faceValue redeemable on $maturityDate by '$issuance', owned by ${owner.toStringShort()})"
|
||||||
|
|
||||||
|
// Although kotlin is smart enough not to need these, as we are using the ICommercialPaperState, we need to declare them explicitly for use later,
|
||||||
|
override fun withOwner(newOwner: PublicKey): ICommercialPaperState = copy(owner = newOwner)
|
||||||
|
override fun withIssuance(newIssuance: PartyReference): ICommercialPaperState = copy(issuance = newIssuance)
|
||||||
|
override fun withFaceValue(newFaceValue: Amount): ICommercialPaperState = copy(faceValue = newFaceValue)
|
||||||
|
override fun withMaturityDate(newMaturityDate: Instant): ICommercialPaperState = copy(maturityDate = newMaturityDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Commands : CommandData {
|
interface Commands : CommandData {
|
||||||
|
@ -19,14 +19,16 @@ import java.util.*;
|
|||||||
import static core.ContractsDSLKt.*;
|
import static core.ContractsDSLKt.*;
|
||||||
import static kotlin.collections.CollectionsKt.*;
|
import static kotlin.collections.CollectionsKt.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a Java version of the CommercialPaper contract (chosen because it's simple). This demonstrates how the
|
* This is a Java version of the CommercialPaper contract (chosen because it's simple). This demonstrates how the
|
||||||
* use of Kotlin for implementation of the framework does not impose the same language choice on contract developers.
|
* use of Kotlin for implementation of the framework does not impose the same language choice on contract developers.
|
||||||
*
|
*
|
||||||
* NOTE: For illustration only. Not unit tested.
|
|
||||||
*/
|
*/
|
||||||
public class JavaCommercialPaper implements Contract {
|
public class JavaCommercialPaper implements Contract {
|
||||||
public static class State implements ContractState {
|
public static core.SecureHash JCP_PROGRAM_ID = SecureHash.Companion.sha256("java commercial paper (this should be a bytecode hash)");
|
||||||
|
|
||||||
|
public static class State implements ContractState, ICommercialPaperState {
|
||||||
private PartyReference issuance;
|
private PartyReference issuance;
|
||||||
private PublicKey owner;
|
private PublicKey owner;
|
||||||
private Amount faceValue;
|
private Amount faceValue;
|
||||||
@ -42,8 +44,23 @@ public class JavaCommercialPaper implements Contract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public State copy() {
|
public State copy() {
|
||||||
State ret = new State(this.issuance, this.owner, this.faceValue, this.maturityDate);
|
return new State(this.issuance, this.owner, this.faceValue, this.maturityDate);
|
||||||
return ret;
|
}
|
||||||
|
|
||||||
|
public ICommercialPaperState withOwner(PublicKey newOwner) {
|
||||||
|
return new State(this.issuance, newOwner, this.faceValue, this.maturityDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICommercialPaperState withIssuance(PartyReference newIssuance) {
|
||||||
|
return new State(newIssuance, this.owner, this.faceValue, this.maturityDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICommercialPaperState withFaceValue(Amount newFaceValue) {
|
||||||
|
return new State(this.issuance, this.owner, newFaceValue, this.maturityDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICommercialPaperState withMaturityDate(Instant newMaturityDate) {
|
||||||
|
return new State(this.issuance, this.owner, this.faceValue, newMaturityDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PartyReference getIssuance() {
|
public PartyReference getIssuance() {
|
||||||
@ -120,24 +137,47 @@ public class JavaCommercialPaper implements Contract {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verify(@NotNull TransactionForVerification tx) {
|
public void verify(@NotNull TransactionForVerification tx) {
|
||||||
// There are two possible things that can be done with CP. The first is trading it. The second is redeeming it
|
// There are three possible things that can be done with CP.
|
||||||
// for cash on or after the maturity date.
|
// Issuance, trading (aka moving in this prototype) and redeeming.
|
||||||
|
// Each command has it's own set of restrictions which the verify function ... verifies.
|
||||||
|
|
||||||
List<InOutGroup<State>> groups = tx.groupStates(State.class, State::withoutOwner);
|
List<InOutGroup<State>> groups = tx.groupStates(State.class, State::withoutOwner);
|
||||||
|
|
||||||
// Find the command that instructs us what to do and check there's exactly one.
|
// Find the command that instructs us what to do and check there's exactly one.
|
||||||
AuthenticatedObject<CommandData> cmd = requireSingleCommand(tx.getCommands(), Commands.class);
|
|
||||||
|
|
||||||
TimestampCommand timestampCommand = tx.getTimestampBy(DummyTimestampingAuthority.INSTANCE.getIdentity());
|
AuthenticatedObject<CommandData> cmd = requireSingleCommand(tx.getCommands(), JavaCommercialPaper.Commands.class);
|
||||||
if (timestampCommand == null)
|
|
||||||
throw new IllegalArgumentException("must be timestamped");
|
|
||||||
Instant time = timestampCommand.getMidpoint();
|
|
||||||
|
|
||||||
for (InOutGroup<State> group : groups) {
|
for (InOutGroup<State> group : groups) {
|
||||||
List<State> inputs = group.getInputs();
|
List<State> inputs = group.getInputs();
|
||||||
List<State> outputs = group.getOutputs();
|
List<State> outputs = group.getOutputs();
|
||||||
|
|
||||||
// For now do not allow multiple pieces of CP to trade in a single transaction. Study this more!
|
// For now do not allow multiple pieces of CP to trade in a single transaction.
|
||||||
State input = single(filterIsInstance(inputs, State.class));
|
if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Issue) {
|
||||||
|
State output = single(outputs);
|
||||||
|
if (!inputs.isEmpty()) {
|
||||||
|
throw new IllegalStateException("Failed Requirement: there is no input state");
|
||||||
|
}
|
||||||
|
if (output.faceValue.getPennies() == 0) {
|
||||||
|
throw new IllegalStateException("Failed Requirement: the face value is not zero");
|
||||||
|
}
|
||||||
|
|
||||||
|
TimestampCommand timestampCommand = tx.getTimestampBy(DummyTimestampingAuthority.INSTANCE.getIdentity());
|
||||||
|
if (timestampCommand == null)
|
||||||
|
throw new IllegalArgumentException("Failed Requirement: must be timestamped");
|
||||||
|
|
||||||
|
Instant time = timestampCommand.getBefore();
|
||||||
|
|
||||||
|
if (! time.isBefore(output.maturityDate)) {
|
||||||
|
throw new IllegalStateException("Failed Requirement: the maturity date is not in the past");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cmd.getSigners().contains(output.issuance.getParty().getOwningKey())) {
|
||||||
|
throw new IllegalStateException("Failed Requirement: the issuance is signed by the claimed issuer of the paper");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // Everything else (Move, Redeem) requires inputs (they are not first to be actioned)
|
||||||
|
// There should be only a single input due to aggregation above
|
||||||
|
State input = single(inputs);
|
||||||
|
|
||||||
if (!cmd.getSigners().contains(input.getOwner()))
|
if (!cmd.getSigners().contains(input.getOwner()))
|
||||||
throw new IllegalStateException("Failed requirement: the transaction is signed by the owner of the CP");
|
throw new IllegalStateException("Failed requirement: the transaction is signed by the owner of the CP");
|
||||||
@ -150,11 +190,19 @@ public class JavaCommercialPaper implements Contract {
|
|||||||
!output.getIssuance().equals(input.getIssuance()) ||
|
!output.getIssuance().equals(input.getIssuance()) ||
|
||||||
!output.getMaturityDate().equals(input.getMaturityDate()))
|
!output.getMaturityDate().equals(input.getMaturityDate()))
|
||||||
throw new IllegalStateException("Failed requirement: the output state is the same as the input state except for owner");
|
throw new IllegalStateException("Failed requirement: the output state is the same as the input state except for owner");
|
||||||
} else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) {
|
}
|
||||||
Amount received = CashKt.sumCashOrNull(inputs);
|
else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem)
|
||||||
if (received == null)
|
{
|
||||||
throw new IllegalStateException("Failed requirement: no cash being redeemed");
|
TimestampCommand timestampCommand = tx.getTimestampBy(DummyTimestampingAuthority.INSTANCE.getIdentity());
|
||||||
if (input.getMaturityDate().isAfter(time))
|
if (timestampCommand == null)
|
||||||
|
throw new IllegalArgumentException("Failed Requirement: must be timestamped");
|
||||||
|
Instant time = timestampCommand.getBefore();
|
||||||
|
|
||||||
|
Amount received = CashKt.sumCashBy(tx.getOutStates(), input.getOwner());
|
||||||
|
|
||||||
|
if (! received.equals(input.getFaceValue()))
|
||||||
|
throw new IllegalStateException(String.format("Failed Requirement: received amount equals the face value"));
|
||||||
|
if (time.isBefore(input.getMaturityDate()))
|
||||||
throw new IllegalStateException("Failed requirement: the paper must have matured");
|
throw new IllegalStateException("Failed requirement: the paper must have matured");
|
||||||
if (!input.getFaceValue().equals(received))
|
if (!input.getFaceValue().equals(received))
|
||||||
throw new IllegalStateException("Failed requirement: the received amount equals the face value");
|
throw new IllegalStateException("Failed requirement: the received amount equals the face value");
|
||||||
@ -163,6 +211,7 @@ public class JavaCommercialPaper implements Contract {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
@ -170,4 +219,22 @@ public class JavaCommercialPaper implements Contract {
|
|||||||
// TODO: Should return hash of the contract's contents, not its URI
|
// TODO: Should return hash of the contract's contents, not its URI
|
||||||
return SecureHash.Companion.sha256("https://en.wikipedia.org/wiki/Commercial_paper");
|
return SecureHash.Companion.sha256("https://en.wikipedia.org/wiki/Commercial_paper");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TransactionBuilder craftIssue(@NotNull PartyReference issuance, @NotNull Amount faceValue, @Nullable Instant maturityDate) {
|
||||||
|
State state = new State(issuance,issuance.getParty().getOwningKey(), faceValue, maturityDate);
|
||||||
|
return new TransactionBuilder().withItems(state, new Command( new Commands.Issue(), issuance.getParty().getOwningKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void craftRedeem(TransactionBuilder tx, StateAndRef<State> paper, List<StateAndRef<Cash.State>> wallet) throws InsufficientBalanceException {
|
||||||
|
new Cash().craftSpend(tx, paper.getState().getFaceValue(), paper.getState().getOwner(), wallet, null);
|
||||||
|
tx.addInputState(paper.getRef());
|
||||||
|
tx.addCommand(new Command( new Commands.Redeem(), paper.getState().getOwner()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void craftMove(TransactionBuilder tx, StateAndRef<State> paper, PublicKey newOwner) {
|
||||||
|
tx.addInputState(paper.getRef());
|
||||||
|
tx.addOutputState(new State(paper.getState().getIssuance(), newOwner, paper.getState().getFaceValue(), paper.getState().getMaturityDate()));
|
||||||
|
tx.addCommand(new Command(new Commands.Move(), paper.getState().getOwner()));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,17 @@ import java.time.ZoneOffset
|
|||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class CommercialPaperTests {
|
interface ICommercialPaperTestTemplate {
|
||||||
val PAPER_1 = CommercialPaper.State(
|
open fun getPaper() : ICommercialPaperState
|
||||||
issuance = MEGA_CORP.ref(123),
|
open fun getIssueCommand() : CommandData
|
||||||
owner = MEGA_CORP_PUBKEY,
|
open fun getRedeemCommand() : CommandData
|
||||||
faceValue = 1000.DOLLARS,
|
open fun getMoveCommand() : CommandData
|
||||||
maturityDate = TEST_TX_TIME + 7.days
|
}
|
||||||
)
|
|
||||||
|
open class CommercialPaperTestsGeneric(templateToTest: ICommercialPaperTestTemplate) {
|
||||||
|
|
||||||
|
val thisTest = templateToTest
|
||||||
|
val PAPER_1 = thisTest.getPaper()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun ok() {
|
fun ok() {
|
||||||
@ -41,7 +45,7 @@ class CommercialPaperTests {
|
|||||||
transactionGroup {
|
transactionGroup {
|
||||||
transaction {
|
transaction {
|
||||||
output { PAPER_1 }
|
output { PAPER_1 }
|
||||||
arg(DUMMY_PUBKEY_1) { CommercialPaper.Commands.Issue() }
|
arg(DUMMY_PUBKEY_1) { thisTest.getIssueCommand() }
|
||||||
timestamp(TEST_TX_TIME)
|
timestamp(TEST_TX_TIME)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,8 +57,8 @@ class CommercialPaperTests {
|
|||||||
fun `face value is not zero`() {
|
fun `face value is not zero`() {
|
||||||
transactionGroup {
|
transactionGroup {
|
||||||
transaction {
|
transaction {
|
||||||
output { PAPER_1.copy(faceValue = 0.DOLLARS) }
|
output { PAPER_1.withFaceValue(0.DOLLARS) }
|
||||||
arg(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
arg(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() }
|
||||||
timestamp(TEST_TX_TIME)
|
timestamp(TEST_TX_TIME)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,8 +70,8 @@ class CommercialPaperTests {
|
|||||||
fun `maturity date not in the past`() {
|
fun `maturity date not in the past`() {
|
||||||
transactionGroup {
|
transactionGroup {
|
||||||
transaction {
|
transaction {
|
||||||
output { PAPER_1.copy(maturityDate = TEST_TX_TIME - 10.days) }
|
output { PAPER_1.withMaturityDate(TEST_TX_TIME - 10.days) }
|
||||||
arg(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
arg(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() }
|
||||||
timestamp(TEST_TX_TIME)
|
timestamp(TEST_TX_TIME)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +110,7 @@ class CommercialPaperTests {
|
|||||||
transaction {
|
transaction {
|
||||||
input("paper")
|
input("paper")
|
||||||
output { PAPER_1 }
|
output { PAPER_1 }
|
||||||
arg(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
arg(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() }
|
||||||
timestamp(TEST_TX_TIME)
|
timestamp(TEST_TX_TIME)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +193,7 @@ class CommercialPaperTests {
|
|||||||
// Generate a trade lifecycle with various parameters.
|
// Generate a trade lifecycle with various parameters.
|
||||||
fun trade(redemptionTime: Instant = TEST_TX_TIME + 8.days,
|
fun trade(redemptionTime: Instant = TEST_TX_TIME + 8.days,
|
||||||
aliceGetsBack: Amount = 1000.DOLLARS,
|
aliceGetsBack: Amount = 1000.DOLLARS,
|
||||||
destroyPaperAtRedemption: Boolean = true): TransactionGroupDSL<CommercialPaper.State> {
|
destroyPaperAtRedemption: Boolean = true): TransactionGroupDSL<ICommercialPaperState> {
|
||||||
val someProfits = 1200.DOLLARS
|
val someProfits = 1200.DOLLARS
|
||||||
return transactionGroupFor() {
|
return transactionGroupFor() {
|
||||||
roots {
|
roots {
|
||||||
@ -200,7 +204,7 @@ class CommercialPaperTests {
|
|||||||
// Some CP is issued onto the ledger by MegaCorp.
|
// Some CP is issued onto the ledger by MegaCorp.
|
||||||
transaction("Issuance") {
|
transaction("Issuance") {
|
||||||
output("paper") { PAPER_1 }
|
output("paper") { PAPER_1 }
|
||||||
arg(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
arg(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() }
|
||||||
timestamp(TEST_TX_TIME)
|
timestamp(TEST_TX_TIME)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +216,7 @@ class CommercialPaperTests {
|
|||||||
output("borrowed $900") { 900.DOLLARS.CASH `owned by` MEGA_CORP_PUBKEY }
|
output("borrowed $900") { 900.DOLLARS.CASH `owned by` MEGA_CORP_PUBKEY }
|
||||||
output("alice's paper") { "paper".output `owned by` ALICE }
|
output("alice's paper") { "paper".output `owned by` ALICE }
|
||||||
arg(ALICE) { Cash.Commands.Move() }
|
arg(ALICE) { Cash.Commands.Move() }
|
||||||
arg(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Move() }
|
arg(MEGA_CORP_PUBKEY) { thisTest.getMoveCommand() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time passes, and Alice redeem's her CP for $1000, netting a $100 profit. MegaCorp has received $1200
|
// Time passes, and Alice redeem's her CP for $1000, netting a $100 profit. MegaCorp has received $1200
|
||||||
@ -227,14 +231,10 @@ class CommercialPaperTests {
|
|||||||
output { "paper".output }
|
output { "paper".output }
|
||||||
|
|
||||||
arg(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
arg(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
||||||
arg(ALICE) { CommercialPaper.Commands.Redeem() }
|
arg(ALICE) { thisTest.getRedeemCommand() }
|
||||||
|
|
||||||
timestamp(redemptionTime)
|
timestamp(redemptionTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
CommercialPaperTests().trade().visualise()
|
|
||||||
}
|
|
39
src/test/kotlin/contracts/CommercialPaperTestsJava.kt
Normal file
39
src/test/kotlin/contracts/CommercialPaperTestsJava.kt
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
|
||||||
|
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
|
||||||
|
* set forth therein.
|
||||||
|
*
|
||||||
|
* All other rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
import core.CommandData
|
||||||
|
import core.DOLLARS
|
||||||
|
import core.days
|
||||||
|
import core.testutils.MEGA_CORP
|
||||||
|
import core.testutils.MEGA_CORP_PUBKEY
|
||||||
|
import core.testutils.TEST_TX_TIME
|
||||||
|
|
||||||
|
fun getJavaCommericalPaper() : ICommercialPaperState {
|
||||||
|
return JavaCommercialPaper.State(
|
||||||
|
MEGA_CORP.ref(123),
|
||||||
|
MEGA_CORP_PUBKEY,
|
||||||
|
1000.DOLLARS,
|
||||||
|
TEST_TX_TIME + 7.days
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class JavaCommercialPaperTest() : ICommercialPaperTestTemplate {
|
||||||
|
override fun getPaper() : ICommercialPaperState = getJavaCommericalPaper()
|
||||||
|
override fun getIssueCommand() : CommandData = JavaCommercialPaper.Commands.Issue()
|
||||||
|
override fun getRedeemCommand() : CommandData = JavaCommercialPaper.Commands.Redeem()
|
||||||
|
override fun getMoveCommand() : CommandData = JavaCommercialPaper.Commands.Move()
|
||||||
|
}
|
||||||
|
|
||||||
|
class CommercialPaperTestsJava() : CommercialPaperTestsGeneric(JavaCommercialPaperTest()) { }
|
||||||
|
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
CommercialPaperTestsJava().trade().visualise()
|
||||||
|
}
|
39
src/test/kotlin/contracts/CommercialPaperTestsKotlin.kt
Normal file
39
src/test/kotlin/contracts/CommercialPaperTestsKotlin.kt
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
|
||||||
|
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
|
||||||
|
* set forth therein.
|
||||||
|
*
|
||||||
|
* All other rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
import core.CommandData
|
||||||
|
import core.DOLLARS
|
||||||
|
import core.days
|
||||||
|
import core.testutils.MEGA_CORP
|
||||||
|
import core.testutils.MEGA_CORP_PUBKEY
|
||||||
|
import core.testutils.TEST_TX_TIME
|
||||||
|
|
||||||
|
fun getKotlinCommercialPaper() : ICommercialPaperState {
|
||||||
|
return CommercialPaper.State(
|
||||||
|
issuance = MEGA_CORP.ref(123),
|
||||||
|
owner = MEGA_CORP_PUBKEY,
|
||||||
|
faceValue = 1000.DOLLARS,
|
||||||
|
maturityDate = TEST_TX_TIME + 7.days
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class KotlinCommercialPaperTest() : ICommercialPaperTestTemplate {
|
||||||
|
override fun getPaper() : ICommercialPaperState = getKotlinCommercialPaper()
|
||||||
|
override fun getIssueCommand() : CommandData = CommercialPaper.Commands.Issue()
|
||||||
|
override fun getRedeemCommand() : CommandData = CommercialPaper.Commands.Redeem()
|
||||||
|
override fun getMoveCommand() : CommandData = CommercialPaper.Commands.Move()
|
||||||
|
}
|
||||||
|
|
||||||
|
class CommercialPaperTestsKotlin() : CommercialPaperTestsGeneric( KotlinCommercialPaperTest()) { }
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
CommercialPaperTestsKotlin().trade().visualise()
|
||||||
|
}
|
||||||
|
|
@ -53,6 +53,7 @@ val TEST_TX_TIME = Instant.parse("2015-04-17T12:00:00.00Z")
|
|||||||
val TEST_PROGRAM_MAP: Map<SecureHash, Contract> = mapOf(
|
val TEST_PROGRAM_MAP: Map<SecureHash, Contract> = mapOf(
|
||||||
CASH_PROGRAM_ID to Cash(),
|
CASH_PROGRAM_ID to Cash(),
|
||||||
CP_PROGRAM_ID to CommercialPaper(),
|
CP_PROGRAM_ID to CommercialPaper(),
|
||||||
|
JavaCommercialPaper.JCP_PROGRAM_ID to JavaCommercialPaper(),
|
||||||
CROWDFUND_PROGRAM_ID to CrowdFund(),
|
CROWDFUND_PROGRAM_ID to CrowdFund(),
|
||||||
DUMMY_PROGRAM_ID to DummyContract
|
DUMMY_PROGRAM_ID to DummyContract
|
||||||
)
|
)
|
||||||
@ -79,7 +80,8 @@ val TEST_PROGRAM_MAP: Map<SecureHash, Contract> = mapOf(
|
|||||||
// TODO: Make it impossible to forget to test either a failure or an accept for each transaction{} block
|
// TODO: Make it impossible to forget to test either a failure or an accept for each transaction{} block
|
||||||
|
|
||||||
infix fun Cash.State.`owned by`(owner: PublicKey) = this.copy(owner = owner)
|
infix fun Cash.State.`owned by`(owner: PublicKey) = this.copy(owner = owner)
|
||||||
infix fun CommercialPaper.State.`owned by`(owner: PublicKey) = this.copy(owner = owner)
|
infix fun ICommercialPaperState.`owned by`(new_owner: PublicKey) = this.withOwner(new_owner)
|
||||||
|
|
||||||
// Allows you to write 100.DOLLARS.CASH
|
// Allows you to write 100.DOLLARS.CASH
|
||||||
val Amount.CASH: Cash.State get() = Cash.State(MINI_CORP.ref(1,2,3), this, NullPublicKey)
|
val Amount.CASH: Cash.State get() = Cash.State(MINI_CORP.ref(1,2,3), this, NullPublicKey)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user