From 4f469b2ab526d5a8f4ae895c0a1747fd59247b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Guti=C3=A9rrez?= Date: Wed, 13 Mar 2019 13:22:20 +0100 Subject: [PATCH] Use condition contracts hash generation to generate the signature. --- .../templates/AgreementTemplate.abstract.ts | 6 +- .../EscrowAccessSecretStoreTemplate.ts | 71 ++++++++----------- src/ocean/OceanAgreements.ts | 21 +++--- .../ServiceAgreements/ServiceAgreement.ts | 38 +--------- tsconfig.json | 3 +- 5 files changed, 50 insertions(+), 89 deletions(-) diff --git a/src/keeper/contracts/templates/AgreementTemplate.abstract.ts b/src/keeper/contracts/templates/AgreementTemplate.abstract.ts index 3f470b4..213a9be 100644 --- a/src/keeper/contracts/templates/AgreementTemplate.abstract.ts +++ b/src/keeper/contracts/templates/AgreementTemplate.abstract.ts @@ -3,7 +3,7 @@ import { AgreementStoreManager, ConditionStoreManager } from "../managers" import { Condition, ConditionState, conditionStateNames } from "../conditions/Condition.abstract" import Keeper from "../../Keeper" import { DDO } from '../../../ddo/DDO' -import { ServiceAgreementTemplate, ServiceAgreementTemplateCondition } from '../../../ddo/ServiceAgreementTemplate' +import { ServiceAgreementTemplate } from '../../../ddo/ServiceAgreementTemplate' import { zeroX, Logger } from "../../../utils" export abstract class AgreementTemplate extends ContractBase { @@ -53,9 +53,9 @@ export abstract class AgreementTemplate extends ContractBase { .map(address => keeper.getConditionByAddress(address)) } - abstract async getServiceAgreementTemplateValuesMap(ddo: DDO, agreementId: string, consumer: string): Promise<{[value: string]: string}> + abstract getAgreementIdsFromDDO(agreementId: string, ddo: DDO, from: string): Promise - abstract getServiceAgreementTemplate(): Promise + abstract async getServiceAgreementTemplate(): Promise public async getServiceAgreementTemplateConditions() { const serviceAgreementTemplate = await this.getServiceAgreementTemplate() diff --git a/src/keeper/contracts/templates/EscrowAccessSecretStoreTemplate.ts b/src/keeper/contracts/templates/EscrowAccessSecretStoreTemplate.ts index 567ab42..e8ae592 100644 --- a/src/keeper/contracts/templates/EscrowAccessSecretStoreTemplate.ts +++ b/src/keeper/contracts/templates/EscrowAccessSecretStoreTemplate.ts @@ -1,7 +1,6 @@ import { AgreementTemplate } from "./AgreementTemplate.abstract" import { LockRewardCondition, EscrowReward, AccessSecretStoreCondition } from '../conditions' import DIDRegistry from '../DIDRegistry' -import Keeper from "../../Keeper" import { DDO } from '../../../ddo/DDO' import { generateId, zeroX } from '../../../utils' @@ -56,32 +55,15 @@ export class EscrowAccessSecretStoreTemplate extends AgreementTemplate { * @return {Promise} Agreement ID. */ public async createFullAgreement(did: string, amount: number, from?: string): Promise { - from = await this.getFromAddress(from) - - const didRegistry = await DIDRegistry.getInstance() - - const accessSecretStoreCondition = await AccessSecretStoreCondition.getInstance() - const lockRewardCondition = await LockRewardCondition.getInstance() - const escrowReward = await EscrowReward.getInstance() - const agreementId = zeroX(generateId()) - const publisher = await didRegistry.getDIDOwner(did) + const {accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId} = + await this.createFullAgreementData(agreementId, did, amount, from) - const conditionIdAccess = await accessSecretStoreCondition.generateIdHash(agreementId, did, from) - const conditionIdLock = await lockRewardCondition.generateIdHash(agreementId, await escrowReward.getAddress(), amount) - const conditionIdEscrow = await escrowReward.generateIdHash( - agreementId, - amount, - from, - publisher, - conditionIdLock, - conditionIdAccess, - ) await this.createAgreement( agreementId, did, - [conditionIdAccess, conditionIdLock, conditionIdEscrow], + [accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId], [0, 0, 0], [0, 0, 0], from, @@ -90,31 +72,38 @@ export class EscrowAccessSecretStoreTemplate extends AgreementTemplate { return agreementId } - async getServiceAgreementTemplateValuesMap(ddo: DDO, agreementId: string, consumer: string): Promise<{[value: string]: string}> { - const keeper = await Keeper.getInstance() - const ddoOwner = ddo.proof && ddo.proof.creator - const amount = ddo.findServiceByType("Metadata").metadata.base.price + public async getAgreementIdsFromDDO(agreementId: string, ddo: DDO, from: string) { + const {accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId} = + await this.createFullAgreementData(agreementId, ddo.shortId(), ddo.findServiceByType("Metadata").metadata.base.price, from) + return [accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId] + } - let lockCondition - let releaseCondition + private async createFullAgreementData(agreementId: string, did: string, amount: number, from?: string) { + from = await this.getFromAddress(from) - try { - lockCondition = await keeper.conditions.lockRewardCondition.hashValues(ddoOwner, amount) - } catch(e) { } + const didRegistry = await DIDRegistry.getInstance() - try { - releaseCondition = await keeper.conditions.accessSecretStoreCondition.hashValues(ddo.shortId(), consumer) - } catch(e) { } + const accessSecretStoreCondition = await AccessSecretStoreCondition.getInstance() + const lockRewardCondition = await LockRewardCondition.getInstance() + const escrowReward = await EscrowReward.getInstance() + + const publisher = await didRegistry.getDIDOwner(did) + + const lockRewardConditionId = await lockRewardCondition.generateIdHash(agreementId, await escrowReward.getAddress(), amount) + const accessSecretStoreConditionId = await accessSecretStoreCondition.generateIdHash(agreementId, did, from) + const escrowRewardId = await escrowReward.generateIdHash( + agreementId, + amount, + from, + publisher, + lockRewardConditionId, + accessSecretStoreConditionId, + ) return { - rewardAddress: ddoOwner, - amount: amount.toString(), - documentId: ddo.shortId(), - grantee: consumer, - receiver: consumer, - sender: ddoOwner, - lockCondition, - releaseCondition, + lockRewardConditionId, + accessSecretStoreConditionId, + escrowRewardId, } } } diff --git a/src/ocean/OceanAgreements.ts b/src/ocean/OceanAgreements.ts index 4c43767..d0ba0f0 100644 --- a/src/ocean/OceanAgreements.ts +++ b/src/ocean/OceanAgreements.ts @@ -10,7 +10,7 @@ import { zeroX, didPrefixed } from "../utils" import OceanAgreementsConditions from "./OceanAgreementsConditions" -export interface AgreementPreparionResult { +export interface AgreementPrepareResult { agreementId: string signature: string } @@ -50,25 +50,30 @@ export default class OceanAgreements { * @param {string} did Decentralized ID. * @param {string} serviceDefinitionId Service definition ID. * @param {Account} consumer Consumer account. - * @return {Promise} Agreement ID and signaturee. + * @return {Promise} Agreement ID and signaturee. */ public async prepare( did: string, serviceDefinitionId: string, consumer: Account, - ): Promise { - const keeper = await Keeper.getInstance() - + ): Promise { const d: DID = DID.parse(did as string) const ddo = await AquariusProvider.getAquarius().retrieveDDO(d) const agreementId: string = generateId() + const keeper = await Keeper.getInstance() const templateName = ddo.findServiceByType("Access").serviceAgreementTemplate.contractName - const valuesMap = await keeper + const agreementConditionsIds = await keeper .getTemplateByName(templateName) - .getServiceAgreementTemplateValuesMap(ddo, agreementId, consumer.getId()) + .getAgreementIdsFromDDO(agreementId, ddo, consumer.getId()) - const signature = await ServiceAgreement.signServiceAgreement(ddo, serviceDefinitionId, agreementId, valuesMap, consumer) + const signature = await ServiceAgreement.signServiceAgreement( + ddo, + serviceDefinitionId, + agreementId, + agreementConditionsIds, + consumer, + ) return {agreementId, signature} } diff --git a/src/ocean/ServiceAgreements/ServiceAgreement.ts b/src/ocean/ServiceAgreements/ServiceAgreement.ts index a9027e6..c933ade 100644 --- a/src/ocean/ServiceAgreements/ServiceAgreement.ts +++ b/src/ocean/ServiceAgreements/ServiceAgreement.ts @@ -15,13 +15,11 @@ export default class ServiceAgreement { ddo: DDO, serviceDefinitionId: string, serviceAgreementId: string, - valuesMap: {[value: string]: string}, + agreementConditionsIds: string[], consumer: Account, ): Promise { const service = ddo.findServiceById<"Access">(serviceDefinitionId) - const values: ValuePair[][] = ServiceAgreement.getValuesFromService(service, valuesMap) - const valueHashes: string[] = ServiceAgreement.createValueHashes(values) const timelockValues: number[] = ServiceAgreement.getTimeValuesFromService(service, "timelock") const timeoutValues: number[] = ServiceAgreement.getTimeValuesFromService(service, "timeout") @@ -32,7 +30,7 @@ export default class ServiceAgreement { const serviceAgreementHashSignature = await ServiceAgreement.createHashSignature( service.templateId, serviceAgreementId, - valueHashes, + agreementConditionsIds, timelockValues, timeoutValues, consumer, @@ -65,27 +63,6 @@ export default class ServiceAgreement { return serviceAgreementHashSignature } - private static createValueHashes(parameterValuePairs: ValuePair[][]): string[] { - return parameterValuePairs - .map((valuePairs: ValuePair[]) => ServiceAgreement.hashValuePairArray(valuePairs)) - } - - private static hashValuePairArray(valuePairs: ValuePair[]): string { - let hash: string - try { - hash = (Web3Provider as any).getWeb3().utils.soliditySha3(...valuePairs).toString("hex") - } catch (err) { - Logger.error(`Hashing of ${JSON.stringify(valuePairs, null, 2)} failed.`) - throw err - } - - if (!hash) { - throw new Error("hashValuePairArray failed to create hash.") - } - - return hash - } - public static hashServiceAgreement( serviceAgreementTemplateId: string, serviceAgreementId: string, @@ -111,15 +88,4 @@ export default class ServiceAgreement { return timeoutValues } - - private static getValuesFromService(service: ServiceAccess, valuesMap: {[key: string]: string}): ValuePair[][] { - return (service.serviceAgreementTemplate.conditions || []) - .map(condition => - (condition.parameters || []) - .map(({type, name}) => ({ - type, - value: valuesMap[name.replace(/^_/, "")] || "", - })) - ) - } } diff --git a/tsconfig.json b/tsconfig.json index 959c147..2d5ab48 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,6 +25,7 @@ ], "exclude": [ "node_modules", - "**/*.test.ts" + "**/*.test.ts", + "src/examples" ] }