Skip to content
This repository was archived by the owner on Jan 14, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
9ab8913
Remove unused variables
tyleryasaka Apr 30, 2018
2ff0ecb
Move getBytes to ClaimHolder contract and make it internal vs private
tyleryasaka Apr 30, 2018
faf0745
Implement addClaims method on ClaimHolder contract
tyleryasaka Apr 30, 2018
1c52075
Create attestations resource
tyleryasaka May 1, 2018
bcf1fb3
Rename user registry methods
tyleryasaka May 1, 2018
e3bdb81
Make claim holder contract available in contract service
tyleryasaka May 1, 2018
6677875
Create users resource
tyleryasaka May 1, 2018
76703da
Expose attestation and user resources on origin-js
tyleryasaka May 1, 2018
1b5b13a
Properly initialize attestation resource
tyleryasaka May 1, 2018
dbc8eb7
Add rlp dependency
tyleryasaka May 1, 2018
50bd6cb
Add alternative `wallet` param and use it predict identity address
tyleryasaka May 1, 2018
3518b90
Add ethereumjs-util dependency
tyleryasaka May 1, 2018
611e5cc
Ensure identity addresses we send to bridge server are checksummed
tyleryasaka May 1, 2018
b26b7ef
Bug fix: don't hash data that is already a hash :)
tyleryasaka May 1, 2018
286ec28
Add web3-eth-accounts dependency
tyleryasaka May 1, 2018
b463e6f
Validate attestations, client-side
tyleryasaka May 2, 2018
9ca2fdb
Instantiate users separately from other resources
tyleryasaka May 2, 2018
34218e6
Refactor `user registry`/`claim holder` relationship
tyleryasaka May 2, 2018
efc1268
Only accept wallet as param for verify methods
tyleryasaka May 2, 2018
0148631
Don't create identity if one already exists
tyleryasaka May 2, 2018
948d220
Refactor claim holder contract inheritance structure
tyleryasaka May 2, 2018
983769d
Create OriginIdentity contract for issuing attestations
tyleryasaka May 2, 2018
8fdcdd2
Properly verify attestation issuer by checking that it is a valid key
tyleryasaka May 2, 2018
97040ec
Fix the way we reference contracts in migrations
tyleryasaka May 2, 2018
e710d73
Use `deployer.then` to make sure migrations run synchronously
tyleryasaka May 2, 2018
fb23a9b
Remove unnecessary issuer config option
tyleryasaka May 2, 2018
dbfaa14
Hash data in attestation resource rather than user resource
tyleryasaka May 2, 2018
ba48ad6
Never mind - don't hash data in the constructor
tyleryasaka May 3, 2018
932f2cc
Only add new attestations in `set` method
tyleryasaka May 3, 2018
97170b6
Use last rather than first profile event as the current
tyleryasaka May 3, 2018
b88a45a
Add a `service` property to AttestationObject as a convenience
tyleryasaka May 3, 2018
687e355
Return attestation objects in `get` method
tyleryasaka May 3, 2018
75d0623
Return updated user in `set` method
tyleryasaka May 3, 2018
348d494
Pass fetch service into attestations constructor
tyleryasaka May 3, 2018
245d0ef
Move "private" methods to bottom of file
tyleryasaka May 3, 2018
5df0281
Add fetch-mock dependency
tyleryasaka May 3, 2018
3e3abb9
Test attestations resource
tyleryasaka May 3, 2018
5e6195d
Directly use web3 rather than drop in pieces
tyleryasaka May 3, 2018
b6ab69d
Add `deploy` method to contract service
tyleryasaka May 3, 2018
c3e7170
Add optional addres param to deployed method
tyleryasaka May 3, 2018
4f3fc44
Update users resource to use 1.0
tyleryasaka May 3, 2018
88fad96
Coerce claimType to number in AttestationObject constructor
tyleryasaka May 3, 2018
98caf41
Contract service bug fix
tyleryasaka May 3, 2018
4989006
Fix logic error - should use `and` instead of `or` for exact match
tyleryasaka May 3, 2018
d1a4359
Add a second sample issuer during migrations
tyleryasaka May 3, 2018
836a66b
Create separate method for validating a single attestation
tyleryasaka May 3, 2018
2a73835
Code format with `npm run format`
tyleryasaka May 3, 2018
9f03339
Users resource bug fixes
tyleryasaka May 3, 2018
31007f3
Add clearUser method to user registry
tyleryasaka May 3, 2018
636aefc
Test the users resource
tyleryasaka May 3, 2018
b3847fd
Add attestationServerUrl config option to README
tyleryasaka May 3, 2018
e0c97e0
Fall back to current account if wallet is not provided
tyleryasaka May 3, 2018
b3de521
Update `deploy` method to wait until the deploy has finished
tyleryasaka May 4, 2018
d18dddb
Return user object from usrs resource
tyleryasaka May 4, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ And buyers to:
- `ipfsApiPort`
- `ipfsGatewayPort`
- `ipfsGatewayProtocol`
- `attestationServerUrl`

