Skip to content

Commit

Permalink
feat: Proxy upgrade through uups proxy
Browse files Browse the repository at this point in the history
- store contract bytecode
- all test passing
- Proxy deployment to 0xd1D374DDE031075157fDb64536eF5cC13Ae75000
- README.md update
  • Loading branch information
jac18281828 committed Dec 6, 2023
1 parent f416855 commit a5936e9
Show file tree
Hide file tree
Showing 21 changed files with 452 additions and 137 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
path = packages/did-eth-registry/lib/forge-std
url = https://github.com/foundry-rs/forge-std
branch = v1.6.1
[submodule "packages/did-eth-registry/lib/openzeppelin-contracts"]
path = packages/did-eth-registry/lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
14 changes: 8 additions & 6 deletions packages/did-eth-registry/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@
"JuanBlanco.solidity"
]
}
},
"containerEnv": {
"PRIVATE_KEY": "${localEnv:PRIVATE_KEY}",
"PUBLIC_KEY": "${localEnv:PUBLIC_KEY}",
"GOERLI_URL": "${localEnv:GOERLI_URL}",
"RPC_URL": "${localEnv:RPC_URL}",
"ETHERSCAN_API_KEY": "${localEnv:ETHERSCAN_API_KEY}"
}

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Uncomment the next line to run commands after the container is created.
// "postCreateCommand": "cat /etc/os-release",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "devcontainer"
}
}
2 changes: 2 additions & 0 deletions packages/did-eth-registry/.dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ build/
typechain/
typechain-types/
dist/
EIP1056Registry.json
DIDRegistry.bin
6 changes: 6 additions & 0 deletions packages/did-eth-registry/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,9 @@ dist
.svelte-kit

# End of https://www.toptal.com/developers/gitignore/api/node,intellij

broadcast/

