本文介绍了以太坊证明服务(EAS)的功能,探讨了如何创建和验证称为“证明”的索赔,提供了对EAS的核心组件,离线和私有功能的详尽解释,并包括使用SDK创建模式和证明的实际代码示例。通过深入技术细节和结构化的指南,读者能够掌握EAS的使用方法和潜在应用。
想象一个数字世界,在这个世界里,每一条信息、每一个主张以及每一个凭证都可以被验证,无论是在区块链上还是在区块链之外。这就是以太坊证明服务 (Ethereum Attestation Service, EAS) 的力量所在。
在本指南中,我们将探讨 EAS 的功能,包括如何创建称为声明——在 EAS 中称为“证明”——以及对它进行数字签名和验证的步骤。在 EAS 中,证明是一个实体对自己或其他实体所作的声明,涵盖广泛的可验证数据,例如身份、所有权、凭证和权利。
让我们开始吧!
什么是以太坊证明服务 (EAS) 在 YouTube 上观看
依赖 | 版本 |
---|---|
node.js | 18.13.0 |
@ethereum-attestation-service/eas-sdk | 1.3.7 |
建立一个可验证的数字身份是一项复杂的挑战。多个应用已尝试解决这个问题,但它们面临的一个共同问题是缺乏互操作性。EAS 通过提供一个通用框架来处理这个问题,以创建和管理数字证明。
以太坊证明服务 (EAS) 是一个开源公共基础设施,用于在链上或链下进行证明。在 EAS 的上下文中,证明是任何实体关于任何事情的数字签名声明。它是一些结构化数据的数字签名,可以简单地看作是某个实体(例如,另一位个人或 KYC 公司)证明你所说的身份,或者需要信任和验证的其他情况。
接下来,让我们深入了解一下这个协议的设计和功能。
EAS 主要通过两个智能合约和一个可选的解析合约进行操作:
模式创建合约:这个智能合约允许为任何主题和数据类型创建独特的模式。模式定义可以得到证明的数据的结构和类型,更技术上说,要注册一个模式(该模式独特且未在该链上创建),你需要与 register
函数交互。如果你想指向解析合约(我们会很快覆盖),则需要在注册模式时设置它,此时它将具有与未使用解析合约初始化的模式不同的唯一标识符(UID)。
证明创建合约:使用定义的模式,这个智能合约便于创建证明(通过 attest
函数)。这就是实际数据根据指定模式进行证明的地方。此函数接受提供证明者的接收地址、过期时间、可以撤销证明的布尔标志,并可选择通过其唯一标识符(UID)引用另一项证明。
(可选) 解析合约:这是一个可以选择引用的智能合约,可用于执行附加逻辑,例如促进支付或触发其他智能合约功能,如铸造 NFT,或触发 DAO 进行治理相关的操作。请查看 EAS 的 resolver repository 中的构建解析器的模板。
对于链下证明,实际证明不会存储在链上,并且为了确保隐私,它仅编码在创建证明时使用的 URL 的 URI 片段中。唯一标识符 (UID) 是证明的一部分,是该证明本身的哈希。由于证明是链下的,因此没有真相来源(因为它不在区块链账本上)。然而,你仍然可以在链上存储证明的 UID(有效地时间戳),允许其他人查看什么和何时被证明。
为了使你的证明更加私密,你可以创建私有数据证明。这些是通过 Merkle 树创建的 32 字节哈希对链上证明进行编码。它通过允许你定义一个模式、创建证明并仅在链上发布 Merkle 根哈希来实现。Merkle 根哈希由创建模式时所用数据字段的哈希组成,可与基础真实数据进行验证。这在你不想公开例如你的政府身份证、银行账户信息或其他私密数据的情况下非常有用。
EAS 还利用 EIP-712 进行签名,确保证明安全且可验证。这可以被如 MetaMask、Coinbase Wallet、Safe 和其他智能合约使用。
EAS 建立了一个浏览器(类似 Etherscan),称为 EASSCAN。该浏览器当前在多个测试网络和主网络区块链上运行,包括 Sepolia、Optimism、Base 和 Polygon。它使用户能够探索、创建和验证模式和证明。
要与 EAS 协议进行交互,你需要能够与以太坊区块链通信。你可以使用公共节点或部署和管理自己的基础设施;但是,如果你想提高 8 倍的响应时间,可以把繁重的工作留给我们。请在这里注册一个免费账户。
为了在本指南中演示和测试 EAS 的功能,我们将在以太坊的测试网络 Sepolia 上进行交易。
登录 QuickNode 后,单击 创建一个端点 按钮,然后选择 以太坊 链和 Sepolia 网络。
创建端点后,复制 HTTP 提供程序链接,并将其保留,后续部分会用到它。
要在以太坊 Sepolia 上进行交易,我们需要一些测试函数来支付Gas费。如果你需要一些,可以使用 多链 QuickNode 水龙头 来轻松获得测试 ETH!
请导航到多链 QuickNode 水龙头,连接你的钱包(例如 MetaMask、Coinbase 钱包)或粘贴你的钱包地址以获取测试 ETH。请注意,在以太坊主网使用 EVM 水龙头时,需要 0.001 ETH 的主网余额。你还可以通过推特或者登录你的 QuickNode 账户获得奖励!
有多种方法可以将 EAS 配置到你的项目中。你可以通过 UI(可以在 这里 找到)创建并管理证明,或使用 EAS SDK。在本指南中,我们将使用 SDK 选项。
首先,让我们初始化一个 CommonJS 项目:
mkdir eas-project && cd eas-project && npm init es6
接下来,你可以通过 npm 安装 SDK:
npm install @ethereum-attestation-service/eas-sdk dotenv
请注意,你也可以通过 Yarn 安装,但最初的项目设置会有所不同。
最后,我们将创建一个 index.js 和 .env 文件,这些文件稍后将需要使用:
echo > index.js && echo > .env
现在,打开 .env 文件,并输入以下变量名称以及它们在字符串中的相应值(即 " http://quicknode-endpoint):
QUICKNODE_ENDPOINT=
WALLET_PRIVATE_KEY=
记得保存文件。在接下来的部分中,让我们设置一个脚本以获取现有证明(作为热身)。然后,我们将创建一个独特的模式并对其进行证明。
在深入创建新证明之前,让我们先获取一个现有的证明。这将帮助我们理解 EAS 中证明的结构和性质。将以下代码添加到你的 index.js 文件中:
import { EAS } from "@ethereum-attestation-service/eas-sdk";
import { ethers } from "ethers"; // 与 EAS 一起安装
import 'dotenv/config'
async function fetchAttestation() {
// 使用常量进行配置
const EAS_CONTRACT_ADDRESS = "0xC2679fBD37d54388Ce493F1DB75320D236e1815e"; // Sepolia v0.26 地址
// 初始化 EAS 和提供者
const eas = new EAS(EAS_CONTRACT_ADDRESS);
const provider = new ethers.JsonRpcProvider(process.env.QUICKNODE_ENDPOINT);
eas.connect(provider);
// 如果不动态定义 UID,则将其定义为常量
const UID = "0x62aa93fbae908100345fe96150c6f57ea70946bd8dec4df99bcdb7186f233e39";
try {
const attestation = await eas.getAttestation(UID); // 此函数返回一个证明对象
console.log(attestation);
} catch (error) {
console.error("获取证明时出错:", error);
}
}
fetchAttestation();
你可以选择更改 UID 变量中的值,以获取有关其他证明的详细信息。你可以在 EASSCAN 上探索并查找其他 UID。
然后,在终端窗口中运行以下命令来执行脚本:
node index.js
你将看到类似于以下输出的信息。它包含有关特定链上证明的信息。
Result(10) [\
'0x62aa93fbae908100345fe96150c6f57ea70946bd8dec4df99bcdb7186f233e39', // UID\
'0xf164b8a3b56bcc6f0e61f395507fd20e772efe9a5f09bd789ec9585ac1acdd74', // 模式标识符\
1701894216n, // 证明创建时的 Unix 时间戳\
0n, // 证明过期的 Unix 时间戳(0 表示没有过期)\
0n, // 如果适用则证明被撤销的 Unix 时间戳\
'0x0000000000000000000000000000000000000000000000000000000000000000', // 如果有,证明的参考 UID\
'0xBe09cDb573E1553672eEC44540754b6F4d5B5112', // 证明接收者的以太坊地址\
'0xBe09cDb573E1553672eEC44540754b6F4d5B5112', // 创建证明的证明者的以太坊地址\
true, // 一个布尔值,指示该证明是否可撤销\
'0x00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000be09cdb573e1553672eec44540754b6f4d5b51120000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000423078356665396535613964613539336630633234636266663030383461396530303262643638636264303233373665643461643039383434643265643238663061310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007726576616e74680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076f7074696f6e31 // 数据\
]
现在,让我们创建自己的模式。正如我们所讨论的,模式可以是任何事物,从简单的声明(例如姓名)到更复杂的数据结构。
所有的模式都是公开的,供任何人使用,任何注册的模式都可以被任何人使用。
提示
需要注意的重要一点是,如果链上存在具有相同数据结构的现有模式,你将无法创建新的模式。如果该模式是使用解析合约调用的,则与未用解析合约初始化的模式的 UID 会有所不同。
在本指南中,我们将展示如何使用 SDK 创建模式。我们的模式将用于内容真实性,定义如下。
bytes32 contentHash,
string urlOfContent
注意:为了使模式不同(以便你实际上可以部署并注册它),请将以上字段调整为更加独特(例如,添加一个数字,和/或不同的文本和大小写)。
上述模式包含一个 contentHash
字段,它表示被证明内容的哈希,和一个 urlOfContent
字段,说明内容所在的 URL。该模式是一个简单模式,可用于证明和验证数字内容的真实性(例如,技术文档、视频等)。
现在,让我们将以下代码更新到 index.js 文件中:
import { SchemaRegistry} from "@ethereum-attestation-service/eas-sdk";
import { ethers } from 'ethers';
import 'dotenv/config'
// 配置常量
const schemaRegistryContractAddress = "0x0a7E2Ff54e76B8E6659aedc9103FB21c038050D0"; // Sepolia 0.26
const schemaRegistry = new SchemaRegistry(schemaRegistryContractAddress);
async function registerSchema() {
try {
// 初始化提供者和签名者
const provider = new ethers.JsonRpcProvider(process.env.QUICKNODE_ENDPOINT);
const signer = new ethers.Wallet(process.env.WALLET_PRIVATE_KEY, provider);
schemaRegistry.connect(signer);
// 使用模式字符串初始化 SchemaEncoder
const schema = "YOUR_SCHEMA"; // 例如,bytes32 contentHash, string urlOfContent
const revocable = true; // 允许撤销证明的标志
const transaction = await schemaRegistry.register({
schema,
revocable,
// 你可以在此处添加解析器字段以实现附加功能
});
// 可选:等待交易验证
await transaction.wait();
console.log("新模式已创建", transaction);
} catch (error) {
console.error("发生错误:", error);
}
}
registerSchema();
你需要将代码中的 YOUR_SCHEMA 占位符替换为你的模式结构。该模式需要是唯一的,示例已在代码注释中提供。
定义模式并保存文件后,再次通过在终端中调用 node index.js 来执行脚本。成功输出后,你可以在 Etherscan 上搜索该哈希。
在 Etherscan 的日志选项卡上,注意 Registered
事件被触发,包含 UID
的 bytes32 哈希的十六进制值和第一条日志主题中的 registerer
地址。你可以在 EASSCAN 中搜索该 UID,查看其是否存在,然后用新创建的模式创建证明。
现在,通过根据你定义的模式输入值,对你创建的模式进行证明。如果你没有创建自己的模式并使用了我们提供的示例模式,则可以使用在线工具(搜索 Google)将字符串转换为 bytes32 值。
在你的 index.js 中更新代码,以包含以下内容:
import { EAS, SchemaEncoder } from "@ethereum-attestation-service/eas-sdk";
import { ethers } from 'ethers';
import 'dotenv/config'
// 配置常量
const EAS_CONTRACT_ADDRESS = "0xC2679fBD37d54388Ce493F1DB75320D236e1815e"; // Sepolia v0.26 地址
async function attest() {
try {
// 初始化提供者和签名者
const provider = new ethers.JsonRpcProvider(process.env.QUICKNODE_ENDPOINT);
const signer = new ethers.Wallet(process.env.WALLET_PRIVATE_KEY, provider);
const eas = new EAS(EAS_CONTRACT_ADDRESS);
eas.connect(signer);
// 使用模式字符串初始化 SchemaEncoder
const schemaEncoder = new SchemaEncoder("YOUR_DEFINED_SCHEMA"); // 例如,bytes32 contentHash, string urlOfContent
const encodedData = schemaEncoder.encodeData([\
{ name: "", value: "", type: "" },\
{ name: "", value: "", type: "" },\
/*\
在我们提供的示例模式中,它看起来会是这样的:\
{ name: "contentHash", value: "0x2d2d2d0a617574686f723a20466572686174204b6f6368616e0a...", type: "bytes32" },\
{ name: "urlOfContent", value: "quicknode.com/guides/ethereum-development/smart-contracts/what-is-ethereum-attestation-service-and-how-to-use-it", type: "string" },\
*/\
]);
const schemaUID = "SCHEMA_ID"; // 模式的 UID。内容模式为:0x43183473396f22ec78464231c356f1763e89e0f5393261dd142ef8bc79a147be
// 发送交易
const tx = await eas.attest({
schema: schemaUID,
data: {
recipient: "YOUR_RECIPIENT_ADDRESS", // 证明接收者的以太坊地址
expirationTime: 0,
revocable: true, // 请注意,如果你的模式不可撤销,则此项必须为 false
data: encodedData,
},
});
const newAttestationUID = await tx.wait();
console.log("新证明 UID:", newAttestationUID);
} catch (error) {
console.error("发生错误:", error);
}
}
attest();
你需要用你唯一定义的结构或我们提供的示例模式填充 schemaEncoder 变量。
此外,还需要填充 encodedData 变量以包含证明的输入数据(我们提供了示例,假设你使用的是我们提供的内容模式)。schemaUID 变量也需要根据你的模式 ID 或已注册的模式更新(请参见代码注释)。
还请将 YOUR_RECIPIENT_ADDRESS 占位符替换为你希望进行证明的以太坊地址。这可以是你自己的地址以便测试,但在理想情况下,它可能是验证实体的地址。
一旦你再次执行该文件并确认交易,你可以在 EAS 浏览器上搜索终端输出的交易哈希。你将看到你的证明信息,类似于以下内容:
就是这样!你现在可以根据本指南中介绍的“获取现有证明”部分的代码示例,再次获取证明。
尝试做简短的测验来测试你的知识!
🧠知识检查
EAS 中的链下证明如何编码?
通过使用先进的加密技术加密整个证明数据 通过将实际证明数据存储在一个私有区块链上 通过对创建证明时使用的 URL 的 URI 片段进行编码 通过使用一个单独的、专用的链下数据库来存储证明
要了解更多关于 EAS 的信息,请查看以下资源:
在本指南中,我们了解了 EAS,并展示了如何以编程方式创建模式、对内容进行证明,并随后验证证明。
请订阅我们的 新闻通讯,获取有关 Web3 和区块链的更多文章和指南。如果你有任何问题或需要进一步的帮助,请随时加入我们的 Discord 服务器,或使用以下表单提供反馈。通过在 Twitter (@QuickNode) 和 Telegram 公告频道 上关注我们,保持信息畅通并保持联系。
让我们知道 如果你有任何反馈或对新主题的请求。我们很乐意听到你的声音。
- 原文链接: quicknode.com/guides/eth...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!