did:cow, a proposal for an ID resolution method with most of the convenience of did:plc/did:web and the robustness of a public blockchain
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

use revert errors, keep a flag for initialized

+50 -11
+17 -6
src/CowRegistry.sol
··· 20 20 string wrappedDID; 21 21 } 22 22 23 + error NotInitialized(); 24 + error NotController(); 25 + error AlreadyDeactivated(); 26 + error EmptyWrappedDID(); 27 + 23 28 /// @notice Mapping from cow hash to current on-chain state. 24 29 /// @dev Returns zero values if the cow has never been registered on-chain. 25 30 mapping(bytes32 => Cow) public cows; ··· 43 48 /// @param _wrappedDID The new wrapped DID, without the leading "did:" prefix. 44 49 function updateWrappedDIDByHash(bytes32 _cowHash, string memory _wrappedDID) public { 45 50 Cow storage cow = cows[_cowHash]; 46 - require(msg.sender == cow.controller && !cow.deactivated); 47 - require(bytes(_wrappedDID).length > 0); 51 + if (!cow.initialized) revert NotInitialized(); 52 + if (cow.deactivated) revert AlreadyDeactivated(); 53 + if (msg.sender != cow.controller) revert NotController(); 54 + if (bytes(_wrappedDID).length == 0) revert EmptyWrappedDID(); 48 55 49 56 cow.wrappedDID = _wrappedDID; 50 57 emit WrappedDIDUpdated(_cowHash, _wrappedDID); ··· 59 66 /// @param _controller The new controller address. 60 67 function updateControllerByHash(bytes32 _cowHash, address _controller) public { 61 68 Cow storage cow = cows[_cowHash]; 62 - require(msg.sender == cow.controller && !cow.deactivated); 69 + if (!cow.initialized) revert NotInitialized(); 70 + if (cow.deactivated) revert AlreadyDeactivated(); 71 + if (msg.sender != cow.controller) revert NotController(); 63 72 64 73 cow.controller = _controller; 65 74 emit ControllerUpdated(_cowHash, _controller); ··· 71 80 /// @param _cowHash The cow's registry key, as returned by calculateCowHash. 72 81 function deactivateByHash(bytes32 _cowHash) public { 73 82 Cow storage cow = cows[_cowHash]; 74 - require(msg.sender == cow.controller && !cow.deactivated); 83 + if (!cow.initialized) revert NotInitialized(); 84 + if (cow.deactivated) revert AlreadyDeactivated(); 85 + if (msg.sender != cow.controller) revert NotController(); 75 86 76 87 cow.deactivated = true; 77 88 cow.controller = address(0); 78 - delete cow.wrappedDID; 89 + cow.wrappedDID = ""; 79 90 80 91 emit CowDeactivated(_cowHash); 81 92 } ··· 92 103 function _ensureCowInitialized(address _controller, string memory _wrappedDID) internal returns (bytes32 cowHash) { 93 104 cowHash = calculateCowHash(_controller, _wrappedDID); 94 105 Cow storage cow = cows[cowHash]; 95 - require(!cow.deactivated); 106 + if (cow.deactivated) revert AlreadyDeactivated(); 96 107 if (!cow.initialized) { 97 108 cow.initialized = true; 98 109 cow.controller = _controller;
+33 -5
test/CowRegistry.t.sol
··· 281 281 bytes32 cowHash = _init(controller1, plcDID1); 282 282 283 283 vm.prank(controller2); 284 - vm.expectRevert(); 284 + vm.expectRevert(CowRegistry.NotController.selector); 285 285 registry.updateWrappedDIDByHash(cowHash, plcDID2); 286 286 } 287 287 ··· 289 289 bytes32 cowHash = _init(controller1, plcDID1); 290 290 291 291 vm.prank(controller2); 292 - vm.expectRevert(); 292 + vm.expectRevert(CowRegistry.NotController.selector); 293 293 registry.updateControllerByHash(cowHash, controller2); 294 294 } 295 295 ··· 301 301 302 302 bytes32 cowHash = registry.calculateCowHash(controller1, plcDID1); 303 303 vm.prank(controller1); 304 - vm.expectRevert(); 304 + vm.expectRevert(CowRegistry.AlreadyDeactivated.selector); 305 305 registry.updateWrappedDIDByHash(cowHash, plcDID2); 306 306 } 307 307 ··· 312 312 registry.deactivateByHash(cowHash); 313 313 314 314 vm.prank(controller1); 315 - vm.expectRevert(); 315 + vm.expectRevert(CowRegistry.AlreadyDeactivated.selector); 316 316 registry.updateControllerByHash(cowHash, controller2); 317 317 } 318 318 ··· 323 323 registry.deactivateByHash(cowHash); 324 324 325 325 vm.prank(controller1); 326 - vm.expectRevert(); 326 + vm.expectRevert(CowRegistry.AlreadyDeactivated.selector); 327 327 registry.deactivateByHash(cowHash); 328 328 } 329 329 ··· 335 335 336 336 (, , , string memory did) = registry.cows(cowHash); 337 337 assertEq(did, ""); 338 + } 339 + 340 + // ========================================================================= 341 + // NotInitialized checks 342 + // ========================================================================= 343 + 344 + function test_updateWrappedDID_rejectsNotInitialized() public { 345 + bytes32 cowHash = registry.calculateCowHash(controller1, plcDID1); 346 + 347 + vm.prank(controller1); 348 + vm.expectRevert(CowRegistry.NotInitialized.selector); 349 + registry.updateWrappedDIDByHash(cowHash, plcDID2); 350 + } 351 + 352 + function test_updateController_rejectsNotInitialized() public { 353 + bytes32 cowHash = registry.calculateCowHash(controller1, plcDID1); 354 + 355 + vm.prank(controller1); 356 + vm.expectRevert(CowRegistry.NotInitialized.selector); 357 + registry.updateControllerByHash(cowHash, controller2); 358 + } 359 + 360 + function test_deactivate_rejectsNotInitialized() public { 361 + bytes32 cowHash = registry.calculateCowHash(controller1, plcDID1); 362 + 363 + vm.prank(controller1); 364 + vm.expectRevert(CowRegistry.NotInitialized.selector); 365 + registry.deactivateByHash(cowHash); 338 366 } 339 367 }