DISCLAMER: This repo is currently under active development and is not ready to be used in production
Phone Number Service (PNS) is a chain agnostic protocol designed to link a mobile phone number with EVM-compatible blockchain addresses.
This repository contains the Solidity smart contracts for the PNS Protocol
- Table of Contents
- Architecture
- Contracts
- Documentation
- Usage
- Prerequisites
- Setup
- Deploying
- Testing
- License
- Contributing
- Code Of Conduct
The PNS Protocol comprises of several components:
The PNS Registry contract holds the core functions that lie at the heart of phone number resolution.
The PNS resolver is responsible for setting resolvers and translating phone numbers into addresses.
The resolver functions allows for:
- setting the resolvers for the phone number
- returning the reolver details of a phone number.
The PNS Resolver mapping is adaptive to ENS EIP 2304 method with a bit of twist:
- ENS
//name -> coinType-> encodedAddressInBytes
mapping(bytes32 => mapping(uint256 => bytes)) versionable_addresses;
- PNS
//name -> coinType-> string
mapping(bytes32 => mapping(uint256 => string)) _resolveAddress;
The PNS Guardian contract is the entry point for record creation and it's responsible for verification of phone numbers. The Guardian contract is the only authorized contract to access the guardian.
The smart contracts are stored under the contracts directory.
contracts/
├── Interface
│ ├── IPNSGuardian.sol * ─ "PNS Guardian Interface"
│ ├── IPNSRegistry.sol * ─ "PNS Registry implementation interface"
│ ├── IPNSResolver.sol * ─ "PNS Resolver implementation interface"
├── PNSGuardian.sol * ─ "PNS Guardian implementation for phone number verification"
├── PNSRegistry.sol * ─ "PNS Registry logic for phone number records"
├── PNSResolver.sol * ─ "Responsible for resolving phone numbers to addresses"
├── PriceOracle.sol * ─ "Handles price calculations and interacts with chainlink oracle for price conversions"PNSRegistry.sol is initializable and accesscontrolUpgradable. It implements the official IPNSRegistry interface.
setPhoneRecord is an external virtual payable function that sets the record for a phoneHash
| Parameter | Type | Description |
|---|---|---|
Phone Hash |
bytes32 |
The phone hash to update |
Resolver |
string |
The address the phone number resolves to |
setGracePeriod is an external function that can only be called by system roles. It updates the contract's grace period.
| Parameter | Type | Description |
|---|---|---|
Time |
uint256 |
The new grace period in seconds. |
renew is an external virtual payable function that can renews a phone record. The phone record must have expired and the user must be authorized to modify it.
| Parameter | Type | Description |
|---|---|---|
Phone Hash |
bytes32 |
The phone hash to renew |
| Type | Description |
|---|---|
authorised(phoneHash) |
Permits modifications only by the owner of the specified phoneHash. |
hasExpired(phoneHash) |
Permits the function to run only if phone record is expired. |
getVersion is an external virtual view function that Gets the current version of the smart contract.
| Type | Description |
|---|---|
uint32 |
The current version of the contract |
getRecordFull is an external view function that retrieves the full record of a phone number, including its owner, expiration date, creation date, and whether it is currently expired or in grace period.
| Parameter | Type | Description |
|---|---|---|
Phone Hash |
bytes32 |
The phone hash to renew |
| Type | Description |
|---|---|
owner |
The address of the current owner of the phone number. |
isExpired |
A boolean indicating whether the phone number is currently expired. |
isInGracePeriod |
A boolean indicating whether the phone number is currently in the grace period. |
expiration |
A timestamp indicating when the phone number will expire. |
creation |
A timestamp indicating when the phone number was first registered. |
getRecord is an external view function that retrieves the phone record for a given phone hash.
| Parameter | Type | Description |
|---|---|---|
Phone Hash |
bytes32 |
The phone hash to retrieve the record for |
| Type | Description |
|---|---|
PhoneRecord |
The phone record for the given phone hash. |
isRecordVerified is a public view function that checks if the specified phoneHash is verified.
| Parameter | Type | Description |
|---|---|---|
Phone Hash |
bytes32 |
The phone hash to check verification status for |
| Type | Description |
|---|---|
bool |
A boolean indicating whether the phone record is verified or not. |
transfer is a public virtual function that transfers ownership of a phoneHash to a new address. Can only be called by the current owner of the phoneHash.
| Parameter | Type | Description |
|---|---|---|
Phone Hash |
bytes32 |
The phoneHash to transfer ownership of |
New Owner |
address |
The address of the new owner |
| Type | Description |
|---|---|
authorised(phoneHash) |
Permits modifications only by the owner of the specified phoneHash. |
authenticated(phoneHash) |
Permits the function to run only if phone record is still authenticated. |
getVerificationStatus is a public view function that retrieves the verification status for a given phone hash from the PNS guardian contract.
| Parameter | Type | Description |
|---|---|---|
Phone Hash |
bytes32 |
The phone hash to check verification status for |
| Type | Description |
|---|---|
bool |
A boolean indicating whether the phone record is verified or not. |
recordExists is a public view function that returns whether a given phone hash exists in the phone registry
| Parameter | Type | Description |
|---|---|---|
Phone Hash |
bytes32 |
The phone hash to check verification status for |
| Type | Description |
|---|---|
bool |
A boolean indicating whether a phone record exists. |
_hasPassedExpiryTime is a public view function that checks whether a phone record has passed its expiry time.
| Parameter | Type | Description |
|---|---|---|
Phone Hash |
bytes32 |
The phone hash to check |
| Type | Description |
|---|---|
bool |
A boolean indicating whether the phonehash has expired. |
_hasPassedGracePeriod is a public view function that checks whether a phone record has passed its grace period.
| Parameter | Type | Description |
|---|---|---|
Phone Hash |
bytes32 |
The phone hash to check |
| Type | Description |
|---|---|
bool |
A boolean indicating whether the phone record has passed its grace period. |
PNSResolver.sol is initializable and OwnableUpgradeable. It inherits the AddressResolver contract.
getVersion is an external virtual view function that returns the version number of the contract.
| Type | Description |
|---|---|
uint32 |
The version number of the contract. |
setPNSRegistry is an external function that sets the address of the IPNSRegistry contract. This function can only be called by the owner of the contract.
| Parameter | Type | Description |
|---|---|---|
_newRegistry |
address |
The address of the new IPNSRegistry contract. |
seedResolver is an external function that seeds the resolver address for the specified phone number hash and coin type.
| Parameter | Type | Description |
|---|---|---|
phoneHash |
bytes32 |
The hash of the phone number to seed the resolver for. |
a |
address |
The address to seed. |
| Type | Description |
|---|---|
registryAuthorised(phoneHash) |
Modifier to check if the message sender is authorized by the IPNSRegistry contract. |
getRecord is a public view function that returns the record associated with the specified phone number hash.
| Parameter | Type | Description |
|---|---|---|
phoneHash |
bytes32 |
The hash of the phone number to retrieve the record for. |
| Type | Description |
|---|---|
PhoneRecord |
The PhoneRecord associated with the specified phone number hash. |
getOwner is a public view function that returns the address that owns the specified phone number.
| Parameter | Type | Description |
|---|---|---|
phoneHash |
bytes32 |
The specified phoneHash. |
| Type | Description |
|---|---|
address |
address of the owner. |
PNSGuardian.sol is initializable and OwnableUpgradeable. It inherits the AddressResolver contract.
getVerificationRecord is an external view function that gets the verification record for a phone hash.
| Parameter | Type | Description |
|---|---|---|
phoneHash |
bytes32 |
Hash of the phone number being verified. |
| Type | Description |
|---|---|
VerificationRecord |
Verification record associated with the phone hash |
getVerifiedOwner is an external view function that gets the verified owner for a phone hash.
| Parameter | Type | Description |
|---|---|---|
phoneHash |
bytes32 |
Hash of the phone number being verified. |
| Type | Description |
|---|---|
address |
Verified owner associated with the phone hash. |
setPNSRegistry is an external function that sets the PNS registry address.
| Parameter | Type | Description |
|---|---|---|
_registryAddress |
address |
Address of the PNS registry. |
| Type | Description |
|---|---|
onlyGuardianVerifier |
Modifier that permits modifications only by the PNS guardian verifier. |
setGuardianVerifier is an external function that sets the PNS registry address.
| Parameter | Type | Description |
|---|---|---|
_guardianVerifier |
address |
Address of the guardian verifier. |
| Type | Description |
|---|---|
onlyGuardianVerifier |
Modifier that permits modifications only by the PNS guardian verifier. |
verifyPhoneHash is an external function that verifies a phone number hash
| Parameter | Type | Description |
|---|---|---|
phoneHash |
bytes32 |
Hash of the phone number being verified. |
_hashedMessage |
bytes32 |
Hashed message. |
status |
bool |
New verification status. |
owner |
address |
Address of the owner. |
_signature |
bytes |
Signature provided by the off-chain verifier. |
| Type | Description |
|---|---|
onlyGuardianVerifier |
Modifier that permits modifications only by the PNS guardian verifier. |
| Type | Description |
|---|---|
bool |
A boolean indicating if the verification record has been updated and is no longer a zero-address. |
- git
- nodeJS
- brew
- foundry - You can run
sh ./setup.shto install Foundry and its dependencies. - Hardhat
-
Clone the repository
git clone https://github.com/pnslabs/pns-contracts.git cd pns-contracts -
Install packages
yarn -
Build contracts
```
yarn build
```
Create a .env in the root with:
PRIVATE_KEY=PRIVATE_KEY
ALCHEMY_API_KEY=
Then run:
yarn run deploy:ethereum_goerli
To run unit tests:
yarn run testMIT Copyright 2022 PNS Labs
Contributions are always welcome!
See contributing.md for ways to get started
Please adhere to this project's Code of Conduct