Quantova/QCore.js

GitHub: Quantova/QCore.js

QCore.js 是 Quantova 区块链的后量子客户端核心库,通过 Rust 编译的 WebAssembly 核心在浏览器和 Node 中提供密钥派生、ML-DSA-65 签名与交易构建能力。

Stars: 362 | Forks: 336

# QCore.js [![ci](https://static.pigsec.cn/wp-content/uploads/repos/cas/99/993938d8ce5e902ccfb9d6747725c320d855dea3235ed9a304cedf0d94c9321f.svg)](https://github.com/Quantova/QCore.js/actions/workflows/ci.yml) [![npm 版本](https://img.shields.io/npm/v/@quantovainc/qcore)](https://www.npmjs.com/package/@quantovainc/qcore) Quantova 的后量子客户端核心。它使用 ML-DSA-65 进行签名,构建 Q1 地址,并在浏览器和 Node 中运行相同的编译核心。 **此 npm 账户和此软件包归 Quantova Inc 所有。它是官方的 Quantova 客户端 SDK。任何在不同账户下发布的类似名称的软件包都不是此软件包,也不是来自 Quantova。** ## 安装 ``` npm install @quantovainc/qcore ``` ## 快速开始 ``` const { Client, core, generateSeed } = require('@quantovainc/qcore'); async function main() { // Create an account. The seed is the only backup and it never leaves the device. const seed = generateSeed(); const phrase = core.mnemonicFromSeed(seed); // Derive the Q1 address for account index zero, and a recipient at index one. const from = core.address(seed, 0n); const to = core.address(seed, 1n); console.log('from', from); // Open a client against a node you trust. Plaintext http is allowed only to a loopback node. const client = new Client('http://127.0.0.1:8645'); // A fixed ceiling your app is willing to pay in fees, chosen here and never read back from the gateway. const MAX_FEE_QUON = '2000'; // Amounts and the ceiling are decimal strings or BigInt values, never JavaScript numbers. const { signed, outcome } = await client.transfer(seed, 0, to, '1000', MAX_FEE_QUON); console.log('submitted', signed.tx_id, outcome.verdict); } main().catch((err) => { console.error(err.message); process.exit(1); }); ``` 此代码的可运行副本位于 [examples/quickstart.js](examples/quickstart.js)。 ## 安全姿态 每个签名均为 FIPS 204 标准化的 ML-DSA-65,地址和交易摘要使用 SHA-3 构建。此包中没有任何椭圆曲线,没有 secp256k1,也没有 ECDSA。当您通过 Client 发送时,您需要传递一个由您自己选择的最大费用,如果 gateway 报告的费用超过该值,Client 将拒绝签名,因此恶意的 gateway 无法抬高费用并耗尽余额。Client 还会拒绝不安全的传输方式。远程 gateway 必须通过 https 访问,明文 http 仅允许用于 loopback 节点,因为通过明文读回的费用和 nonce 可能会在传输过程中被篡改。此包目前处于 testnet(测试网)和审计前阶段,因此请勿将其视为已通过审计。 ## 此库的用途 任何持有 Quantova 账户、读取区块链并发送签名交易的浏览器应用、扩展程序或 Node 服务。例如钱包、dApp、区块链浏览器前端或水龙头页面。您的代码执行其偏好的网络请求,而 QCore.js 负责派生密钥、签署交易并构建请求体,因此关于加密或交易字节布局的任何逻辑都不会用 JavaScript 编写。第二种签名实现意味着又有一次可能用错用户资金的机会,因此永远只有这一种实现。 ## 它处理的后量子密码学 Quantova 从根本上就是后量子的。它内部没有任何椭圆曲线,没有 secp256k1,没有 ECDSA,没有 Ethereum 地址,也没有 Substrate 信封。下面的每个原语都是 Quantova 在 Q Crypto 库中从零开始的独立实现,不携带任何第三方密码学依赖,并被编译到随此包发布的核心模块中。 1. 密钥派生。您的应用持有一个 32 字节的主种子。QCore.js 通过 SHAKE256 对主种子、方案字节和账户索引进行计算,从中生长出每个账户的种子,然后从该种子派生出模块格密钥对。节点运行相同的派生过程,因此密钥签发使用的账户就是持有资金的账户。 2. 签名方案。默认方案是 FIPS 204 标准化的模块格签名 ML-DSA-65,在线路上作为方案一传输。FIPS 205 标准化的基于哈希的签名 SLH-DSA 是方案二。签名是确定性的,因此一个交易体总是被签发为完全一致的一串字节,这使得签名交易可以在浏览器中重现和测试。 3. 地址。Quantova 地址是 Bech32m Q1 字符串,它渲染了方案字节连同 1952 字节的完整模块格公钥的 SHA3 256 哈希。整个公钥都绑定到地址中。没有任何内容被截断为 20 字节的哈希,并且无法从签名中恢复密钥,因此一个地址精确地命名一个后量子密钥。 4. 交易。交易体携带发送方、nonce、计量限制、费用和调用。签名所涵盖的字节是规范交易体的 SHA3 256 哈希,后跟固定的 Quantova 交易 domain tag,因此交易签名永远不会被重放为另一种类型的签名消息。QCore.js 组装交易体,在编译核心内部对摘要进行签名,并返回准备好供 gateway 使用的包装字节和交易 ID。 5. 可支付调用。`core.signPayableCall` 携带原生价值和显式的 chain id,以及发送方、nonce、计量限制、费用和调用,因此对合约的调用可以在与转账相同的签名交易体中转移价值,并且相同的签名可以固定到一个网络上。发送方和目标永远不会以渲染的 Q1 字符串形式进入该签名,因为显示约定可能会随时间改变。每一项都会首先被解析回其原始的 32 字节 payload,而该 payload(绝不是字符串)才是 preimage 所携带的内容,因此签名始终绑定到账户,而不是绑定到地址碰巧被打印出来的方式。 ## 它如何为 Quantova 定制且不继承行业中的任何内容 Quantova 不与任何其他区块链共享网络协议、地址或单位,QCore.js 只使用 Quantova 的规范。地址是基于完整后量子密钥的 Q1 Bech32m 字符串,绝不是十六进制的 20 字节地址,也绝不是 SS58 字符串。资金以 Quon(最小单位)计算,100 万 Quon 等于 1 QTOV,并且它总是以十进制字符串的形式通过网络传输。您以十进制字符串或 BigInt 的形式传递金额,而不是 JavaScript number,因为 number 在超过 2^53 时会静默舍入并签署错误的金额。网络层是 Quantova gateway,即对版本前缀下的命名方法进行的 HTTP POST 请求,带有扁平的 JSON body,而不是 Ethereum JSON RPC,也不是 Substrate WebSocket。交易编码是 Quantova 自己的规范编解码器,而不是 RLP,也不是 SCALE。签名来自 Q Crypto,这是 Quantova 从零开始编写的格和哈希标准的独立实现,而不是借用库。这里没有 ethers,没有 web3,也没有 polkadot。 ## 创建钱包 ``` const { generateSeed, core } = require('@quantovainc/qcore'); const seed = generateSeed(); // thirty two random bytes as hex from the platform source const phrase = core.mnemonicFromSeed(seed); // the only backup, shown once and kept on the device ``` ## 使用方法 Client 签名调用(transfer、register、call 或 callSignedOrder)的最后一个参数是费用 上限,即您愿意为一笔交易支付的最高费用。您可以自行选择,作为您的应用 自行决定的固定数值,并在您签名之前确定。Client 会读取 gateway 报告的费用, 将其与您的上限进行比较,并在报告的费用高于上限时拒绝签名,因此 独立选择的上限是介于恶意 gateway 和您的余额之间的唯一限制。只有 当您自己选择该数值时,它才能保护您。如果您读取了 gateway 自己报告的费用并将其 作为上限传回,那么您就已经将上限设置为了 gateway 所要求的数值,您将根本没有任何 保护。请以十进制字符串或 BigInt 的形式传递上限,而不是 JavaScript number, 原因与金额相同,因为 number 在超过 2^53 时会静默舍入,并可能将上限设置得 高于您的预期。 此比较存在于 Client 中,且仅存在于 Client 中。原始的 core.* 签名函数,例如 core.sign_transfer,将网络上传输的实际费用作为其最后一个参数,而不是上限,并且 根本不做 gateway 比较。直接调用 core.* 的开发者没有费用上限,因此每当您无法控制的 gateway 报告费用时,请使用 Client。 ``` const { Client } = require('@quantovainc/qcore'); const client = new Client('http://127.0.0.1:8645'); const seed = '0b'.repeat(32); const to = client.address(seed, 1); // A fixed ceiling your app is willing to pay, chosen here and never read back from the gateway. const MAX_FEE_QUON = '2000'; // The amount is a decimal string or a BigInt, never a JavaScript number. const { signed, outcome } = await client.transfer(seed, 0, to, '1000', MAX_FEE_QUON); const status = await client.transaction(signed.tx_id); ``` Client 坚持使用安全的传输方式。远程 gateway 必须通过 https 访问,明文 http 仅允许用于如 `127.0.0.1`、`localhost` 或 `[::1]` 的 loopback 节点。在构建 Client 时,指向 任何其他主机的明文 http 基地址都会被拒绝,因为通过明文读回的 费用和 nonce 是未经身份验证的,并且可以在传输过程中被重写,从而可能被用于耗尽资金。 通过转账(例如水龙头申领)注资的账户到达时带有余额,但区块链上没有密钥, 因此它会在首次发送前注册一次其密钥。之后它就可以如上所述进行发送。 ``` // Once, after the account is funded and before its first send. await client.register(seed, 0, MAX_FEE_QUON); ``` 同时也转移价值的调用(例如可支付合约调用)会直接使用 `core.signPayableCall`。 它将价值和 chain id 作为显式参数,价值作为十进制字符串或 BigInt(原因与金额相同),而 chain id 来自 `core.localChainId()`、 `core.mainnetChainId()` 或 `core.testnetChainId()`,因此网络绝不是一个 magic number。 ``` const { core } = require('@quantovainc/qcore'); const signed = JSON.parse( core.signPayableCall(seed, 0n, contract, argsHex, nonce, meterLimit, fee, '1000', core.testnetChainId()), ); ``` ## 编译核心 此包中的编译核心仅仅是单一 Rust 核心的发布形式,其构建目的是让相同的密钥派生、签名和网络协议代码能在浏览器和 Node 中运行。它不是虚拟机,也不是区块链运行的组件。Quantova 区块链仅执行 QVM,即运行合约的 container 机器。这里的编译核心只是一个客户端构建产物,仅此而已。 ## TypeScript 此包在 `index.d.ts` 中提供了 TypeScript 类型,因此 Client、核心函数和 Network 助手都带有类型定义,无需额外安装。 ## 构建 此包提供了一个受保护的接口,即带有费用上限和金额保护的 Client,其背后是 单一核心的两种构建版本,并且每个默认入口都会将相同的 Client 交给您。Node 解析到 node 入口,该入口从 `pkg-node` 加载 nodejs 构建,从磁盘读取它,不需要 实验性标志,适用于所有受支持的 Node(无论是 require 还是 import),并且是测试 运行的构建版本。浏览器或 bundler(如 webpack 或 Vite)通过 exports 映射解析到 浏览器入口,该入口将 `pkg` 中的 bundler 构建包装在相同的 Client 中,因此浏览器钱包可获得 费用上限和金额保护,而绝不会接触到裸签名函数。 原始构建版本仍然可以通过各自的子路径访问:`@quantovainc/qcore/pkg` 用于 bundler 构建, `@quantovainc/qcore/pkg-node` 用于 nodejs 构建。这些路径仅导出 core.* 函数,没有 Client,没有费用上限,也没有金额保护,适用于独立组装费用比较的 高级调用者。默认的浏览器、import、node 和 require 解析永远不会触及它们。 要从源代码构建两者,请运行这两个已记录的构建命令或 `npm run build`。 ``` wasm-pack build --target bundler --out-dir pkg wasm-pack build --target nodejs --out-dir pkg-node ``` 离线测试脚本通过 `npm test` 运行,它们不需要网络,也不需要运行中的 gateway。 ## 一致性向量 固定的一致性向量位于此存储库的 [conformance](conformance) 文件夹中。地址派生位于 `conformance/address.derivation.json`,转账位于 `conformance/transaction.transfer.json`,可支付调用位于 `conformance/transaction.payable.json`。离线测试 `test-conformance.js` 从这些向量进行签名,并逐字节检查绑定是否匹配,因此任何会改变签名交易的变更都会导致测试失败。 ## 示例 [examples](examples) 文件夹包含一个可运行的快速开始示例,与上面的示例相对应。如需更完整的入门指南,请查看 Quantova 组织下的 Q-Scaffold 和 Q-Forge 存储库,网址为 https://github.com/Quantova/Q-Scaffold 和 https://github.com/Quantova/Q-Forge。 ## 发布与来源证明 发布是通过 `.github/workflows/publish.yml` 中的发布工作流由 CI 完成的,该工作流在推送的 git tag 上运行。它构建两个 wasm 目标,运行离线测试,并使用 npm 来源证明进行发布,因此注册表上的软件包副本带有经过验证的来源徽章,将其与此确切的公共提交绑定。如果没有显式的 tag,任何内容都不会发布到注册表。此包处理用户的密钥,已发布的版本无法撤回。 为了让来源证明发布得以运行,维护者需将 `NPM_TOKEN` 自动化密钥添加到存储库中,或者为软件包配置 npm trusted publishing,以便工作流通过 OIDC 进行身份验证而无需存储 token。 ## 安全 要报告漏洞,请参阅 [SECURITY.md](SECURITY.md)。请私下报告,不要通过公开的 issue 报告。 ## 所有权与许可 QCore.js 由 Quantova Inc 构建并拥有,其签名存在于一个编译核心中,且从未用 JavaScript 重写。它不携带任何行业技术栈,也不继承其中的任何内容。它采用 Apache 2.0 和 MIT 双重许可,因此任何钱包、浏览器或服务都可以基于它构建,版权归 Quantova Inc 所有。
标签:AI工具, CVE, JavaScript SDK, MITM代理, Rust, WebAssembly, 加密货币, 区块链, 可视化界面, 后量子密码学, 数字签名, 数据可视化, 暗色界面, 网络流量审计, 自定义脚本