Skip to content

Commit

Permalink
Upgrade to Solc 0.4.22. Use 'bytes' instead of 'bytes32' in ERC 725 i…
Browse files Browse the repository at this point in the history
…mplementation. Lots of UI improvements.
  • Loading branch information
nick committed Apr 18, 2018
1 parent e2acfc5 commit 4df9c31
Show file tree
Hide file tree
Showing 32 changed files with 577 additions and 762 deletions.
89 changes: 5 additions & 84 deletions contracts/ClaimHolder.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.4.18;
pragma solidity ^0.4.22;

import './ERC735.sol';
import './KeyHolder.sol';
Expand All @@ -14,7 +14,7 @@ contract ClaimHolder is KeyHolder, ERC735 {
uint256 _scheme,
address _issuer,
bytes _signature,
bytes32 _data,
bytes _data,
string _uri
)
public
Expand All @@ -24,7 +24,7 @@ contract ClaimHolder is KeyHolder, ERC735 {
KeyHolder issuer = KeyHolder(issuer);

if (msg.sender != address(this)) {
require(keyHasPurpose(keccak256(msg.sender), 3)); // Sender has MANAGEMENT_KEY
require(keyHasPurpose(keccak256(msg.sender), 3), "Sender does not have management key");
}

if (claims[claimId].issuer != _issuer) {
Expand Down Expand Up @@ -53,7 +53,7 @@ contract ClaimHolder is KeyHolder, ERC735 {

function removeClaim(bytes32 _claimId) public returns (bool success) {
if (msg.sender != address(this)) {
require(keyHasPurpose(keccak256(msg.sender), 1)); // Sender has MANAGEMENT_KEY
require(keyHasPurpose(keccak256(msg.sender), 1), "Sender does not have management key");
}

/* uint index; */
Expand Down Expand Up @@ -82,7 +82,7 @@ contract ClaimHolder is KeyHolder, ERC735 {
uint256 scheme,
address issuer,
bytes signature,
bytes32 data,
bytes data,
string uri
)
{
Expand All @@ -96,85 +96,6 @@ contract ClaimHolder is KeyHolder, ERC735 {
);
}

function getClaimSig(bytes32 _claimId)
public
constant
returns(
bytes32 data,
bytes32 r,
bytes32 s,
uint8 v
)
{
bytes32 ra;
bytes32 sa;
uint8 va;

bytes memory sig = claims[_claimId].signature;

// Check the signature length
if (sig.length != 65) {
return (0, 0, 0, 0);
}

// Divide the signature in r, s and v variables
assembly {
ra := mload(add(sig, 32))
sa := mload(add(sig, 64))
va := byte(0, mload(add(sig, 96)))
}

if (va < 27) {
va += 27;
}

bytes32 dataHash = keccak256(address(this), claims[_claimId].claimType, claims[_claimId].data);
bytes32 prefixedHash = keccak256("\x19Ethereum Signed Message:\n32", dataHash);

return (prefixedHash, ra, sa, va);
}

function recoverIssuer(bytes32 _claimId)
private
constant
returns(address issuer)
{
bytes32 dataHash;
bytes32 sig_r;
bytes32 sig_s;
uint8 sig_v;

(dataHash, sig_r, sig_s, sig_v ) = getClaimSig(_claimId);

return ecrecover(dataHash, sig_v, sig_r, sig_s);
}

function isClaimValid(bytes32 _claimId)
public
view
returns(bool result)
{
address issuer = claims[_claimId].issuer;
if (issuer == address(this)) {
return true;
}

address recovered = recoverIssuer(_claimId);
bytes32 hashedAddr = keccak256(recovered);

uint size;
assembly { size := extcodesize(issuer) }

if (size == 0) {
return false;
}

KeyHolder certifier = KeyHolder(claims[_claimId].issuer);

bool isValid = certifier.keyHasPurpose(hashedAddr, claims[_claimId].claimType);
return isValid;
}

function getClaimIdsByType(uint256 _claimType)
public
constant
Expand Down
70 changes: 36 additions & 34 deletions contracts/ClaimVerifier.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
pragma solidity ^0.4.18;
pragma solidity ^0.4.22;

import './ClaimHolder.sol';

contract ClaimVerifier {

event ClaimValid(ClaimHolder _identity, uint256 claimType, bytes32 recoveredKey);
event ClaimInvalid(ClaimHolder _identity, uint256 claimType, bytes32 recoveredKey);
event ClaimValid(ClaimHolder _identity, uint256 claimType);
event ClaimInvalid(ClaimHolder _identity, uint256 claimType);

ClaimHolder public trustedClaimHolder;

Expand All @@ -17,49 +17,37 @@ contract ClaimVerifier {
public
returns (bool claimValid)
{
uint256 foundClaimType;
uint256 scheme;
address issuer;

// Construct claimId (identifier + claim type)
bytes32 claimId = keccak256(trustedClaimHolder, claimType);

// Fetch claim from user
( foundClaimType, scheme, issuer, ) = _identity.getClaim(claimId);

// Recover address of data signer
address recovered = getRecoveredAddress(_identity, claimId);

// Take hash of recovered address
bytes32 hashedAddr = keccak256(recovered);

// Does the trusted identifier have they key which signed the user's claim?
if (trustedClaimHolder.keyHasPurpose(hashedAddr, 3)) {
emit ClaimValid(_identity, claimType, hashedAddr);
if (claimIsValid(_identity, claimType)) {
emit ClaimValid(_identity, claimType);
return true;
} else {
emit ClaimInvalid(_identity, claimType, hashedAddr);
emit ClaimInvalid(_identity, claimType);
return false;
}
}

function checkClaimConstant(ClaimHolder _identity, uint256 claimType)
function claimIsValid(ClaimHolder _identity, uint256 claimType)
public
constant
returns (bool claimValid)
{
uint256 foundClaimType;
uint256 scheme;
address issuer;
bytes memory sig;
bytes memory data;

// Construct claimId (identifier + claim type)
bytes32 claimId = keccak256(trustedClaimHolder, claimType);

// Fetch claim from user
( foundClaimType, scheme, issuer, ) = _identity.getClaim(claimId);
( foundClaimType, scheme, issuer, sig, data, ) = _identity.getClaim(claimId);

bytes32 dataHash = keccak256(_identity, claimType, data);
bytes32 prefixedHash = keccak256("\x19Ethereum Signed Message:\n32", dataHash);

// Recover address of data signer
address recovered = getRecoveredAddress(_identity, claimId);
address recovered = getRecoveredAddress(sig, prefixedHash);

// Take hash of recovered address
bytes32 hashedAddr = keccak256(recovered);
Expand All @@ -68,20 +56,34 @@ contract ClaimVerifier {
return trustedClaimHolder.keyHasPurpose(hashedAddr, 3);
}

function getRecoveredAddress(ClaimHolder _identity, bytes32 claimId)
function getRecoveredAddress(bytes sig, bytes32 dataHash)
public
view
returns (address addr)
{
bytes32 dataHash;
bytes32 sig_r;
bytes32 sig_s;
uint8 sig_v;
bytes32 ra;
bytes32 sa;
uint8 va;

// Check the signature length
if (sig.length != 65) {
return (0);
}

// Divide the signature in r, s and v variables
assembly {
ra := mload(add(sig, 32))
sa := mload(add(sig, 64))
va := byte(0, mload(add(sig, 96)))
}

if (va < 27) {
va += 27;
}

(dataHash, sig_r, sig_s, sig_v ) = _identity.getClaimSig(claimId);
address recoveredAddress = ecrecover(dataHash, va, ra, sa);

address recoveredAddress = ecrecover(dataHash, sig_v, sig_r, sig_s);
return (recoveredAddress);
return (recoveredAddress);
}

}
2 changes: 1 addition & 1 deletion contracts/ERC725.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.4.18;
pragma solidity ^0.4.22;

contract ERC725 {

Expand Down
16 changes: 8 additions & 8 deletions contracts/ERC735.sol
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
pragma solidity ^0.4.18;
pragma solidity ^0.4.22;

contract ERC735 {

event ClaimRequested(uint256 indexed claimRequestId, uint256 indexed claimType, uint256 scheme, address indexed issuer, bytes signature, bytes32 data, string uri); event ClaimAdded(bytes32 indexed claimId, uint256 indexed claimType, address indexed issuer, uint256 signatureType, bytes32 signature, bytes claim, string uri);
event ClaimAdded(bytes32 indexed claimId, uint256 indexed claimType, uint256 scheme, address indexed issuer, bytes signature, bytes32 data, string uri);
event ClaimRemoved(bytes32 indexed claimId, uint256 indexed claimType, uint256 scheme, address indexed issuer, bytes signature, bytes32 data, string uri);
event ClaimChanged(bytes32 indexed claimId, uint256 indexed claimType, uint256 scheme, address indexed issuer, bytes signature, bytes32 data, string uri);
event ClaimRequested(uint256 indexed claimRequestId, uint256 indexed claimType, uint256 scheme, address indexed issuer, bytes signature, bytes data, string uri); event ClaimAdded(bytes32 indexed claimId, uint256 indexed claimType, address indexed issuer, uint256 signatureType, bytes32 signature, bytes claim, string uri);
event ClaimAdded(bytes32 indexed claimId, uint256 indexed claimType, uint256 scheme, address indexed issuer, bytes signature, bytes data, string uri);
event ClaimRemoved(bytes32 indexed claimId, uint256 indexed claimType, uint256 scheme, address indexed issuer, bytes signature, bytes data, string uri);
event ClaimChanged(bytes32 indexed claimId, uint256 indexed claimType, uint256 scheme, address indexed issuer, bytes signature, bytes data, string uri);

struct Claim {
uint256 claimType;
uint256 scheme;
address issuer; // msg.sender
bytes signature; // this.address + claimType + data
bytes32 data;
bytes data;
string uri;
}

function getClaim(bytes32 _claimId) public constant returns(uint256 claimType, uint256 scheme, address issuer, bytes signature, bytes32 data, string uri);
function getClaim(bytes32 _claimId) public constant returns(uint256 claimType, uint256 scheme, address issuer, bytes signature, bytes data, string uri);
function getClaimIdsByType(uint256 _claimType) public constant returns(bytes32[] claimIds);
function addClaim(uint256 _claimType, uint256 _scheme, address issuer, bytes _signature, bytes32 _data, string _uri) public returns (bytes32 claimRequestId);
function addClaim(uint256 _claimType, uint256 _scheme, address issuer, bytes _signature, bytes _data, string _uri) public returns (bytes32 claimRequestId);
function removeClaim(bytes32 _claimId) public returns (bool success);
}
7 changes: 5 additions & 2 deletions contracts/Identity.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@ contract Identity is ClaimHolder {
uint256[] _scheme,
address[] _issuer,
bytes _signature,
bytes32[] _data,
bytes _data,
string _uri,
uint256[] _sigSizes,
uint256[] dataSizes,
uint256[] uriSizes
)
public
{
bytes32 claimId;
uint offset = 0;
uint uoffset = 0;
uint doffset = 0;

for (uint i = 0; i < _claimType.length; i++) {

Expand All @@ -30,12 +32,13 @@ contract Identity is ClaimHolder {
_scheme[i],
_issuer[i],
getBytes(_signature, offset, _sigSizes[i]),
_data[i],
getBytes(_data, doffset, dataSizes[i]),
getString(_uri, uoffset, uriSizes[i])
);

offset += _sigSizes[i];
uoffset += uriSizes[i];
doffset += dataSizes[i];

emit ClaimAdded(
claimId,
Expand Down
12 changes: 6 additions & 6 deletions contracts/KeyHolder.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.4.18;
pragma solidity ^0.4.22;

import './ERC725.sol';

Expand Down Expand Up @@ -57,9 +57,9 @@ contract KeyHolder is ERC725 {
public
returns (bool success)
{
require(keys[_key].key != _key); // Key should not already exist
require(keys[_key].key != _key, "Key already exists"); // Key should not already exist
if (msg.sender != address(this)) {
require(keyHasPurpose(keccak256(msg.sender), 1)); // Sender has MANAGEMENT_KEY
require(keyHasPurpose(keccak256(msg.sender), 1), "Sender does not have management key"); // Sender has MANAGEMENT_KEY
}

keys[_key].key = _key;
Expand All @@ -77,7 +77,7 @@ contract KeyHolder is ERC725 {
public
returns (bool success)
{
require(keyHasPurpose(keccak256(msg.sender), 2));
require(keyHasPurpose(keccak256(msg.sender), 2), "Sender does not have action key");

emit Approved(_id, _approve);

Expand Down Expand Up @@ -112,7 +112,7 @@ contract KeyHolder is ERC725 {
public
returns (uint256 executionId)
{
require(!executions[executionNonce].executed);
require(!executions[executionNonce].executed, "Already executed");
executions[executionNonce].to = _to;
executions[executionNonce].value = _value;
executions[executionNonce].data = _data;
Expand All @@ -131,7 +131,7 @@ contract KeyHolder is ERC725 {
public
returns (bool success)
{
require(keys[_key].key == _key);
require(keys[_key].key == _key, "No such key");
emit KeyRemoved(keys[_key].key, keys[_key].purpose, keys[_key].keyType);

/* uint index;
Expand Down
6 changes: 3 additions & 3 deletions issuer-services/_facebook.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ module.exports = function facebook(app, { web3, facebookApp, baseUrl }) {
async (req, res) => {
// var data = JSON.stringify({ user_id: req.tokenDebug.user_id })
var rawData = 'Verified OK'
var hashedData = web3.utils.soliditySha3(rawData)
var hashed = web3.utils.soliditySha3(req.session.targetIdentity, ClaimType, hashedData)
var hexData = web3.utils.asciiToHex(rawData)
var hashed = web3.utils.soliditySha3(req.session.targetIdentity, ClaimType, hexData)
req.signedData = await web3.eth.accounts.sign(hashed, facebookApp.claimSignerKey)

res.send(HTML(`
Expand All @@ -105,7 +105,7 @@ module.exports = function facebook(app, { web3, facebookApp, baseUrl }) {
window.done = function() {
window.opener.postMessage('signed-data:${
req.signedData.signature
}:${req.signedData.messageHash}:${ClaimType}', '*')
}:${rawData}:${ClaimType}', '*')
}
</script>`
))
Expand Down
Loading

0 comments on commit 4df9c31

Please sign in to comment.