FollowerContract followerContract = new FollowerContract(); followerContract.setNodeInfoProvider(nodeInfoProvider); followerContract.setApiLevel(3); Contract.Definition cd = followerContract.getDefinition(); cd.setExpiresAt(followerContract.getCreatedAt().plusMonths(60)); followerContract.registerRole(issuerRole); followerContract.createRole("issuer", issuerRole); followerContract.createRole("creator", issuerRole); followerContract.registerRole(ownerRole); followerContract.createRole("owner", ownerRole); followerContract.addPermission(changeOwnerPerm); followerContract.addPermission(revokePerm1); followerContract.addPermission(revokePerm2); followerContract.addFollowerSpecific(); followerContract.seal(); followerContract.addSignatureToSeal(issuerKeys);
addError(Errors.FAILED_CHECK, "Environment should be not null"); return checkResult; checkResult = getExtendedType().equals(SmartContractType.FOLLOWER1.name()); if(!checkResult) { addError(Errors.FAILED_CHECK, "definition.extended_type", "illegal value, should be " + SmartContractType.FOLLOWER1.name() + " instead " + getExtendedType()); return checkResult; addError(Errors.FAILED_CHECK, "Tracking origin is missed"); return checkResult; checkResult = false; if(!checkResult) { addError(Errors.FAILED_CHECK, "Callback key for tracking origin is missed"); return checkResult;
@Override public boolean beforeCreate(ImmutableEnvironment c) { boolean checkResult = true; // recalculate prepaid origins*days without saving to state calculatePrepaidOriginDays(false); int paidU = getPaidU(); if(paidU == 0) { if(getPaidU(true) > 0) { addError(Errors.FAILED_CHECK, "Test payment is not allowed for follower contracts"); } checkResult = false; } else if(paidU < getMinPayment()) { addError(Errors.FAILED_CHECK, "Payment for follower contract is below minimum level of " + getMinPayment() + "U"); checkResult = false; } if(!checkResult) { addError(Errors.FAILED_CHECK, "Follower contract hasn't valid payment"); return checkResult; } // check that payment was not hacked checkResult = prepaidOriginDays == getStateData().getInt(PREPAID_OD_FIELD_NAME, 0); if(!checkResult) { addError(Errors.FAILED_CHECK, "Wrong [state.data." + PREPAID_OD_FIELD_NAME + "] value. " + "Should be sum of early paid U and paid U by current revision."); return checkResult; } // and call common follower check checkResult = additionallyFollowerCheck(c); return checkResult; }
@Override public boolean beforeUpdate(ImmutableEnvironment c) { boolean checkResult = false; // recalculate prepaid origins*days without saving to state calculatePrepaidOriginDays(false); // check that payment was not hacked checkResult = prepaidOriginDays == getStateData().getInt(PREPAID_OD_FIELD_NAME, 0); if(!checkResult) { addError(Errors.FAILED_CHECK, "Wrong [state.data." + PREPAID_OD_FIELD_NAME + "] value. " + "Should be sum of early paid U and paid U by current revision."); return checkResult; } // and call common follower check checkResult = additionallyFollowerCheck(c); return checkResult; }
followerContract.putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7781/follow.callback", callbackKey.getPublicKey()); if (!c.equals(followerContract)) { baseContract.getNewItems().remove(c); followerContract.addNewItems(c); followerContract.seal(); baseContract.seal(); break; followerContract.check(); followerContract.traceErrors(); assertTrue(followerContract.isOk()); assertEquals(NSmartContract.SmartContractType.FOLLOWER1.name(), followerContract.getDefinition().getExtendedType()); assertEquals(NSmartContract.SmartContractType.FOLLOWER1.name(), followerContract.get("definition.extended_type")); assertEquals(200 * config.getServiceRate(NSmartContract.SmartContractType.FOLLOWER1.name()).doubleValue(), followerContract.getPrepaidOriginsDays().doubleValue(), 0.1); uContract = followerContract.getNew().get(0); assertEquals(ItemState.APPROVED, node.waitItem(followerContract.getId(), 8000).state); assertEquals(ItemState.APPROVED, node.waitItem(followerContract.getNew().get(0).getId(), 8000).state); assertEquals(ItemState.APPROVED, node.waitItem(payingParcel.getPayload().getContract().getId(), 8000).state); assertEquals(ItemState.REVOKED, node.waitItem(payingParcel.getPayment().getContract().getId(), 8000).state); ItemResult itemResult = node.waitItem(followerContract.getId(), 8000); assertEquals("ok", itemResult.extraDataBinder.getBinder("onCreatedResult").getString("status", null)); assertEquals(followerContract.getCallbackKeys().get("http://localhost:7781/follow.callback"), callbackKey.getPublicKey());
followerContract.putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7785/follow.callback", callbackKey.getPublicKey()); Parcel payingParcel = ContractsService.createPayingParcel(followerContract.getTransactionPack(), payment, 1, 200, new HashSet<>(Arrays.asList(TestKeys.privateKey(1))), false); followerContract.check(); followerContract.traceErrors(); assertTrue(followerContract.isOk()); itemResult = testSpace.client.getState(followerContract.getId()); assertEquals("ok", itemResult.extraDataBinder.getBinder("onCreatedResult").getString("status", null)); assertEquals(ItemState.APPROVED, testSpace.client.getState(followerContract.getNew().get(0).getId()).state); assertEquals(ItemState.REVOKED, testSpace.client.getState(payingParcel.getPayment().getContract().getId()).state); payment = followerContract.getNew().get(0); FollowerContract newRevFollowerContract = (FollowerContract) followerContract.createRevision(key); newRevFollowerContract.setNodeInfoProvider(nodeInfoProvider); newRevFollowerContract.seal(); payingParcel = ContractsService.createPayingParcel(newRevFollowerContract.getTransactionPack(), payment, 1, 200, new HashSet<>(Arrays.asList(TestKeys.privateKey(1))), false); newRevFollowerContract.check(); newRevFollowerContract.traceErrors(); assertTrue(newRevFollowerContract.isOk()); itemResult = testSpace.client.getState(newRevFollowerContract.getId()); assertEquals("ok", itemResult.extraDataBinder.getBinder("onUpdateResult").getString("status", null));
Contract smartContract = new FollowerContract(key); ((FollowerContract)smartContract).setNodeInfoProvider(nodeInfoProvider); ((FollowerContract)smartContract).putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7777/follow.callback", callbackKey); assertEquals(((FollowerContract) smartContract).getCallbackKeys().get("http://localhost:7777/follow.callback"),callbackKey ); assertEquals(((FollowerContract) smartContract).getTrackingOrigins().get(simpleContract.getOrigin()), "http://localhost:7777/follow.callback"); assertTrue(((FollowerContract) smartContract).isOriginTracking(simpleContract.getOrigin())); assertTrue(((FollowerContract) smartContract).isCallbackURLUsed("http://localhost:7777/follow.callback")); newRevFollowerContract.putTrackingOrigin(simpleContract2.getOrigin(), "http://localhost:7777/follow.callbackTwo", callbackKey); newRevFollowerContract.setNodeInfoProvider(nodeInfoProvider); newRevFollowerContract.seal(); newRevFollowerContract.check(); newRevFollowerContract.traceErrors(); assertTrue(newRevFollowerContract.isOk()); assertEquals(NSmartContract.SmartContractType.FOLLOWER1.name(), newRevFollowerContract.getDefinition().getExtendedType()); assertEquals(NSmartContract.SmartContractType.FOLLOWER1.name(), newRevFollowerContract.get("definition.extended_type")); assertEquals(newRevFollowerContract.getCallbackKeys().get("http://localhost:7777/follow.callback"),callbackKey ); assertEquals(newRevFollowerContract.getTrackingOrigins().get(simpleContract.getOrigin()), "http://localhost:7777/follow.callback"); assertTrue(newRevFollowerContract.isOriginTracking(simpleContract.getOrigin())); assertTrue(newRevFollowerContract.isCallbackURLUsed("http://localhost:7777/follow.callback")); assertEquals(newRevFollowerContract.getCallbackKeys().get("http://localhost:7777/follow.callbackTwo"),callbackKey );
followerContract.putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7781/follow.callback", callbackKey.getPublicKey()); Parcel payingParcel = ContractsService.createPayingParcel(baseContract.getTransactionPack(), paymentContract, 1, nodeInfoProvider.getMinPayment(followerContract.getExtendedType()) - 1, stepaPrivateKeys, false); for (Contract c : baseContract.getNew()) if (!c.equals(followerContract)) { baseContract.getNewItems().remove(c); followerContract.addNewItems(c); followerContract.seal(); baseContract.seal(); break; followerContract.check(); followerContract.traceErrors(); assertTrue(followerContract.isOk()); assertEquals(NSmartContract.SmartContractType.FOLLOWER1.name(), followerContract.getDefinition().getExtendedType()); assertEquals(NSmartContract.SmartContractType.FOLLOWER1.name(), followerContract.get("definition.extended_type")); uContract = followerContract.getNew().get(0);
FollowerContract followerContract = new FollowerContract(followerKey); followerContract.setNodeInfoProvider(nodeInfoProvider); followerContract.putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7777/follow.callback", callbackKey.getPublicKey()); followerContract.seal(); assertFalse(followerContract.canFollowContract(simpleContract)); assertTrue(simpleContract.isOk()); assertTrue(followerContract.canFollowContract(simpleContract)); assertTrue(simpleContract.isOk()); assertFalse(followerContract.canFollowContract(simpleContract)); assertTrue(simpleContract.isOk()); assertTrue(followerContract.canFollowContract(simpleContract)); assertTrue(simpleContract.isOk()); assertFalse(followerContract.canFollowContract(simpleContract)); assertTrue(followerContract.canFollowContract(simpleContract)); assertFalse(followerContract.canFollowContract(simpleContract));
followerContract.setNodeInfoProvider(nodeInfoProvider); followerContract.putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7777/follow.callback", callbackKey.getPublicKey()); Parcel parcel = ContractsService.createPayingParcel(followerContract.getTransactionPack(), stepaU, 1, 200, new HashSet<>(Arrays.asList(TestKeys.privateKey(1))), false); Binder followerInfo = client.queryFollowerInfo(followerContract.getId()); System.out.println("follower info is null: " + (followerInfo == null)); assertNull(followerInfo); itemResult = client.getState(followerContract.getId()); System.out.println("follower : " + itemResult); assertEquals(ItemState.APPROVED, itemResult.state); followerInfo = client.queryFollowerInfo(followerContract.getId()); assertEquals(followerInfo.getInt("paid_U", 0),followerContract.getStateData().get("paid_U")); assertTrue(followerInfo.getDouble("prepaid_OD") == followerContract.getPrepaidOriginsDays().doubleValue()); assertEquals(followerInfo.getLong("prepaid_from", 0), followerContract.getStateData().get("prepaid_from")); assertEquals(followerInfo.getInt("followed_origins", 0), followerContract.getStateData().get("followed_origins")); assertEquals(followerInfo.getDouble("spent_OD"), followerContract.getStateData().get("spent_OD")); assertEquals(followerInfo.getLong("spent_OD_time", 0), followerContract.getStateData().get("spent_OD_time")); assertEquals(followerInfo.getDouble("callback_rate"), followerContract.getStateData().get("callback_rate")); assertEquals(followerInfo.getBinder("callback_keys").get("http://localhost:7777/follow.callback"), callbackKey.getPublicKey().pack()); assertEquals(followerInfo.getBinder("tracking_origins").get(simpleContract.getOrigin().toBase64String()), "http://localhost:7777/follow.callback"); assertEquals(followerContract.getCallbackKeys().get("http://localhost:7777/follow.callback"), callbackKey.getPublicKey()); assertEquals(followerContract.getTrackingOrigins().get(simpleContract.getOrigin()), "http://localhost:7777/follow.callback"); assertTrue(followerContract.isOriginTracking(simpleContract.getOrigin())); assertTrue(followerContract.isCallbackURLUsed("http://localhost:7777/follow.callback"));
Contract smartContract = new FollowerContract(key); ((FollowerContract)smartContract).setNodeInfoProvider(nodeInfoProvider); ((FollowerContract)smartContract).putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7777/follow.callback", callbackKey); assertEquals(((FollowerContract) smartContract).getCallbackKeys().get("http://localhost:7777/follow.callback"), callbackKey ); assertEquals(((FollowerContract) smartContract).getTrackingOrigins().get(simpleContract.getOrigin()), "http://localhost:7777/follow.callback"); assertTrue(((FollowerContract) smartContract).isOriginTracking(simpleContract.getOrigin())); assertTrue(((FollowerContract) smartContract).isCallbackURLUsed("http://localhost:7777/follow.callback")); assertFalse(((FollowerContract) smartContract).updateCallbackKey("http://localhost:8888/follow.callback", newCallbackKey.getPublicKey())); assertTrue(((FollowerContract) smartContract).updateCallbackKey("http://localhost:7777/follow.callback", newCallbackKey.getPublicKey())); assertEquals(((FollowerContract) smartContract).getCallbackKeys().get("http://localhost:7777/follow.callback"), newCallbackKey.getPublicKey()); assertNotEquals(((FollowerContract) smartContract).getCallbackKeys().get("http://localhost:7777/follow.callback"), callbackKey); assertEquals(((FollowerContract) smartContract).getTrackingOrigins().get(simpleContract.getOrigin()), "http://localhost:7777/follow.callback"); assertTrue(((FollowerContract) smartContract).isOriginTracking(simpleContract.getOrigin())); assertTrue(((FollowerContract) smartContract).isCallbackURLUsed("http://localhost:7777/follow.callback")); ((FollowerContract)smartContract).removeTrackingOrigin(simpleContract.getOrigin()); assertNotEquals(((FollowerContract) smartContract).getCallbackKeys().get("http://localhost:7777/follow.callback"), callbackKey ); assertNotEquals(((FollowerContract) smartContract).getTrackingOrigins().get(simpleContract.getOrigin()), "http://localhost:7777/follow.callback"); assertFalse(((FollowerContract) smartContract).isOriginTracking(simpleContract.getOrigin())); assertFalse(((FollowerContract) smartContract).isCallbackURLUsed("http://localhost:7777/follow.callback"));
PublicKey callbackKey = privateKey.getPublicKey(); Contract smartContract = new FollowerContract(key); ((FollowerContract)smartContract).setNodeInfoProvider(nodeInfoProvider); assertTrue(((ModifyDataPermission)mdp.iterator().next()).getFields().containsKey("action")); ((FollowerContract)desContract).putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7777/follow.callback", callbackKey); assertEquals(((FollowerContract) desContract).getCallbackKeys().get("http://localhost:7777/follow.callback"),callbackKey ); assertEquals(((FollowerContract) desContract).getTrackingOrigins().get(simpleContract.getOrigin()), "http://localhost:7777/follow.callback"); assertTrue(((FollowerContract) desContract).isOriginTracking(simpleContract.getOrigin())); assertTrue(((FollowerContract) desContract).isCallbackURLUsed("http://localhost:7777/follow.callback")); assertTrue(((ModifyDataPermission)mdp.iterator().next()).getFields().containsKey("action")); ((FollowerContract)copiedContract).putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7777/follow.callback", callbackKey); assertEquals(((FollowerContract) copiedContract).getCallbackKeys().get("http://localhost:7777/follow.callback"),callbackKey ); assertEquals(((FollowerContract) copiedContract).getTrackingOrigins().get(simpleContract.getOrigin()), "http://localhost:7777/follow.callback"); assertTrue(((FollowerContract) copiedContract).isOriginTracking(simpleContract.getOrigin())); assertTrue(((FollowerContract) copiedContract).isCallbackURLUsed("http://localhost:7777/follow.callback"));
PublicKey callbackKey = privateKey.getPublicKey(); Contract smartContract = FollowerContract.fromDslFile(rootPath + "FollowerDSLTemplate.yml"); smartContract.addSignerKeyFromFile(rootPath + "_xer0yfe2nn1xthc.private.unikey"); ((FollowerContract)smartContract).setNodeInfoProvider(nodeInfoProvider); ((FollowerContract)smartContract).putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7777/follow.callback", callbackKey); assertTrue(((ModifyDataPermission)mdp.iterator().next()).getFields().containsKey("action")); assertEquals(((FollowerContract) smartContract).getCallbackKeys().get("http://localhost:7777/follow.callback"),callbackKey ); assertEquals(((FollowerContract) smartContract).getTrackingOrigins().get(simpleContract.getOrigin()), "http://localhost:7777/follow.callback"); assertTrue(((FollowerContract) smartContract).isOriginTracking(simpleContract.getOrigin())); assertTrue(((FollowerContract) smartContract).isCallbackURLUsed("http://localhost:7777/follow.callback"));
paidU = getPaidU(); callbackRate = getRate("callback").doubleValue(); long wasPrepaidFrom = now.toEpochSecond(); long spentEarlyODsTimeSecs = now.toEpochSecond(); Contract parentContract = getRevokingItem(getParent()); if(parentContract != null) { wasPrepaidOriginDays = parentContract.getStateData().getDouble(PREPAID_OD_FIELD_NAME); prepaidOriginDays = wasPrepaidOriginDays + paidU * getRate().doubleValue(); getStateData().set(PAID_U_FIELD_NAME, paidU); getStateData().set(PREPAID_OD_FIELD_NAME, prepaidOriginDays); if(getRevision() == 1) getStateData().set(PREPAID_FROM_TIME_FIELD_NAME, now.toEpochSecond()); getStateData().set(FOLLOWED_ORIGINS_FIELD_NAME, trackingOrigins.size()); getStateData().set(SPENT_OD_FIELD_NAME, spentODs); getStateData().set(SPENT_OD_TIME_FIELD_NAME, spentODsTime.toEpochSecond()); getStateData().set(CALLBACK_RATE_FIELD_NAME, callbackRate);
if(getDefinition().getExtendedType() == null || !getDefinition().getExtendedType().equals(SmartContractType.FOLLOWER1.name())) getDefinition().setExtendedType(SmartContractType.FOLLOWER1.name()); registerRole(ownerLink); HashMap<String, Object> fieldsMap = new HashMap<>(); fieldsMap.put("action", null); Binder modifyDataParams = Binder.of("fields", fieldsMap); ModifyDataPermission modifyDataPermission = new ModifyDataPermission(ownerLink, modifyDataParams); addPermission(modifyDataPermission);
/** * Method creates {@link FollowerContract} contract from dsl file where contract is described. * * @param fileName is path to dsl file with yaml structure of data for contract. * @return created and ready {@link FollowerContract} contract. * @throws IOException if something went wrong */ public static FollowerContract fromDslFile(String fileName) throws IOException { Yaml yaml = new Yaml(); try (FileReader r = new FileReader(fileName)) { Binder binder = Binder.from(DefaultBiMapper.deserialize((Map) yaml.load(r))); return new FollowerContract().initializeWithDsl(binder); } }
private void saveTrackingOriginsToState() { Binder origins = new Binder(); for (Map.Entry<HashId, String> entry: trackingOrigins.entrySet()) { origins.set(entry.getKey().toBase64String(), entry.getValue()); } getStateData().set(TRACKING_ORIGINS_FIELD_NAME, origins); Binder callbacks = new Binder(); for (Map.Entry<String, PublicKey> entry: callbackKeys.entrySet()) { callbacks.set(entry.getKey(), entry.getValue().pack()); } getStateData().set(CALLBACK_KEYS_FIELD_NAME, callbacks); }
contract = new FollowerContract(bb, this); break;
/** * Follower contract is one of several types of smarts contracts that can be run on the node. Follower contract * provides paid of sending callbacks when registering a new contract (revision) in the chain. * <br><br> * Create a default empty new follower contract using a provided key as issuer and owner and sealer. Will set * follower's specific permissions and values. * <p> * This constructor adds key as sealing signature so it is ready to {@link #seal()} just after construction, thought * it is necessary to put real data to it first. It is allowed to change owner, expiration and data fields after * creation (but before sealing). * * @param key is {@link PrivateKey} for creating roles "issuer", "owner", "creator" and sign contract */ public FollowerContract(PrivateKey key) { super(key); addFollowerSpecific(); }
followerContract.putTrackingOrigin(simpleContract.getOrigin(), "http://localhost:7777/follow.callback", callbackKey.getPublicKey()); Parcel payingParcel = ContractsService.createPayingParcel(followerContract.getTransactionPack(), paymentContract, 1, 200, stepaPrivateKeys, false); followerContract.check(); followerContract.traceErrors(); assertTrue(followerContract.isOk()); assertEquals(NSmartContract.SmartContractType.FOLLOWER1.name(), followerContract.getDefinition().getExtendedType()); assertEquals(NSmartContract.SmartContractType.FOLLOWER1.name(), followerContract.get("definition.extended_type")); assertEquals(200 * config.getServiceRate(NSmartContract.SmartContractType.FOLLOWER1.name()).doubleValue(), followerContract.getPrepaidOriginsDays().doubleValue(), 0.1); Multimap<String, Permission> permissions = followerContract.getPermissions(); Collection<Permission> mdp = permissions.get("modify_data"); assertNotNull(mdp); assertTrue(((ModifyDataPermission)mdp.iterator().next()).getFields().containsKey("action")); assertEquals(followerContract.getCallbackKeys().get("http://localhost:7777/follow.callback"),callbackKey.getPublicKey()); assertEquals(followerContract.getTrackingOrigins().get(simpleContract.getOrigin()), "http://localhost:7777/follow.callback"); assertTrue(followerContract.isOriginTracking(simpleContract.getOrigin())); assertTrue(followerContract.isCallbackURLUsed("http://localhost:7777/follow.callback")); assertEquals(ItemState.APPROVED, node.waitItem(followerContract.getId(), 8000).state); assertEquals(ItemState.APPROVED, node.waitItem(followerContract.getNew().get(0).getId(), 8000).state); assertEquals(ItemState.REVOKED, node.waitItem(payingParcel.getPayment().getContract().getId(), 8000).state);