/** * Pack the contract to the most modern .unicon format, same as {@link TransactionPack#pack()}. Uses bounded {@link * TransactionPack} instance to save together the contract, revoking and new items (if any). This is a binary format * using to submit for approval. Use {@link #fromPackedTransaction(byte[])} to read this format. * * @return packed binary form. */ public byte[] getPackedTransaction() { return getTransactionPack().pack(); }
/** * Register a paying parcel. * * @param contract must be a sealed binary. */ public static Parcel prepareForRegisterPayingParcel(Contract contract, Contract u, int amount, int amountStorage, Set<PrivateKey> uKeys, boolean withTestPayment) throws IOException { List<ErrorRecord> errors = contract.getErrors(); if (errors.size() > 0) { report("contract has errors and can't be submitted for registration"); report("contract id: " + contract.getId().toBase64String()); addErrors(errors); } else { Set<PrivateKey> keys = new HashSet<>(keysMapContract().values()); if (keys != null && keys.size() > 0) contract.addSignerKeys(keys); Parcel parcel = ContractsService.createPayingParcel(contract.getTransactionPack(), u, amount, amountStorage, uKeys, withTestPayment); return parcel; } return null; }
@Override public NImmutableEnvironment getEnvironment(long environmentId) { return protect(() -> { List<byte[]> smkv = getSmartContractForEnvironmentId(environmentId); HashId nContractHashId = HashId.withDigest(smkv.get(2)); Contract contract = NSmartContract.fromPackedTransaction(smkv.get(0)); Contract findNContract = contract.getTransactionPack().getSubItem(nContractHashId); contract = findNContract == null ? contract : findNContract; NSmartContract nSmartContract = (NSmartContract) contract; Binder kvBinder = Boss.unpack(smkv.get(1)); Collection<ContractSubscription> contractSubscriptions = getContractSubscriptions(environmentId); Collection<ContractStorage> contractStorages = getContractStorages(environmentId); FollowerService followerService = getFollowerService(environmentId); List<String> reducedNames = getReducedNames(environmentId); List<NameRecord> nameRecords = new ArrayList<>(); for (String reducedName : reducedNames) { NNameRecord nr = getNameRecord(reducedName); //nr.setId(nrModel.id); nameRecords.add(nr); } NImmutableEnvironment nImmutableEnvironment = new NImmutableEnvironment(nSmartContract, kvBinder, contractSubscriptions, contractStorages, nameRecords, followerService, this); nImmutableEnvironment.setId(environmentId); return nImmutableEnvironment; }); }
@Override synchronized public Approvable getItem(HashId itemId, NodeInfo nodeInfo, Duration maxTimeout) throws InterruptedException { Node node = nodes.get(nodeInfo); Approvable item = node.getItem(itemId); if(item instanceof Contract) { TransactionPack tp_before = ((Contract) item).getTransactionPack(); byte[] data = tp_before.pack(); // here we "send" data and "got" it TransactionPack tp_after = null; try { tp_after = TransactionPack.unpack(data); Contract gotMainContract = tp_after.getContract(); return gotMainContract; } catch (IOException e) { e.printStackTrace(); } } return item; }
/** * Imitate of sending contract from one part of swappers to another. * * Method packs sending contracts with main swap contract (can be blank - doesn't matter) into TransactionPack. * Then restore from packed binary main swap contract, contracts sending with. * * @param mainContract * @return * @throws Exception */ public synchronized Contract imitateSendingTransactionToPartner(Contract mainContract) throws Exception { TransactionPack tp_before = mainContract.getTransactionPack(); byte[] data = tp_before.pack(); // here we "send" data and "got" it TransactionPack tp_after = TransactionPack.unpack(data); Contract gotMainContract = tp_after.getContract(); return gotMainContract; }
/** * Create paid transaction, which consist from contract you want to register and payment contract that will be * spend to process transaction. * <br><br> * * @param payload is prepared contract you want to register in the Universa. * @param payment is approved contract with "U" belongs to you. * @param amount is number of "U" you want to spend to register payload contract. * @param keys is own private keys, which are set as owner of payment contract * @param withTestPayment if true {@link Parcel} will be created with test payment * @return parcel, it ready to send to the Universa. */ public synchronized static Parcel createParcel(Contract payload, Contract payment, int amount, Set<PrivateKey> keys, boolean withTestPayment) { Contract paymentDecreased = payment.createRevision(keys); paymentDecreased.getTransactionalData().set("id",payload.getId().toBase64String()); if (withTestPayment) { paymentDecreased.getStateData().set("test_transaction_units", payment.getStateData().getIntOrThrow("test_transaction_units") - amount); } else { paymentDecreased.getStateData().set("transaction_units", payment.getStateData().getIntOrThrow("transaction_units") - amount); } paymentDecreased.seal(); Parcel parcel = new Parcel(payload.getTransactionPack(), paymentDecreased.getTransactionPack()); return parcel; }
checkSimplePack(tp); assertSame(tp,c.getTransactionPack()); assertSame(tp1,c1.getTransactionPack());
@Test public void shouldTransferTheSameValue() throws Exception { Decimal valueToSend = new Decimal(5); List<Contract> listOfCoinsWithAmount = createListOfCoinsWithAmount(Arrays.asList(5)); List<Wallet> wallets = Wallet.determineWallets(listOfCoinsWithAmount); assertEquals(1, wallets.size()); assertEquals(1, wallets.get(0).getContracts().size()); Wallet wallet = wallets.get(0); Contract contract = wallet.buildContractWithValue(FIELD_NAME, valueToSend); contract.addSignerKeyFromFile(PRIVATE_KEY_PATH); sealCheckTrace(contract, true); assertEquals(0, wallet.getContracts().size()); TransactionPack tp = contract.getTransactionPack(); Contract contractToSend = new Contract(contract.seal(), tp); contractToSend.addSignerKeyFromFile(PRIVATE_KEY_PATH); sealCheckTrace(contractToSend, true); assertEquals(valueToSend.intValue(), contractToSend.getStateData().getIntOrThrow(FIELD_NAME)); }
/** * Create paid transaction, which consist from prepared TransactionPack you want to register * and payment contract that will be * spend to process transaction. * <br><br> * * @param payload is prepared TransactionPack you want to register in the Universa. * @param payment is approved contract with "U" belongs to you. * @param amount is number of "U" you want to spend to register payload contract. * @param keys is own private keys, which are set as owner of payment contract * @param withTestPayment if true {@link Parcel} will be created with test payment * @return parcel, it ready to send to the Universa. */ public synchronized static Parcel createParcel(TransactionPack payload, Contract payment, int amount, Set<PrivateKey> keys, boolean withTestPayment) { Contract paymentDecreased = payment.createRevision(keys); if (withTestPayment) { paymentDecreased.getStateData().set("test_transaction_units", payment.getStateData().getIntOrThrow("test_transaction_units") - amount); } else { paymentDecreased.getStateData().set("transaction_units", payment.getStateData().getIntOrThrow("transaction_units") - amount); } paymentDecreased.seal(); Parcel parcel = new Parcel(payload, paymentDecreased.getTransactionPack()); return parcel; }
@Test public void shouldTransferSumOf7() throws Exception { Decimal valueToSend = new Decimal(280); List<Contract> listOfCoinsWithAmount = createListOfCoinsWithAmount(Arrays.asList(5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60)); List<Wallet> wallets = Wallet.determineWallets(listOfCoinsWithAmount); assertEquals(1, wallets.size()); assertEquals(12, wallets.get(0).getContracts().size()); Wallet wallet = wallets.get(0); Contract contract = wallet.buildContractWithValue(FIELD_NAME, valueToSend); contract.addSignerKeyFromFile(PRIVATE_KEY_PATH); sealCheckTrace(contract, true); assertEquals(6, wallet.getContracts().size()); TransactionPack tp = contract.getTransactionPack(); Contract contractToSend = new Contract(contract.seal(), tp); contractToSend.addSignerKeyFromFile(PRIVATE_KEY_PATH); sealCheckTrace(contractToSend, true); assertEquals(valueToSend.intValue(), contractToSend.getStateData().getIntOrThrow(FIELD_NAME)); }
@Test public void shouldTransferAmountFromCoupleContracts() throws Exception { Decimal valueToSend = new Decimal(70); List<Contract> listOfCoinsWithAmount = createListOfCoinsWithAmount(Arrays.asList(50, 45)); List<Wallet> wallets = Wallet.determineWallets(listOfCoinsWithAmount); assertEquals(1, wallets.size()); assertEquals(2, wallets.get(0).getContracts().size()); //gonna send 70 but I have 2 contracts (50, 45) Wallet wallet = wallets.get(0); Contract contract = wallet.buildContractWithValue(FIELD_NAME, valueToSend); contract.addSignerKeyFromFile(PRIVATE_KEY_PATH); assertEquals(1, wallet.getContracts().size()); sealCheckTrace(contract, true); TransactionPack tp = contract.getTransactionPack(); Contract contractToSend = new Contract(contract.seal(), tp); contractToSend.addSignerKeyFromFile(PRIVATE_KEY_PATH); sealCheckTrace(contractToSend, true); assertEquals(valueToSend.intValue(), contractToSend.getStateData().getIntOrThrow(FIELD_NAME)); }
@Test(timeout = 90000) public void declinePaymentAndPaymentWithChangedData2() throws Exception { Set<PrivateKey> stepaPrivateKeys = new HashSet<>(); stepaPrivateKeys.add(new PrivateKey(Do.read(ROOT_PATH + "keys/stepan_mamontov.private.unikey"))); Contract uContract = getApprovedUContract(); // stepaPrivateKeys - is also U keys Contract paymentDecreased = uContract.createRevision(stepaPrivateKeys); paymentDecreased.getStateData().set("transaction_units", uContract.getStateData().getIntOrThrow("transaction_units") - 5); paymentDecreased.seal(); Contract modifiedU = paymentDecreased.createRevision(stepaPrivateKeys); modifiedU.getStateData().set("transaction_units", modifiedU.getStateData().getIntOrThrow("transaction_units") - 1); modifiedU.seal(); Parcel parcel = new Parcel(modifiedU.getTransactionPack(), paymentDecreased.getTransactionPack()); System.out.println("-------------"); node.registerParcel(parcel); synchronized (uContractLock) { uContract = parcel.getPaymentContract(); } waitAndCheckState(parcel, ItemState.UNDEFINED); }
@Test public void packAndUnpackWithKeys() throws Exception { TransactionPack tp = new TransactionPack(); tp.setContract(c); // tp.addKeys(publicKey); checkPackWithKeys(tp); assertSame(tp,c.getTransactionPack()); byte[] packedTp = tp.pack(); TransactionPack tp1 = TransactionPack.unpack(packedTp); checkPackWithKeys(tp1); }
@Test public void shouldTransferAndSplitRest() throws Exception { Decimal valueToSend = new Decimal(15); List<Contract> listOfCoinsWithAmount = createListOfCoinsWithAmount(Arrays.asList(1, 2, 3, 5, 8)); List<Wallet> wallets = Wallet.determineWallets(listOfCoinsWithAmount); assertEquals(1, wallets.size()); assertEquals(5, wallets.get(0).getContracts().size()); Wallet wallet = wallets.get(0); Contract contract = wallet.buildContractWithValue(FIELD_NAME, valueToSend); contract.addSignerKeyFromFile(PRIVATE_KEY_PATH); assertEquals(1, wallet.getContracts().size()); sealCheckTrace(contract, true); Contract restContract = wallet.getContracts().get(0); assertEquals(4, restContract.getStateData().getIntOrThrow(FIELD_NAME)); sealCheckTrace(restContract, true); contract.seal(); TransactionPack tp = contract.getTransactionPack(); Contract contractToSend = new Contract(contract.seal(), tp); contractToSend.addSignerKeyFromFile(PRIVATE_KEY_PATH); sealCheckTrace(contractToSend, true); assertEquals(valueToSend.intValue(), contractToSend.getStateData().getIntOrThrow(FIELD_NAME)); }
transactionRoot.getIssuer().addRequiredReference("ref1", Role.RequiredMode.ALL_OF); transactionRoot.seal(); transactionRoot.getTransactionPack().addReferencedItem(referencedContract2); transactionRoot.getTransactionPack().addReferencedItem(referencedContract); assertTrue(transactionRoot.check());
transactionRoot.addReference(rootReference); transactionRoot.seal(); transactionRoot.getTransactionPack().addReferencedItem(referencedContract);
transactionRoot.getIssuer().addRequiredReference("ref1", Role.RequiredMode.ALL_OF); transactionRoot.seal(); transactionRoot.getTransactionPack().addReferencedItem(referencedContract2); transactionRoot.getTransactionPack().addReferencedItem(referencedContract); assertTrue(transactionRoot.check());
@Test public void revokeDifferentNameValidRefRoleNotRegistered() throws Exception { Contract referencedContract = new Contract(key1); referencedContract.seal(); Contract revokingContract = new Contract(key2); Reference revokeReference = new Reference(revokingContract); revokeReference.setName("ref1"); ArrayList<String> revokeCondtitions = new ArrayList<>(); revokeCondtitions.add("ref.id=="+referencedContract.getId().toBase64String()); revokeReference.setConditions(Binder.of("all_of",revokeCondtitions)); revokingContract.addReference(revokeReference); SimpleRole role = new SimpleRole("@revoke"); role.addRequiredReference(revokeReference.getName(), Role.RequiredMode.ALL_OF); RevokePermission permission = new RevokePermission(role); revokingContract.addPermission(permission); revokingContract.seal(); Contract transactionRoot = new Contract(key3); transactionRoot.addRevokingItems(revokingContract); Reference rootReference = new Reference(transactionRoot); rootReference.setName("ref2"); ArrayList<String> rootConditions = new ArrayList<>(); rootConditions.add("ref.id=="+referencedContract.getId().toBase64String()); rootReference.setConditions(Binder.of("all_of",rootConditions)); transactionRoot.addReference(rootReference); transactionRoot.seal(); transactionRoot.getTransactionPack().addReferencedItem(referencedContract); transactionRoot = Contract.fromPackedTransaction(transactionRoot.getPackedTransaction()); transactionRoot.check(); assertTrue(transactionRoot.isOk()); }
transactionRoot.addReference(rootReference); transactionRoot.seal(); transactionRoot.getTransactionPack().addReferencedItem(referencedContract);
contract.getTransactionPack().addReferencedItem(goodReferencedContract);