Identity and Claim (ERC734/735) ~ Introduction ~

Yuya Sugano
23 min readJun 1, 2019

--

アイデンティティー(ID)は、ブロックチェーンエコシステムで欠けている重要な要素の1つです。アカウント(Externally Owned Account)やコントラクトのアドレスではなくアイデンティティ(ID)を表現する規格であるERC734(ERC725 v1)とERC725(ERC725 v2)、またサードパーティーの Claim を実装するERC735の概要と実装例を調べてみました。

※ERC725/ERC735はまだドラフトや議論の段階で承認されていません

Who’s got the key ? and Who are you ?

分散信用スコアリングが検討される中で個人のアイデンティティ(ID)をどのように分散型システムで確立するかという議論がなされています。社会保障番号などを証明としてIDへ紐づけることはできますが、分散型のシステムへ集権的な情報を使用することにはあまり意味がありません。

以下は分散信用スコアリングについての素晴らしい記事。[1]

なぜアイデンティティ(ID)が分散型システムで求められるのか、分散信用スコアリングのケースから考えてみます。

分散信用スコアリング

BloomColendiなどブロックチェーンを活用した信用スコアリングのプロジェクトが複数動いています。いままで中央集権的に提供されていた信用スコアリングを分散型とすることで従来の信用スコアリングサービスが抱えていた課題が解決されそうです。

格付け会社による個人情報の漏洩事故や不透明なスコアリングのプロセスが問題視され、それらの問題に対して特に分散信用スコアリングは有効です。

途上国などではそもそも信用情報を提供することが難しいという現状があります。金融サービスを利用していない人々であってもインターネット上のブロックチェーンにおける分散信用スコアリングであれば、ビットコインやトークンによってローンを組むことができるようになるかもしれません。[2]

※ここの携帯電話はスマホと読み替え可能と思われる

世界全体では、銀行口座を保有しない成人の数は依然として 17 億人に上る。だがその内 3 分の 2 は、金融サービスへのアクセスに使える携帯電話を所有しており、デジタル技術を活用すれば、現行の現金取引を生かして、こうした人々を金融システムに組み込める可能性がある

分散信用スコアリングによって次のようなメリットが生まれます。

  • 特定の企業に個人情報を預けないことで情報漏洩リスクを低減
  • ブロックチェーン(インターネット上)によるアクセシビリティの向上
  • スコアリング方法の開示によるシステムの透明性の向上

プライバシーとセキュリティ

信用スコアリングに関する個人情報は当然ながら公開してよいものではなく、ブロックチェーンにおいてデータを秘匿化する『Enigma』をColendiは採用しています。他のユーザだけでなくノードなど中継するポイントなどでもデータを読み取られないようにします。

また分散信用スコアリングにはシビルアタックの問題が存在しています。シビルアタックとは個人や組織が大量のアカウントを作成し、それによって不正な取引や大量の取引によって悪意ある結果を引き起こす攻撃です。

そこで個人の固有のアイデンティティに基づいたIDをアカウントとして使用できればよいのですが、マイナンバーや社会保障番号のような証明書とアカウントを紐づけることにはいくつかの問題が指摘されています。

  1. 特定の組織が中央集権的に管理(総務省など)
  2. 特定の地域や国の中でのみ有効な証明
  3. 身分証明書がない人(難民など)

汎用性の高いERC725規格や生体認証(バイオメトリクス)などの適用が望まれます。生体認証についてはこの記事の趣旨からそれるため触れません。[3]

この記事では Ethereum でスマートコントラクトとして発行するアイデンティティ(ID)であるERC725/ERC735規格の概要と実装をみてみたいと思います。

ERC725 (ERC734/ ERC725 v2) — Identity

ERC725として進められていたID管理の規格は現在、ERC734(ERC725 v1)の鍵管理(Key Manager)の規格とERC725(ERC725 v2)のプロキシーアカウント(Proxy Account)の規格に分けて進められています。

