1
0
mirror of https://github.com/oceanprotocol-archive/squid-js.git synced 2024-02-02 15:31:51 +01:00

Use condition contracts hash generation to generate the signature.

This commit is contained in:
Pedro Gutiérrez 2019-03-13 13:22:20 +01:00 committed by Pedro Gutiérrez
parent f8b3d839eb
commit 4f469b2ab5
5 changed files with 50 additions and 89 deletions

View File

@ -3,7 +3,7 @@ import { AgreementStoreManager, ConditionStoreManager } from "../managers"
import { Condition, ConditionState, conditionStateNames } from "../conditions/Condition.abstract" import { Condition, ConditionState, conditionStateNames } from "../conditions/Condition.abstract"
import Keeper from "../../Keeper" import Keeper from "../../Keeper"
import { DDO } from '../../../ddo/DDO' import { DDO } from '../../../ddo/DDO'
import { ServiceAgreementTemplate, ServiceAgreementTemplateCondition } from '../../../ddo/ServiceAgreementTemplate' import { ServiceAgreementTemplate } from '../../../ddo/ServiceAgreementTemplate'
import { zeroX, Logger } from "../../../utils" import { zeroX, Logger } from "../../../utils"
export abstract class AgreementTemplate extends ContractBase { export abstract class AgreementTemplate extends ContractBase {
@ -53,9 +53,9 @@ export abstract class AgreementTemplate extends ContractBase {
.map(address => keeper.getConditionByAddress(address)) .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<string[]>
abstract getServiceAgreementTemplate(): Promise<ServiceAgreementTemplate> abstract async getServiceAgreementTemplate(): Promise<ServiceAgreementTemplate>
public async getServiceAgreementTemplateConditions() { public async getServiceAgreementTemplateConditions() {
const serviceAgreementTemplate = await this.getServiceAgreementTemplate() const serviceAgreementTemplate = await this.getServiceAgreementTemplate()

View File

@ -1,7 +1,6 @@
import { AgreementTemplate } from "./AgreementTemplate.abstract" import { AgreementTemplate } from "./AgreementTemplate.abstract"
import { LockRewardCondition, EscrowReward, AccessSecretStoreCondition } from '../conditions' import { LockRewardCondition, EscrowReward, AccessSecretStoreCondition } from '../conditions'
import DIDRegistry from '../DIDRegistry' import DIDRegistry from '../DIDRegistry'
import Keeper from "../../Keeper"
import { DDO } from '../../../ddo/DDO' import { DDO } from '../../../ddo/DDO'
import { generateId, zeroX } from '../../../utils' import { generateId, zeroX } from '../../../utils'
@ -56,32 +55,15 @@ export class EscrowAccessSecretStoreTemplate extends AgreementTemplate {
* @return {Promise<string>} Agreement ID. * @return {Promise<string>} Agreement ID.
*/ */
public async createFullAgreement(did: string, amount: number, from?: string): Promise<string> { public async createFullAgreement(did: string, amount: number, from?: string): Promise<string> {
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 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( await this.createAgreement(
agreementId, agreementId,
did, did,
[conditionIdAccess, conditionIdLock, conditionIdEscrow], [accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId],
[0, 0, 0], [0, 0, 0],
[0, 0, 0], [0, 0, 0],
from, from,
@ -90,31 +72,38 @@ export class EscrowAccessSecretStoreTemplate extends AgreementTemplate {
return agreementId return agreementId
} }
async getServiceAgreementTemplateValuesMap(ddo: DDO, agreementId: string, consumer: string): Promise<{[value: string]: string}> { public async getAgreementIdsFromDDO(agreementId: string, ddo: DDO, from: string) {
const keeper = await Keeper.getInstance() const {accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId} =
const ddoOwner = ddo.proof && ddo.proof.creator await this.createFullAgreementData(agreementId, ddo.shortId(), ddo.findServiceByType("Metadata").metadata.base.price, from)
const amount = ddo.findServiceByType("Metadata").metadata.base.price return [accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId]
}
let lockCondition private async createFullAgreementData(agreementId: string, did: string, amount: number, from?: string) {
let releaseCondition from = await this.getFromAddress(from)
try { const didRegistry = await DIDRegistry.getInstance()
lockCondition = await keeper.conditions.lockRewardCondition.hashValues(ddoOwner, amount)
} catch(e) { }
try { const accessSecretStoreCondition = await AccessSecretStoreCondition.getInstance()
releaseCondition = await keeper.conditions.accessSecretStoreCondition.hashValues(ddo.shortId(), consumer) const lockRewardCondition = await LockRewardCondition.getInstance()
} catch(e) { } 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 { return {
rewardAddress: ddoOwner, lockRewardConditionId,
amount: amount.toString(), accessSecretStoreConditionId,
documentId: ddo.shortId(), escrowRewardId,
grantee: consumer,
receiver: consumer,
sender: ddoOwner,
lockCondition,
releaseCondition,
} }
} }
} }

View File

@ -10,7 +10,7 @@ import { zeroX, didPrefixed } from "../utils"
import OceanAgreementsConditions from "./OceanAgreementsConditions" import OceanAgreementsConditions from "./OceanAgreementsConditions"
export interface AgreementPreparionResult { export interface AgreementPrepareResult {
agreementId: string agreementId: string
signature: string signature: string
} }
@ -50,25 +50,30 @@ export default class OceanAgreements {
* @param {string} did Decentralized ID. * @param {string} did Decentralized ID.
* @param {string} serviceDefinitionId Service definition ID. * @param {string} serviceDefinitionId Service definition ID.
* @param {Account} consumer Consumer account. * @param {Account} consumer Consumer account.
* @return {Promise<AgreementPreparionResult>} Agreement ID and signaturee. * @return {Promise<AgreementPrepareResult>} Agreement ID and signaturee.
*/ */
public async prepare( public async prepare(
did: string, did: string,
serviceDefinitionId: string, serviceDefinitionId: string,
consumer: Account, consumer: Account,
): Promise<AgreementPreparionResult> { ): Promise<AgreementPrepareResult> {
const keeper = await Keeper.getInstance()
const d: DID = DID.parse(did as string) const d: DID = DID.parse(did as string)
const ddo = await AquariusProvider.getAquarius().retrieveDDO(d) const ddo = await AquariusProvider.getAquarius().retrieveDDO(d)
const agreementId: string = generateId() const agreementId: string = generateId()
const keeper = await Keeper.getInstance()
const templateName = ddo.findServiceByType("Access").serviceAgreementTemplate.contractName const templateName = ddo.findServiceByType("Access").serviceAgreementTemplate.contractName
const valuesMap = await keeper const agreementConditionsIds = await keeper
.getTemplateByName(templateName) .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} return {agreementId, signature}
} }

View File

@ -15,13 +15,11 @@ export default class ServiceAgreement {
ddo: DDO, ddo: DDO,
serviceDefinitionId: string, serviceDefinitionId: string,
serviceAgreementId: string, serviceAgreementId: string,
valuesMap: {[value: string]: string}, agreementConditionsIds: string[],
consumer: Account, consumer: Account,
): Promise<string> { ): Promise<string> {
const service = ddo.findServiceById<"Access">(serviceDefinitionId) 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 timelockValues: number[] = ServiceAgreement.getTimeValuesFromService(service, "timelock")
const timeoutValues: number[] = ServiceAgreement.getTimeValuesFromService(service, "timeout") const timeoutValues: number[] = ServiceAgreement.getTimeValuesFromService(service, "timeout")
@ -32,7 +30,7 @@ export default class ServiceAgreement {
const serviceAgreementHashSignature = await ServiceAgreement.createHashSignature( const serviceAgreementHashSignature = await ServiceAgreement.createHashSignature(
service.templateId, service.templateId,
serviceAgreementId, serviceAgreementId,
valueHashes, agreementConditionsIds,
timelockValues, timelockValues,
timeoutValues, timeoutValues,
consumer, consumer,
@ -65,27 +63,6 @@ export default class ServiceAgreement {
return serviceAgreementHashSignature 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( public static hashServiceAgreement(
serviceAgreementTemplateId: string, serviceAgreementTemplateId: string,
serviceAgreementId: string, serviceAgreementId: string,
@ -111,15 +88,4 @@ export default class ServiceAgreement {
return timeoutValues 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(/^_/, "")] || "",
}))
)
}
} }

View File

@ -25,6 +25,7 @@
], ],
"exclude": [ "exclude": [
"node_modules", "node_modules",
"**/*.test.ts" "**/*.test.ts",
"src/examples"
] ]
} }