@ayanworks/polygon-did-registry-contract 2.0.1-alpha.2 → 2.0.1-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  //SPDX-License-Identifier: Apache 2.0
2
- pragma solidity ^0.8.16;
2
+ pragma solidity 0.8.16;
3
3
 
4
4
  /**
5
5
  *@title PolygonDidRegistry
@@ -8,7 +8,6 @@ pragma solidity ^0.8.16;
8
8
  contract PolygonDidRegistry {
9
9
  uint256 totalDIDs;
10
10
  address owner;
11
- uint256 deletedDID;
12
11
  struct PolyDID {
13
12
  address controller;
14
13
  uint256 created;
@@ -16,56 +15,71 @@ contract PolygonDidRegistry {
16
15
  string didDoc;
17
16
  }
18
17
 
19
- modifier onlyController(address _id) {
20
- require(
21
- polyDIDs[_id].controller == msg.sender,
22
- "message sender is not the controller of the DID Doc"
23
- );
24
- _;
25
- }
26
18
  mapping(address => PolyDID) polyDIDs;
27
19
  mapping(uint256 => address) activeDIDs;
28
20
  mapping(address => uint256) activeAddress;
21
+ mapping(address => mapping(string => string)) resourceData;
22
+ mapping(address => string[]) private keysById;
29
23
  event DIDCreated(address id, string doc);
30
24
  event DIDUpdated(address id, string doc);
31
- event DIDDeleted(address id);
32
25
  event TransferOwnership(address newOwner);
26
+ event ResourceAdded(
27
+ address _id,
28
+ string _resourceId,
29
+ string _resourcePayload
30
+ );
31
+
33
32
  bool private initialized;
34
33
 
35
34
  /**
36
- *@dev initializes the ownership of contract
35
+ *@dev modifiers for access control
37
36
  **/
38
37
 