ERC734(ERC725 v1)はプロキシーアカウント(ERC725 v2)などに使用することができる鍵管理の規格です。鍵管理のコントラクトは複数の鍵を管理してトランザクションやドキュメント、ログインなどに対して署名することができます。[4]

The following describes standard functions for a key manager to be used in conjunction with ERC725.
This contract can hold keys to sign actions (transactions, documents, logins, access, etc), as well as execute instructions through an ERC 725 proxy account.

ERC725 v2のプロキシーアカウントは以前のERC725 v1のプロキシー部分を切り出した規格です。Ethereum でのアイデンティティ(ID)を定義し、設定したIDから他コントラクトの呼び出しを行うインターフェースを実装しています。プロキシーアカウント自体はアカウント(Externally Owned Account)による管理や、上記の鍵管理コントラクトによる管理ができます。

ERC734は鍵束のようなもの(このコントラクトに複数の鍵がある)で、保管される鍵は公開鍵です。ERC734では鍵は以下の構造体で表現されます。

struct Key {
uint256[] purposes;
uint256 keyType;
bytes32 key;
}
  • purpose: 鍵の目的(githubでは、例として 1 = MANAGEMENT、 2 = EXECUTIONが挙げられている)
    1: MANAGEMENT 対象IDの管理の目的
    2: EXECUTION 対象IDでサインインやログイン、トランザクションを実行する目的
  • keyType: キータイプ、例として 1 = ECDSA、2 = RSA など
  • key: 鍵データ本体、keccak256でハッシュ化した鍵

鍵を使用する際は execute でERC725へパスするインストラクションを作成し、 approve で承認することでインストラクションの実行やIDへの Claim の追加が可能です。※ Claim はERC735として議論されている『Claim Holder』という規格、後ほど登場します

execute は1つか複数の鍵によって approve される必要があり、 approve メソッドは n 個の鍵による許可がないと実行されません。ここは実装次第の部分が大きいと思います。

鍵束に紐づくIDが個人ではなく組織である場合は、複数の鍵の許可によるオペレーション実行のケースが考えられます。

execute

Passes an execution instruction to an ERC725 identity.

SHOULD require approve to be called with one or more keys of purpose 1 or 2 to approve this execution.

approve

Approves an execution or claim addition.

This SHOULD require n of m approvals of keys purpose 1, if the _to of the execution is the identity contract itself, to successfully approve an execution.
And COULD require n of m approvals of keys purpose 2, if the _to of the execution is another contract, to successfully approve an execution.

インターフェースです。

contract ERC734 {

uint256 constant MANAGEMENT_KEY = 1;
uint256 constant EXECUTION_KEY = 2;

event KeyAdded(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType);
event KeyRemoved(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType);
event ExecutionRequested(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data);
event Executed(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data);
event Approved(uint256 indexed executionId, bool approved);
event KeysRequiredChanged(uint256 purpose, uint256 number);

struct Key {
uint256 purpose; //e.g., MANAGEMENT_KEY = 1, EXECUTION_KEY = 2, etc.
uint256 keyType; // e.g. 1 = ECDSA, 2 = RSA, etc.
bytes32 key;
}

function getKey(bytes32 _key) public constant returns(uint256[] purposes, uint256 keyType, bytes32 key);
function keyHasPurpose(bytes32 _key, uint256 _purpose) public constant returns (bool exists);
function getKeysByPurpose(uint256 _purpose) public constant returns (bytes32[] keys);
function addKey(bytes32 _key, uint256 _purpose, uint256 _keyType) public returns (bool success);
function removeKey(bytes32 _key, uint256 _purpose) public returns (bool success);
function changeKeysRequired(uint256 purpose, uint256 number) external;
function getKeysRequired(uint256 purpose) external view returns(uint256);
function execute(address _to, uint256 _value, bytes _data) public returns (uint256 executionId);
function approve(uint256 _id, bool _approve) public returns (bool success);
}

