跳到主要内容

机密性模型

OXN 加密你的合约做了什么,但把合约是什么、以及它在共识中如何嵌入保持公开。本页是这条边界的参考。

什么被加密

面向合约的数据——你的 Solidity 代码产生、消费或读回的东西:

  • 合约存储。 每一次 SSTORE。静态由 enclave 持有的密钥加密。节点运营方 dump 原始存储树看到的是密文。
  • 交易 calldata。 函数选择器、所有参数、任何原始字节。Wrapped 客户端对此完全透明。
  • 返回数据。 你函数产出的 abi.encode(...)。用调用者的会话密钥加密回给调用者。
  • eth_call 输入与输出。 签名查询和加密 view 调用的输入输出都是端到端加密的。
  • 事件日志内容。 topic 和 data 都加密。关于谁能解密请见下方警告
  • Revert reason。 require(cond, "msg") 和自定义 error 的错误字符串。加密回给调用者——没有调用者的会话密钥,从外部无法调试失败的交易。

什么不被加密

链自身用来路由、排序、结算交易所需的元数据:

  • 发送方与接收方地址tx.fromtx.to)。始终可见。
  • 外层交易的 msg.value 如果价值通过一次合约调用流动,value 字段是可见的,尽管移动它的合约逻辑不可见。
  • Gas 价格、gas limit、gas used。 每个区块公开。
  • 合约字节码。 每一份已部署合约的代码都是公开可查的,与以太坊一致。
  • 合约地址与创建交易。 公开。
  • 区块元数据——区块号、时间戳、区块哈希、区块内交易顺序。
  • 交易状态(成功或 revert)。Revert 原因被加密,但成功标志本身不加密。

速查表

项目是否加密谁能解密
合约存储仅 enclave
交易 calldataenclave(执行期间),之后丢弃
交易返回数据enclave + 调用者的会话密钥
eth_call 输入 / 输出enclave + 调用者的会话密钥
事件 topic + dataenclave + emit 它们的调用者
Revert reasonenclave + 调用者的会话密钥
msg.sendertx.origin所有人
msg.value、gas 相关字段所有人
区块号、时间戳、区块哈希所有人
合约地址、字节码所有人
交易哈希、from / to / 交易状态所有人

事件日志:每个索引器团队都会踩的坑

事件的 topic 和 data 是端到端加密的,使用的是产生它们的那次加密调用的同一把会话密钥。这意味着:

  • 发起调用的账户可以解密它自己的日志。 Alice 用 wrapped signer 调用 contract.transfer(bob, 100),Alice 用同一个 wrapped provider 监听时可以读到 Transfer(Alice, bob, 100) 事件。
  • 其他任何人都无法解密这些日志——不是 Bob,不是合约 owner,不是全局索引器服务,也不是从外部监听 Alice 账户的你。

如果你的架构需要第三方(索引器、监控面板、通知服务)跨用户观察合约事件,加密事件日志无法工作。可选方案:

  1. 同时 emit 一份公开事件与一份私密事件。 例如包含参与方但不包含金额。牺牲一部分机密性换回可观测性。
  2. 使用公开事件中继合约。 中继合约以机密合约的名义 emit 明文事件,规则由机密合约控制。
  3. 让调用者自己在链下中继事件。 每个调用者都持有会话密钥可以解密,然后可以发到他信任的任何聚合服务。

按你应用的威胁模型明确选择。指导见最佳实践

加密如何工作

对机制的简短描述,便于你推理失败模式。这不是正式规范。

基础。 每个 OXN enclave 有一把长期公钥(按周期轮换)。客户端按需从网络获取这把公钥。

加密调用(交易或 eth_call)。

  1. 客户端为每次调用生成一对全新的 X25519 临时密钥。
  2. 客户端通过 X25519 从 (ephemeral_secret, enclave_public) 派生对称密钥。
  3. 客户端用 Deoxys-II 对称加密算法在该密钥下加密明文 calldata,配一个随机 nonce。
  4. 客户端把 (ephemeral_public, nonce, ciphertext) 封装在 CBOR 信封里,作为 tx.data 提交。
  5. Enclave 用 (enclave_secret, ephemeral_public) 派生出同一把对称密钥,解密并执行。
  6. 返回数据用同一会话密钥加密回给客户端。

存储加密。 每个合约都有一把独有的存储密钥,通过 enclave 持有的主密钥与合约地址确定性地派生。SSTORE 透明加密、SLOAD 透明解密。Solidity 作者写普通存储代码——无需任何显式加密调用。

临时密钥一次性使用。 调用结束后,会话密钥在双方都被丢弃。即便 enclave 的长期密钥之后泄漏,也无法回溯解密旧交易的 calldata。

常见误解

"机密性是每个函数可选的。" 错。合约存储加密在 OXN 上对每一个合约都默认开启。当客户端使用 wrapped provider 时,加密 calldata 也默认开启。合约作者不需要主动 opt-in。

"msg.sender 可以被伪造。" 错。msg.sender 在共识层 / 交易签名层被校验,不在加密层。与以太坊行为完全一致。签名验证端到端保护它。

"给我的事件加密就够了保持它们私密。" 对调用者来说——是;对任何其他人——否。见上文事件日志的坑

"我可以隐藏我调用了哪个合约。" 错。tx.to 始终可见。机密性隐藏的是你请求合约做什么,而不是你调用了它这件事。

下一步