Skip to content

Commit

Permalink
Corrected legacy DID mapping storage
Browse files Browse the repository at this point in the history
Signed-off-by: artem.ivanov <[email protected]>
  • Loading branch information
Artemkaaas committed Feb 19, 2024
1 parent fe96be9 commit 814f564
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 52 deletions.
2 changes: 1 addition & 1 deletion examples/migration/src/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use indy_vdr::{
utils::did::DidValue,
};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use serde_json::json;
use std::{env, fs, str::FromStr, time::Duration};

pub enum Ledgers {
Expand Down
6 changes: 5 additions & 1 deletion network/config/besu/genesis.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion network/config/nodes/validator5/key
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0x07ea290d6bbf126219bdc300a3297528833af27e0e10355e2d2d8a76f04045af
0x93945e32f8cb4afb4275cb014b363ccc794b0991eeab810ceadcaedf400d8c28
21 changes: 16 additions & 5 deletions smart_contracts/contracts-ts/LegacyMappingRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@ export class LegacyMappingRegistry extends Contract {

public async createDidMapping(
identity: string,
identifier: string,
legacyIdentifier: string,
newDid: string,
ed25519Key: Uint8Array,
ed25519Signature: Uint8Array,
) {
const tx = await this.instance.createDidMapping(identity, identifier, ed25519Key, ed25519Signature)
const tx = await this.instance.createDidMapping(identity, legacyIdentifier, newDid, ed25519Key, ed25519Signature)
return tx.wait()
}

public async createDidMappingSigned(
identity: string,
identifier: string,
legacyIdentifier: string,
newDid: string,
ed25519Key: Uint8Array,
ed25519Signature: Uint8Array,
signature: Signature,
Expand All @@ -28,7 +30,8 @@ export class LegacyMappingRegistry extends Contract {
signature.v,
signature.r,
signature.s,
identifier,
legacyIdentifier,
newDid,
ed25519Key,
ed25519Signature,
)
Expand Down Expand Up @@ -82,12 +85,20 @@ export class LegacyMappingRegistry extends Contract {
identity: string,
privateKey: Uint8Array,
identifier: string,
issuerDid: string,
ed25519Key: Uint8Array,
ed25519Signature: Uint8Array,
) {
return this.signEndorsementData(
privateKey,
concat([identity, toUtf8Bytes('createDidMapping'), toUtf8Bytes(identifier), ed25519Key, ed25519Signature]),
concat([
identity,
toUtf8Bytes('createDidMapping'),
toUtf8Bytes(identifier),
toUtf8Bytes(issuerDid),
ed25519Key,
ed25519Signature,
]),
)
}

Expand Down
6 changes: 6 additions & 0 deletions smart_contracts/contracts/migration/LegacyMappingErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ pragma solidity ^0.8.20;
*/
error DidMappingAlreadyExist(string identifier);

/**
* @notice Error that occurs when DID mapping does not exist.
* @param identifier Legacy DID identifier.
*/
error DidMappingDoesNotExist(string identifier);

/**
* @notice Error that occurs when trying to add a duplicating mapping for a legacy resource identifier.
* @param identifier Legacy Schema/CredDef identifier.
Expand Down
55 changes: 37 additions & 18 deletions smart_contracts/contracts/migration/LegacyMappingRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
pragma solidity ^0.8.20;

import { ControlledUpgradeable } from "../upgrade/ControlledUpgradeable.sol";
import { DidMappingAlreadyExist, ResourceMappingAlreadyExist, InvalidEd25519Key, InvalidResourceId } from "./LegacyMappingErrors.sol";
import { NotIdentityOwner } from "../did/DidErrors.sol";
import { DidMappingAlreadyExist, ResourceMappingAlreadyExist, InvalidEd25519Key, InvalidResourceId, DidMappingDoesNotExist } from "./LegacyMappingErrors.sol";
import { NotIdentityOwner, IncorrectDid } from "../did/DidErrors.sol";
import { UniversalDidResolverInterface } from "../did/UniversalDidResolverInterface.sol";
import { LegacyMappingRegistryInterface } from "./LegacyMappingRegistryInterface.sol";
import { RoleControlInterface } from "../auth/RoleControl.sol";
import { DidUtils } from "../did/DidUtils.sol";

import { Base58 } from "../utils/Base58.sol";
import { toSlice } from "@dk1a/solidity-stringutils/src/StrSlice.sol";
import { toSlice, isEmpty } from "@dk1a/solidity-stringutils/src/StrSlice.sol";

using { toSlice } for string;

Expand All @@ -21,11 +22,10 @@ contract LegacyMappingRegistry is LegacyMappingRegistryInterface, ControlledUpgr

RoleControlInterface internal _roleControl;

// FIXME: Now, since we have `indybesu` and `ethr` DID methods having account as identifier we need to change value of `didMapping`
/*
* Mapping storing indy/sov DID identifiers to the corresponding account address
*/
mapping(string legacyDid => address account) public didMapping;
mapping(string legacyDid => string did) public didMapping;

/*
* Mapping storing indy/sov formatted identifiers of schema/credential-definition to the corresponding new form
Expand Down Expand Up @@ -61,11 +61,12 @@ contract LegacyMappingRegistry is LegacyMappingRegistryInterface, ControlledUpgr
/// @inheritdoc LegacyMappingRegistryInterface
function createDidMapping(
address identity,
string calldata identifier,
string calldata legacyIdentifier,
string calldata newDid,
bytes32 ed25519Key,
bytes calldata ed25519Signature
) public virtual {
_createDidMapping(identity, msg.sender, identifier, ed25519Key, ed25519Signature);
_createDidMapping(identity, msg.sender, legacyIdentifier, newDid, ed25519Key, ed25519Signature);
}

/// @inheritdoc LegacyMappingRegistryInterface
Expand All @@ -74,7 +75,8 @@ contract LegacyMappingRegistry is LegacyMappingRegistryInterface, ControlledUpgr
uint8 sigV,
bytes32 sigR,
bytes32 sigS,
string calldata identifier,
string calldata legacyIdentifier,
string calldata newDid,
bytes32 ed25519Key,
bytes calldata ed25518Signature
) public virtual {
Expand All @@ -85,12 +87,20 @@ contract LegacyMappingRegistry is LegacyMappingRegistryInterface, ControlledUpgr
address(this),
identity,
"createDidMapping",
identifier,
legacyIdentifier,
newDid,
ed25519Key,
ed25518Signature
)
);
_createDidMapping(identity, ecrecover(hash, sigV, sigR, sigS), identifier, ed25519Key, ed25518Signature);
_createDidMapping(
identity,
ecrecover(hash, sigV, sigR, sigS),
legacyIdentifier,
newDid,
ed25519Key,
ed25518Signature
);
}

/// @inheritdoc LegacyMappingRegistryInterface
Expand Down Expand Up @@ -137,20 +147,24 @@ contract LegacyMappingRegistry is LegacyMappingRegistryInterface, ControlledUpgr
function _createDidMapping(
address identity,
address actor,
string calldata identifier,
string calldata legacyIdentifier,
string calldata newDid,
bytes32 ed25519Key,
bytes calldata ed25518Signature
) internal _identityOwner(identity, actor) _senderIsTrusteeOrEndorserOrSteward {
// Checks the uniqueness of the DID mapping
if (didMapping[identifier] != address(0x00)) revert DidMappingAlreadyExist(identifier);
if (!isEmpty(didMapping[legacyIdentifier].toSlice())) revert DidMappingAlreadyExist(legacyIdentifier);

// Checks that Ed25519 key matches to the legacy DID identifier
if (bytes16(Base58.decodeFromString(identifier)) != bytes16(ed25519Key))
revert InvalidEd25519Key(ed25519Key, identifier);
if (bytes16(Base58.decodeFromString(legacyIdentifier)) != bytes16(ed25519Key))
revert InvalidEd25519Key(ed25519Key, legacyIdentifier);

if (identity != DidUtils.convertEthereumIdentifierToAddress(DidUtils.parseDid(newDid).identifier))
revert IncorrectDid(newDid);

// TODO: check ed25519 signature validity
didMapping[identifier] = identity;
emit DidMappingCreated(identifier, identity);
didMapping[legacyIdentifier] = newDid;
emit DidMappingCreated(legacyIdentifier, newDid);
}

function _createResourceMapping(
Expand All @@ -163,9 +177,14 @@ contract LegacyMappingRegistry is LegacyMappingRegistryInterface, ControlledUpgr
// Checks the uniqueness of the Resource mapping
if (bytes(resourceMapping[legacyIdentifier]).length != 0) revert ResourceMappingAlreadyExist(legacyIdentifier);

// Check that DID mapping was created
if (isEmpty(didMapping[legacyIssuerIdentifier].toSlice())) revert DidMappingDoesNotExist(legacyIdentifier);

// Checks that owner of legacy DID controlled by identity account
if (identity != didMapping[legacyIssuerIdentifier])
revert NotIdentityOwner(identity, didMapping[legacyIssuerIdentifier]);
address owner = DidUtils.convertEthereumIdentifierToAddress(
DidUtils.parseDid(didMapping[legacyIssuerIdentifier]).identifier
);
if (identity != owner) revert NotIdentityOwner(identity, owner);

// Checks that legacy issuer identifier is included into resource identifier
if (!legacyIdentifier.toSlice().contains(legacyIssuerIdentifier.toSlice()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ interface LegacyMappingRegistryInterface {
/**
* @dev Event that is sent when a DID mapping is created.
*
* @param identifier legacy DID identifier.
* @param identity Corresponding account address of DID owner.
* @param legacyIdentifier legacy DID identifier.
* @param newDid Corresponding new did.
*/
event DidMappingCreated(string identifier, address identity);
event DidMappingCreated(string legacyIdentifier, string newDid);

/**
* @dev Event that is sent when a new Resource (SchemaId/CredentialDefinitionId) mapping is created.
Expand All @@ -26,18 +26,21 @@ interface LegacyMappingRegistryInterface {
*
* This function can revert with following errors:
* - `MappingAlreadyExist`: Raised if DID mapping with provided identifier already exist.
* - `IncorrectDid`: New DID does not match to identity
* - `InvalidEd25519Key`: Raised if provided ED25519 verification key does not match to the DID identifier.
* - `NotIdentityOwner`: Raised if sender account is not owner of the provided identity.
* - `Unauthorized`: Raised if sender account does not have non of the roles assigned: TRUSTEE, ENDORSER, STEWARD.
*
* @param identity Account address of the DID's owner.
* @param identifier legacy DID identifier.
* @param ed25519Key Ed25519 verification key of the legacy DID identifier.
* @param ed25519Signature ED25519 signature to prove key possession.
* @param identity Account address of the DID's owner.
* @param legacyIdentifier legacy DID identifier.
* @param newDid Corresponding new did.
* @param ed25519Key Ed25519 verification key of the legacy DID identifier.
* @param ed25519Signature ED25519 signature to prove key possession.
*/
function createDidMapping(
address identity,
string calldata identifier,
string calldata legacyIdentifier,
string calldata newDid,
bytes32 ed25519Key,
bytes calldata ed25519Signature
) external;
Expand All @@ -50,6 +53,7 @@ interface LegacyMappingRegistryInterface {
*
* This function can revert with following errors:
* - `MappingAlreadyExist`: Raised if DID mapping with provided identifier already exist.
* - `IncorrectDid`: New DID does not match to identity
* - `InvalidEd25519Key`: Raised if provided ED25519 verification key does not match to the DID identifier.
* - `NotIdentityOwner`: Raised if signer account is not owner of the provided identity
* - `Unauthorized`: Raised if sender account does not have non of the roles assigned: TRUSTEE, ENDORSER, STEWARD.
Expand All @@ -58,7 +62,8 @@ interface LegacyMappingRegistryInterface {
* @param sigV Part of EcDSA signature.
* @param sigR Part of EcDSA signature.
* @param sigS Part of EcDSA signature.
* @param identifier legacy DID identifier.
* @param legacyIdentifier legacy DID identifier.
* @param newDid Corresponding new did.
* @param ed25519Key Ed25519 verification key of the legacy DID identifier.
* @param ed25519Signature ED25519 signature to prove key possession.
*/
Expand All @@ -67,7 +72,8 @@ interface LegacyMappingRegistryInterface {
uint8 sigV,
bytes32 sigR,
bytes32 sigS,
string calldata identifier,
string calldata legacyIdentifier,
string calldata newDid,
bytes32 ed25519Key,
bytes calldata ed25519Signature
) external;
Expand Down
Loading

0 comments on commit 814f564

Please sign in to comment.