# A Universal Privacy-Preserving Multi-Blockchain Aggregated Identity Scheme
## 3 System Design
### Smart Contracts  
The IDNFT contract is the core part of implementing the business logic of the identity management system. The contract is shown in Figure 2.  
The four mappings are used to record the expiration time of the identity, record the corresponding relationship between the user's admin account and the user data, record the corresponding relationship between the user's admin account and the identity NFT, and control the validity of the identity. The struct userData includes the id of an identity NFT, an accumulator value, and the public key parameters of the accumulator. Algorithm 1 is used to mint the NFT to store some immutable data. The NFT data is stored in IPFS with the storage path fileUrl, which will be used as the token URL of the NFT. The function will then set the identity NFT's expiration time and unlock the identity. ```
Input:  string tokenURL, address to, uint expirationTime 1:_mint(to, tokenURL) 2:updateExpirationTime(NFTId, expirationTime) 3:unlockIDNFT(NFTId, True) 4:AdminToUserData[to].NFTId=NFTId
```  
**Algorithm 1**mintIDNFT () public onlyOwner  
Some of the main functions of the IDNFT contract are shown in Algorithms 2-6. The modifier onlyOwner is used to restrict the caller of the function to be the owner of the IDNFT Contract, which is the identity provider. Algorithm 2 is used to control the validity of the user's identity. This function uses a mapping variable to record whether the current identity is valid. If the identity provider needs to freeze an identity due to reasons such as identity data expiration, they can set the mapping value corresponding to NFTId to False. ```
Input:  uint NFTId, bool approveOrLock 1:NFTIdToAvailable[NFTId]=approveOrLock
```  
**Algorithm 2**unlockIDNFT () public onlyOwner  
Algorithm 3 can only be called by the Owner to transfer the identity NFT to a new admin account. Before calling this function, the owner needs the user's approval to transfer the IDNFT. To avoid unexpected errors, the function performs a check to ensure that the new  
Figure 2: IDNFT contract. admin account is not a contract address. The function then updates the old admin account in the relevant data to the new admin account and transfers the NFT to the new account. ```
Input: address oldAdmin, addressnewAdmin
1: require(isContract(newAdmin) == false)
2: UserData memory userdata = AdminToUserData[oldAdmin]
3: uint256 nftId = userdata.NFTId
4: require(nftId > 0)
5: AdminToUserData[newAdmin] = userdata
6: transferFrom(oldAdmin, newAdmin, nftId)
```  
**Algorithm 3**modifyAdminAddr() public onlyOwner  
The function _beforeTokenTransfer() is overridden in the Algorithm 4 so that functions such as transfer() and mint() can only be called by the contract owner. Users cannot transfer their IDNFTs by themselves, which avoids the loss or theft of the IDNFT caused by the loss or theft of the private key of the admin account. ```
Input: addressfrom, addressto, uinttokenId
1: super_beforeTokenTransfer(from, to, tokenId)
2: require(msg.sender == owner())
```  
**Algorithm 4**_beforeTokenTransfer() internal override  
Algorithm 5 is used to update the accumulator value (acc) and the public key parameters (n, g), and to specify the verifier (verifier). When a user wants to prove identity authorization for certain wallet accounts, a new accumulator value will be calculated. The user then update this new value into the contract data through this function. When the user presents the proof of identity authorization to the verifier, the verifier will use the latest accumulator value stored in the smart contract for verification. ```
Input: bytes acc, bytes n, uint g, address verifier,
1: UserData storage userdata = AdminToUserData[msg.sender]
2: userdata.acc= acc
3: userdata.n = n
4: userdata.g = g
5: userdata.verifier = verifier
6: userdata.verified = False
```  
**Algorithm 6**updateUserData() public  
Algorithm 6 is called by the verifier specified by the user in Algorithm 5, which is used to mark the accumulator value and public key parameters as verified to prevent them from being reused.