ERC725 v2はユニークで識別可能なプロキシーアカウントで、個人だけでなくグループ、組織や物などにも利用できます。このプロキシー(『代理』という意味)コントラクトから任意のコントラクトを呼び出せることと、またキーバリューストア的に任意の値を保存できることの2つが要件付けされています。キーの1つは必ずコントラクトのオーナーである必要があり、所有者は通常のアカウント(Externally Owned Account)かERC734の鍵管理のコントラクトになります。[5]

A unique identifiable proxy account to be used by humans, groups, organisations, objects and machines. The proxy has 2 abilities: (1) it can execute arbitrary contract calls, and (2) it can hold arbitrary data through a generic key/value store. One of these keys should hold the owner of the contract. The owner may be an address or a key manager contract for more complex management logic.

IDコントラクトは Claim など多彩な情報を追加することができます。

ERC725(ERC725 v2)のインターフェースです。

interface ERC725 {
event DataChanged(bytes32 indexed key, bytes32 indexed value);
event OwnerChanged(address indexed ownerAddress);
event ContractCreated(address indexed contractAddress);

// address public owner;

function changeOwner(address _owner) external;
function getData(bytes32 _key) external view returns (bytes32 _value);
function setData(bytes32 _key, bytes32 _value) external;
function execute(uint256 _operationType, address _to, uint256 _value, bytes calldata _data) external;
}

owner である所有者がこのコントラクトを操作します。 ownerから execute をフックして他のコントラクトのコールや送金ができ、 _operationType を指定することでアセンブリの操作を変更します。規格では 0 の呼び出しと、 1 の作成があります。

  • 0 for call (呼び出し)
  • 1 for create (作成)

キーは必ずキーの文字列をkeccak256でハッシュ化する必要があり、以下の3つが現在定義されています。

  • owner — The owner of the proxy
    0x000000000000000000000000de0B295669a9FD93d5F28D9Ec85E40f4cb697BAe
  • 735 — The proxy accounts claim holder contract
    0x000000000000000000000000de0B295669a9FD93d5F28D9Ec85E40f4cb697BAe
  • 735 — The proxy accounts claim holder contract
    0x000000000000000000000000de0B295669a9FD93d5F28D9Ec85E40f4cb697BAe

先に述べたとおり少なくともownerはキーとして設定しておく必要があり、その値はアカウント(Externally Owned Account)かERC734で発行した鍵管理のコントラクトのアドレスです。

ERC735 — Claim

Claim はサードパーティーから提供される証明で、IDへ添付し証明書のように使用することができます。証明書の1つである運転免許証を例で考えましょう。運転免許証は路上での検問や、コンビニでお酒やタバコを購入する際に年齢を証明するために提示することができ、都道府県公安委員会 Claim Issuerから発行されるものです。

この運転免許証があなたのIDへ Claim として発行された証明書 Verifiable Claimで、路上での検問のケースでは直接提示することも、警察官 Verifer が照会してシステム Claim Holder で確認することもできます。

あなたというIDへ様々な Claim を付与していくことができるのがERC725 v2であるプロキシーコントラクトです。そしてIDというのは個人を表現するものでも組織や会社を表現するためでもよく、単一のアカウント(Externally Owned Account)やERC734(ERC725 v1)の鍵管理による所有ができるということでした。

ERC735は Claim の追加や削除などの管理を行うコントラクトで、運転免許証の例のような証明だけでなく自己証明も行えます。[6]

Standard functions for adding, removing and holding of claims.
These claims can attested from third parties (issuers) or self attested.

This standardised claim holder interface will allow Dapps and smart contracts to check the claims about a claim holder. Trust is here transfered to the issuers of claims.

Claim は構造体で定義されます。

