ERC-1056: 以太坊轻量级身份
Authors | Pelle Braendgaard <pelle.braendgaard@consensys.net>, Joel Torstensson <oed@consensys.net> |
---|---|
Created | 2018-05-03 |
Discussion Link | https://github.com/ethereum/EIPs/issues/1056 |
Table of Contents
简单总结
一个用于轻量级区块链身份的密钥和属性管理的注册表。
摘要
此 ERC 描述了一个用于创建和更新身份的标准,该标准对区块链资源的使用有限。一个身份可以有无限数量的与之相关的 delegates
和 attributes
。身份创建就像创建一个常规的密钥对以太坊账户一样简单,这意味着它是免费的(没有 gas 成本),并且所有以太坊账户都是有效的身份。此外,此 ERC 完全符合 DID compliant。
动机
在过去的几年里,我们在 uPort 一直在开发身份系统,很明显,身份创建的成本是一个很大的问题。之前的身份提案 ERC-725 正面临着这个问题。我们在创建此 ERC 时的要求是身份创建应该是免费的,并且应该可以在离线环境中进行(例如,难民情况)。但是,还必须能够在不更改身份的主要标识符的情况下轮换密钥。身份系统应适合链下和链上使用。
定义
-
Identifier
:唯一标识身份的一段数据,一个以太坊地址 -
delegate
:一个被委托在特定时间内代表身份执行某种功能的地址 -
delegateType
:delegate 的类型,由更高的协议或应用程序确定 示例:did-jwt
raiden
-
attribute
:与身份相关的一段数据
规范
此 ERC 指定了一个名为 EthereumDIDRegistry
的合约,该合约部署一次,然后可以被所有人共同使用。
身份所有权
默认情况下,身份由其自身所有,这意味着由控制具有该地址的以太坊账户的任何人所有。所有者可以更新为新的密钥对账户或多重签名账户等。
identityOwner
返回给定身份的所有者。
function identityOwner(address identity) public view returns(address);
changeOwner
将给定身份的所有者设置为另一个以太坊账户。
function changeOwner(address identity, address newOwner) public;
changeOwnerSigned
与上面相同,但使用原始签名。
function changeOwnerSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, address newOwner) public;
Delegate 管理
Delegate 可以在链上和链下使用。它们都具有一个 delegateType
,可用于指定 delegate 的目的。
validDelegate
如果给定的 delegate
是 identity
的具有类型 delegateType
的 delegate,则返回 true。
function validDelegate(address identity, bytes32 delegateType, address delegate) public view returns(bool);
addDelegate
添加具有给定类型的新 delegate。validity
指示 delegate 有效的秒数,之后它将不再是 identity
的 delegate。
function addDelegate(address identity, bytes32 delegateType, address delegate, uint validity) public;
addDelegateSigned
与上面相同,但使用原始签名。
function addDelegateSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 delegateType, address delegate, uint validity) public;
revokeDelegate
撤销给定 identity
的给定 delegate
。
function revokeDelegate(address identity, bytes32 delegateType, address delegate) public;
revokeDelegateSigned
与上面相同,但使用原始签名。
function revokeDelegateSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 delegateType, address delegate) public;
属性管理
属性包含有关身份的简单数据。它们只能由身份的所有者管理。
setAttribute
设置具有给定 name
和 value
的属性,有效期为 validity
秒。
function setAttribute(address identity, bytes32 name, bytes value, uint validity) public;
setAttributeSigned
与上面相同,但使用原始签名。
function setAttributeSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 name, bytes value, uint validity) public;
revokeAttribute
撤销属性。
function revokeAttribute(address identity, bytes32 name, bytes value) public;
revokeAttributeSigned
与上面相同,但使用原始签名。
function revokeAttributeSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 name, bytes value) public;
事件
DIDOwnerChanged
当成功调用 changeOwner
或 changeOwnerSigned
时,必须触发。
event DIDOwnerChanged(
address indexed identity,
address owner,
uint previousChange
);
DIDDelegateChanged
当成功更改 delegate 时,必须触发。
event DIDDelegateChanged(
address indexed identity,
bytes32 delegateType,
address delegate,
uint validTo,
uint previousChange
);
DIDAttributeChanged
当成功更改属性时,必须触发。
event DIDAttributeChanged(
address indexed identity,
bytes32 name,
bytes value,
uint validTo,
uint previousChange
);
通过链接的身份事件高效查找事件
合约事件是一个有用的功能,用于专门为链下使用存储来自智能合约的数据。不幸的是,当前的以太坊实现提供了一个非常低效的查找机制。通过使用始终链接到身份更改的前一个区块的链接事件,我们可以通过大大提高的性能来解决这个问题。每个身份的前一个更改区块都存储在 changed
映射中。
-
查找身份的
previousChange
区块 -
使用 web3 查找给定身份地址的所有事件,但仅针对
previousChange
区块 -
对事件执行某些操作
-
从事件中找到
previousChange
并重复
示例代码:
const history = []
previousChange = await didReg.changed(identity)
while (previousChange) {
const filter = await didReg.allEvents({topics: [identity], fromBlock: previousChange, toBlock: previousChange})
const events = await getLogs(filter)
previousChange = undefined
for (let event of events) {
history.unshift(event)
previousChange = event.args.previousChange
}
}
为身份构建 DID 文档
应该使用 identityOwner(identity)
查找主所有者密钥。这应该是列出的第一个 publicKeys。迭代 DIDDelegateChanged
事件,以根据需要构建其他密钥和身份验证部分的列表。要包含的 delegateType 列表仍有待确定。迭代 DIDAttributeChanged
事件以查找服务条目、加密公钥和其他公共名称。属性名称仍有待确定。
基本原理
对于链上交互,以太坊具有内置的账户抽象,无论账户是智能合约还是密钥对,都可以使用。任何交易都有一个 msg.sender
作为交易的已验证发送者。
由于每笔以太坊交易都必须有资金支持,因此通过外部创建的签名而不是由实际交易发起者进行身份验证的链上交易的趋势越来越明显。这允许第三方资金服务或接收方支付,而无需对底层以太坊架构进行任何根本性的更改。这些类型的交易必须由实际密钥对签名,因此不能用于表示基于智能合约的以太坊账户。
我们提出了一种智能合约或常规密钥对将各种用途的签名委托给外部管理的密钥对的方法。这允许智能合约通过临时或永久 delegate 在链上以及链下或支付通道中表示。
向后兼容性
使用此标准,所有以太坊账户都是有效的身份(并且与 DID 兼容)。这意味着任何使用密钥对账户的钱包提供商都已经支持此标准的最低要求,并且只需使用下面引用的 ethr-did
即可实现 delegate
和 attribute
功能。随着 DID Auth 标准的巩固,这也意味着所有这些钱包都将与 DID decentralized login system 兼容。
实现
ethr-did-registry(EthereumDIDRegistry
合约实现)
ethr-did-resolver (DID 兼容解析器)
ethr-did (用于使用身份的 JavaScript 库)
部署
EthereumDIDRegistry
的地址在 Mainnet、Ropsten、Rinkeby 和 Kovan 上是 0xdca7ef03e98e0dc2b855be647c39abe984fcf21b
。
版权
通过 CC0 放弃版权及相关权利。
Citation
Please cite this document as:
Pelle Braendgaard <pelle.braendgaard@consensys.net>, Joel Torstensson <oed@consensys.net>, "ERC-1056: 以太坊轻量级身份 [DRAFT]," Ethereum Improvement Proposals, no. 1056, May 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1056.