Skip to content

部署合约 ​

部署是一笔发往 neuro:system.deploy 的普通签名交易。每个验证者都会在共识中用 VMGuardian 审计字节码;未通过审计的合约在任何地方都不会被创建。

部署流程:构建 wasm32 合约,可选地先做分析,发送部署交易;每个验证者运行 VMGuardian 关卡;风险分数达到或超过阈值时交易失败且不收费,否则创建合约,运行其 init 导出,再以 init_args 调用 initialize

1. 构建 ​

合约是以 cdylib 形式编译到 wasm32-unknown-unknown 的 no_std Rust 代码,从 env 模块导入宿主函数——用 #[link(wasm_import_module = "env")] 声明它们,才能与当前版本的 Rust 正确链接。接口说明和完整示例见 NeuroWASM。

toml
[lib]
crate-type = ["cdylib"]

[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
bash
cargo build --release --target wasm32-unknown-unknown
od -An -tx1 -v target/wasm32-unknown-unknown/release/my_contract.wasm | tr -d ' \n' > my_contract.hex

十六进制必须以 0061736d(WASM 魔数)开头。字节码最大 512 KiB(MAX_BYTECODE_SIZE)。

仓库中可用的示例:neurochain/contracts/nrc20(同质化代币)、ncert(安全证书,NRC-721 风格)、dao 和 gov_dao。

2. 发送前检查 可选 ​

端点返回内容
POST /api/v1/contracts/analyze { "bytecode_hex": "…" }risk_score、security_score、ml_score、model、violations——与关卡运行的分析相同
POST /api/v1/contracts/attest { "bytecode_hex": "…" }同样的结果,由节点用 ML-DSA-65 签名,可在浏览器中验证

Web 应用的部署页面会先在浏览器中运行分析,然后向节点请求签名的证明。

3. 发送部署 ​

使用 SDK(推荐):

js
await nc.deployContract({
  wallet,
  bytecodeHex,
  name: 'MyToken',            // 唯一的合约名称,可选
  description: '…',
  template: 'nrc20',          // 已注册模板的 id,可选
  initArgs: { … },            // 传给 initialize,可选;decimals 用数字
  gasPrice,
})

手动发送——POST /api/v1/transactions,其中 to: "neuro:system.deploy"、value: 0,data 设为如下 JSON 字符串:

json
{ "bytecode_hex": "0061736d…", "name": "MyToken", "description": "", "template": "", "init_args": { } }

签名方式与任何交易相同(nc-tx-v2|from|neuro:system.deploy|0|nonce)。

节点还提供 POST /api/v1/contracts/deploy(owner、bytecode_hex 或 base64_wasm,外加针对 neuro:system.deploy 的签名操作);它会替你构造同样的交易。

4. 每个验证者做什么 ​

  1. 关卡。 解码字节码并查找其 SHA3-256 哈希:
    • 在白名单中(如 NRC-20 等官方模板)→ 安全分数 100,不做分析;
    • 关卡已被治理关闭(deploy_security_enabled = 0)→ 中性分数 70;
    • 否则运行 VMGuardian analyze_v2。如果 risk_score ≥ deploy_risk_threshold(默认 0.80),交易失败且不收取手续费,拒绝记录连同违反的规则一起写入日志,并由 nc_deploy_rejected_total 指标计数。
  2. 扣费 10 000 gas 单位 × gas_price。
  3. 创建合约,地址为 neuro:<10 hex>.app——即 SHA3-256(owner ‖ nonce) 的前 5 个字节。如果合约名称已被其他合约占用,部署失败。
  4. 构造函数。 如果模块导出 init,它会在部署的存储上运行一次。
  5. 初始化。 如果存在 init_args,会以 {"function": "initialize", …init_args} 调用合约——参数平铺在 JSON 顶层——调用者是你。
  6. 模板费用。 如果 template 指向一个带费用的已注册模板,该费用从你转给模板作者。

最终的安全分数为 100 − risk_score × 100,与合约一起存储。

费用 ​

项目费用
部署10 000 gas 单位 × gas_price(按 1 uNRO 计:0.01 NRO)
被关卡拒绝不收费
模板模板自身的费用(如有)

部署后:持续监控 ​

每个节点每 20 秒(MONITOR_INTERVAL_SECS)重新审计已部署的合约。当合约分数变化达到 10 分或以上(MONITOR_SCORE_THRESHOLD)——例如模型更新之后——会通过共识发出一笔证书更新交易。证书可通过 GET /api/v1/certificates/contract/:address 读取。参见 VMGuardian。

故障排查 ​

错误原因
Deploy rejected by VMGuardian: risk_score … >= threshold …审计发现了有风险的模式;analyze 会列出它们。
gas_price … below block base_fee …把 gasPrice 提高到当前基础费用之上。
Contract name '…' is already taken换一个 name,或留空。
大小错误字节码超过 512 KiB——用 opt-level = "z" 和 LTO 构建。