uport-registry
和uport-proxy
是合約的部署與web3.js操作介面library- 部署合約使用 truffle
uport-persona
是uport的profile schema操作介面- 注意和uport-registry & uport-proxy 中的schema不同。
uport-lib
是web application的library
-
Core uPort registry contract for linking attributes to uPort identities.
-
需介接IPFS Service
-
設定ipfsApi interface:
uportRegistry.setIpfsProvider(ipfsApi(<hostname>, <port>));
-
設定web3 interface:
uportRegistry.setWeb3Provider(new web3.providers.HttpProvider('http://localhost:8545'));
-
UportRegistry.sol
pragma solidity ^0.4.3; contract UportRegistry { event AttributesSet(address indexed _sender, uint _timestamp); uint public version; address public previousPublishedVersion; mapping(address => bytes) public ipfsAttributeLookup; function UportRegistry(address _previousPublishedVersion) { version = 1; previousPublishedVersion = _previousPublishedVersion; } function setAttributes(bytes ipfsHash) { ipfsAttributeLookup[msg.sender] = ipfsHash; AttributesSet(msg.sender, now); } function getAttributes(address personaAddress) constant returns(bytes) { return ipfsAttributeLookup[personaAddress]; } }
-
Deploy
-
Note: ConsenSys做的
ipfs-js
與 IPFS所做的ipfs-api
最新版本不合,注意要裝的是[email protected]
-
若使用testnet,修改
config.json
:"testnet": { "web3Host": "139.162.75.109", "web3Port": "8545", "ipfsHost": "localhost", "ipfsPort": "5001", "ipfsWebPort": "8080", "uportRegistry": "0x0" }, "selection": "testnet"
-
若使用testnet,修改
deploy.js
,需自行設定from_address
&password
:// Deploying a new PersonaRegistry // // Usage: // * modify app/javascripts/config.js so that selection // is your target. // * node app/javascripts/deploy.js 0xaabbbcc // where 0xaabbbcc is the address of the previous version // of PersonaRegistry // Node modules var Persona = require('./lib/uportregistry.js'); var Web3 = require('web3'); var Promise = require('bluebird'); var fs = require('fs'); // Data / Registries / Contracts var config = require('./config.json'); console.log( config ) // Web3 Instance var web3 = new Web3(); // CLI Args var prevRegistryAddr = process.argv[2]; var host = config[config['selection']].web3Host; var web3port = 8545 console.log(host) // Set Defaults if (host === undefined) { host = 'localhost'; } if (web3port === undefined) { web3port = '8545'; } // Make Providers var web3prov = new web3.providers.HttpProvider('http://' + host + ':' + web3port); const UportRegistry = require('./build/contracts/UportRegistry.sol.js') // Set Providers web3.setProvider(web3prov); UportRegistry.setProvider(web3prov) var from_address = '<from_address>'; var password = '<password>' web3.personal.unlockAccount(from_address, password); // Create new Persona Registry web3.eth.getAccounts(function(err, acct) { console.log('prev reg: ' + prevRegistryAddr) if (prevRegistryAddr === undefined) { prevRegistryAddr = '0x0000000000000000000000000000000000000000' } UportRegistry.new(prevRegistryAddr, {from: from_address, gas: 500000, gasPrice: 20000000000}) .then(function(uportReg) { config[config['selection']].uportRegistry = uportReg.address; var output = JSON.stringify(config, null, 2) + '\n'; fs.writeFile('./config.json', output); console.log('UportRegistry: ' + uportReg.address); })
});
```
- setAttribute/getAttribute example
- 使用建立好的合約
```
var regestryContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"personaAddress","type":"address"}],"name":"getAttributes","outputs":[{"name":"","type":"bytes"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"previousPublishedVersion","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"ipfsHash","type":"bytes"}],"name":"setAttributes","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"ipfsAttributeLookup","outputs":[{"name":"","type":"bytes"}],"payable":false,"type":"function"},{"inputs":[{"name":"_previousPublishedVersion","type":"address"}],"type":"constructor","payable":true},{"anonymous":false,"inputs":[{"indexed":true,"name":"_sender","type":"address"},{"indexed":false,"name":"_timestamp","type":"uint256"}],"name":"AttributesSet","type":"event"}]);
var registryAddress = '0x50D70fE5b00aD97b3Ab8389CA4EbE6BdC0320084';
var registry = regestryContract.at(registryAddress)
var attributes =
{
"@context": "http://schema.org",
"@type": "Person",
"name": "Pinkman",
"image": [{"@type": "ImageObject",
"name": "avatar",
"contentUrl" : "/ipfs/QmUSBKeGYPmeHmLDAEHknAm5mFEvPhy2ekJc6sJwtrQ6nk"}]
}
var txHash = registry.setAttributes(attributes, {from: address, gas: '2000000'});
console.log('txHash:', txHash);
var regData = registry.getAttributes.call(address);
console.log('regData', regData);
// 要等transaction pended後,才可getAttibutes
var regData = registry.getAttributes.call(proxy.address);
console.log('regData', regData); ``` - 使用uport-registry library(會寫到IPFS)
```
var uportRegistry = require("uport-registry");
var ipfsApi = require('ipfs-api');
var web3 = require('web3'); uportRegistry.setIpfsProvider(ipfsApi(, ));
uportRegistry.setWeb3Provider(new web3.providers.HttpProvider('http://localhost:8545'));
var registryAddress = '0xbf014c4d7697cd83c9451a93648773cf510dc766'
var attributes =
{
"@context": "http://schema.org",
"@type": "Person",
"name": "Christian Lundkvist",
"image": [{"@type": "ImageObject",
"name": "avatar",
"contentUrl" : "/ipfs/QmUSBKeGYPmeHmLDAEHknAm5mFEvPhy2ekJc6sJwtrQ6nk"}]
}
uPortRegistry.setAttributes(
registryAddress,
attributes,
{from: myAddr}).then(function ()
{console.log('Attributes set.')})
```
- uPort Proxy and Owner contracts
- Owner contract with an
User key
that controls the proxy contract. - There is also an
Admin key
that can unilaterally replace theUser key
. - contracts
Proxy.sol
IdentityFactory.sol
Lib1.sol
MetaTxController.sol
Mirgration.sol
Owned.sol
Proxy.sol
RecoverableController.sol
RecoveryQuorum.sol
TestRegistry.sol
- Deploy
-
Run
truffle compile
,會產生build\contracts\
目錄下的檔案 -
Run
node deploy.js
,會產生IdentityFactory Contract Address -
CreateProxyWithControllerAndRecovery
- address
userKey
: user key - address[]
delegates
: recovery keys - uint
longTimeLock
: long timelock - uint
shortTimeLock
: short timelock
- address
-
identityFactory.CreateProxyWithControllerAndRecovery(userKey, delegates, longTimeLock, shortTimeLock, { from: address, gas: 2500000}); console.log('CreateProxyWithControllerAndRecovery created!!!!') ``` - Get related contract address
```
function getCreatedContractAddress() {
var event = identityFactory.IdentityCreated({creator: creatorAddress})
event.watch((error, result) => {
event.stopWatching();
proxyAddress = result.args.proxy;
controllerAddress = result.args.controller;
console.log("proxyAddress:", proxyAddress);
console.log("controllerAddress:", controllerAddress);
});
}
```
- 測試
-
(1) 用TestRegistry Contract測試
- address 需先unlock
var lightwallet = require('eth-signer'); function forwardTestRegistryFromController() { var LOG_NUMBER_1 = 12345678 var data = lightwallet.txutils._encodeFunctionTxData('register', ['uint256'], [LOG_NUMBER_1]); data = '0x' + data; console.log('data:', data); // Example: var controllerParams = {from: address} var txHash = controller.forward(testReg.address, 0, data, controllerParams); var regData = testReg.registry.call(proxy.address); console.log('regData', regData); }
-
(2) 用Registry Contract 測試
var lightwallet = require('eth-signer'); function forwardRegistryFromController() { var attributes = { "@context": "http://schema.org", "@type": "Person", "name": "Amy Santiago", "image": [{"@type": "ImageObject", "name": "avatar", "contentUrl" : "/ipfs/QmUSBKeGYPmeHmLDAEHknAm5mFEvPhy2ekJc6sJwtrQ6nk"}] } var data = lightwallet.txutils._encodeFunctionTxData('setAttributes', ['bytes'], [attributes]); data = '0x' + data; console.log('data:', data); var controllerParams = {from: address, gas: '2000000'} var txHash = controller.forward(registry.address, 0, data, controllerParams); console.log('txHash:', txHash); var regData = registry.getAttributes.call(proxy.address); console.log('regData', regData); }
-
-
A library for creating, updating and reading attributes and claims on uport personas.
-
Importing Example
import { Persona, MutablePersona } from 'uport-persona';
-
Query Persona
// the address of the persona you want to interact with let myAddress = "0x123..."; let ipfsProvider = { host: 'localhost', port: '5001', protocol: 'https', root: '' } let persona = new Persona(myAddress, ipfs, web3.currentProvider); persona.load().then(() => { ... });
-
UportProvider interface
-
dependent to
uport-persona
-
需搭配
messaging server
和mobile app
操作 -
RemoteMutablePersona
- display QR code,由mobile app註冊/登入後,由 Chasqui (Messaging server)
-
UportSubprovider
- options: msgServer, uportConnectHandler, ethUriHandler, closeQR
-
Importing example
import Web3 from 'web3' import { Uport } from 'uport-lib' let web3 = new Web3() let options = { ipfsProvider: { host: '<IPFS_HOST>', port: '5001', protocol: 'https', root: '' } } let uport = new Uport('MyDApp', options) let rpcUrl = "http://<WEB3_HOST>:8545" let uportProvider = uport.getUportProvider(rpcUrl) web3.setProvider(uportProvider) uport.getUserPersona() .then((persona) => { let profile = persona.getProfile() console.log(profile) })
-
其他未開源Componet
- Mobile Application
- Chasqui (Messaging server)
- Sensui (Fueling server)