## IPFS

Expand Down
33 changes: 9 additions & 24 deletions contracts/contracts/UserRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,18 @@ contract UserRegistry {
* Public functions
*/

/// @dev create(): Create a user
function create() public
/// @dev registerUser(): Add a user to the registry
function registerUser()
public
{
ClaimHolder _identity = new ClaimHolder();
users[msg.sender] = _identity;
emit NewUser(msg.sender, _identity);
users[tx.origin] = msg.sender;
emit NewUser(tx.origin, msg.sender);
}

/// @dev createWithClaims(): Create a user with presigned claims
// Params correspond to params of ClaimHolderPresigned
function createWithClaims(
uint256[] _claimType,
address[] _issuer,
bytes _signature,
bytes _data,
uint256[] _offsets
)
public
/// @dev clearUser(): Remove user from the registry
function clearUser()
public
{
ClaimHolderPresigned _identity = new ClaimHolderPresigned(
_claimType,
_issuer,
_signature,
_data,
_offsets
);
users[msg.sender] = _identity;
emit NewUser(msg.sender, _identity);
users[msg.sender] = 0;
}
}
33 changes: 33 additions & 0 deletions contracts/contracts/identity/ClaimHolder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,26 @@ contract ClaimHolder is KeyHolder, ERC735 {
return claimId;
}

function addClaims(
uint256[] _claimType,
address[] _issuer,
bytes _signature,
bytes _data
)
public
{
for (uint8 i = 0; i < _claimType.length; i++) {
addClaim(
_claimType[i],
1,
_issuer[i],
getBytes(_signature, (i * 65), 65),
getBytes(_data, (i * 32), 32),
""
);
}
}