EIP1056Registry.json
EIP1056RegistryProxy.bin
DIDRegistry.bin
2 changes: 1 addition & 1 deletion packages/did-eth-registry/.solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"rules": {
"compiler-version": [
"error",
"^0.8.15"
"^0.8.20"
],
"func-visibility": [
"warn",
Expand Down
91 changes: 91 additions & 0 deletions packages/did-eth-registry/.vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,97 @@
"isDefault": false
}
},
{
"label": "dumpregistry",
"type": "shell",
"command": "yarn dumpregistry",
"options": {
"cwd": "${workspaceFolder}"
},
"dependsOn": "test",
"group": {
"kind": "test",
"isDefault": false
}
},
{
"label": "dumpproxy",
"type": "shell",
"command": "yarn dumpproxy",
"options": {
"cwd": "${workspaceFolder}",
"env": {
"CONTRACT_ROLE_ADMIN": "0x6CEb0bF1f28ca4165d5C0A04f61DC733987eD6ad",
"REGISTRY_ADDRESS": "0xD1D8360742139fD76C16c397A4d5ECA9E2A73c4b"
}
},
"dependsOn": "test",
"group": {
"kind": "test",
"isDefault": false
}
},
{
"label": "registryaddress",
"type": "shell",
"command": "yarn registryaddress",
"options": {
"cwd": "${workspaceFolder}"
},
"dependsOn": "dumpregistry",
"group": {
"kind": "test",
"isDefault": false
}
},
{
"label": "vanity",
"type": "shell",
"command": "yarn vanity",
"options": {
"cwd": "${workspaceFolder}"
},
"dependsOn": "dumpproxy",
"group": {
"kind": "test",
"isDefault": false
}
},
{
"label": "deployregistry",
"type": "shell",
"command": "forge script ./script/DeployRegistry.s.sol:DeployRegistry --sig 'deploy()' --slow --broadcast --rpc-url ${GOERLI_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify",
"options": {
"cwd": "${workspaceFolder}",
"env": {
"CONTRACT_ROLE_ADMIN": "0x6CEb0bF1f28ca4165d5C0A04f61DC733987eD6ad",
"CONTRACT_ROLE_UPGRADE": "0x6CEb0bF1f28ca4165d5C0A04f61DC733987eD6ad,0x22A653801bB0bb85BE38765cC072144736635eE8",
"CONTRACT_SALT": "0xa650bcc7b18a1b8ee999056c89f3adbe79f5c69bcc68f164e9760a0e0e1b5960",
"REGISTRY_SALT": "0xa3cf9c5bc4043744d6ce20e743000b2a92113cff47d618a20365366f8729a5ba"
}
},
"dependsOn": "test",
"group": {
"kind": "test",
"isDefault": false
},
},
{
"label": "upgraderegistry",
"type": "shell",
"command": "forge script ./script/DeployRegistry.s.sol:DeployRegistry --sig 'upgrade()' --slow --broadcast --rpc-url ${RPC_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify",
"options": {
"cwd": "${workspaceFolder}",
"env": {
"PROXY_ADDRESS": "0xd1D374DDE031075157fDb64536eF5cC13Ae75000"
}
},
"dependsOn": "test",
"group": {
"kind": "test",
"isDefault": false
},
},
{
"label": "gas",
"type": "shell",
Expand Down
86 changes: 70 additions & 16 deletions packages/did-eth-registry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,14 @@ needed. The list of delegateTypes to include is still to be determined.
Iterate through `DIDAttributeChanged` events for service entries, encrypted public keys, and other public names. The
attribute names are still to be determined.

## Quick Start
## Deployment Address

| Contract | Ethereum Address | Network |
| --------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------ |
| EIP1056Registry | 0xd1D374DDE031075157fDb64536eF5cC13Ae75000 | [Sepolia](https://sepolia.etherscan.io/address/0xd1d374dde031075157fdb64536ef5cc13ae75000) |
| EIP1056Registry | 0xd1D374DDE031075157fDb64536eF5cC13Ae75000 | [Görli](https://goerli.etherscan.io/address/0xd1d374dde031075157fdb64536ef5cc13ae75000) |

## Quick Start (Development)

### Submodules

Expand All @@ -314,9 +321,9 @@ First, init submodules from the project root
$ git submodule update --recursive --init -f
```

### Registry Development
### Dev Containers Development

This contract supports containerized development. From Visual Studio Code Remote Containers extension
This contract supports containerized development. From Visual Studio Code Dev Containers extension

`Reopen in Container`

Expand All @@ -328,28 +335,75 @@ Command line build using docker
$ docker build packages/did-eth-registry -t did-eth:1
```

## Deploy contract
## Testing the Contracts

First run,
From the containerized environment:

```bash
$ scripts/generateDeployTxs.js
$ yarn install --frozen-lockfile
$ yarn prettier:check
$ yarn lint
$ forge test -vvv
```

You will get the data needed to deploy as an output from this command.
## Initial Deployment

Copy the `senderAddress` and send `cost` amount of ether to that address on the Ethereum network you wish to deploy to.
### Using vanity address

Once this funding transaction is confirmed, simply send the `rawTx` to the same network.
`contractAddress` is the address of the deployed contract.
1\. dump out registry init code

`chainId` is intentionally not used in the transaction to make it simpler to deploy to the same address on all networks.
```bash
$ yarn dumpregistry
```

## Testing the Contracts
2\. compute the address for the registry

```bash
$ yarn install --frozen-lockfile
$ yarn prettier:check
$ yarn lint
$ forge test -v
$ yarn registryaddress
```

Make a note of the registry address and registry salt. Convert the salt to a 32 byte hex string using `cast --tobase`

```bash
$ cast --to-base 74093810807909736385031531802484957602545215186873255285560364360670735082938 16
0xa3cf9c5bc4043744d6ce20e743000b2a92113cff47d618a20365366f8729a5ba
```

3\. dump out the proxy init code

```bash
CONTRACT_ROLE_ADMIN=0x521DBc90a1687d0ed050Cf4ba47d5A04d8253f46 \
REGISTRY_ADDRESS=0xD1D8360742139fD76C16c397A4d5ECA9E2A73c4b \
yarn dumpproxy
```

4\. run the create2 function to choose a vanity address for the proxy

```bash
$ yarn vanity
```

Make a note of the salt for the proxy contract. Convert the salt to a 32 byte hex string using cast --to-base

```bash
cast --to-base 75226583542044164422273476230409956855417563147003477807955548159938739788128 16
0xa650bcc7b18a1b8ee999056c89f3adbe79f5c69bcc68f164e9760a0e0e1b5960
```

5. Deploy the registry and proxy

```bash
$ CONTRACT_ROLE_ADMIN=0x521DBc90a1687d0ed050Cf4ba47d5A04d8253f46 \
CONTRACT_ROLE_UPGRADE="0x521DBc90a1687d0ed050Cf4ba47d5A04d8253f46,0x2746bC0bE84D7CC9A63526C02746d12FA20621F3" \
CONTRACT_SALT=0xa650bcc7b18a1b8ee999056c89f3adbe79f5c69bcc68f164e9760a0e0e1b5960 \
REGISTRY_SALT=0xa3cf9c5bc4043744d6ce20e743000b2a92113cff47d618a20365366f8729a5ba \
forge script ./script/DeployRegistry.s.sol:DeployRegistry --sig 'deploy()' --slow --broadcast --rpc-url ${RPC_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify
```

### Upgrade Deployment

Post initial deployment, the contract can be upgraded directly through the [UUPSUpgradeable](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) interface

```solidity
registry.upgradeToAndCall(address(logic), "");
```
40 changes: 38 additions & 2 deletions packages/did-eth-registry/contracts/DIDRegistry.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.15;
pragma solidity ^0.8.20;

import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol";
import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import { UUPSUpgradeable } from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";
import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";

import { EIP1056Registry } from "./EIP1056Registry.sol";

/**
* @title DIDRegistry
* @dev The DIDRegistry contract is a registry of decentralized identifiers (DIDs) and their attributes.
*/
contract DIDRegistry is EIP1056Registry {
contract DIDRegistry is EIP1056Registry, Initializable, UUPSUpgradeable, AccessControl {
bytes32 public constant REGISTRY_ADMIN_ROLE = keccak256("REGISTRY_ADMIN_ROLE");

mapping(address => address) public owners;
mapping(address => mapping(bytes32 => mapping(address => uint256))) public delegates;
mapping(address => uint256) public changed;
Expand All @@ -19,6 +28,16 @@ contract DIDRegistry is EIP1056Registry {
_;
}

/// @dev constructor is forbidden for upgradeable contracts
constructor() {
_disableInitializers();
}

/// @dev initializer is required for proxy contracts
function initialize(address _roleAdmin) public initializer {
_grantRole(DEFAULT_ADMIN_ROLE, _roleAdmin);
}

/**
* Return the current owner of an identity.
* @param identity The identity to check.
Expand Down Expand Up @@ -280,6 +299,23 @@ contract DIDRegistry is EIP1056Registry {
_revokeAttribute(identity, _checkSignature(identity, sigV, sigR, sigS, digest), name, value);
}

/**
* @notice authorize code upgrade or revert
* @dev required by UUPSUpgradeable
*/
// solhint-disable-next-line no-empty-blocks
function _authorizeUpgrade(address) internal override onlyRole(REGISTRY_ADMIN_ROLE) {}

/**
* @dev required by ERC165
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControl) returns (bool) {
return
interfaceId == type(EIP1056Registry).interfaceId ||
interfaceId == type(IAccessControl).interfaceId ||
super.supportsInterface(interfaceId);
}

/**
* @dev check signature of the owner
* @param identity address of the identity
Expand Down
2 changes: 1 addition & 1 deletion packages/did-eth-registry/contracts/EIP1056Registry.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.15;
pragma solidity ^0.8.20;

/**
* @title EIP1056Registry
Expand Down
25 changes: 25 additions & 0 deletions packages/did-eth-registry/contracts/EIP1056RegistryProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.20;

import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import { ERC1967Utils } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";

import { EIP1056RegistryProxy } from "./EIP1056RegistryProxy.sol";
import { DIDRegistry } from "./DIDRegistry.sol";

contract EIP1056RegistryProxy is ERC1967Proxy {
constructor(address _logic, address _roleAdmin)
ERC1967Proxy(_logic, abi.encodeWithSignature("initialize(address)", _roleAdmin))
// solhint-disable-next-line no-empty-blocks
{

}
}

// solhint-disable-next-line func-visibility
function createEIP1056Registry(address _roleAdmin) returns (address) {
DIDRegistry logic = new DIDRegistry(); // logic contract
EIP1056RegistryProxy proxy = new EIP1056RegistryProxy(address(logic), _roleAdmin);
return address(proxy);
}
1 change: 1 addition & 0 deletions packages/did-eth-registry/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
src = "contracts"
out = "out"
libs = ["node_modules", "lib"]
fs_permissions = [{access = "write", path = "./"}]

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
1 change: 1 addition & 0 deletions packages/did-eth-registry/lib/openzeppelin-contracts
Submodule openzeppelin-contracts added at 932fdd
Loading

0 comments on commit a5936e9

Please sign in to comment.