39
- function initialize() public {
40
- require(!initialized, "Contract instance has already been initialized");
38
+ modifier onlyController(address _id) {
39
+ require(
40
+ polyDIDs[_id].controller == msg.sender,
41
+ 'message sender is not the controller of the DID Doc'
42
+ );
43
+ _;
44
+ }
45
+
46
+ modifier nonReentrant() {
47
+ require(!initialized, 'Contract instance has already been initialized');
41
48
  initialized = true;
42
- owner = msg.sender;
43
49
  totalDIDs = 0;
44
- deletedDID = 0;
50
+ _;
45
51
  }
46
52
 
47
53
  modifier onlyOwner() {
48
- require(msg.sender == owner, "message sender is not the owner");
54
+ require(msg.sender == owner, 'message sender is not the owner');
49
55
  _;
50
56
  }
51
57
 
58
+ /**
59
+ *@dev initializes the ownership of contract
60
+ **/
61
+
62
+ function initialize() external nonReentrant {
63
+ require(msg.sender != address(0), 'Invalid owner address');
64
+ owner = msg.sender;
65
+ }
66
+
52
67
  /**
53
68
  *@dev transfer the ownership of contract
54
69
  *@param _newOwner - Address of the new owner to whom the ownership needs to be passed
55
70
  **/
56
71
 
57
- function transferOwnership(address _newOwner)
58
- public
59
- onlyOwner
60
- returns (string memory)
61
- {
62
- if (owner != _newOwner) {
63
- owner = _newOwner;
64
- emit TransferOwnership(owner);
65
- return ("Ownership transferred successfully");
66
- } else {
67
- return ("Ownership cannot be transferred to the same account");
68
- }
72
+ function transferOwnership(
73
+ address _newOwner
74
+ ) external onlyOwner returns (string memory) {
75
+ require(_newOwner != address(0), 'Invalid owner address');
76
+ require(
77
+ owner != _newOwner,
78
+ 'Ownership cannot be transferred to the same account'
79
+ );
80
+ owner = _newOwner;
81
+ emit TransferOwnership(owner);
82
+ return ('Ownership transferred successfully');
69
83
  }
70
84
 
71
85
  /**
@@ -82,8 +96,11 @@ contract PolygonDidRegistry {
82
96
  *@param _doc - A string object that holds the DID Doc
83
97
  */
84
98
 
85
- function createDID(address _id, string memory _doc)
86
- public
99
+ function createDID(
100
+ address _id,
101
+ string memory _doc
102
+ )
103
+ external
87
104
  returns (
88
105
  address controller,
89
106
  uint256 created,
@@ -91,6 +108,7 @@ contract PolygonDidRegistry {
91
108
  string memory didDoc
92
109
  )
93
110
  {
111
+ require(_id != address(0), 'Invalid address provided');
94
112
  polyDIDs[_id].controller = msg.sender;
95
113
  polyDIDs[_id].created = block.timestamp;
96
114
  polyDIDs[_id].updated = block.timestamp;
@@ -112,32 +130,23 @@ contract PolygonDidRegistry {
112
130
  *@param _id - Address that refers to the DID doc position
113
131
  */
114
132
 
115
- function getDIDDoc(address _id) public view returns (string memory) {
116
- return polyDIDs[_id].didDoc;
117
- }
133
+ function getDIDDoc(
134
+ address _id
135
+ ) public view returns (string memory, string[] memory) {
136
+ string[] memory result = new string[](keysById[_id].length);
118
137
 
119
- /**
120
- *@dev Reads total number of DIDs and total number of active DIDs from Chain
121
- */
122
-
123
- function getTotalNumberOfDIDs()
124
- public
125
- view
126
- returns (uint256 _totalDIDs, uint256 _activeDIDs)
127
- {
128
- return (totalDIDs, (totalDIDs - deletedDID));
138
+ for (uint256 i = 0; i < keysById[_id].length; i++) {
139
+ result[i] = resourceData[_id][keysById[_id][i]];
140
+ }
141
+ return (polyDIDs[_id].didDoc, result);
129
142
  }
130
143
 
131
144
  /**
132
- *@dev Reads total number of DIDs deleted from Chain
145
+ *@dev Reads total number of DIDs and total number of active DIDs from Chain
133
146
  */
134
147
 
135
- function getTotalNumberOfDeletedDIDs()
136
- public
137
- view
138
- returns (uint256 _deletedDID)
139
- {
140
- return deletedDID;
148
+ function getTotalNumberOfDIDs() public view returns (uint256 _totalDIDs) {
149
+ return (totalDIDs);
141
150
  }
142
151
 
143
152
  /**
@@ -146,11 +155,9 @@ contract PolygonDidRegistry {
146
155
  *@return _did - returns the DID Doc assciated with the index. Returns null if the DID Doc is deleted.
147
156
  */
148
157
 
149
- function getDIDDOcByIndex(uint256 _index)
150
- public
151
- view
152
- returns (string memory)
153
- {
158
+ function getDIDDocByIndex(
159
+ uint256 _index
160
+ ) public view returns (string memory) {
154
161
  return polyDIDs[activeDIDs[_index]].didDoc;
155
162
  }
156
163
 
@@ -160,8 +167,11 @@ contract PolygonDidRegistry {
160
167
  *@param _doc - A String that holds the DID doc
161
168
  */
162
169
 
163
- function updateDIDDoc(address _id, string memory _doc)
164
- public
170
+ function updateDIDDoc(
171
+ address _id,
172
+ string memory _doc
173
+ )
174
+ external
165
175
  onlyController(_id)
166
176
  returns (
167
177
  address controller,
@@ -182,14 +192,53 @@ contract PolygonDidRegistry {
182
192
  }
183
193
 
184
194
  /**
185
- *@dev To delete a DID from chain
186
- *@param _id - Address that refers to the DID doc that need to be deleted
195
+ *@dev To add linked resource in the DID doc
196
+ *@param _id - Address that refers to the DID doc
197
+ *@param _resourceId - Id that refers to the resource
187
198
  */
199
+ function addResource(
200
+ address _id,
201
+ string memory _resourceId,
202
+ string memory _resourcePayload
203
+ )
204
+ external
205
+ onlyController(_id)
206
+ returns (address, string memory, string memory)
207
+ {
208
+ require(_id != address(0), 'Invalid address provided');
209
+ resourceData[_id][_resourceId] = _resourcePayload;
210
+ keysById[_id].push(_resourceId);
211
+ emit ResourceAdded(_id, _resourceId, _resourcePayload);
212
+ return (_id, _resourceId, _resourcePayload);
213
+ }
214
+
215
+ /**
216
+ *@dev Reads DID linked resource from Chain
217
+ *@param _id - Address that refers to the DID doc
218
+ *@param _resourceId - Id that refers to a specific resource
219
+ */
220
+
221
+ function getResource(
222
+ address _id,
223
+ string memory _resourceId
224
+ ) public view returns (string memory) {
225
+ return resourceData[_id][_resourceId];
226
+ }
227
+
228
+ /**
229
+ *@dev Reads all DID linked resource for a specific DID from Chain
230
+ *@param _id - Address that refers to the DID doc
231
+ */
232
+
233
+ function getAllResources(
234
+ address _id
235
+ ) public view returns (string[] memory) {
236
+ string[] memory result = new string[](keysById[_id].length);
237
+
238
+ for (uint256 i = 0; i < keysById[_id].length; i++) {
239
+ result[i] = resourceData[_id][keysById[_id][i]];
240
+ }
188
241
 
189
- function deleteDIDDoc(address _id) public onlyController(_id) {
190
- delete polyDIDs[_id];
191
- delete activeDIDs[activeAddress[_id]];
192
- ++deletedDID;
193
- emit DIDDeleted(_id);
242
+ return result;
194
243
  }
195
- }
244
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @type import('hardhat/config').HardhatUserConfig
3
+ */
4
+
5
+ // import 'hardhat';
6
+ require('@nomicfoundation/hardhat-ethers')
7
+ require('@openzeppelin/hardhat-upgrades')
8
+ require('@nomicfoundation/hardhat-verify')
9
+
10
+ require('dotenv/config')
11
+
12
+ module.exports = {
13
+ solidity: {
14
+ version: '0.8.16',
15
+ settings: {
16
+ optimizer: {
17
+ enabled: true,
18
+ runs: 200,
19
+ },
20
+ },
21
+ },
22
+ networks: {
23
+ hardhat: {},
24
+ amoy: {
25
+ url: process.env.AMOY_RPCURL,
26
+ accounts: [`0x${process.env.SIGNER}`],
27
+ },
28
+ //Use for mainnet deployment
29
+ // polygon: {
30
+ // url: process.env.RPCURL_POLYON_MAINNET,
31
+ // accounts: [`0x${process.env.SIGNER}`],
32
+ // },
33
+ },
34
+ etherscan: {
35
+ apiKey: {
36
+ polygonMumbai: process.env.VERIFICATION_KEY,
37
+ },
38
+ },
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ayanworks/polygon-did-registry-contract",
3
- "version": "2.0.1-alpha.2",
3
+ "version": "2.0.1-alpha.4",
4
4
  "description": "Smart Contract to register DID on Polygon",
5
5
  "main": "build/index.js",
6
6
  "directories": {
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "scripts": {
10
10
  "deploy": "node deploy.js",
11
- "test": "node compile.js && mocha --timeout 30000",
11
+ "test": "node --require ts-node/register --test ./tests/polygon_did_registry_test.test.js",
12
12
  "clean": "rm -rf build",
13
13
  "clean:deps": "pnpm clean && rm -rf node_modules",
14
14
  "build": "pnpm clean && pnpm build:sol && tsc",
@@ -17,24 +17,24 @@
17
17
  "check-format": "pnpm prettier --list-different",
18
18
  "check-types": "pnpm build --noEmit",
19
19
  "format": "pnpm prettier --write",
20
- "release": "git status && release-it"
20
+ "release": "release-it"
21
21
  },
22
22
  "license": "MIT",
23
23
  "devDependencies": {
24
- "@openzeppelin/truffle-upgrades": "^1.15.0",
25
- "@truffle/hdwallet-provider": "^2.0.10",
24
+ "@nomicfoundation/hardhat-ethers": "^3.0.5",
25
+ "@nomicfoundation/hardhat-verify": "^2.0.3",
26
+ "@openzeppelin/hardhat-upgrades": "^3.0.1",
26
27
  "@types/fs-extra": "^11.0.1",
27
28
  "@types/node": "^18.17.0",
28
29
  "dotenv": "^16.0.2",
29
30
  "eslint": "^8.23.1",
30
31
  "ethers": "^6.9.0",
31
32
  "fs-extra": "^11.1.1",
32
- "ganache-cli": "6.12.2",
33
+ "hardhat": "^2.19.4",
33
34
  "mocha": "^7.0.0",
34
35
  "prettier": "^3.0.2",
35
36
  "release-it": "^16.3.0",
36
- "solc": "^0.8.21",
37
- "truffle": "^5.5.20",
37
+ "solc": "0.8.16",
38
38
  "ts-node": "^10.9.1",
39
39
  "typescript": "^5.1.6"
40
40
  },
@@ -52,5 +52,6 @@
52
52
  "bugs": {
53
53
  "url": "https://github.com/ayanworks/polygon-did-registry-contract/issues"
54
54
  },
55
- "homepage": "https://github.com/ayanworks/polygon-did-registry-contract#readme"
55
+ "homepage": "https://github.com/ayanworks/polygon-did-registry-contract#readme",
56
+ "dependencies": {}
56
57
  }
@@ -0,0 +1,31 @@
1
+ const { ethers, upgrades } = require('hardhat')
2
+
3
+ async function main() {
4
+ try {
5
+ console.log('Deploying the smart contract...')
6
+ const PolygonDidRegistry =
7
+ await ethers.getContractFactory('PolygonDidRegistry')
8
+
9
+ // To deploy the initial upgradable smart contract
10
+
11
+ const contract = await upgrades.deployProxy(PolygonDidRegistry, {
12
+ initializer: 'initialize',
13
+ })
14
+
15
+ // const contract = await upgrades.upgradeProxy(
16
+ // process.env.CONTRACT_ADDRESS,
17
+ // PolygonDidRegistry,
18
+ // {
19
+ // initializer: 'initialize',
20
+ // },
21
+ // )
22
+
23
+ await contract.waitForDeployment()
24
+
25
+ console.log('Contract address::', contract.target)
26
+ } catch (error) {
27
+ console.error('Error deploying contract:', error.message)
28
+ }
29
+ }
30
+
31
+ main()
package/sst-config.json CHANGED
@@ -1,3 +1 @@
1
- {
2
- "sourceHash": "0xd34bb18b8a1a061e975b0850a1887bacdf0b8891d51e51399492bb038c05ff96"
3
- }
1
+ {"sourceHash":"0x99e57955d85cedd34a3d4d094b89b3fbcf3fd704b4c4b67d6dd6544f783afe53"}
@@ -0,0 +1,117 @@
1
+ const { ethers, upgrades } = require('hardhat')
2
+ const assert = require('assert')
3
+ const { describe, it } = require('node:test')
4
+
5
+ // Initializing the build files
6
+ const PolygonDIDRegistryJSON = require('../artifacts/contracts/PolygonDidRegistry.sol/PolygonDidRegistry.json')
7
+
8
+ let PolygonUpgradableInstance, PolygonUpgradableInstance_test
9
+ walletKey = process.env.SIGNER
10
+
11
+ // Upgradable with Proxy
12
+ // Deployment Testing 1.0
13
+ describe('Setting up the Upgradable Smart Contract', async () => {
14
+ describe('Setting up the contract', async () => {
15
+ it('Should deploy contract with Proxy, with no parameters/Constructor', async () => {
16
+ const PolygonDidRegistry =
17
+ await ethers.getContractFactory('PolygonDidRegistry')
18
+ PolygonUpgradableInstance = await upgrades.deployProxy(PolygonDidRegistry)
19
+ await PolygonUpgradableInstance.waitForDeployment()
20
+ PolygonUpgradableInstance_test = new ethers.Contract(
21
+ PolygonUpgradableInstance.target,
22
+ PolygonDIDRegistryJSON.abi,
23
+ walletKey,
24
+ )
25
+ assert.ok(
26
+ PolygonUpgradableInstance.target,
27
+ 'Upgradeable contract is deployed',
28
+ )
29
+ })
30
+ })
31
+
32
+ //Check Create Function test 1.1
33
+ describe('Checking the Create function using Upgradeable Contract', async () => {
34
+ it('This should store the DID doc on Upgradable Contract and will read and check if the value stored is correct', async () => {
35
+ // This will send the value to local ganache blockchain
36
+ const did = '0x2f65b747440deaf596892dfc7965040be8b99100'
37
+ const doc =
38
+ '{"@context":"https://w3id.org/did/v1","id":"did:polygon:0x2f65b747440deaf596892dfc7965040be8b99100","verificationMethod":[{"id":"did:polygon:0x2f65b747440deaf596892dfc7965040be8b99100","type":"EcdsaSecp256k1VerificationKey2019","controller":"did:polygon:0x2f65b747440deaf596892dfc7965040be8b99100","publicKeyBase58":"NDaEdTguJV39Ns8BZkxQ3XR6GUinZAJfVoyEMkK9fP7XQmpSkT3UsLHB52cFpDqoM6m4Hevtba8pkmjvEG3Ur7ji"}]}'
39
+ const tx = await PolygonUpgradableInstance.createDID(did, doc)
40
+
41
+ // Getting the set value in ganache blockchain
42
+ const currentValue = await PolygonUpgradableInstance.getDIDDoc(did)
43
+ // Comparing the set value to confirm
44
+ assert.notEqual(currentValue, null, 'value set must be able to get')
45
+
46
+ assert.notEqual(currentValue, null, 'value should not be empty')
47
+ })
48
+ })
49
+
50
+ //Describing the 1.2 Test Case
51
+ describe('Checking the getTotalNumberOfDIDs Function', async () => {
52
+ it('This should get correct number of DIDs registered', async () => {
53
+ const currentValue =
54
+ await PolygonUpgradableInstance.getTotalNumberOfDIDs()
55
+ assert(currentValue > 0, 'value should be less than 0')
56
+ })
57
+ })
58
+
59
+ // Describing the 1.3 Test case
60
+ describe('Checking the Update function in Upgradable Contract', async () => {
61
+ it('This should update the DID doc on Upgradable Contract and will read and check if the value stored is correct', async () => {
62
+ // This will send the value to local ganache blockchain
63
+ const did = '0x2f65b747440deaf596892dfc7965040be8b99100'
64
+ //changed the controller
65
+ const doc =
66
+ '{"@context":"https://w3id.org/did/v1","id":"did:polygon:0x2f65b747440deaf596892dfc7965040be8b99100","verificationMethod":[{"id":"did:polygon:0x2f65b747440deaf596892dfc7965040be8b99100","type":"EcdsaSecp256k1VerificationKey2019","controller":"did:polygon:0x2f65b747440deaf596892dfc7965040be8c66666","publicKeyBase58":"NDaEdTguJV39Ns8BZkxQ3XR6GUinZAJfVoyEMkK9fP7XQmpSkT3UsLHB52cFpDqoM6m4Hevtba8pkmjvEG3Ur7ji"}]}'
67
+ const tx = await PolygonUpgradableInstance.updateDIDDoc(did, doc)
68
+
69
+ // Getting the set value in ganache blockchain
70
+ const currentValue = await PolygonUpgradableInstance.getDIDDoc(did)
71
+
72
+ // Comparing the set value to confirm
73
+ assert.notEqual(currentValue, null, 'value set must be able to get')
74
+ })
75
+ })
76
+
77
+ //Describing test 1.4 to check if test fails if we update with different controller
78
+ describe('Checking update with wrong controller', async () => {
79
+ it('This should not update DID doc ', async () => {
80
+ const did = '0x2f65b747440deaf596892dfc7965040be8b99109'
81
+ const doc =
82
+ '{"@context":"https://w3id.org/did/v1","id":"did:polygon:0x2f65b747440deaf596892dfc7965040be8b99100","verificationMethod":[{"id":"did:polygon:0x2f65b747440deaf596892dfc7965040be8b99100","type":"EcdsaSecp256k1VerificationKey2019","controller":"did:polygon:0x2f65b747440deaf596892dfc7965040be8c66666","publicKeyBase58":"NDaEdTguJV39Ns8BZkxQ3XR6GUinZAJfVoyEMkK9fP7XQmpSkT3UsLHB52cFpDqoM6m4Hevtba8pkmjvEG3Ur7ji"}]}'
83
+ try {
84
+ assert.ifError(
85
+ //sending transaction using different controller
86
+ await PolygonUpgradableInstance_test.functions.updateDID(did, doc),
87
+ )
88
+ } catch (error) {}
89
+ })
90
+ })
91
+
92
+ // //Describing the 1.10 Test Case
93
+ describe('Checking the Transafer Ownership Function', async () => {
94
+ it('This should transfer ownership of contract to another user', async () => {
95
+ const newOwner = '0x2f65b747440deaf596892dfc7965040be8b99109'
96
+ const owner = await PolygonUpgradableInstance.getOwner()
97
+ const tx = await PolygonUpgradableInstance.transferOwnership(newOwner)
98
+ const currentOwner = await PolygonUpgradableInstance.getOwner()
99
+ assert.notEqual(owner, currentOwner, 'value should not be equal')
100
+ })
101
+ })
102
+
103
+ //Describing the 1.11 Test Case
104
+ describe('Checking the Transafer Ownership Function', async () => {
105
+ it('This should not transfer ownership of contract to another user since the transaction is being initiated by different owner', async () => {
106
+ const newOwner = '0x2f65b747440deaf596892dfc7965040be8b99100'
107
+ try {
108
+ assert.ifError(
109
+ //sending transaction using different controller
110
+ await PolygonUpgradableInstance_test.functions.transferOwnership(
111
+ newOwner,
112
+ ),
113
+ )
114
+ } catch (error) {}
115
+ })
116
+ })
117
+ })
@@ -1,5 +0,0 @@
1
- const Migrations = artifacts.require('Migrations')
2
-
3
- module.exports = function (deployer) {
4
- deployer.deploy(Migrations)
5
- }
@@ -1,8 +0,0 @@
1
- const { deployProxy } = require('@openzeppelin/truffle-upgrades')
2
-
3
- const PolygonDidRegistry = artifacts.require('PolygonDidRegistry')
4
-
5
- module.exports = async function (deployer) {
6
- const instance = await deployProxy(PolygonDidRegistry, { deployer })
7
- console.log('Deployed', instance.address)
8
- }