In POA Network, identity of individual validators plays a major role for selected consensus. We propose additional checks of identity, performed in a decentralized way. Proof of Identity DApps is a series of decentralized applications focused on connecting a user's identity to his/her wallet. Applications can be run on any Ethereum-compatible network.
Using Proof of Physical Address, a user can confirm his/her physical address. It can be used to prove connection between residency and a network address (wallet). User submits a form with his physical address details (name, state, city, etc) on DApp main page. This data is added to the PoPA contract deployed to the network and thus a correspondence between a wallet and physical address is registered in the contract. However, this correspondence is not yet verified.
To verify the address server sends a postcard (via post office) with confirmation code to the registered physical address. Confirmation code is used by the user to call one of contract's methods (via DApp confirmation page) to verify the correspondence between the confirmation code and the wallet used initially to register the physical address.
A more detailed schematic view of the process:
Clone this repository:
$ git clone https://github.com/poanetwork/poa-popa.git
$ cd poa-popa
In the following steps, we'll refer to this directory as $REPO_DIR
.
Make sure you have node.js version >= 6.9.1 installed.
Install the project dependencies:
$ npm install
Sensitive data (like lob api key) has to be added to
web-dapp/server-config-private.js
. You can create this file by copying the
example:
$ cd $REPO_DIR/web-dapp
$ cp server-config-private.example.js server-config-private.js
This file exports a config object whose keys will replace the ones in web-dapp/server-config.js
.
Note: you can get the lobApiKey
registering on Lob and copying your Test API Key from User -> Settings -> API Keys.
Open a new terminal and start testrpc with a set of predefined accounts:
$ npm run start-testrpc
Leave this tab open until your test is complete.
Deploy the contracts:
$ cd $REPO_DIR/blockchain
$ ./node_modules/.bin/truffle migrate
This will send several transactions. One of them will create the PoPA contract. You have to have its address in the .env
file. If you followed these steps, the address will be the same as the one in .env.example
, so it will be enough to copy it:
$ cd $REPO_DIR
$ cp .env.example .env
Start the application. This will build the frontend and start the sever.
$ cd $REPO_DIR
$ npm start
Wait until you see Listening on 3000
in the terminal
Go to the terminal where you executed the npm run start-testrpc
command and use those private keys or the mnemonic in MetaMask. You should have an account with a little less than 100 ETH (100 - contract deployment fee).
Navigate to http://localhost:3000 in your browser.
To find out the confirmation code, look for a line like
[prepareRegTx] confirmation confirmationCodePlain: y8t44s8yrt
in the server logs (the terminal where you ran npm start
).
To find response details from Lob, including links to the postcard, look for a line like
[notifyRegTx] postcard: {"id":"psc_106fe1363e5b9521", ..., "to": ..., thumbnails": ... }
in the server logs.
Note: in the property thumbnails
you can find the url of the front and back sides of the postcard with the confirmation code:
"thumbnails": [
{
"small": "https://s3.us-west-2.amazonaws.com/assets.lob.com/psc_...",
"medium": "https://s3.us-west-2.amazonaws.com/assets.lob.com/psc_...",
"large": "https://s3.us-west-2.amazonaws.com/assets.lob.com/psc_..."
},
{
"small": "https://s3.us-west-2.amazonaws.com/assets.lob.com/psc_..",
"medium": "https://s3.us-west-2.amazonaws.com/assets.lob.com/psc_..",
"large": "https://s3.us-west-2.amazonaws.com/assets.lob.com/psc_.."
}
]
Start testrpc
$ cd $REPO_DIR
$ npm run start-testrpc
In another terminal, go to the blockchain
directory.
$ cd $REPO_DIR/blockchain
Run tests
./node_modules/.bin/truffle test
Go to the root directory and run the tests:
$ cd $REPO_DIR
$ npm test
If you want to run the linter:
$ npm run lint
Note: Before running the npm install
script, a pre-push
hook will be copied to the .git
folder, so, before each git push
, it will run the tests. Also for some tests you need to have redis server running locally. If you don't have it, you can skip tests with --no-verify
git flag and they will be run by travis.
git clone https://github.com/poanetwork/poa-popa.git
cd poa-popa
npm install
.env
with the following structure:
REACT_APP_POPA_CONTRACT_ADDRESS=0x...
put the correct PoPA contract address here.
poa-popa/web-dapp/server-config-private.js
with the following content:
'use strict';
module.exports = function (cfgPublic) { return { lobApiKey: ' LOB TEST OR PROD API KEY ', lobApiVersion: ' LOB TEST OR PROD API VERSION ', rpc: ' PROBABLY INFURA ', signer: ' SIGNER ADDRESS, 0x... ', // with 0x prefix signerPrivateKey: ' SIGNER PRIVATE KEY ', // without 0x prefix confirmationPageUrl: ' URL FOR CONFIRMATION PAGE, e.g. https://yourserver.com/confirm ', // used only for postcard // it is recommended to install and use redis for keeping session keys sessionStore: { "type": "redis", "params": { REDIS CONNECTION PARAMETERS } }, }; };
6. build react components
npm run build
7. start server
node server
or, still better, use pm2
pm2 start -i 0 server
## Description
### contract
Contract source file is `blockchain/contracts/ProofOfPhysicalAddress.sol`.
* main data structures are `User` and `PhysicalAddress`:
```solidity
struct PhysicalAddress {
string name;
string country;
string state;
string city;
string location;
string zip;
uint256 creationBlock;
bytes32 keccakIdentifier;
bytes32 confirmationCodeSha3;
uint256 confirmationBlock;
}
struct User {
uint256 creationBlock;
PhysicalAddress[] physicalAddresses;
}
mapping (address => User) public users;
location
in contract is alias for address
in dapp.
there are also three variables for statistics
uint64 public totalUsers;
uint64 public totalAddresses;
uint64 public totalConfirmed;
Note: they represent an overall number of users/addresses/confirmation, not number at any particular time
contract has owner
which is the account that sent the transaction to deploy the contract.
contract has signer
which is the account that is used to calculate signatures on server-side and validate parameters from contract-side. By default when contract is created, signer
is set to owner
. You can change it later with setSigner
method.
main methods are
function registerAddress(
string name,
string country, string state, string city, string location, string zip,
uint256 priceWei,
bytes32 confirmationCodeSha3, uint8 sigV, bytes32 sigR, bytes32 sigS)
public payable
used to register a new address,
function confirmAddress(
string confirmationCodePlain,
uint8 sigV,
bytes32 sigR,
bytes32 sigS)
public
used to confirm an address and
function unregisterAddress(
string country,
string state,
string city,
string location,
string zip)
public
used to remove an existing address
name
may be different for each new address
country
, state
, city
, location
and zip
are trim()
ed and toLowerCase()
ed by dapp before passing them to the contract.
PoPA uses EthereumClaimsRegistry contract (the Register) proposed in https://github.com/ethereum/EIPs/issues/780 to store attestations
when address is confirmed in PoPA, a new claim is added to the Register with the following structure
issuer
: PoPA contract addresssubject
: user's eth wallet addresskey
: keccakIdentifier
of the addressvalue
: bytes32
array containing confirmation date and library versionwhen address is removed in PoPA, corresponding claim is removed from the Register