diff --git a/network/config.json b/network/config.json index a1cabe4b..42d50ad0 100644 --- a/network/config.json +++ b/network/config.json @@ -41,6 +41,10 @@ "universalDidResolver": { "specPath": "smart_contracts/artifacts/contracts/migration/UniversalDidResolver.sol/UniversalDidResolver.json", "address": "0x000000000000000000000000000000000019999" + }, + "revocationRegistry": { + "specPath": "smart_contracts/artifacts/contracts/revoke/RevocationRegistry.sol/RevocationRegistry.json", + "address": "0x0000000000000000000000000000000000021111" } } } diff --git a/network/config/besu/genesis.json b/network/config/besu/genesis.json index b0c5d961..f0006ca7 100644 --- a/network/config/besu/genesis.json +++ b/network/config/besu/genesis.json @@ -232,7 +232,22 @@ "0xe7088f06ea5b03450396bfa213a34bc6f6dc1b8c": { "comment": "Implementation: Smart contract to store mapping of legacy identifiers to new one", "code": "0x6080604052600436106100915760003560e01c80639a3265d9116100595780639a3265d914610140578063ad3cb1cc14610160578063c0c53b8b14610191578063c612ab58146101b1578063d924aedb146101d157600080fd5b80634f1ef2861461009657806352d1902d146100ab57806353aac465146100d35780637223460a146100f357806393a8c74214610113575b600080fd5b6100a96100a4366004612326565b6101f1565b005b3480156100b757600080fd5b506100c0610210565b6040519081526020015b60405180910390f35b3480156100df57600080fd5b506100a96100ee3660046123d9565b61022d565b3480156100ff57600080fd5b506100a961010e3660046124b7565b6102ee565b34801561011f57600080fd5b5061013361012e366004612587565b6103a8565b6040516100ca919061261f565b34801561014c57600080fd5b506100a961015b366004612632565b61044d565b34801561016c57600080fd5b50610133604051806040016040528060058152602001640352e302e360dc1b81525081565b34801561019d57600080fd5b506100a96101ac3660046126e5565b610468565b3480156101bd57600080fd5b506101336101cc366004612587565b61057c565b3480156101dd57600080fd5b506100a96101ec366004612728565b6105a0565b6101f96105b9565b61020282610660565b61020c82826106c6565b5050565b600061021a61078d565b50600080516020612c4f83398151915290565b6000601960f81b600060f81b308e8b8b8b8b8b8b8b60405160200161025c9b9a999897969594939291906127d2565b60408051601f1981840301815282825280516020918201206000845290830180835281905260ff8e1691830191909152606082018c9052608082018b905291506102e0908d9060019060a0016020604051602081039080840390855afa1580156102ca573d6000803e3d6000fd5b505050602060405103518a8a8a8a8a8a8a6107d6565b505050505050505050505050565b60405160009061031890601960f81b90839030908f908c908c908c908c908c908c90602001612864565b60408051601f1981840301815282825280516020918201206000845290830180835281905260ff8d1691830191909152606082018b9052608082018a9052915061039b908c9060019060a0016020604051602081039080840390855afa158015610386573d6000803e3d6000fd5b50505060206040510351898989898989610ad5565b5050505050505050505050565b8051602081830181018051600382529282019190930120915280546103cc906128fa565b80601f01602080910402602001604051908101604052809291908181526020018280546103f8906128fa565b80156104455780601f1061041a57610100808354040283529160200191610445565b820191906000526020600020905b81548152906001019060200180831161042857829003601f168201915b505050505081565b61045e8833898989898989896107d6565b5050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805460019190600160401b900460ff16806104b1575080546001600160401b03808416911610155b156104cf5760405163f92ee8a960e01b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b1781556104f985610e0e565b600180546001600160a01b038681166001600160a01b0319928316179092556002805492861692909116919091179055805468ff0000000000000000191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b8051602081830181018051600482529282019190930120915280546103cc906128fa565b6105b08733888888888888610ad5565b50505050505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061064057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610634600080516020612c4f833981519152546001600160a01b031690565b6001600160a01b031614155b1561065e5760405163703e46dd60e11b815260040160405180910390fd5b565b60005460405163574a81d760e01b81523060048201526001600160a01b0383811660248301529091169063574a81d79060440160006040518083038186803b1580156106ab57600080fd5b505afa1580156106bf573d6000803e3d6000fd5b5050505050565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610720575060408051601f3d908101601f1916820190925261071d9181019061292e565b60015b61074d57604051634c9c8ce360e01b81526001600160a01b03831660048201526024015b60405180910390fd5b600080516020612c4f833981519152811461077e57604051632a87526960e21b815260048101829052602401610744565b6107888383610e38565b505050565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461065e5760405163703e46dd60e11b815260040160405180910390fd5b8888806001600160a01b0316826001600160a01b03161461081d576040516316343f1760e31b81526001600160a01b03808316600483015283166024820152604401610744565b6002546040516301daf29b60e21b81523360048201526001600160a01b039091169063076bca6c9060240160006040518083038186803b15801561086057600080fd5b505afa158015610874573d6000803e3d6000fd5b5050505061093961092c60038b8b604051610890929190612947565b908152602001604051809103902080546108a9906128fa565b80601f01602080910402602001604051908101604052809291908181526020018280546108d5906128fa565b80156109225780601f106108f757610100808354040283529160200191610922565b820191906000526020600020905b81548152906001019060200180831161090557829003601f168201915b5050505050610e8e565b6001600160801b03161590565b61095a578888604051630ab7bdc760e21b8152600401610744929190612980565b846001600160801b0319166109a48a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e9f92505050565b6109ad90612994565b6001600160801b031916146109db57848989604051630876c99d60e21b8152600401610744939291906129cb565b610a26610a1d88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610eaa92505050565b60200151610ff5565b6001600160a01b03168b6001600160a01b031614610a5b578686604051631859e3bb60e11b8152600401610744929190612980565b868660038b8b604051610a6f929190612947565b90815260200160405180910390209182610a8a929190612a35565b507ff214be33ffacf63cd5f2d1636bef433e47c400b94d565c786049bfa836c20e1989898989604051610ac09493929190612af4565b60405180910390a15050505050505050505050565b8787806001600160a01b0316826001600160a01b031614610b1c576040516316343f1760e31b81526001600160a01b03808316600483015283166024820152604401610744565b6002546040516301daf29b60e21b81523360048201526001600160a01b039091169063076bca6c9060240160006040518083038186803b158015610b5f57600080fd5b505afa158015610b73573d6000803e3d6000fd5b5050505060048686604051610b89929190612947565b90815260200160405180910390208054610ba2906128fa565b159050610bc65785856040516327ef3c3d60e01b8152600401610744929190612980565b610bde61092c60038a8a604051610890929190612947565b15610c0057858560405163a54e9cfb60e01b8152600401610744929190612980565b6000610cb6610a1d60038b8b604051610c1a929190612947565b90815260200160405180910390208054610c33906128fa565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5f906128fa565b8015610cac5780601f10610c8157610100808354040283529160200191610cac565b820191906000526020600020905b815481529060010190602001808311610c8f57829003601f168201915b5050505050610eaa565b9050806001600160a01b03168b6001600160a01b031614610cfd576040516316343f1760e31b81526001600160a01b03808d16600483015282166024820152604401610744565b610d84610d3f8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e8e92505050565b610d7e89898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e8e92505050565b9061102e565b610da95786868a8a60405163998f70a160e01b81526004016107449493929190612af4565b848460048989604051610dbd929190612947565b90815260200160405180910390209182610dd8929190612a35565b507f87526cc0385862de920bf8b05560b5c9eb58f8af45be9f917801198166655f8887878787604051610ac09493929190612af4565b610e16611041565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b610e418261108a565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115610e865761078882826110ef565b61020c611165565b6000610e9982611184565b92915050565b6060610e9982611198565b60408051808201909152606080825260208201526000610ec983610e8e565b90506000610eef604051806040016040528060018152602001601d60f91b815250610e8e565b9050600080610efe84846114be565b955092509050801580610f3c5750610f3a610f3360405180604001604052806003815260200162191a5960ea1b815250610e8e565b839061150c565b155b15610f5c5785604051631859e3bb60e11b8152600401610744919061261f565b610f6684846114be565b95509250905080610f8c5785604051631859e3bb60e11b8152600401610744919061261f565b6040805180820190915260608082526020820152610fa983611518565b81526040805180820190915260018152601d60f91b6020820152610fd790610fd090610e8e565b8690611523565b9450610fe69150849050611518565b60208201529695505050505050565b60006016611001835190565b0361100e57506000919050565b60006110198361154d565b905061102481612b26565b60601c9392505050565b600061103a838361173f565b9392505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661065e57604051631afcd79f60e31b815260040160405180910390fd5b806001600160a01b03163b6000036110c057604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610744565b600080516020612c4f83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b03168460405161110c9190612b59565b600060405180830381855af49150503d8060008114611147576040519150601f19603f3d011682016040523d82523d6000602084013e61114c565b606091505b509150915061115c858383611757565b95945050505050565b341561065e5760405163b398979f60e01b815260040160405180910390fd5b60008060208301905061103a8184516117b3565b80516060906031906000805b82811080156111cb5750838682815181106111c1576111c1612b75565b016020015160f81c145b156111dc57600191820191016111a4565b5060008080806117e361209f8702046001016002026001600160401b038111156112085761120861229b565b6040519080825280601f01601f191660200182016040528015611232576020820181803683370190505b5090506000600460038801046001600160401b038111156112555761125561229b565b60405190808252806020026020018201604052801561127e578160200160208202803683370190505b50905060005b8a5181101561137c5760008b82815181106112a1576112a1612b75565b602001015160f81c60f81b90506112d06040518060600160405280603a8152602001612c8f603a9139826117bf565b9096509450846112f5578b604051634cb9e47360e11b8152600401610744919061261f565b8251600019015b60008112611372578684828151811061131757611317612b75565b602002602001015163ffffffff16603a026001600160401b0316019750602088901c96508763ffffffff1684828151811061135457611354612b75565b63ffffffff90921660209283029190910190910152600019016112fc565b5050600101611284565b50600860038816026001600160401b038116600003611399575060205b600719016000805b8351811015611443575b6020836001600160401b0316101561143757826001600160401b03168482815181106113d9576113d9612b75565b602002602001015163ffffffff16901c60f81b8583815181106113fe576113fe612b75565b60200101906001600160f81b031916908160001a90535060019091019060086001600160401b03841610611437576008830392506113ab565b601892506001016113a1565b50875b84518110156114a157600060f81b85828151811061146657611466612b75565b01602001516001600160f81b031916111561149957611488858a830384611822565b9d9c50505050505050505050505050565b600101611446565b506114ae84600083611822565b9c9b505050505050505050505050565b60008080806114cd86866118d3565b905060001981036114e957600086600093509350935050611505565b6114fd86826001600160801b0388166119de565b935093509350505b9250925092565b600061103a8383611a4b565b6060610e9982611a95565b60008080806115328686611b0c565b905060001981036114e9576000808793509350935050611505565b6060600061155a83610e8e565b9050600061158160405180604001604052806002815260200161060f60f31b815250610e8e565b90506115b06115a960405180604001604052806002815260200161060f60f31b815250610e8e565b8390611bfe565b6115cb57505060408051602081019091526000815292915050565b6115dd6115d88383611c0a565b611518565b935060008490506000600282516115f49190612ba1565b6001600160401b0381111561160b5761160b61229b565b6040519080825280601f01601f191660200182016040528015611635576020820181803683370190505b50905060005b81518110156117355760008061167a85611656856002612bc3565b8151811061166657611666612b75565b01602001516001600160f81b031916611c16565b915091508061169f575050604080516020810190915260008152979650505050505050565b6000806116bc876116b1876002612bc3565b611656906001612bda565b91509150806116e35750506040805160208101909152600081529998505050505050505050565b816116ef856010612bed565b6116f99190612c09565b60f81b86868151811061170e5761170e612b75565b60200101906001600160f81b031916908160001a905350506001909301925061163b915050565b5095945050505050565b600060001961174e84846118d3565b14159392505050565b60608261176c5761176782611cfc565b61103a565b815115801561178357506001600160a01b0384163b155b156117ac57604051639996b31560e01b81526001600160a01b0385166004820152602401610744565b5092915050565b600061103a8383611d25565b60008060005b845181101561181257836001600160f81b0319168582815181106117eb576117eb612b75565b01602001516001600160f81b0319160361180a5791506001905061181b565b6001016117c5565b50600080915091505b9250929050565b606060008383036001600160401b038111156118405761184061229b565b6040519080825280601f01601f19166020018201604052801561186a576020820181803683370190505b50905060005b8484038110156118ca57858582018151811061188e5761188e612b75565b602001015160f81c60f81b8282815181106118ab576118ab612b75565b60200101906001600160f81b031916908160001a905350600101611870565b50949350505050565b60006001600160801b038381169083168083036118f557600092505050610e99565b81158061190157508181115b156119125760001992505050610e99565b600061191e8660801c90565b9050600061192c8660801c90565b9050600061193b825160001a90565b90505b600061194b848784611d31565b90506000198103611966576000199650505050505050610e99565b94859003949283019285851115611987576000199650505050505050610e99565b848320858520036119b35761199c8960801c90565b6119a69085612c22565b9650505050505050610e99565b856001036119cb576000199650505050505050610e99565b600019909501946001909301925061193e565b6000806000806119ee8760801c90565b90506001600160801b03871685870181811115611a1e576040516365f4e9df60e01b815260040160405180910390fd5b6001996001600160801b03988916608085811b919091179a50928290039098169201901b17949350505050565b60006001600160801b038381169083168114611a6b576000915050610e99565b611a8d611a788560801c90565b611a828560801c90565b839081902091201490565b949350505050565b60606001600160801b0382166001600160401b03811115611ab857611ab861229b565b6040519080825280601f01601f191660200182016040528015611ae2576020820181803683370190505b50905060208101611b0681611af78560801c90565b6001600160801b038616611df8565b50919050565b60006001600160801b03838116908316808303611b2e57600092505050610e99565b811580611b3a57508181115b15611b4b5760001992505050610e99565b6000611b578660801c90565b90506000611b658660801c90565b90506000611b7287611e06565b905060001984015b6000611b87858885611e4b565b90506000198103611ba357600019975050505050505050610e99565b80821115611bbc57600019975050505050505050610e99565b858420828203868101889020909103611bde579750610e999650505050505050565b8115611bec57509550611b7a565b60001998505050505050505050610e99565b600061103a8383611eff565b600061103a8383611f4c565b600080600360fc1b6001600160f81b0319841610801590611c455750603960f81b6001600160f81b0319841611155b15611c6357611c59603060f885901c612c35565b9360019350915050565b604160f81b6001600160f81b0319841610801590611c8f5750602360f91b6001600160f81b0319841611155b15611caf576041611ca560f885901c600a612c09565b611c599190612c35565b606160f81b6001600160f81b0319841610801590611cdb5750603360f91b6001600160f81b0319841611155b15611cf1576061611ca560f885901c600a612c09565b506000928392509050565b805115611d0c5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b600061103a8383611fa6565b600060208311611d4d57611d4684848461200c565b905061103a565b83601f8416808503820160ff8516600080516020612c6f833981519152025b81881015611dae5787518118611d818161211d565b15611da257848903611d958a60208a61200c565b019550505050505061103a565b60208901985050611d6c565b82600003611dc45760001994505050505061103a565b611dcf82848861200c565b94506000198503611de85760001994505050505061103a565b838203850194505050505061103a565b8083828460045afa50505050565b60006001600160801b038216808203611e32576040516365f4e9df60e01b815260040160405180910390fd5b61103a60018203611e438560801c90565b015160001a90565b600060208311611e6057611d46848484612168565b601f83168484018115611e98578190036000611e7d828487612168565b90506000198114611e96579086900301915061103a9050565b505b60ff8416600080516020612c6f833981519152025b86821115611ef157601f1990910180519091908118611ecb8161211d565b15611eeb57878303611edf84602089612168565b0194505050505061103a565b50611ead565b506000199695505050505050565b60006001600160801b0383811690831680821015611f2257600092505050610e99565b8481831115611f3857611f3586836121b1565b90505b611f428186611a4b565b9695505050505050565b60006001600160801b0383811690831681811115611f6e578492505050610e99565b600080611f7b87846121fc565b9092509050611f8a8287611a4b565b15611f9a579350610e9992505050565b86945050505050610e99565b60006001600160801b03831115611fd05760405163fee7506f60e01b815260040160405180910390fd5b6001600160801b03821115611ff857604051633b6b098d60e01b815260040160405180910390fd5b506001600160801b031660809190911b1790565b825160009081602085111561202057602094505b601285106120aa5760ff8416600080516020612c6f8339815191520282186120506001600160801b03821761211d565b6000036120865760109150601a8610612081576120756001600160401b03821761211d565b60000361208157601891505b6120a4565b6120986001600160c01b03821761211d565b6000036120a457600891505b506120e8565b600a85106120e85760ff8416600080516020612c6f8339815191520282186120da6001600160c01b03821761211d565b6000036120e657600891505b505b848110156121105781811a60ff851681036121075750915061103a9050565b506001016120e8565b5060001995945050505050565b7ffefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefeff81019019167f80808080808080808080808080808080808080808080808080808080808080801690565b6000602083111561217857602092505b83515b83156121a5576000199093019280841a60ff8416810361219f57849250505061103a565b5061217b565b50600019949350505050565b60006001600160801b038316808311156121de576040516365f4e9df60e01b815260040160405180910390fd5b611a8d6121eb8560801c90565b60801b6001600160801b0385161790565b600080600061220b8560801c90565b90506001600160801b03851680851115612238576040516365f4e9df60e01b815260040160405180910390fd5b608082901b6001600160801b038616176122726122558785612bda565b61225f8885612c22565b6001600160801b031660809190911b1790565b9350935050509250929050565b80356001600160a01b038116811461229657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b03808411156122cb576122cb61229b565b604051601f8501601f19908116603f011681019082821181831017156122f3576122f361229b565b8160405280935085815286868601111561230c57600080fd5b858560208301376000602087830101525050509392505050565b6000806040838503121561233957600080fd5b6123428361227f565b915060208301356001600160401b0381111561235d57600080fd5b8301601f8101851361236e57600080fd5b61237d858235602084016122b1565b9150509250929050565b803560ff8116811461229657600080fd5b60008083601f8401126123aa57600080fd5b5081356001600160401b038111156123c157600080fd5b60208301915083602082850101111561181b57600080fd5b60008060008060008060008060008060006101008c8e0312156123fb57600080fd5b6124048c61227f565b9a5061241260208d01612387565b995060408c0135985060608c013597506001600160401b038060808e0135111561243b57600080fd5b61244b8e60808f01358f01612398565b909850965060a08d013581101561246157600080fd5b6124718e60a08f01358f01612398565b909650945060c08d0135935060e08d013581101561248e57600080fd5b5061249f8d60e08e01358e01612398565b81935080925050509295989b509295989b9093969950565b60008060008060008060008060008060e08b8d0312156124d657600080fd5b6124df8b61227f565b99506124ed60208c01612387565b985060408b0135975060608b0135965060808b01356001600160401b038082111561251757600080fd5b6125238e838f01612398565b909850965060a08d013591508082111561253c57600080fd5b6125488e838f01612398565b909650945060c08d013591508082111561256157600080fd5b5061256e8d828e01612398565b915080935050809150509295989b9194979a5092959850565b60006020828403121561259957600080fd5b81356001600160401b038111156125af57600080fd5b8201601f810184136125c057600080fd5b611a8d848235602084016122b1565b60005b838110156125ea5781810151838201526020016125d2565b50506000910152565b6000815180845261260b8160208601602086016125cf565b601f01601f19169290920160200192915050565b60208152600061103a60208301846125f3565b60008060008060008060008060a0898b03121561264e57600080fd5b6126578961227f565b975060208901356001600160401b038082111561267357600080fd5b61267f8c838d01612398565b909950975060408b013591508082111561269857600080fd5b6126a48c838d01612398565b909750955060608b0135945060808b01359150808211156126c457600080fd5b506126d18b828c01612398565b999c989b5096995094979396929594505050565b6000806000606084860312156126fa57600080fd5b6127038461227f565b92506127116020850161227f565b915061271f6040850161227f565b90509250925092565b60008060008060008060006080888a03121561274357600080fd5b61274c8861227f565b965060208801356001600160401b038082111561276857600080fd5b6127748b838c01612398565b909850965060408a013591508082111561278d57600080fd5b6127998b838c01612398565b909650945060608a01359150808211156127b257600080fd5b506127bf8a828b01612398565b989b979a50959850939692959293505050565b6001600160f81b03198c811682528b1660018201526001600160601b031960608b811b821660028401528a901b1660168201526f6372656174654469644d617070696e6760801b602a82015260008789603a840137878201603a8101600081528789823750868101905085603a8201528385605a83013760009301605a0192835250909b9a5050505050505050505050565b6001600160f81b03198b811682528a1660018201526001600160601b031960608a811b8216600284015289901b166016820152746372656174655265736f757263654d617070696e6760581b602a82015260008688603f840137868201603f81016000815286888237508581019050603f810160008152848682375060009301603f0192835250909a9950505050505050505050565b600181811c9082168061290e57607f821691505b602082108103611b0657634e487b7160e01b600052602260045260246000fd5b60006020828403121561294057600080fd5b5051919050565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000611a8d602083018486612957565b805160208201516001600160801b031980821692919060108310156129c35780818460100360031b1b83161693505b505050919050565b83815260406020820152600061115c604083018486612957565b601f821115610788576000816000526020600020601f850160051c81016020861015612a0e5750805b601f850160051c820191505b81811015612a2d57828155600101612a1a565b505050505050565b6001600160401b03831115612a4c57612a4c61229b565b612a6083612a5a83546128fa565b836129e5565b6000601f841160018114612a945760008515612a7c5750838201355b600019600387901b1c1916600186901b1783556106bf565b600083815260209020601f19861690835b82811015612ac55786850135825560209485019460019092019101612aa5565b5086821015612ae25760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000612b08604083018688612957565b8281036020840152612b1b818587612957565b979650505050505050565b805160208201516001600160601b031980821692919060148310156129c35760149290920360031b82901b161692915050565b60008251612b6b8184602087016125cf565b9190910192915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082612bbe57634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610e9957610e99612b8b565b80820180821115610e9957610e99612b8b565b60ff81811683821602908116908181146117ac576117ac612b8b565b60ff8181168382160190811115610e9957610e99612b8b565b81810381811115610e9957610e99612b8b565b60ff8281168282160390811115610e9957610e99612b8b56fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc010101010101010101010101010101010101010101010101010101010101010131323334353637383941424344454647484a4b4c4d4e505152535455565758595a6162636465666768696a6b6d6e6f707172737475767778797aa2646970667358221220d082e1f6555e53a96f9a2a79f9d1524aa10ace94483d7a38bb4ec41bad6454d364736f6c63430008170033" - } + }, + "0x0000000000000000000000000000000000021111": { + "comment": "Proxy: Smart contract to manage revocation of credential definitions", + "code": "0x6080604052600a600c565b005b60186014601a565b6051565b565b6000604c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b3660008037600080366000845af43d6000803e808015606f573d6000f35b3d6000fdfea2646970667358221220dcc306d465d9048151323886ce1f129e7683015ca2023dd2f174e9f3b9f7dac464736f6c634300081a0033", + "storage": { + "0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000009999", + "0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000004444", + "0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000006666", + "f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00": "0x0000000000000000000000000000000000000000000000000000000000000001", + "360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000860ad7830bfb91bce8e73651698aa9738d894c9a" + } + }, + "0x860ad7830bfb91bce8e73651698aa9738d894c9a": { + "comment": "Implementation: Smart contract to manage revocation of credential definitions", + "code": "0x6080604052600436106100c25760003560e01c80638d8fdefd1161007f578063c0c53b8b11610059578063c0c53b8b14610202578063c1bf7cb314610222578063e1d38d8c14610242578063e5dca78e1461026f57600080fd5b80638d8fdefd146101845780639e6abf56146101a4578063ad3cb1cc146101c457600080fd5b806308aab503146100c75780634f1ef286146100e957806352d1902d146100fc578063621eaff5146101245780636242f8ea1461014457806369dfde3e14610164575b600080fd5b3480156100d357600080fd5b506100e76100e2366004611852565b61028f565b005b6100e76100f7366004611933565b610380565b34801561010857600080fd5b5061011161039f565b6040519081526020015b60405180910390f35b34801561013057600080fd5b506100e761013f3660046119d4565b6103bc565b34801561015057600080fd5b506100e761015f366004611a69565b610579565b34801561017057600080fd5b506100e761017f3660046119d4565b610695565b34801561019057600080fd5b506100e761019f3660046119d4565b610848565b3480156101b057600080fd5b506100e76101bf366004611ad0565b6109fc565b3480156101d057600080fd5b506101f5604051806040016040528060058152602001640352e302e360dc1b81525081565b60405161011b9190611baa565b34801561020e57600080fd5b506100e761021d366004611bbd565b610bf5565b34801561022e57600080fd5b506100e761023d366004611852565b610d09565b34801561024e57600080fd5b5061026261025d366004611c00565b610def565b60405161011b9190611c2f565b34801561027b57600080fd5b506100e761028a366004611852565b610f18565b80600080828152600460208190526040909120015460ff1660028111156102b8576102b8611c19565b036102de57604051639779315960e01b8152600481018290526024015b60405180910390fd5b6002546040516301daf29b60e21b81523360048201526001600160a01b039091169063076bca6c9060240160006040518083038186803b15801561032157600080fd5b505afa158015610335573d6000803e3d6000fd5b505050600083815260046020526040812060010154849250900361036f576040516305ed361b60e11b8152600481018290526024016102d5565b61037a843385610fff565b50505050565b6103886110eb565b61039182611192565b61039b82826111f8565b5050565b60006103a96112ba565b50600080516020611ef383398151915290565b80600080828152600460208190526040909120015460ff1660028111156103e5576103e5611c19565b14610406576040516317f5e2d560e11b8152600481018290526024016102d5565b6002546040516301daf29b60e21b81523360048201526001600160a01b039091169063076bca6c9060240160006040518083038186803b15801561044957600080fd5b505afa15801561045d573d6000803e3d6000fd5b5050506000838152600460205260408120600101548492509003610497576040516305ed361b60e11b8152600481018290526024016102d5565b604051601960f81b60208201526000602182018190526001600160601b031930606090811b821660228501528a901b166036830152701cdd5cdc195b9910dc9959195b9d1a585b607a1b604a830152605b820185905290607b0160408051601f1981840301815282825280516020918201206000845290830180835281905260ff8a16918301919091526060820188905260808201879052915061056f90899060019060a0016020604051602081039080840390855afa15801561055f573d6000803e3d6000fd5b5050506020604051035186611303565b5050505050505050565b6000838152600460205260409020600101548390156105ae57604051631011c86360e21b8152600481018290526024016102d5565b6002546040516301daf29b60e21b81523360048201526001600160a01b039091169063076bca6c9060240160006040518083038186803b1580156105f157600080fd5b505afa158015610605573d6000803e3d6000fd5b5050600354604051639f889db560e01b8152600481018990528893506001600160a01b039091169150639f889db5906024016000604051808303816000875af1158015610656573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261067e9190810190611caa565b5061068c87338787876113e6565b50505050505050565b8060026000828152600460208190526040909120015460ff1660028111156106bf576106bf611c19565b036106e057604051631fb5de4d60e31b8152600481018290526024016102d5565b6002546040516301daf29b60e21b81523360048201526001600160a01b039091169063076bca6c9060240160006040518083038186803b15801561072357600080fd5b505afa158015610737573d6000803e3d6000fd5b5050506000838152600460205260408120600101548492509003610771576040516305ed361b60e11b8152600481018290526024016102d5565b604051601960f81b60208201526000602182018190526001600160601b031930606090811b821660228501528a901b1660368301526f1c995d9bdad950dc9959195b9d1a585b60821b604a830152605a820185905290607a0160408051601f1981840301815282825280516020918201206000845290830180835281905260ff8a16918301919091526060820188905260808201879052915061056f90899060019060a0016020604051602081039080840390855afa158015610838573d6000803e3d6000fd5b50505060206040510351866114c9565b80600080828152600460208190526040909120015460ff16600281111561087157610871611c19565b0361089257604051639779315960e01b8152600481018290526024016102d5565b6002546040516301daf29b60e21b81523360048201526001600160a01b039091169063076bca6c9060240160006040518083038186803b1580156108d557600080fd5b505afa1580156108e9573d6000803e3d6000fd5b5050506000838152600460205260408120600101548492509003610923576040516305ed361b60e11b8152600481018290526024016102d5565b604051601960f81b60208201526000602182018190526001600160601b031930606090811b821660228501528a901b166036830152711d5b9c995d9bdad950dc9959195b9d1a585b60721b604a830152605c820185905290607c0160408051601f1981840301815282825280516020918201206000845290830180835281905260ff8a16918301919091526060820188905260808201879052915061056f90899060019060a0016020604051602081039080840390855afa1580156109ec573d6000803e3d6000fd5b5050506020604051035186610fff565b600083815260046020526040902060010154839015610a3157604051631011c86360e21b8152600481018290526024016102d5565b6002546040516301daf29b60e21b81523360048201526001600160a01b039091169063076bca6c9060240160006040518083038186803b158015610a7457600080fd5b505afa158015610a88573d6000803e3d6000fd5b5050600354604051639f889db560e01b8152600481018990528893506001600160a01b039091169150639f889db5906024016000604051808303816000875af1158015610ad9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b019190810190611caa565b50604051601960f81b60208201526000602182018190526001600160601b031930606090811b821660228501528d901b1660368301527f6372656174655265766f636174696f6e52656769737472790000000000000000604a830152606282018790529060820160408051601f1981840301815282825280516020918201206000845290830180835281905260ff8d1691830191909152606082018b9052608082018a90529150610be8908c9060019060a0016020604051602081039080840390855afa158015610bd6573d6000803e3d6000fd5b505050602060405103518888886113e6565b5050505050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805460019190600160401b900460ff1680610c3e575080546001600160401b03808416911610155b15610c5c5760405163f92ee8a960e01b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610c86856115ac565b600380546001600160a01b038681166001600160a01b0319928316179092556002805492861692909116919091179055805468ff0000000000000000191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b80600080828152600460208190526040909120015460ff166002811115610d3257610d32611c19565b14610d53576040516317f5e2d560e11b8152600481018290526024016102d5565b6002546040516301daf29b60e21b81523360048201526001600160a01b039091169063076bca6c9060240160006040518083038186803b158015610d9657600080fd5b505afa158015610daa573d6000803e3d6000fd5b5050506000838152600460205260408120600101548492509003610de4576040516305ed361b60e11b8152600481018290526024016102d5565b61037a843385611303565b610df76117f7565b600082815260046020526040908190208151808301909252805482908290610e1e90611d7d565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4a90611d7d565b8015610e975780601f10610e6c57610100808354040283529160200191610e97565b820191906000526020600020905b815481529060010190602001808311610e7a57829003601f168201915b50505091835250506040805160808101825260018401805482526002808601546001600160a01b03166020848101919091526003870154948401949094526004860154939094019391929091606084019160ff1690811115610efb57610efb611c19565b6002811115610f0c57610f0c611c19565b90525090525092915050565b8060026000828152600460208190526040909120015460ff166002811115610f4257610f42611c19565b03610f6357604051631fb5de4d60e31b8152600481018290526024016102d5565b6002546040516301daf29b60e21b81523360048201526001600160a01b039091169063076bca6c9060240160006040518083038186803b158015610fa657600080fd5b505afa158015610fba573d6000803e3d6000fd5b5050506000838152600460205260408120600101548492509003610ff4576040516305ed361b60e11b8152600481018290526024016102d5565b61037a8433856114c9565b8282806001600160a01b0316826001600160a01b031614611046576040516316343f1760e31b81526001600160a01b038083166004830152831660248201526044016102d5565b60008381526004602052604090206002015483906001600160a01b0316331461108557604051636a30256b60e01b8152600481018290526024016102d5565b600084815260046020818152604092839020918201805460ff191690554260039092019190915581513381529081018690527fdb163580dafb038cd13b1485440f6ebe8a82579386e20558a0664d046875e6dd91015b60405180910390a1505050505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061117257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611166600080516020611ef3833981519152546001600160a01b031690565b6001600160a01b031614155b156111905760405163703e46dd60e11b815260040160405180910390fd5b565b60005460405163574a81d760e01b81523060048201526001600160a01b0383811660248301529091169063574a81d79060440160006040518083038186803b1580156111dd57600080fd5b505afa1580156111f1573d6000803e3d6000fd5b5050505050565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611252575060408051601f3d908101601f1916820190925261124f91810190611db7565b60015b61127a57604051634c9c8ce360e01b81526001600160a01b03831660048201526024016102d5565b600080516020611ef383398151915281146112ab57604051632a87526960e21b8152600481018290526024016102d5565b6112b583836115d6565b505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111905760405163703e46dd60e11b815260040160405180910390fd5b8282806001600160a01b0316826001600160a01b03161461134a576040516316343f1760e31b81526001600160a01b038083166004830152831660248201526044016102d5565b60008381526004602052604090206002015483906001600160a01b0316331461138957604051636a30256b60e01b8152600481018290526024016102d5565b600084815260046020818152604092839020918201805460ff191660011790554260039092019190915581513381529081018690527fb32212b4b379a83be8b70b861923dd9e3005a1345479bf6bb0b35b974da7e14791016110db565b8484806001600160a01b0316826001600160a01b03161461142d576040516316343f1760e31b81526001600160a01b038083166004830152831660248201526044016102d5565b6000858152600460205260409020611446848683611e17565b506000858152600460208181526040928390204260018201819055600282018054336001600160a01b0319909116811790915560038301919091559201805460ff19169055825191825281018790527f6c44b4d67cb7e3ad0e80b3290a3c81a1064334098034e0a639f4f6240b4f9406910160405180910390a150505050505050565b8282806001600160a01b0316826001600160a01b031614611510576040516316343f1760e31b81526001600160a01b038083166004830152831660248201526044016102d5565b60008381526004602052604090206002015483906001600160a01b0316331461154f57604051636a30256b60e01b8152600481018290526024016102d5565b600084815260046020818152604092839020918201805460ff191660021790554260039092019190915581513381529081018690527f3026993f4e06fc52b2f2f8ee2035821b9b29172ab964da353b6ba3c89133727e91016110db565b6115b461162c565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6115df82611675565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115611624576112b582826116da565b61039b611750565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661119057604051631afcd79f60e31b815260040160405180910390fd5b806001600160a01b03163b6000036116ab57604051634c9c8ce360e01b81526001600160a01b03821660048201526024016102d5565b600080516020611ef383398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b0316846040516116f79190611ed6565b600060405180830381855af49150503d8060008114611732576040519150601f19603f3d011682016040523d82523d6000602084013e611737565b606091505b509150915061174785838361176f565b95945050505050565b34156111905760405163b398979f60e01b815260040160405180910390fd5b6060826117845761177f826117ce565b6117c7565b815115801561179b57506001600160a01b0384163b155b156117c457604051639996b31560e01b81526001600160a01b03851660048201526024016102d5565b50805b9392505050565b8051156117de5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6040518060400160405280606081526020016118316040805160808101825260008082526020820181905291810182905290606082015290565b905290565b80356001600160a01b038116811461184d57600080fd5b919050565b6000806040838503121561186557600080fd5b61186e83611836565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156118b4576118b461187c565b60405290565b604051602081016001600160401b03811182821017156118b4576118b461187c565b604051601f8201601f191681016001600160401b03811182821017156119045761190461187c565b604052919050565b60006001600160401b038211156119255761192561187c565b50601f01601f191660200190565b6000806040838503121561194657600080fd5b61194f83611836565b915060208301356001600160401b0381111561196a57600080fd5b8301601f8101851361197b57600080fd5b803561198e6119898261190c565b6118dc565b8181528660208385010111156119a357600080fd5b816020840160208301376000602083830101528093505050509250929050565b803560ff8116811461184d57600080fd5b600080600080600060a086880312156119ec57600080fd5b6119f586611836565b9450611a03602087016119c3565b94979496505050506040830135926060810135926080909101359150565b60008083601f840112611a3357600080fd5b5081356001600160401b03811115611a4a57600080fd5b602083019150836020828501011115611a6257600080fd5b9250929050565b600080600080600060808688031215611a8157600080fd5b611a8a86611836565b9450602086013593506040860135925060608601356001600160401b03811115611ab357600080fd5b611abf88828901611a21565b969995985093965092949392505050565b60008060008060008060008060e0898b031215611aec57600080fd5b611af589611836565b9750611b0360208a016119c3565b965060408901359550606089013594506080890135935060a0890135925060c08901356001600160401b03811115611b3a57600080fd5b611b468b828c01611a21565b999c989b5096995094979396929594505050565b60005b83811015611b75578181015183820152602001611b5d565b50506000910152565b60008151808452611b96816020860160208601611b5a565b601f01601f19169290920160200192915050565b6020815260006117c76020830184611b7e565b600080600060608486031215611bd257600080fd5b611bdb84611836565b9250611be960208501611836565b9150611bf760408501611836565b90509250925092565b600060208284031215611c1257600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b602081526000825160a06020840152611c4b60c0840182611b7e565b905060208401518051604085015260018060a01b036020820151166060850152604081015160808501526060810151905060038110611c9a57634e487b7160e01b600052602160045260246000fd5b60a0939093019290925250919050565b600060208284031215611cbc57600080fd5b81516001600160401b03811115611cd257600080fd5b82018084036040811215611ce557600080fd5b611ced611892565b82516001600160401b03811115611d0357600080fd5b8301601f81018713611d1457600080fd5b8051611d226119898261190c565b818152886020838501011115611d3757600080fd5b611d48826020830160208601611b5a565b835250506020601f1983011215611d5e57600080fd5b611d666118ba565b602093840151815292810192909252509392505050565b600181811c90821680611d9157607f821691505b602082108103611db157634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215611dc957600080fd5b5051919050565b601f8211156112b557806000526020600020601f840160051c81016020851015611df75750805b601f840160051c820191505b818110156111f15760008155600101611e03565b6001600160401b03831115611e2e57611e2e61187c565b611e4283611e3c8354611d7d565b83611dd0565b6000601f841160018114611e765760008515611e5e5750838201355b600019600387901b1c1916600186901b1783556111f1565b600083815260209020601f19861690835b82811015611ea75786850135825560209485019460019092019101611e87565b5086821015611ec45760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008251611ee8818460208701611b5a565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca264697066735822122031520613c3bb19cd4ad53aee460e59c106794eb737b71883210abfc34a5e8b3c64736f6c634300081a0033" + } } } diff --git a/smart_contracts/contracts-ts/RevocationRegistry.ts b/smart_contracts/contracts-ts/RevocationRegistry.ts new file mode 100644 index 00000000..3cdd1865 --- /dev/null +++ b/smart_contracts/contracts-ts/RevocationRegistry.ts @@ -0,0 +1,119 @@ +import { concat, getBytes, keccak256, Signature, toUtf8Bytes, toUtf8String } from 'ethers' +import { RevocationMetadataStruct } from '../typechain-types/contracts/revoke/RevocationRegistry' +import { Contract } from '../utils/contract' + +export type RevocationRecord = { + revocationRecord: any + revocation: string + metadata: RevocationMetadataStruct +} + +export class RevocationRegistry extends Contract { + constructor(sender?: any) { + super(RevocationRegistry.name, sender) + } + + public async createRevocationRegistry( + identity: string, + CredDefId: string, + revocationRegistryId: string, + revocationDocumente: string, + ) { + const tx = await this.instance.createRevocationRegistry( + identity, + keccak256(toUtf8Bytes(CredDefId)), + keccak256(toUtf8Bytes(revocationRegistryId)), + toUtf8Bytes(revocationDocumente), + ) + return tx.wait() + } + + public async createCredentialDefinitionSigned( + identity: string, + CredDefId: string, + revocationRegistryId: string, + revocationDocumente: string, + signature: Signature, + ) { + const tx = await this.instance.createRevocationRegistrySigned( + identity, + signature.v, + signature.r, + signature.s, + keccak256(toUtf8Bytes(CredDefId)), + keccak256(toUtf8Bytes(revocationRegistryId)), + toUtf8Bytes(revocationDocumente), + ) + return tx.wait() + } + + public async resolveRevocation(id: string): Promise { + const record = await this.instance.resolveRevocation(keccak256(toUtf8Bytes(id))) + return record.metadata.status + } + + public signCreateRevocationWithEndorsementData( + identity: string, + privateKey: Uint8Array, + id: string, + revocation: string, + ) { + return this.signEndorsementData( + privateKey, + concat([ + identity, + toUtf8Bytes('createRevocationRegistry'), + getBytes(keccak256(toUtf8Bytes(id)), 'hex'), + toUtf8Bytes(revocation), + ]), + ) + } + + public async revokeCredential(identity: string, id: string) { + const tx = await this.instance.revokeCredential(identity, keccak256(toUtf8Bytes(id))) + return tx.wait() + } + + public async revokeCredentialSigned(identity: string, signature: Signature, id: string) { + const tx = await this.instance.revokeCredentialSigned( + identity, + signature.v, + signature.r, + signature.s, + keccak256(toUtf8Bytes(id)), + ) + return tx.wait() + } + + public async suspendCredential(identity: string, id: string) { + const tx = await this.instance.suspendCredential(identity, keccak256(toUtf8Bytes(id))) + return tx.wait() + } + + public async suspendCredentialSigned(identity: string, signature: Signature, id: string) { + const tx = await this.instance.suspendCredentialSigned( + identity, + signature.v, + signature.r, + signature.s, + keccak256(toUtf8Bytes(id)), + ) + return tx.wait() + } + + public async unrevokeCredential(identity: string, id: string) { + const tx = await this.instance.unrevokeCredential(identity, keccak256(toUtf8Bytes(id))) + return tx.wait() + } + + public async unrevokeCredentialSigned(identity: string, signature: Signature, id: string) { + const tx = await this.instance.unrevokeCredentialSigned( + identity, + signature.v, + signature.r, + signature.s, + keccak256(toUtf8Bytes(id)), + ) + return tx.wait() + } +} diff --git a/smart_contracts/contracts-ts/index.ts b/smart_contracts/contracts-ts/index.ts index b12ce4e7..fdfd21cf 100644 --- a/smart_contracts/contracts-ts/index.ts +++ b/smart_contracts/contracts-ts/index.ts @@ -8,3 +8,4 @@ export * from './UniversalDidReolver' export * from './UpgradeControl' export * from './ValidatorControl' export * from './LegacyMappingRegistry' +export * from './RevocationRegistry' diff --git a/smart_contracts/contracts/anoncreds/AnoncredsErrors.sol b/smart_contracts/contracts/anoncreds/AnoncredsErrors.sol index 9723d2f7..952648fa 100644 --- a/smart_contracts/contracts/anoncreds/AnoncredsErrors.sol +++ b/smart_contracts/contracts/anoncreds/AnoncredsErrors.sol @@ -48,3 +48,53 @@ error CredentialDefinitionAlreadyExist(bytes32 id); * @param id Keccak hash of Credential definition ID. */ error CredentialDefinitionNotFound(bytes32 id); + +// Revocation errors + +/** + * @notice Error that occurs when the specified revocation is not found. + * @param id Keccak hash of Revocation ID. + */ +error RevocationNotFound(bytes32 id); + +/** + * @notice Error that occurs when trying to create a revocation with an already existing identifier. + * @param id Keccak hash of Revocation ID. + */ +error RevocationAlreadyExist(bytes32 id); + +/** + * @notice Error that occurs when trying to revoke a credential without being listed in the Revocation registry. + * @param id Keccak hash of Revocation ID. + */ +error RevocationDoesntExist(bytes32 id); + +/** + * @notice Error that occurs when attempting to perform an operation on a revocation that is not active. + * @param id Keccak hash of Revocation ID. + */ +error RevocationIsNotActived(bytes32 id); + +/** + * @notice Error that occurs when attempting to perform an operation on a revocation that is not suspended. + * @param id Keccak hash of Revocation ID. + */ +error RevocationIsNotsuspended(bytes32 id); + +/** + * @notice Error that occurs when attempting to perform an operation on a revocation that is not revoked. + * @param id Keccak hash of Revocation ID. + */ +error RevocationIsNotRevoked(bytes32 id); + +/** + * @notice Error that occurs when attempting to revoke a credential that is already revoked. + * @param id Keccak hash of Credential ID. + */ +error CredentialIsAlreadyRevoked(bytes32 id); + +/** + * @notice Error that occurs when the specified issuer is invalid. + * @param id Keccak hash of Issuer ID. + */ +error InvalidIssuer(bytes32 id); diff --git a/smart_contracts/contracts/revoke/RevocationRegistry.sol b/smart_contracts/contracts/revoke/RevocationRegistry.sol new file mode 100644 index 00000000..a802adb4 --- /dev/null +++ b/smart_contracts/contracts/revoke/RevocationRegistry.sol @@ -0,0 +1,296 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.20; + +import { UniversalDidResolverInterface } from "../did/UniversalDidResolverInterface.sol"; +import { IndyDidRegistryInterface } from "../did/IndyDidRegistryInterface.sol"; +import { ControlledUpgradeable } from "../upgrade/ControlledUpgradeable.sol"; +import { RevocationRegistryInterface } from "./RevocationRegistryInterface.sol"; +import { CredentialDefinitionRecord } from "../anoncreds/CredentialDefinitionTypes.sol"; +import { CredentialDefinitionRegistryInterface } from "../anoncreds/CredentialDefinitionRegistryInterface.sol"; +import { RevocationRecord, Status } from "./RevocationRegistryTypes.sol"; +import { AnoncredsRegistry } from "../anoncreds/AnoncredsRegistry.sol"; +import { RevocationNotFound, RevocationAlreadyExist, CredentialDefinitionNotFound, RevocationIsNotActived, RevocationIsNotsuspended, RevocationIsNotRevoked, CredentialIsAlreadyRevoked, InvalidIssuer, RevocationDoesntExist } from "../anoncreds/AnoncredsErrors.sol"; +import { RoleControlInterface } from "../auth/RoleControl.sol"; + +contract RevocationRegistry is RevocationRegistryInterface, ControlledUpgradeable, AnoncredsRegistry { + /** + * @dev Reference to the contract that manages anoncreds credDefs + */ + CredentialDefinitionRegistryInterface private _credDefRegistry; + + /** + * Mapping Revocation ID to its Revocation Details and Metadata. + */ + mapping(bytes32 id => RevocationRecord revocationRecord) private _revReg; + + /** + * Check that the revocation exist + */ + modifier _revocationExist(bytes32 id) { + if (_revReg[id].metadata.created != 0) revert RevocationAlreadyExist(id); + _; + } + + /** + * Check that the revocation does not exist + */ + modifier _revocationNotExist(bytes32 id) { + if (_revReg[id].metadata.created == 0) revert RevocationDoesntExist(id); + _; + } + + /** + * + * Check that the status is not revoked + */ + modifier _CredentialNotRevoked(bytes32 id) { + if (_revReg[id].metadata.status == Status.revoked) revert CredentialIsAlreadyRevoked(id); + _; + } + + /** + * Check that the status is not actived + */ + modifier _CredentialNotActived(bytes32 id) { + if (_revReg[id].metadata.status != Status.active) revert RevocationIsNotActived(id); + _; + } + + /** + * Check that the status is actived + */ + modifier _CredentialIsActived(bytes32 id) { + if (_revReg[id].metadata.status == Status.active) revert RevocationIsNotRevoked(id); + _; + } + + /** + * Сhecks the Issuer of revocation + */ + + modifier _checkIssuer(bytes32 id) { + if (_revReg[id].metadata.creator != msg.sender) revert InvalidIssuer(id); + _; + } + + /** + * Checks that the credDef exists + */ + modifier _credDefExist(bytes32 id) { + _credDefRegistry.resolveCredentialDefinition(id); + _; + } + + function initialize( + address upgradeControlAddress, + address credDefRegistryAddress, + address roleControlContractAddress + ) public reinitializer(1) { + _initializeUpgradeControl(upgradeControlAddress); + _credDefRegistry = CredentialDefinitionRegistryInterface(credDefRegistryAddress); + _roleControl = RoleControlInterface(roleControlContractAddress); + } + + /** + * Revoke functions: + */ + + function revokeCredential( + address identity, + bytes32 RevokId + ) public _CredentialNotRevoked(RevokId) _senderIsTrusteeOrEndorserOrSteward _revocationNotExist(RevokId) { + _revokeCredential(identity, msg.sender, RevokId); + } + + /// @inheritdoc RevocationRegistryInterface + function revokeCredentialSigned( + address identity, + uint8 sigV, + bytes32 sigR, + bytes32 sigS, + bytes32 RevokId + ) public virtual _CredentialNotRevoked(RevokId) _senderIsTrusteeOrEndorserOrSteward _revocationNotExist(RevokId) { + bytes32 hash = keccak256( + abi.encodePacked(bytes1(0x19), bytes1(0), address(this), identity, "revokeCredential", RevokId) + ); + + _revokeCredential(identity, ecrecover(hash, sigV, sigR, sigS), RevokId); + } + + /** + * Suspend functions: + */ + function suspendCredential( + address identity, + bytes32 RevokId + ) public _CredentialNotActived(RevokId) _senderIsTrusteeOrEndorserOrSteward _revocationNotExist(RevokId) { + _suspendCredential(identity, msg.sender, RevokId); + } + + /// @inheritdoc RevocationRegistryInterface + function suspendCredentialSigned( + address identity, + uint8 sigV, + bytes32 sigR, + bytes32 sigS, + bytes32 RevokId + ) public virtual _CredentialNotActived(RevokId) _senderIsTrusteeOrEndorserOrSteward _revocationNotExist(RevokId) { + bytes32 hash = keccak256( + abi.encodePacked(bytes1(0x19), bytes1(0), address(this), identity, "suspendCredential", RevokId) + ); + + _suspendCredential(identity, ecrecover(hash, sigV, sigR, sigS), RevokId); + } + + /** + * Unrevok functions: + */ + function unrevokeCredential( + address identity, + bytes32 RevokId + ) public _CredentialIsActived(RevokId) _senderIsTrusteeOrEndorserOrSteward _revocationNotExist(RevokId) { + _UnrevokedCredential(identity, msg.sender, RevokId); + } + + /// @inheritdoc RevocationRegistryInterface + function unrevokeCredentialSigned( + address identity, + uint8 sigV, + bytes32 sigR, + bytes32 sigS, + bytes32 RevokId + ) public virtual _CredentialIsActived(RevokId) _senderIsTrusteeOrEndorserOrSteward _revocationNotExist(RevokId) { + bytes32 hash = keccak256( + abi.encodePacked(bytes1(0x19), bytes1(0), address(this), identity, "unrevokeCredential", RevokId) + ); + + _UnrevokedCredential(identity, ecrecover(hash, sigV, sigR, sigS), RevokId); + } + + /** + * create Revocation functions: + */ + function createRevocationRegistry( + address identity, + bytes32 CreDefid, + bytes32 RevokId, + bytes calldata revokeDocument + ) public + _revocationExist(RevokId) + _senderIsTrusteeOrEndorserOrSteward + _credDefExist(CreDefid) + { + _createRevocation(identity, msg.sender, RevokId, revokeDocument); + } + + /// @inheritdoc RevocationRegistryInterface + function createRevocationRegistrySigned( + address identity, + uint8 sigV, + bytes32 sigR, + bytes32 sigS, + bytes32 CreDefid, + bytes32 RevokId, + bytes calldata revokeDocument + ) public virtual _revocationExist(RevokId) _senderIsTrusteeOrEndorserOrSteward _credDefExist(CreDefid) { + bytes32 hash = keccak256( + abi.encodePacked(bytes1(0x19), bytes1(0), address(this), identity, "createRevocationRegistry", RevokId) + ); + + _createRevocation(identity, ecrecover(hash, sigV, sigR, sigS), RevokId, revokeDocument); + } + + /** + * Create Revocation functions: + */ + + function _createRevocation( + address identity, + address actor, + bytes32 RevokId, + bytes calldata document + ) + private + _identityOwner(identity, actor) // the sender must be equal to the identity + { + _revReg[RevokId].document = document; + _revReg[RevokId].metadata.created = block.timestamp; + _revReg[RevokId].metadata.creator = msg.sender; + _revReg[RevokId].metadata.updated = block.timestamp; + _revReg[RevokId].metadata.status = Status.active; + + emit RevocationCreated(msg.sender, RevokId); + } + + /** + * Revok Credential functions: + */ + + function _revokeCredential( + address identity, + address actor, + bytes32 RevokId + ) + private + _identityOwner(identity, actor) // the sender must be equal to the identity + _checkIssuer(RevokId) + { + _revReg[RevokId].metadata.status = Status.revoked; + _revReg[RevokId].metadata.updated = block.timestamp; + + ///credential revocation event + emit CredentialRevoked(msg.sender, RevokId); + } + + /** + * suspend Credential functions: + */ + + function _suspendCredential( + address identity, + address actor, + bytes32 RevokId + ) + private + _identityOwner(identity, actor) // the sender must be equal to the identity + _checkIssuer(RevokId) + { + _revReg[RevokId].metadata.status = Status.suspended; + _revReg[RevokId].metadata.updated = block.timestamp; + + ///suspended credential event + emit CredentialSuspended(msg.sender, RevokId); + } + + /** + * Unrevoke Credential functions: + */ + + function _UnrevokedCredential( + address identity, + address actor, + bytes32 RevokId + ) + private + _identityOwner(identity, actor) // the sender must be equal to the identity + _checkIssuer(RevokId) + { + _revReg[RevokId].metadata.status = Status.active; + _revReg[RevokId].metadata.updated = block.timestamp; + + ///credential Unrevoked event + emit CredentialUnrevoked(msg.sender, RevokId); + } + + /** + * Resolve Revocation functions: + */ + + /// @inheritdoc RevocationRegistryInterface + function resolveRevocation(bytes32 RevokId) public view returns (RevocationRecord memory revocationRecord) { + return _revReg[RevokId]; + } + + + +} diff --git a/smart_contracts/contracts/revoke/RevocationRegistryInterface.sol b/smart_contracts/contracts/revoke/RevocationRegistryInterface.sol new file mode 100644 index 00000000..90f81cd8 --- /dev/null +++ b/smart_contracts/contracts/revoke/RevocationRegistryInterface.sol @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.20; + +import { RevocationRecord } from "./RevocationRegistryTypes.sol"; + +interface RevocationRegistryInterface { + /** + * @dev Event emitted when a revocation is created + * @param sender Address of the sender + * @param revocationId ID of the created revocation + */ + event RevocationCreated(address sender, bytes32 revocationId); + + /** + * @dev Event emitted when a credential is revoked + * @param sender Address of the sender + * @param revocationId ID of the revoked credential + */ + event CredentialRevoked(address sender, bytes32 revocationId); + + /** + * @dev Event emitted when a credential is suspended + * @param sender Address of the sender + * @param revocationId ID of the suspended credential + */ + event CredentialSuspended(address sender, bytes32 revocationId); + + /** + * @dev Event emitted when a credential is unrevoked + * @param sender Address of the sender + * @param revocationId ID of the unrevoked credential + */ + event CredentialUnrevoked(address sender, bytes32 revocationId); + + /** + * @notice Function to revoke a credential + * @param identity The address of the identity + * @param id The id of revogation + * */ + function revokeCredential(address identity, bytes32 id) external; + + /** + * @notice Function to revoke a credential with a signed message + * @param identity The address of the identity + * @param sigV The V part of the signature + * @param sigR The R part of the signature + * @param sigS The S part of the signature + * @param id The id of revogation + */ + function revokeCredentialSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 id) external; + + /** + * @notice Function to suspend a credential + * @param identity The address of the identity + * @param id The id of revogation + * d + */ + function suspendCredential(address identity, bytes32 id) external; + + /** + * @notice Function to suspend a credential with a signed message + * @param identity The address of the identity + * @param sigV The V part of the signature + * @param sigR The R part of the signature + * @param sigS The S part of the signature + * @param id The id of revogation + * d + */ + function suspendCredentialSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 id) external; + + /** + * @notice Function to unrevoke a credential + * @param identity The address of the identity + * @param id The id of revogation + * d + */ + function unrevokeCredential(address identity, bytes32 id) external; + + /** + * @notice Function to unrevoke a credential with a signed message + * @param identity The address of the identity + * @param sigV The V part of the signature + * @param sigR The R part of the signature + * @param sigS The S part of the signature + * @param id The id of revogation + * d + */ + function unrevokeCredentialSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 id) external; + + /** + * @notice Function to create a revocation registry + * @param identity The address of the identity + * @param CredDefId The ID of the credential registry + * @param RevicationId The ID of the revocation registry to be created + * @param revokeDocument The document of the revocation + */ + function createRevocationRegistry( + address identity, + bytes32 CredDefId, + bytes32 RevicationId, + bytes calldata revokeDocument + ) external; + + /** + * @notice Function to create a revocation registry with a signed message + * @param identity The address of the identity + * @param sigV The V part of the signature + * @param sigR The R part of the signature + * @param sigS The S part of the signature + * @param CredDefId The ID of the credential registry + * @param RevicationId The ID of the revocation registry to be created + * @param revokeDocument The document of the revocation + */ + function createRevocationRegistrySigned( + address identity, + uint8 sigV, + bytes32 sigR, + bytes32 sigS, + bytes32 CredDefId, + bytes32 RevicationId, + bytes calldata revokeDocument + ) external; + + /** + * @notice Function to resolve a revocation + * @param id The ID of the revocation to be resolved + * @return The RevocationRecord associated with the given ID + */ + function resolveRevocation(bytes32 id) external view returns (RevocationRecord memory); + + +} diff --git a/smart_contracts/contracts/revoke/RevocationRegistryTypes.sol b/smart_contracts/contracts/revoke/RevocationRegistryTypes.sol new file mode 100644 index 00000000..5476dc1e --- /dev/null +++ b/smart_contracts/contracts/revoke/RevocationRegistryTypes.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.20; + +/** + * @title RevocationRecord + * @dev This struct holds the details of a Revocation + * and its associated metadata. + * + * @param document The revocation document in bytes. + * @param metadata Additional metadata associated with the revocation. + */ +struct RevocationRecord { + bytes document; + RevocationMetadata metadata; +} + +/** + * @title RevocationMetadata + * @dev This struct holds additional metadata for a Revocation. + * + * @param created Timestamp indicating when the revocation was created. + * @param creator The address of the creator of the revocation. + * @param updated Timestamp indicating when the revocation was last updated. + * @param status The current status of the revocation (active, suspended, revoked). + */ +struct RevocationMetadata { + uint256 created; + address creator; + uint256 updated; + Status status; +} + +/** + * @title Status + * @dev Enum representing the possible statuses of a revocation. + * + * @param active Indicates that the revocation is currently active. + * @param suspended Indicates that the revocation is currently suspended. + * @param revoked Indicates that the revocation has been revoked. + */ +enum Status { + active, + suspended, + revoked +} diff --git a/smart_contracts/contracts/upgrade/ControlledUpgradeable.sol b/smart_contracts/contracts/upgrade/ControlledUpgradeable.sol index 6f00d722..84bf65d2 100644 --- a/smart_contracts/contracts/upgrade/ControlledUpgradeable.sol +++ b/smart_contracts/contracts/upgrade/ControlledUpgradeable.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.20; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; -import { UpgradeControlInterface } from "contracts/upgrade/UpgradeControlInterface.sol"; +import { UpgradeControlInterface } from "./UpgradeControlInterface.sol"; /** * @title ControlledUpgradeable diff --git a/smart_contracts/demos/flow.ts b/smart_contracts/demos/flow.ts index fd08f751..02e3e2b2 100644 --- a/smart_contracts/demos/flow.ts +++ b/smart_contracts/demos/flow.ts @@ -1,10 +1,11 @@ import environment from '../environment' import { Actor } from './utils/actor' import { ROLES } from '../contracts-ts' -import { createCredentialDefinitionObject, createSchemaObject } from '../utils' +import { createCredentialDefinitionObject, createRevocationRegistryObject, createSchemaObject } from '../utils' async function demo() { let receipt: any + let verify: any const trustee = await new Actor(environment.accounts.account1).init() const faber = await new Actor().init() @@ -14,13 +15,16 @@ async function demo() { receipt = await trustee.roleControl.assignRole(ROLES.ENDORSER, faber.address) console.log(`Role ${ROLES.ENDORSER} assigned to account ${faber.address}. Receipt: ${JSON.stringify(receipt)}`) + const issuerAddress = faber.address + const issuerId = `did:indybesu:mainnet:${issuerAddress}` + console.log('2. Faber creates DID Document') - receipt = await faber.didRegistry.createDid(faber.address, faber.didDocument) - console.log(`Did Document created for DID ${faber.did}. Receipt: ${JSON.stringify(receipt)}`) + receipt = await faber.didRegistry.createDid(issuerAddress, faber.didDocument) + console.log(`Did Document created for DID ${issuerId}. Receipt: ${JSON.stringify(receipt)}`) console.log('3. Faber creates Test Schema') - const { id: schemaId, schema } = createSchemaObject({ issuerId: faber.did }) - receipt = await faber.schemaRegistry.createSchema(faber.address, schemaId, faber.did, schema) + const { id: schemaId, schema } = createSchemaObject({ issuerId }) + receipt = await faber.schemaRegistry.createSchema(issuerAddress, schemaId, issuerId, schema) console.log(`Schema created for id ${schemaId}. Receipt: ${JSON.stringify(receipt)}`) console.log('4. Faber resolves Test Schema to ensure its written') @@ -29,13 +33,13 @@ async function demo() { console.log('5. Faber create Test Credential Definition') const { id: credentialDefinitionId, credDef: credentialDefinition } = createCredentialDefinitionObject({ - issuerId: faber.did, - schemaId: schemaId, + issuerId, + schemaId, }) receipt = await faber.credentialDefinitionRegistry.createCredentialDefinition( - faber.address, + issuerAddress, credentialDefinitionId, - faber.did, + issuerId, schemaId, credentialDefinition, ) @@ -50,8 +54,8 @@ async function demo() { ) console.log("7. ALice resolves Faber's Did Document") - const faberDidDocument = await alice.didRegistry.resolveDid(faber.address) - console.log(`Did Document resolved for ${faber.did}. DID Document: ${faberDidDocument?.document}`) + const faberDidDocument = await alice.didRegistry.resolveDid(issuerAddress) + console.log(`Did Document resolved for ${issuerId}. DID Document: ${faberDidDocument?.document}`) console.log('8. Alice resolves Test Schema') const testSchema = await alice.schemaRegistry.resolveSchema(schemaId) @@ -64,6 +68,45 @@ async function demo() { console.log( `Credential Definition resolved for ${credentialDefinitionId}. Credential Definition: ${testCredentialDefinition.credDef}`, ) + + // Revocations + + console.log('10. Faber creates Test Revocation Registry') + const { revRegId, revReg } = createRevocationRegistryObject({ + issuerId, + }) + + receipt = await faber.revocationRegistry.createRevocationRegistry( + issuerAddress, + credentialDefinitionId, + revRegId, + revReg, + ) + console.log(`Revocation Registry created for id ${revRegId}. Receipt: ${JSON.stringify(receipt)}`) + + console.log('11. Alice resolves the Revocation Registry') + const resolvedRevocationRegistry = await alice.revocationRegistry.resolveRevocation(revRegId) + const replacer = (key, value) => (typeof value === 'bigint' ? value.toString() : value) + verify = JSON.stringify(resolvedRevocationRegistry, replacer, 2) + if (verify === '"0"') { + verify = 'Revocation Registry actived' + } else { + verify = 'Revocation Registry is Not actived' + } + console.log(`Revocation Registry resolved for ${revRegId}. Revocation Registry: ${verify}`) + + console.log('12. Faber revokes a credential') + receipt = await faber.revocationRegistry.revokeCredential(issuerAddress, revRegId) + console.log(`Credential revoked. Receipt: ${receipt}`) + + console.log('12. Alice checks if the credential is revoked') + const isRevoked = await alice.revocationRegistry.resolveRevocation(revRegId) + verify = JSON.stringify(isRevoked, replacer, 2) + if (verify === '"2"') { + console.log(`Credential is revoked!`) + } else { + console.log(`Credential is not revoked!`) + } } if (require.main === module) { diff --git a/smart_contracts/demos/utils/actor.ts b/smart_contracts/demos/utils/actor.ts index 43242ffa..2c58b5a4 100644 --- a/smart_contracts/demos/utils/actor.ts +++ b/smart_contracts/demos/utils/actor.ts @@ -7,6 +7,7 @@ import { ValidatorControl, UpgradeControl, EthereumExtDidRegistry, + RevocationRegistry, } from '../../contracts-ts' import { Account, AccountInfo } from '../../utils' @@ -19,6 +20,7 @@ export class Actor { public schemaRegistry!: SchemaRegistry public credentialDefinitionRegistry!: CredentialDefinitionRegistry public upgradeControl!: UpgradeControl + public revocationRegistry!: RevocationRegistry constructor(accountInfo?: AccountInfo) { this.account = accountInfo ? new Account(accountInfo) : new Account() @@ -39,6 +41,9 @@ export class Actor { contracts.credDefRegistry.address, ) this.upgradeControl = await new UpgradeControl(this.account).getInstance(contracts.upgradeControl.address) + this.revocationRegistry = await new RevocationRegistry(this.account).getInstance( + contracts.revocationRegistry.address, + ) return this } diff --git a/smart_contracts/scripts/genesis/contracts/index.ts b/smart_contracts/scripts/genesis/contracts/index.ts index 7a2f5f4e..71ecea72 100644 --- a/smart_contracts/scripts/genesis/contracts/index.ts +++ b/smart_contracts/scripts/genesis/contracts/index.ts @@ -8,3 +8,4 @@ export * from './universalDidResolver' export * from './upgradeControl' export * from './validatorControl' export * from './legacyMappingRegistry' +export * from './revocationRegistry' diff --git a/smart_contracts/scripts/genesis/contracts/revocationRegistry.ts b/smart_contracts/scripts/genesis/contracts/revocationRegistry.ts new file mode 100644 index 00000000..0135925d --- /dev/null +++ b/smart_contracts/scripts/genesis/contracts/revocationRegistry.ts @@ -0,0 +1,25 @@ +import { padLeft } from 'web3-utils' +import { ContractConfig } from '../contractConfig' +import { buildProxySection, slots } from '../helpers' + +export interface RevocationConfig extends ContractConfig { + data: { + credDefRegistryAddress: string + upgradeControlAddress: string + roleControlContractAddress: string + } +} + +export function revocationRegistry(config: RevocationConfig) { + const { name, address, description, data } = config + const storage: any = {} + + // address of upgrade control contact stored in slot 0 + storage[slots['0']] = padLeft(data.upgradeControlAddress, 64) + // address of Credential Definition registry contact stored in slot 2 + storage[slots['1']] = padLeft(data.credDefRegistryAddress, 64) + // address of Role control contact stored in slot 3 + storage[slots['2']] = padLeft(data.roleControlContractAddress, 64) + + return buildProxySection(name, address, description, storage) +} diff --git a/smart_contracts/scripts/genesis/generate.ts b/smart_contracts/scripts/genesis/generate.ts index 7d186950..0b674012 100644 --- a/smart_contracts/scripts/genesis/generate.ts +++ b/smart_contracts/scripts/genesis/generate.ts @@ -5,6 +5,7 @@ import { ethereumDidRegistry, indyDidRegistry, legacyMappingRegistry, + revocationRegistry, roleControl, schemaRegistry, universalDidResolver, @@ -27,6 +28,7 @@ function main() { ...schemaRegistry(config.schemaRegistry), ...credentialDefinitionRegistry(config.credentialDefinitionRegistry), ...legacyMappingRegistry(config.legacyMapping), + ...revocationRegistry(config.revocationRegistry), } writeJson(contracts, 'ContractsGenesis.json') } diff --git a/smart_contracts/scripts/genesis/helpers.ts b/smart_contracts/scripts/genesis/helpers.ts index a43dbab1..5cdf7b45 100644 --- a/smart_contracts/scripts/genesis/helpers.ts +++ b/smart_contracts/scripts/genesis/helpers.ts @@ -9,6 +9,7 @@ import { EthereumDidRegistryConfig, IndyDidRegistryConfig, LegacyMappingRegistryConfig, + RevocationConfig, RolesConfig, SchemasConfig, UniversalDidResolverConfig, @@ -108,6 +109,7 @@ export interface ContractsConfigs { upgradeControl: UpgradeControlConfig validatorControl: ValidatorsConfig legacyMapping: LegacyMappingRegistryConfig + revocationRegistry: RevocationConfig } export function prepareConfig(): ContractsConfigs { @@ -251,5 +253,15 @@ export function prepareConfig(): ContractsConfigs { roleControlContractAddress: contracts.roleControl.address, }, }, + revocationRegistry: { + name: 'RevocationRegistry', + address: contracts.revocationRegistry.address, + description: 'Smart contract to manage revocation of credential definitions', + data: { + credDefRegistryAddress: contracts.credDefRegistry.address, + upgradeControlAddress: contracts.upgradeControl.address, + roleControlContractAddress: contracts.roleControl.address, + }, + }, } } diff --git a/smart_contracts/test/revoke/RevocationRegistry.spec.ts b/smart_contracts/test/revoke/RevocationRegistry.spec.ts new file mode 100644 index 00000000..329cca45 --- /dev/null +++ b/smart_contracts/test/revoke/RevocationRegistry.spec.ts @@ -0,0 +1,190 @@ +import { expect } from 'chai' +import { keccak256, toUtf8Bytes, toUtf8String, Wallet } from 'ethers' +import { IndyDidRegistry } from '../../contracts-ts' +import { createRevocationRegistryObject } from '../../utils' +import { + createCredentialDefinition, + createDid, + createSchema, + deployRevocationRegistry, + TestableCredentialDefinitionRegistry, + TestableRevocationRegistry, + TestableRoleControl, + TestableSchemaRegistry, +} from '../utils/contract-helpers' + +import { AnoncredsErrors, AuthErrors, ClErrors, DidErrors } from '../utils/errors' + +import { TestAccounts } from '../utils/test-entities' + +describe('RevocationRegistry', function () { + let didRegistry: IndyDidRegistry + let schemaRegistry: TestableSchemaRegistry + let credentialDefinitionRegistry: TestableCredentialDefinitionRegistry + let roleControl: TestableRoleControl + let testAccounts: TestAccounts + let schemaId: string + let credDefId: string + let issuerAddress: string + let issuerId: string + let revocationRegistry: TestableRevocationRegistry + + beforeEach(async function () { + const { + revocationRegistry: revocationRegistryInit, + indyDidRegistry: didRegistryInit, + schemaRegistry: schemaRegistryInit, + credentialDefinitionRegistry: credentialDefinitionRegistryInit, + roleControl: roleControlInit, + testAccounts: testAccountsInit, + } = await deployRevocationRegistry() + + didRegistryInit.connect(testAccountsInit.trustee.account) + schemaRegistryInit.connect(testAccountsInit.trustee.account) + credentialDefinitionRegistryInit.connect(testAccountsInit.trustee.account) + revocationRegistryInit.connect(testAccountsInit.trustee.account) + + issuerAddress = testAccountsInit.trustee.account.address + issuerId = `did:indybesu:mainnet:${issuerAddress}` + await createDid(didRegistryInit, issuerAddress, issuerId) + + const { id: schemaIdInit } = await createSchema(schemaRegistryInit, issuerAddress, issuerId) + schemaId = schemaIdInit + + const { id: initCredDefId } = await createCredentialDefinition( + credentialDefinitionRegistryInit, + issuerAddress, + issuerId, + schemaId, + ) + + didRegistry = didRegistryInit + testAccounts = testAccountsInit + schemaRegistry = schemaRegistryInit + credentialDefinitionRegistry = credentialDefinitionRegistryInit + roleControl = roleControlInit + credDefId = initCredDefId + revocationRegistry = revocationRegistryInit + }) + + describe('Create/Resolve Revocation', function () { + it('Should Create revocation', async function () { + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + const result = await revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg) + + expect(result).to.exist + }) + + it('Should resolve revocation', async function () { + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + await revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg) + + const result = await revocationRegistry.resolveRevocation(revRegId) + expect(result).to.equal(0) + }) + }) + + describe('Revoke/Suspend/Unrevoke Credential', function () { + it('Should suspend and Resolve Revocation Registry', async function () { + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + await revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg) + await revocationRegistry.suspendCredential(issuerAddress, revRegId) + + const status = await revocationRegistry.resolveRevocation(revRegId) + expect(status).to.equal(1) + }) + + it('Should unrevoke and Resolve Revocation Registry', async function () { + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + await revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg) + await revocationRegistry.suspendCredential(issuerAddress, revRegId) + await revocationRegistry.unrevokeCredential(issuerAddress, revRegId) + + const status = await revocationRegistry.resolveRevocation(revRegId) + expect(status).to.equal(0) + }) + + it('Should revoke and Resolve Revocation Registry', async function () { + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + await revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg) + await revocationRegistry.revokeCredential(issuerAddress, revRegId) + + const status = await revocationRegistry.resolveRevocation(revRegId) + + expect(status).to.equal(2) + }) + }) + describe('Create/Revoke/Suspend/Unrevoke Credential fail', function () { + it('should fail if trying to create a revocation registry and the revocation registry already exists', async function () { + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + await revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg) + + await expect(revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg)) + .to.be.revertedWithCustomError(revocationRegistry.baseInstance, AnoncredsErrors.RevocationAlreadyExist) + .withArgs(keccak256(toUtf8Bytes(revRegId))) + }) + it('Should fail if trying to revoke an already revoked Credential', async function () { + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + await revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg) + await revocationRegistry.revokeCredential(issuerAddress, revRegId) + + await expect(revocationRegistry.revokeCredential(issuerAddress, revRegId)) + .to.be.revertedWithCustomError(revocationRegistry.baseInstance, AnoncredsErrors.CredentialIsAlreadyRevoked) + .withArgs(keccak256(toUtf8Bytes(revRegId))) + }) + + it('Should fail if trying to suspend an already suspended Credential', async function () { + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + await revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg) + await revocationRegistry.suspendCredential(issuerAddress, revRegId) + + await expect(revocationRegistry.suspendCredential(issuerAddress, revRegId)) + .to.be.revertedWithCustomError(revocationRegistry.baseInstance, AnoncredsErrors.RevocationIsNotActived) + .withArgs(keccak256(toUtf8Bytes(revRegId))) + }) + + it('Should fail if trying to unrevoke a non-revoked Credential', async function () { + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + await revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg) + + await expect(revocationRegistry.unrevokeCredential(issuerAddress, revRegId)) + .to.be.revertedWithCustomError(revocationRegistry.baseInstance, AnoncredsErrors.RevocationIsNotRevoked) + .withArgs(keccak256(toUtf8Bytes(revRegId))) + }) + }) + + describe('Fail by not find the requirements', function () { + it('Should fail if trying to operate on a Credential with a non-existent Credential Definition', async function () { + const unknownCredentialDefinitionId = keccak256(toUtf8Bytes('unknown-cred-def-id')) + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + await expect( + revocationRegistry.createRevocationRegistry(issuerAddress, unknownCredentialDefinitionId, revRegId, revReg), + ).to.be.revertedWithCustomError( + credentialDefinitionRegistry.baseInstance, + AnoncredsErrors.CredentialDefinitionNotFound, + ) + }) + + it('Should fail if trying to operate on a Revacation without required role', async function () { + const { revRegId, revReg } = createRevocationRegistryObject({ issuerId }) + + await revocationRegistry.createRevocationRegistry(issuerAddress, credDefId, revRegId, revReg) + revocationRegistry.connect(testAccounts.noRole.account) + + await expect(revocationRegistry.revokeCredential(issuerAddress, revRegId)).to.be.revertedWithCustomError( + roleControl.baseInstance, + AuthErrors.Unauthorized, + ) + }) + }) +}) diff --git a/smart_contracts/test/upgrade/UpgradeControl.spec.ts b/smart_contracts/test/upgrade/UpgradeControl.spec.ts index 4f2fea62..3a3d76db 100644 --- a/smart_contracts/test/upgrade/UpgradeControl.spec.ts +++ b/smart_contracts/test/upgrade/UpgradeControl.spec.ts @@ -1,13 +1,11 @@ import { loadFixture } from '@nomicfoundation/hardhat-network-helpers' -import chai from 'chai' +import { expect } from 'chai' import { RoleControl } from '../../contracts-ts' import { TestableRoleControl, TestableUpgradeControl, UpgradablePrototype } from '../utils/contract-helpers' import { AuthErrors, ProxyError, UpgradeControlErrors } from '../utils/errors' import { ProxyEvents, UpgradeControlEvents } from '../utils/events' import { getTestAccounts, ZERO_ADDRESS } from '../utils/test-entities' -const { expect } = chai - describe('UpgradableControl', function () { async function deployUpgradableContractFixture() { const roleControl = await new TestableRoleControl().deployProxy({ params: [ZERO_ADDRESS] }) diff --git a/smart_contracts/test/utils/contract-helpers.ts b/smart_contracts/test/utils/contract-helpers.ts index dbb6fbcd..c5c01cd1 100644 --- a/smart_contracts/test/utils/contract-helpers.ts +++ b/smart_contracts/test/utils/contract-helpers.ts @@ -4,13 +4,15 @@ import { EthereumExtDidRegistry, IndyDidRegistry, LegacyMappingRegistry, + RevocationRegistry, RoleControl, SchemaRegistry, UniversalDidResolver, UpgradeControl, ValidatorControl, } from '../../contracts-ts' -import { Contract, createBaseDidDocument, createSchemaObject } from '../../utils' + +import { Contract, createBaseDidDocument, createCredentialDefinitionObject, createSchemaObject } from '../../utils' import { getTestAccounts, ZERO_ADDRESS } from './test-entities' export const testActorAddress = '0x2036C6CD85692F0Fb2C26E6c6B2ECed9e4478Dfd' @@ -44,6 +46,8 @@ export class TestableUniversalDidResolver extends testableContractMixin(Universa export class TestableLegacyMappingRegistry extends testableContractMixin(LegacyMappingRegistry) {} +export class TestableRevocationRegistry extends testableContractMixin(RevocationRegistry) {} + export async function deployRoleControl() { const roleControl = await new TestableRoleControl().deployProxy({ params: [ZERO_ADDRESS] }) const testAccounts = await getTestAccounts(roleControl) @@ -145,3 +149,38 @@ function testableContractMixin Contract>(Base: } } } + +export async function deployRevocationRegistry() { + const { + roleControl, + universalDidResolver, + indyDidRegistry, + schemaRegistry, + testAccounts, + credentialDefinitionRegistry, + } = await deployCredentialDefinitionRegistry() + const revocationRegistry = await new TestableRevocationRegistry().deployProxy({ + params: [ZERO_ADDRESS, credentialDefinitionRegistry.address, roleControl.address], + }) + + return { + roleControl, + credentialDefinitionRegistry, + universalDidResolver, + indyDidRegistry, + schemaRegistry, + testAccounts, + revocationRegistry, + } +} + +export async function createCredentialDefinition( + CredentialDefinition: CredentialDefinitionRegistry, + identity: string, + issuerId: string, + schemaId: string, +) { + const { id, credDef } = createCredentialDefinitionObject({ issuerId, schemaId }) + await CredentialDefinition.createCredentialDefinition(identity, id, issuerId, schemaId, credDef) + return { id, credDef } +} diff --git a/smart_contracts/test/utils/errors.ts b/smart_contracts/test/utils/errors.ts index 46d9f201..cf8800c3 100644 --- a/smart_contracts/test/utils/errors.ts +++ b/smart_contracts/test/utils/errors.ts @@ -51,3 +51,23 @@ export namespace MigrationErrors { export const InvalidEd25519Key = 'InvalidEd25519Key' export const DidMappingDoesNotExist = 'DidMappingDoesNotExist' } + +export namespace AnoncredsErrors { + // Schema errors + export const SchemaAlreadyExist = 'SchemaAlreadyExist' + export const SchemaNotFound = 'SchemaNotFound' + + // CredDef errors + export const CredentialDefinitionAlreadyExist = 'CredentialDefinitionAlreadyExist' + export const CredentialDefinitionNotFound = 'CredentialDefinitionNotFound' + + // Revocation erros + export const RevocationNotFound = 'RevocationNotFound' + export const RevocationAlreadyExist = 'RevocationAlreadyExist' + export const RevocationIsNotActived = 'RevocationIsNotActived' + export const RevocationIsNotsuspended = 'RevocationIsNotsuspended' + export const RevocationIsNotRevoked = 'RevocationIsNotRevoked' + export const CredentialIsAlreadyRevoked = 'CredentialIsAlreadyRevoked' + export const InvalidIssuer = 'InvalidIssuer' + export const RevocationDoesntExist = 'RevocationDoesntExist' +} diff --git a/smart_contracts/utils/common.ts b/smart_contracts/utils/common.ts index 843a4a2b..dff4362c 100644 --- a/smart_contracts/utils/common.ts +++ b/smart_contracts/utils/common.ts @@ -25,6 +25,7 @@ export interface ContractsConfigs { ethereumDidRegistry: ContractConfig indyDidRegistry: ContractConfig universalDidResolver: ContractConfig + revocationRegistry: ContractConfig } export interface BesuConfig { diff --git a/smart_contracts/utils/entity-factories.ts b/smart_contracts/utils/entity-factories.ts index 25067ada..77b2fc85 100644 --- a/smart_contracts/utils/entity-factories.ts +++ b/smart_contracts/utils/entity-factories.ts @@ -81,3 +81,40 @@ export function createCredentialDefinitionObject({ }), } } + +interface CreateRevocationRegistryParams { + version?: string + tag?: string + revRegId?: string + revRegDefType?: string + credDefId?: string + schemaId?: string + issuanceType?: number + tailsHash?: string + issuerId: string +} + +export function createRevocationRegistryObject({ + version = '1.0.0', + issuerId, + tag = 'BasicIdentity', + revRegDefType = 'CL_ACCUM', + schemaId = `${issuerId}/anoncreds/v0/SCHEMA/${tag}/${version}`, + revRegId = `${issuerId}/anoncreds/v0/REV_REG_DEF/${schemaId}/auth_cred-def-este4:${revRegDefType}:0`, + credDefId = `${issuerId}/anoncreds/v0/CLAIM_DEF/${schemaId}/${tag}`, + issuanceType = 0, + tailsHash = 'AAAAA', +}: CreateRevocationRegistryParams) { + return { + revRegId, + revReg: JSON.stringify({ + version, + revRegId, + type: revRegDefType, + credentialDefinitionId: credDefId, + issuanceType, + tailsHash, + issuerId, + }), + } +}