function removeClaim(bytes32 _claimId) public returns (bool success) {
if (msg.sender != address(this)) {
require(keyHasPurpose(keccak256(msg.sender), 1), "Sender does not have management key");
Expand Down Expand Up @@ -104,4 +124,17 @@ contract ClaimHolder is KeyHolder, ERC735 {
return claimsByType[_claimType];
}

function getBytes(bytes _str, uint256 _offset, uint256 _length)
internal
pure
returns (bytes)
{
bytes memory sig = new bytes(_length);
uint256 j = 0;
for (uint256 k = _offset; k< _offset + _length; k++) {
sig[j] = _str[k];
j++;
}
return sig;
}
}
20 changes: 4 additions & 16 deletions contracts/contracts/identity/ClaimHolderPresigned.sol
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
pragma solidity ^0.4.23;

import './ClaimHolder.sol';
import './ClaimHolderRegistered.sol';

/**
* NOTE: This contract exists as a convenience for deploying an identity with
* some 'pre-signed' claims. If you don't care about that, just use ClaimHolder
* instead.
*/

contract ClaimHolderPresigned is ClaimHolder {
contract ClaimHolderPresigned is ClaimHolderRegistered {

constructor(
address _userRegistryAddress,
uint256[] _claimType,
address[] _issuer,
bytes _signature,
bytes _data,
uint256[] _offsets
)
ClaimHolderRegistered(_userRegistryAddress)
public
{
uint offset = 0;
Expand All @@ -32,18 +34,4 @@ contract ClaimHolderPresigned is ClaimHolder {
offset += _offsets[i];
}
}

function getBytes(bytes _str, uint256 _offset, uint256 _length)
private
pure
returns (bytes)
{
bytes memory sig = new bytes(_length);
uint256 j = 0;
for (uint256 k = _offset; k< _offset + _length; k++) {
sig[j] = _str[k];
j++;
}
return sig;
}
}
16 changes: 16 additions & 0 deletions contracts/contracts/identity/ClaimHolderRegistered.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pragma solidity ^0.4.23;

import './ClaimHolder.sol';
import '../UserRegistry.sol';

contract ClaimHolderRegistered is ClaimHolder {

constructor (
address _userRegistryAddress
)
public
{
UserRegistry userRegistry = UserRegistry(_userRegistryAddress);
userRegistry.registerUser();
}
}
8 changes: 8 additions & 0 deletions contracts/contracts/identity/OriginIdentity.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pragma solidity ^0.4.23;

import './ClaimHolder.sol';

// This will be deployed exactly once and represents Origin Protocol's
// own identity for use in signing attestations.

contract OriginIdentity is ClaimHolder {}
22 changes: 15 additions & 7 deletions contracts/migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ var ListingsRegistry = artifacts.require("./ListingsRegistry.sol");
var Listing = artifacts.require("./Listing.sol");
var UserRegistry = artifacts.require("./UserRegistry.sol");
var PurchaseLibrary = artifacts.require("./PurchaseLibrary.sol");
var OriginIdentity = artifacts.require("./OriginIdentity.sol");

module.exports = function(deployer) {
deployer.deploy(PurchaseLibrary);
deployer.link(PurchaseLibrary, ListingsRegistry)
deployer.link(PurchaseLibrary, Listing)
deployer.deploy(ListingsRegistry);
deployer.deploy(UserRegistry);
};
module.exports = function(deployer, network) {
return deployer.then(() => {
return deployContracts(deployer)
})
}

async function deployContracts(deployer) {
await deployer.deploy(PurchaseLibrary);
await deployer.link(PurchaseLibrary, ListingsRegistry)
await deployer.link(PurchaseLibrary, Listing)
await deployer.deploy(ListingsRegistry);
await deployer.deploy(UserRegistry);
await deployer.deploy(OriginIdentity);
}
37 changes: 15 additions & 22 deletions contracts/migrations/3_create_sample_listings.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
var ListingsRegistryContract = require("../build/contracts/ListingsRegistry.json")
var ListingContract = require("../build/contracts/Listing.json")
var PurchaseContract = require("../build/contracts/Purchase.json")
var contract = require("truffle-contract")
var ListingsRegistry = artifacts.require("./ListingsRegistry.sol");
var Listing = artifacts.require("./Listing.sol");
var Purchase = artifacts.require("./Purchase.sol");

module.exports = function(deployer, network) {
return deploy_sample_contracts(network)
return deployer.then(() => {
return deploy_sample_contracts(network)
})
}

async function deploy_sample_contracts(network) {
Expand All @@ -15,56 +16,48 @@ async function deploy_sample_contracts(network) {
const a_buyer_account = web3.eth.accounts[2]
const another_buyer_account = web3.eth.accounts[3]

const listingRegistryContract = contract(ListingsRegistryContract)
listingRegistryContract.setProvider(web3.currentProvider)
const listingRegistry = await listingRegistryContract.deployed()

const listingContract = contract(ListingContract)
listingContract.setProvider(web3.currentProvider)

const purchaseContract = contract(PurchaseContract)
purchaseContract.setProvider(web3.currentProvider)
const listingsRegistry = await ListingsRegistry.deployed()

const getListingContract = async transaction => {
const index = transaction.logs.find(x => x.event == "NewListing").args._index
const info = await listingRegistry.getListing(index)
const info = await listingsRegistry.getListing(index)
const address = info[0]
return listingContract.at(address)
return Listing.at(address)
}

const buyListing = async (listing, qty, from) => {
const price = await listing.price()
const transaction = await listing.buyListing(qty, { from: from, value: price, gas: 4476768 })
const address = transaction.logs.find(x => x.event == "ListingPurchased").args._purchaseContract
return purchaseContract.at(address)
return Purchase.at(address)
}

await listingRegistry.create(
await listingsRegistry.create(
"0x4f32f7a7d40b4d65a917926cbfd8fd521483e7472bcc4d024179735622447dc9",
web3.toWei(3, "ether"),
1,
{ from: a_seller_account, gas: 4476768 }
)

await listingRegistry.create(
await listingsRegistry.create(
"0xa183d4eb3552e730c2dd3df91384426eb88879869b890ad12698320d8b88cb48",
web3.toWei(0.6, "ether"),
1,
{ from: default_account, gas: 4476768 }
)
await listingRegistry.create(
await listingsRegistry.create(
"0xab92c0500ba26fa6f5244f8ba54746e15dd455a7c99a67f0e8f8868c8fab4a1a",
web3.toWei(8.5, "ether"),
1,
{ from: a_seller_account, gas: 4476768 }
)
await listingRegistry.create(
await listingsRegistry.create(
"0x6b14cac30356789cd0c39fec0acc2176c3573abdb799f3b17ccc6972ab4d39ba",
web3.toWei(1.5, "ether"),
1,
{ from: default_account, gas: 4476768 }
)
const ticketsTransaction = await listingRegistry.create(
const ticketsTransaction = await listingsRegistry.create(
"0xff5957ff4035d28dcee79e65aa4124a4de4dcc8cb028faca54c883a5497d8917",
web3.toWei(0.3, "ether"),
27,
Expand Down
33 changes: 33 additions & 0 deletions contracts/migrations/4_add_sample_issuers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
var OriginIdentity = artifacts.require("./OriginIdentity.sol");
var Web3 = require("web3")

const issuer_1 = "0x99C03fBb0C995ff1160133A8bd210D0E77bCD101"
const issuer_2 = "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf"
const keyPurpose = 3
const keyType = 1

module.exports = function(deployer, network) {
return deployer.then(() => {
return add_sample_issuer(network)
})
}

async function add_sample_issuer(network) {
let defaultAccount = web3.eth.accounts[0]

let originIdentity = await OriginIdentity.deployed()

await originIdentity.addKey(
Web3.utils.soliditySha3(issuer_1),
keyPurpose,
keyType,
{ from: defaultAccount, gas: 4000000 }
)

return await originIdentity.addKey(
Web3.utils.soliditySha3(issuer_2),
keyPurpose,
keyType,
{ from: defaultAccount, gas: 4000000 }
)
}
71 changes: 6 additions & 65 deletions contracts/test/TestUserRegistry.js
Original file line number Diff line number Diff line change
@@ -1,77 +1,18 @@
const web3Utils = require("web3-utils")

const UserRegistry = artifacts.require("./UserRegistry.sol")
const ClaimHolderPresigned = artifacts.require(
"./dentity/ClaimHolderPresigned.sol"
)

// Used to assert error cases
const isEVMError = function(err) {
let str = err.toString()
return str.includes("revert")
}

const signature_1 =
"0xeb6123e537e17e2c67b67bbc0b93e6b25ea9eae276c4c2ab353bd7e853ebad2446cc7e91327f3737559d7a9a90fc88529a6b72b770a612f808ab0ba57a46866e1c"

const ipfsHash_1 =
"0x4f32f7a7d40b4d65a917926cbfd8fd521483e7472bcc4d024179735622447dc9"

contract("UserRegistry", accounts => {
let userRegistry
let attestation_1 = {
claimType: 1,
scheme: 1,
issuer: accounts[1],
signature: signature_1,
data: ipfsHash_1,
uri: ""
}

beforeEach(async () => {
userRegistry = await UserRegistry.new({ from: accounts[0] })
})

it("should be able to create a user", async function() {
let create = await userRegistry.create({ from: accounts[1] })
it("should be able to register a user", async function() {
let register = await userRegistry.registerUser({ from: accounts[1] })
let identityAddress = await userRegistry.users(accounts[1])
let newUserEvent = create.logs.find(e => e.event == "NewUser")
assert.ok(identityAddress)
assert.notEqual(
identityAddress,
"0x0000000000000000000000000000000000000000"
)
assert.equal(newUserEvent.args["_identity"], identityAddress)
})

it("should be able to create a user with claims", async function() {
let createWithClaims = await userRegistry.createWithClaims(
[attestation_1.claimType],
[attestation_1.issuer],
attestation_1.signature,
attestation_1.data,
[32],
{ from: accounts[1] }
)
let identityAddress = await userRegistry.users(accounts[1])
let newUserEvent = createWithClaims.logs.find(e => e.event == "NewUser")
assert.ok(identityAddress)
assert.equal(newUserEvent.args["_identity"], identityAddress)

// Check that claim was added
let identity = ClaimHolderPresigned.at(identityAddress)
let claimId = web3Utils.soliditySha3(
attestation_1.issuer,
attestation_1.claimType
)
let fetchedClaim = await identity.getClaim(claimId, { from: accounts[1] })
assert.ok(fetchedClaim)
let [claimType, scheme, issuer, signature, data, uri] = fetchedClaim
assert.equal(claimType.toNumber(), attestation_1.claimType)
assert.equal(scheme.toNumber(), attestation_1.scheme)
assert.equal(issuer, attestation_1.issuer)
assert.equal(signature, attestation_1.signature)
assert.equal(data, attestation_1.data)
assert.equal(uri, attestation_1.uri)
let newUserEvent = register.logs.find(e => e.event == "NewUser")
assert.equal(identityAddress, accounts[1])
assert.equal(newUserEvent.args["_address"], accounts[1])
assert.equal(newUserEvent.args["_identity"], accounts[1])
})
})
Loading