ERC-1078: 使用 ENS 子域名进行通用登录/注册
Authors | Alex Van de Sande <avsa@ethereum.org> |
---|---|
Created | 2018-05-04 |
Discussion Link | https://ethereum-magicians.org/t/erc1077-and-1078-the-magic-of-executable-signed-messages-to-login-and-do-actions/351 |
Requires | EIP-191, EIP-681, EIP-725, EIP-1077 |
摘要
本文提出了一种用最小的以太坊原生方案来替换通常的注册/登录设计模式的方法,该方案不需要密码、备份私钥或输入助记词。从用户的角度来看,它将非常类似于他们已经习惯的具有二次验证的模式(不依赖于中央服务器),但对于 DApp 开发者来说,它需要一种新的以太坊交易思维方式。
简述
用户的唯一标识符是一个合约,它同时实现了 Identity 和 Executable Signed Messages ERC。用户不应直接提供此地址,只需提供指向它的 ENS 名称。这些类型的合约间接受私钥控制,私钥可以签署指示意图的消息,然后由第三方(或去中心化的部署者网络)将其部署到合约。
因此,在这种情况下,设备使用身份“登录”应用程序,意味着设备将在本地生成一个私钥,然后请求授权以将该密钥添加为该身份的签名者之一,并具有给定的权限集。由于该私钥仅用于签署消息,因此不需要持有 ether、tokens 或 assets,并且如果丢失,可以简单地用新的私钥替换——用户的资金保存在身份合约中。
在这种情况下,以太坊账户的使用方式更类似于 auth tokens,而不是唯一的密钥。
登录过程如下:
1) 向用户请求名称
该过程的第一步是从用户那里请求指向他们身份的 ENS 名称。如果用户没有设置登录名,则应用程序应该——如果他们有集成的身份管理器——提供一个选项来提供一个子域名或他们拥有的名称。
用户体验注意事项: 有很多方法可以提供此界面,应用程序可以事先询问他们是否要注册/登录,或者直接要求他们输入名称。请注意,由于验证用户名是否存在很简单,因此您的应用程序应该优雅地适应它,并且不需要用户两次输入他们的姓名。如果他们要求注册并提供一个存在的名称,然后询问他们是否要使用该名称登录,或者类似地,如果他们要求连接到现有名称但输入一个不存在的名称,则向他们显示一个友好的警报,并询问他们是否要立即创建该名称。不要强迫他们在两个不同的字段中两次输入相同的名称。
2.a) 创建新身份
如果用户没有身份,应用程序应提供为他们创建身份的选项。每个应用程序必须拥有一个或多个他们控制的域名,他们可以在这些域名上按需创建即时子域名。因此,应用程序将在后台执行以下操作:
- 生成一个私钥,并以尽可能安全的方式将其保存在设备或浏览器本地。
- 创建(或设置)一个同时支持 ERC720 和 ERC1077 的身份合约。
- 将步骤 1 中创建的私钥注册为合约的唯一管理员密钥(应用程序不得添加任何应用程序控制的密钥,除非作为恢复选项 - 参见 5)。
- 注册请求的子域名,并将其所有权转移到合约(虽然应用程序控制着主域名,并且可以随意保留重新分配它们的选项,但子域名本身的所有权应属于身份,因此允许他们转移它)。
- (可选) 在合约上注册一种恢复方法,允许用户在主密钥丢失的情况下重新获得对合约的访问权限。
所有这些步骤都可以设计为在单个以太坊交易中设置。由于此步骤不是免费的,因此应用程序保留对注册用户收费的权利,或者要求用户以应用程序选择的抗女巫攻击方式进行验证(验证码、设备 ID 注册、工作量证明等)
不应强迫用户等待交易确认时间。相反,在应用程序的某个地方设置一个指示器来显示进度,然后允许用户正常地与您的应用程序交互。他们不太可能在最初的几分钟内需要该身份,如果出现问题(用户名同时被注册),您可以要求用户采取行动。
实现说明: 为了节省 gas,其中一些步骤可以提前完成。应用程序可以在 gas 价格较低时自动部署少量合约,并将所有主要变量设置为 0xFFFFFF…FFFFF。这些应被视为“空缺”,当用户注册一个时,他们将获得 gas 折扣以释放链上的空间。这还具有允许用户选择合约地址/图标的额外好处。
2.b) 连接到现有身份
如果用户想要连接到现有身份,那么应用程序需要了解的第一件事是它将要求什么级别的权限:
Manager(管理者) 更高级别,允许密钥发起或签署更改身份本身的交易,例如添加或删除密钥。如果应用程序集成了身份管理器,则只应要求此级别。根据身份的设置方式,在部署这些交易之前,可能需要更多密钥的签名。
Action(操作) 此级别允许密钥在自身以外的地址上发起或签署交易。它可以移动资金、ether、assets 等。如果应用程序是用于发送以太坊交易的通用钱包或浏览器,则只应要求此权限级别。根据身份的设置方式,在部署这些交易之前,可能需要更多密钥的签名。
Encryption(加密) 较低级别无权发起任何交易,但它可用于在特定实例或链下签名消息中代表用户。它是游戏、聊天或社交媒体应用程序的理想权限级别,因为它们可用于签署移动、发送消息等。如果游戏需要实际资金(例如,以资金开始游戏),则仍应使用加密级别,然后要求用户的主要钱包/浏览器使用 ethereum URI 标准签署消息。
一旦知道所需的级别,应用程序必须采取以下步骤:
- 生成一个私钥,并以尽可能安全的方式将其保存在设备或浏览器本地。
- 查询 ens 以确定身份的现有地址。
- 生成字节码 以调用函数
addKey(PUBLICKEY,LEVEL)
的交易。 - 在 whisper 频道上广播交易请求 或其他一些去中心化的对等网络。此步骤的详细信息需要进一步讨论。
- 如果 web3 可用,则尝试调用 web3.eth.sendTransaction。这可以是自动的或由用户操作提示的。
- 尝试调用 URI 如果应用程序支持 URL format for transaction requests EIP,则尝试调用它。这可以是自动的或由用户操作提示的。
- 显示二维码:带有 EIP681 格式的 URL。该二维码可以是可点击的,以尝试重试其他选项,但应最后完成:如果步骤 1 有效,用户应在其兼容设备上收到通知,并且无需使用二维码。
以下是一个与 EIP681 兼容的地址示例,用于添加在应用程序本地生成的公钥:
ethereum:bob.example.eth?function=addKey(address='0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef',uint=1)
如果添加新密钥需要多个签名,或者如果接收该请求的应用程序专门处理可执行签名消息并且自身没有 ether,则应按照下一节中的步骤操作,了解如何请求交易。
和以前一样,不应强迫用户等待交易确认时间。相反,在应用程序的某个地方设置一个指示器来显示进度,然后允许用户正常地与您的应用程序交互。
3) 请求交易
在步骤 2 之后,最终结果应该是您的应用程序应该具有用户的身份地址、他们的主要 ens 名称和一个私钥,其公共帐户已在身份上列为他们的密钥之一,角色为管理者、操作或加密。现在它可以开始使用该信息来签名和执行交易。
并非所有交易都需要在链上,实际上,签名消息最常见的用途应该是在链下。例如,如果您有一个聊天应用程序,则可以使用本地密钥对消息进行签名并将其发送给其他方,他们只需查询身份合约即可查看该密钥是否确实来自用户。如果您有一个有资金风险的游戏,只有移动资金和设置初始游戏的第一笔交易需要由身份执行:在每一回合中,玩家都可以签署当前棋盘状态的哈希值,最后,可以使用最后两个移动来确定获胜者。请注意,密钥可以随时被撤销,因此您的应用程序应考虑到这一点,例如在游戏开始时保存所有密钥。只需要此较低级别权限的密钥应设置为级别 4(加密)。
一旦您决定确实需要进行链上交易,请执行以下步骤:
- 找出 TO、FROM、VALUE 和 DATA。这些是任何以太坊交易的基础。
from
是您希望从中部署交易的兼容合约。 - 检查您需要的权限级别: 如果
to
和from
字段是相同的合约,即,如果交易需要身份对其自身采取行动(例如,添加或删除密钥时),则您需要级别 1(管理),否则为 2(操作)。验证您的应用程序拥有的密钥是否对应于所需的级别。 - 通过在目标合约上调用
requiredSignatures(uint level)
来验证需要多少个密钥 - 找出 gasLimit:估算所需交易的 gas 成本,并添加一个余量(建议:添加 100k gas)
- 找出 gasToken 和 gasPrice:考虑网络拥塞和用户将要支付的 token 的市场价格,检查当前的 gas 价格。将 gasToken 保留为 0 表示为 ether。如果您要自己部署并在其他地方补贴成本,则将 gasPrice 保留为 0。
- 通过遵循该标准来签署可执行的签名交易。
在拥有所有签名的可执行消息后,我们需要将其部署到链中。如果交易只需要单个签名,则应用提供商可以自己部署它。将交易发送到 from
地址,并尝试使用您刚收集的参数和签名来调用函数 executeSigned
。
如果交易需要收集更多签名,或者应用没有可部署的服务器,则应用应执行以下步骤:
- 在 whisper 频道上广播交易 或其他一些去中心化的对等网络。此步骤的详细信息需要进一步讨论。
- 如果 web3 可用,则尝试调用 web3.eth.personal_sign。这可以是自动的或由用户操作提示的。
- 显示二维码:带有签名的交易和要签名的新数据。该二维码可以是可点击的,以尝试重试其他选项,但应最后完成:如果步骤 1 有效,用户应在其兼容设备上收到通知,并且无需使用二维码。
目标是继续通过 whisper 广播签名,直到愿意部署它们的节点能够收集所有消息。
完成上述步骤后,请观察交易池中到该地址的任何交易,然后将用户带到您的应用程序。一旦您看到所需的交易,您可以停止显示二维码并继续使用该程序,同时保留一些指示交易正在进行中的指示。订阅所需合约的事件 ExecutedSigned
:一旦您看到具有 nonce 的交易,您就可以称其为成功。如果您看到具有相同或更高 nonce(或时间戳)的不同交易,则认为该交易永久失败并重新启动该过程。
实现
不存在此实现的实际示例,但许多开发人员已表示有兴趣采用它。本节将在将来进行编辑以反映这一点。
结论和未来的改进
该方案将允许更多的轻量级应用程序,这些应用程序不需要持有 ether,并且可以在设备上保持解锁的私钥,以便能够发送消息和玩游戏,而无需每次都请求用户提示。需要更多的工作来标准化常见的去中心化消息传递协议以及用于部署节点的开源工具,以便为消息部署创建一个去中心化且可靠的层。
参考文献
版权
在 CC0 下放弃版权及相关权利。
Citation
Please cite this document as:
Alex Van de Sande <avsa@ethereum.org>, "ERC-1078: 使用 ENS 子域名进行通用登录/注册 [DRAFT]," Ethereum Improvement Proposals, no. 1078, May 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1078.