struct Claim {
uint256 topic;
uint256 scheme;
address issuer; // msg.sender
bytes signature; // this.address + topic + data
bytes data;
string uri;
}
  • claim issuer: アカウント(Externally Owned Account)か他のスマートコントラクトでIDに対して Claim を発行する主体、ID自体が発行する自己証明も可能
  • topic: uint256 の任意の数字で用途を定義する、例として、1 = Biometric、2 = Residence
  • scheme : Claimの確認方法や処理スキーム、例として、1 = ECDSA、2 = RSAなど
  • issuer: Claimを発行者のIDのコントラクトアドレス、もしくはメッセージに署名するアドレス、署名に使用する鍵が存在しなくなった場合は Claimは無効として取り扱われる
  • signature: IDに対して Claim Issuerが発行した署名、以下のいずれかの方法で署名される
    keccak256(address identityHolder_address, uint256 _ topic, bytes data)
    keccak256(abi.encode(identityHolder_address, topic, data))
  • data: ハッシュ化されたデータ、ビットマスク、コールデータや実データなど schemeによる
  • uri: Claimの場所、HTTPリンクやSwarmハッシュ、IPFSなど

インターフェースです。

contract ERC735 {

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

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

function getClaim(bytes32 _claimId) public constant returns(uint256 topic, uint256 scheme, address issuer, bytes signature, bytes data, string uri);
function getClaimIdsByTopic(uint256 _ topic) public constant returns(bytes32[] claimIds);
function addClaim(uint256 _topic, uint256 _scheme, address _issuer, bytes _signature, bytes _data, string _uri) public returns (uint256 claimRequestId);
changeClaim(bytes32 _claimId, uint256 _topic, uint256 _scheme, address _issuer, bytes _signature, bytes _data, string _uri) returns (bool success);
function removeClaim(bytes32 _claimId) public returns (bool success);
}

ERC735やまたERC780がオンチェーンの Claim の規格であることに対してERC1812のようなオフチェーンの Claim もドラフトされています。

クラウドセールとKYCの実装例

KYCの必要な(IDプロバイダーからの)クラウドセールにおけるFractal IDのERC725/ERC735サンプルです。[8]

このサンプルにおけるIDとKYC、サービスの連携を見てみます。

  • Fractal ID: サービスプロバイダでKYCやAMLのサービス提供を行う主体、 Claim Issuer となる
  • Very Good Company: トークン発行およびクラウドファンディングを行う主体、ただしクラウドセールにはKYCが必要で『Fractal ID』は有効なKYCであると認識している
  • Investor: 『Fractal ID』側からKYCのステータスを取得および保持することでクラウドセールへ参加するユーザ、 Claim Holder となる
https://medium.com/@kctheservant/a-companion-guide-to-first-impressions-with-erc-725-and-erc-735-identity-and-claims-part-1-51b53603cfc0
  1. 『Investor』は自身のIDに必要なKYCの ClaimClaim Issuerである『Fractal ID』へ依頼する。ここでは事前に必要なコントラクトの発行や署名などの処理は行われているものとする。
  2. 『Fractal ID』はKYCの Claimを『Investor』へ発行する。KYCは『Fractal ID』によって署名されており『Investor』のIDはいまKYCの Claimを保持している状態である。
  3. 『Investor』はトークンを購入するために、資金と『Fractal ID』で証明されるKYCの Claimを提示する。
  4. 『Very Good Company』は『Fractal ID』のKYCを有効なサードパーティーの証明と認識しているため、この購入依頼を承認してトークンを『Investor』へ送付する。

このようにしてIDコントラクトと Claim を使用したID認証が実現できます。実装例とサンプルコードのテストは次回に行います。

まとめ

  • 分散信用スコアリングなど様々な分散型システムにおいてアイデンティティ(ID)管理が求められている
  • アイデンティティを規定する規格であったERC725はERC734(ERC725 v1)とERC725(ERC725 v2)に分割されてドラフトされている
  • ERC735/ERC780がオンチェーンの Claim 規格として、ERC1812はオフチェーンのClaim 規格として議論されている

--

--

Yuya Sugano
Yuya Sugano

Written by Yuya Sugano

Cloud Architect and Blockchain Enthusiast, techflare.blog, Vinyl DJ, Backpacker. ブロックチェーン・クラウド(AWS/Azure)関連の記事をパブリッシュ。バックパッカーとしてユーラシア大陸を陸路横断するなど旅が趣味。

No responses yet