Preview copy · BSC testnet, not mainnet. Read-only calls: no wallet, nothing to sign.预览副本 · BSC 测试网,不是主网。只读调用:不需要钱包,没有签名。
BNNX · live on BSC testnetBNNX · 已上线 BSC 测试网
Run neural networks inside smart contracts让神经网络直接跑在智能合约里
BNNX compiles trained models into contracts on BNB Chain. Call one for free, and check every answer against a reference program, integer for integer.BNNX 把训练好的模型编译成 BNB Chain 上的合约。免费调用,并和参考程序逐个整数核对每一个答案。
measured, last check 2026-10-22实测,最近一次检查 2026-10-22
differences from the reference program, over 1,350 inputs on two nodes处与参考程序的差异,共 1,350 个输入,两个节点
0
measured实测
shared operator contracts that every graph model calls个共用算子合约,所有图模型都调用它们
15
pure, deployed once纯函数,只部署一次
automated tests behind the library个自动化测试,支撑着这套库
3,300+
measured 2026-10-23实测,2026-10-23
1 · the idea1 · 理念与设计
A model you can audit, because it is only integers只由整数组成,所以能被审计的模型
Most AI runs on a server you have to trust. A contract cannot work that way: it has no floating point and no network, and everything it computes must come out the same on every node. BNNX takes that as its design rule. A network is trained in PyTorch, then turned into integers: weights of +1 or −1, thresholds, small integer levels. Those integers are the model, and a reference program and a contract compute exactly the same ones.大多数 AI 跑在你只能选择相信的服务器上。合约做不到这样:它没有浮点数,也没有网络,算出的每一个结果在每个节点上都必须相同。BNNX 把这当成设计规则:网络在 PyTorch 里训练,然后变成整数:+1 或 −1 的权重、阈值、几位的整数电平。这些整数就是模型本身,参考程序和合约算出的是完全相同的整数。
1 · integers all the way down1 · 全程都是整数
One binarised neuron. Flip any input or weight: the sum of the products is an exact integer, and the output is +1 when it reaches zero. A whole layer is many of these, so the contract needs only adds and compares.一个二值化的神经元。翻转任意输入或权重:乘积之和是精确的整数,和大于等于 0 时输出 +1。一整层就是很多个这样的神经元,所以合约只需要加法和比较。
2 · the same answer everywhere2 · 到处都是同一个答案
The trained network becomes one fixed integer form, the IR. A reference program runs it on a laptop; the contract runs it on chain. Both return the same label and the same score for every class, and any node can be asked.训练好的网络变成一种固定的整数形式,叫 IR。参考程序在笔记本上运行它,合约在链上运行它。两边对每个类别返回同样的标签和同样的得分,谁都可以去问任意一个节点。
3 · free to read, easy to compose3 · 读取免费,容易组合
Anyone can call a model with a read-only eth_call: no wallet, no fee. Another contract can call it too, inside a transaction, and act on the answer. That is how the gomoku game on this page works: the game contract asks the network for each move in the player's own transaction.任何人都可以用只读的 eth_call 调用模型:不需要钱包,也不收费。别的合约也可以在交易里调用它,并按答案行动。这页上的五子棋就是这样做的:对弈合约在玩家自己的交易里向网络要每一步棋。
Cheap arithmetic. A ±1 multiply-add costs about 0.65 gas and an int8 one about 6.1 (measured, unoptimised), so small networks fit in one call.便宜的算术。一次 ±1 乘加约 0.65 gas,int8 约 6.1 gas(实测,未优化),所以小网络放得进一次调用。
Weights are contract code. They live in immutable data contracts of at most 24,000 bytes and are read with EXTCODECOPY: no storage, no owner.权重就是合约代码。它们放在不可变的数据合约里,每个最多 24,000 字节,用 EXTCODECOPY 读取:没有存储,没有管理员。
Pure by construction. The runner reads no state and no block data, so its output depends on the input only.从构造上就是纯函数。运行器不读任何状态和区块数据,所以输出只取决于输入。
Every claim can be checked. The IR hash names the model, and bnnx verify compares the contract's code and data with it.每个说法都能核对。IR 哈希给模型命名,bnnx verify 把合约的代码和数据与它逐项比对。
DigitReader.sol
// ask a model from any contract
interface IBnnxModel {
function classify(bytes calldata pixels)
external view
returns (uint256 label, int256[] memory scores);
function modelInfo()
external view
returns (bytes32 name, bytes32 irHash,
uint256 inputLength, uint256 numClasses);
}
contract DigitReader {
IBnnxModel public immutable model;
constructor(address runner) {
model = IBnnxModel(runner);
}
function read(bytes calldata pixels)
external view returns (uint256 label)
{
(label, ) = model.classify(pixels);
}
}
Where BNNX fits in TapeOutBNNX 在 TapeOut 里的位置
TapeOut already puts a site's front end on chain (DeWeb) and its state in a container. What a site cannot yet do is call logic that is just as verifiable. BNNX is the project that supplies that missing layer: a trained model becomes a pure contract that a page, a circuit's owner or another contract can call, and anyone can check.TapeOut 已经把网站的前端放上了链(DeWeb),把状态放进了容器。网站目前还做不到的,是调用同样可验证的逻辑。BNNX 就是补上这一层的项目:训练好的模型变成一个纯函数合约,页面、电路持有人或别的合约都能调用,任何人都能核对。
true today今天已经成立
This page is a DeWeb site. It is built to TapeKit's rules (relative paths, 24,000-byte chunks, nothing loaded from outside) and is meant to be published into a TapeOut container on X Layer. You are looking at a preview copy on an ordinary server.这个页面就是一个 DeWeb 站。按 TapeKit 的规则做(相对路径、24,000 字节分块、不加载任何外部资源),准备发布到 X Layer 上的 TapeOut 容器里。你现在看的是放在普通服务器上的预览副本。
The model contracts follow the pure-function rules that a component slot needs: no storage, no external calls, output depends on the input only.模型合约遵守元件插槽需要的纯函数规则:不读存储、不调外部合约,输出只取决于输入。
A command-line publisher for DeWeb sites was built for this page. TapeKit's README lists a publishing CLI as still to be done.为这个页面做了一个 DeWeb 站点的命令行发布工具。TapeKit 的 README 里把发布命令行列为尚未完成的事。
next, not decided下一步,尚未定
Put a model into a V2 component slot, once its interface is available.等 V2 元件插槽的接口拿到之后,把模型放进插槽。
Deploy the models on mainnet, and publish this page there too.把模型部署到主网,并在主网上也发布这个页面。
Whatever else TapeOut wants from an on-chain model; this list is a proposal, not a plan.TapeOut 还希望链上模型做什么,就做什么;这份清单是提议,不是计划。
not yet目前还没有
The models are standalone contracts on BSC testnet. They are not TapeOut circuits or processors, and no TapeOut product calls them yet.模型是 BSC 测试网上独立的合约,不是 TapeOut 的电路或处理器,也还没有任何 TapeOut 产品在调用它们。
Nothing is deployed on mainnet, and no token is involved.主网上没有部署任何东西,也不涉及任何代币。
2 · where it stands2 · 项目进展
From a first digit model to a whole toolchain从第一个数字模型到一整套工具链
Everything below was built and checked on BSC testnet between 2026-09-28 and 2026-10-22. Each line points at the report it comes from.下面的一切都在 2026-09-28 到 2026-10-22 之间做完,并在 BSC 测试网上检查过。每一条都指向它所依据的报告。
The first two models on chain前两个模型上链
Binarised networks for digits (97.86%) and small photos (81.42%). The chain returns exactly the integers the reference runtime computes.二值化网络,识别手写数字(97.86%)和小图(81.42%)。链上返回的整数和参考运行时算出的完全一样。
The developer toolkit开发者工具包
A Python package and the bnnx command, training layers, a JavaScript SDK, a Solidity interface, receipts, a model zoo and a tutorial.Python 包和 bnnx 命令、训练层、JavaScript SDK、Solidity 接口、收据、模型库和教程。
Graph models and shared operators图模型和共用算子
A model becomes a graph of nodes; small pure operator contracts are deployed once and shared by every model.模型变成由节点组成的图;小的纯算子合约只部署一次,所有模型共用。
Board layers, and a gomoku network棋盘类的层,和一个五子棋网络
Padding, 1×1 convolutions, lookup tables and adds. A contract calls the network in one transaction and gets a correct move.补边、1×1 卷积、查表和相加。合约在一笔交易里调用网络,得到正确的一步棋。
Few-bit layers多位的层
4-bit activations and int8 weights. A CIFAR-10 network (79.63%) that a contract can call inside a single transaction.4 位激活和 int8 权重。一个 CIFAR-10 网络(79.63%),合约在单笔交易里就能调用。
Networks trained by someone else别人训练的网络
The QONNX importer takes a Brevitas network on chain. On 10,000 test images its labels match the original's own executor exactly.QONNX 导入器把一个 Brevitas 网络搬上链。在 10,000 张测试图上,标签和原模型自己的执行器完全相同。
Bigger models更大的模型
A new dispatcher takes up to 64 data chunks. A 21-chunk digit network is the first model past the old limit of 16.新的调度合约最多支持 64 个数据块。一个 21 块的数字网络,是第一个超过原来 16 块上限的模型。
A second imported network第二个导入的网络
LFC from the QONNX model zoo: 98.81% on MNIST, no label differs from the original on 10,000 test images.来自 QONNX 模型库的 LFC:MNIST 上 98.81%,10,000 张测试图上没有一个标签与原模型不同。
A whole game, played on chain一整盘棋,在链上下完
A game contract lets the network play inside the player's own transactions. One full game is on BSC testnet, and every AI move was re-checked on two nodes.对弈合约让网络在玩家自己的交易里落子。一整盘棋在 BSC 测试网上,AI 的每一手都在两个节点上复核过。
The toolkit工具包
Python bnnx
Train binarised and few-bit networks in PyTorch with bnnx.nn. Reproducible CPU training; export checks the IR against PyTorch before it writes a file.用 bnnx.nn 在 PyTorch 里训练二值和多位网络。CPU 训练可复现;导出时先对照 PyTorch 检查 IR,再写文件。
The command line命令行
12 commands: inspect, compile, deploy, verify, call, replay, import-qonnx and more. Your wallet signs; no command takes a private key.12 个命令:inspect、compile、deploy、verify、call、replay、import-qonnx 等。用你自己的钱包签名,没有任何命令接受私钥。
JavaScript SDKJavaScript SDK
No dependencies, plain ES modules, several nodes at once, receipts that bnnx replay can check. The demos below run on it.没有依赖,纯 ES 模块,同时问多个节点,收据可以用 bnnx replay 核对。下面的演示就是用它跑的。
Solidity interfaceSolidity 接口
IBnnxModel with classify and modelInfo, an example consumer, and a whole gomoku game contract.IBnnxModel:classify 和 modelInfo,一个示例消费合约,以及一整个五子棋对弈合约。
QONNX importerQONNX 导入器
Brevitas and FINN networks in, a model out, with an exact self-check. 3 imported networks are live.Brevitas 和 FINN 的网络进去,模型出来,带精确的自检。现在有 3 个导入的网络在链上。
Reference runtime and checks参考运行时与检查
An integer-only reference implementation, bnnx verify on two nodes, a fuzzer that deploys random models, and 3,300+ automated tests.纯整数的参考实现、在两个节点上跑的 bnnx verify、会部署随机模型的模糊测试,以及 3,300+ 个自动化测试。
What you could build with it可以拿它做什么
The first and last are done. The rest are ideas: nothing here is built yet.第一个和最后一个已经做到了,其余是想法:这里没有哪一个已经做出来。
built已做到
Games with an AI inside the contractAI 就在合约里的游戏
The opponent is not a server. It is part of the game, and every move can be replayed.对手不是服务器,而是游戏的一部分,每一步都可以重放。
idea想法
Guard rails for contracts合约的护栏
A small classifier a contract consults before it acts, for example to flag an unusual input. A contract already calls a model inside one transaction.合约在行动之前先问一个小分类器,比如标出异常的输入。合约已经能在一笔交易里调用模型。
idea想法
Agents for on-chain worlds链上世界里的智能体
Characters whose behaviour is a network anyone can inspect and reproduce, in a game or a simulation that lives on chain.行为由一个任何人都能检查、能复现的网络决定的角色,放在完全跑在链上的游戏或模拟里。
idea想法
Checking what users submit检查用户提交的内容
A contest or a claim that asks for a handwritten digit or a small image, classified on chain instead of by an operator.比赛或申领要求提交手写数字或小图片,由链上分类,而不是由运营方说了算。
Anyone can rerun an inference bit for bit, and a receipt records which nodes said what.任何人都能逐位重跑一次推理,收据会记下哪些节点说了什么。
3 · demos3 · 演示
Every box here is live这里每一个框都是活的
Each demo sends a free read-only call to contracts on BSC testnet, through two independent nodes. Nothing is signed. When two nodes answer differently, or one does not answer, the page says so.每个演示都向 BSC 测试网上的合约发免费的只读调用,经过两个互相独立的节点。不需要签名。两个节点的回答不同,或者有一个没有回答,页面都会直接说出来。
digit lab · one digit, five networks数字实验室 · 一个数字,五个网络
photo lab · one photo, three networks照片实验室 · 一张照片,三个网络
The toolchain is a developer preview: the repository is private while the licence is settled. The steps below are the ones we ran for every model on this page, and the commands are real. Calling and checking the deployed models needs none of it.工具链现在是开发者预览:许可确定之前仓库是私有的。下面的步骤,是我们给这页上每个模型都走过的步骤,命令也是真实的。调用和核对已部署的模型完全用不到这些工具。
Check a deployed model in one command一条命令核对一个已部署的模型
With Foundry installed, ask a node what the contract says it is. The second line of the answer is the IR hash. Ask a second node and it is the same.装好 Foundry,问节点这个合约自称是什么。答案的第二行是 IR 哈希。换一个节点问,是同一个。
bash
cast call 0x9B1FE44987bC449d28aC8c77e6027A6596c91901 \
"modelInfo()(bytes32,bytes32,uint256,uint256)" \
--rpc-url https://bsc-testnet-rpc.publicnode.com
# 0x64312d6d6e697374... the name, "d1-mnist"
# 0x4fd07609d945...b831ec6d the IR hash
# 784 input bytes
# 10 classes
Train and export训练并导出
bnnx.nn checks the layers against the on-chain limits as you put them together. Export compares the integer model with PyTorch before it writes anything, and prints the IR hash.bnnx.nn 在你搭层的时候就按链上的限制检查。导出时先把整数模型和 PyTorch 对比,再写文件,并给出 IR 哈希。
train.py
import bnnx.nn as bn
model = bn.templates.mlp((28, 28, 1), hidden=(256,),
classes=10)
print(model.summary()) # size, gas per call, a verdict
bn.fit(model, (x_train, y_train), (x_val, y_val),
epochs=5, batch=256, lr=1e-2, seed=0)
# checks the integer model against PyTorch,
# then writes it and returns its IR hash
ir_hash = model.cpu().export(
"models/my-digits", name="my-digits",
classes=[str(d) for d in range(10)])
Deploy and verify部署并核对
Foundry signs with your own keystore, so the contracts are yours. deploy simulates until you add --broadcast. verify compares the chain with the model file and the reference program on two nodes.Foundry 用你自己的密钥库签名,合约归你所有。不加 --broadcast 时 deploy 只做模拟。verify 在两个节点上,把链上内容和模型文件、参考程序逐项比对。
bash
# size and gas per call, before you spend anything
bnnx inspect models/my-digits
# dry run: simulates, sends nothing
bnnx deploy models/my-digits \
--rpc-url https://bsc-testnet-rpc.publicnode.com \
--account dev
# for real, signed by your own Foundry keystore
bnnx deploy models/my-digits \
--rpc-url https://bsc-testnet-rpc.publicnode.com \
--account dev --record my-digits.json --broadcast
# the chain against the model file and the reference
# program, on two nodes
bnnx verify models/my-digits \
--deployment my-digits.json --random 100 \
--rpc https://bsc-testnet-rpc.publicnode.com \
--rpc https://bsc-testnet-dataseed.bnbchain.org
Call it from a page在网页里调用
The SDK has no dependencies and no build step, so a static page, even one stored on chain, can import it. It asks every node you list and says whether they agreed.SDK 没有依赖,也不需要构建,所以静态页面,哪怕是存放在链上的页面,也能直接引入。它会问你列出的每个节点,并告诉你它们是否一致。
Networks exported as QONNX (the format of AMD's Brevitas and FINN) are converted instead of retrained. Three of the models on this page were made this way.导出成 QONNX(AMD 的 Brevitas 和 FINN 使用的格式)的网络直接转换,不用重新训练。这页上有三个模型就是这样来的。
At most 16,777,216 gas on BSC. A model that needs more only runs as a read-only call: the CIFAR-10 network of 2026-10-18 fits (16.1M gas), the 44.3M-gas CNV network does not.BSC 上最多 16,777,216 gas。需要更多的模型只能作为只读调用运行:2026-10-18 的 CIFAR-10 网络放得下(16.1M gas),44.3M gas 的 CNV 网络放不下。
One read-only call一次只读调用
About 50M gas on public nodes and about 286M on BNB Chain's own node (measured 2026-09-28). Nodes differ, so the demos ask two.公共节点约 50M gas,BNB Chain 官方节点约 286M(2026-09-28 实测)。节点各不相同,所以演示里同时问两个。
Size大小
Data contracts hold at most 24,000 bytes each. A sequential model takes up to 16 of them, a graph model up to 64 (about 1.5 MB).每个数据合约最多存 24,000 字节。顺序模型最多 16 个,图模型最多 64 个(约 1.5 MB)。
Arithmetic运算
Weights are ±1 or int8. Activations are ±1 or 2 to 4 bits. No floating point; batch normalisation is folded into thresholds. Layers have at most 256 channels; convolutions are 3×3 or 1×1, stride 1 or 2.权重是 ±1 或 int8。激活是 ±1 或 2 到 4 位。没有浮点数;批归一化折进阈值。每层最多 256 个通道;卷积是 3×3 或 1×1,步长 1 或 2。
Input and output输入和输出
The input is uint8 values in height, width, channel order, exactly the length modelInfo() says. The output is one integer score per class; ties go to the lowest index.输入是按高、宽、通道顺序排列的 uint8,长度必须正好等于 modelInfo() 给出的值。输出是每个类别一个整数得分;平局取序号最小的。
Cost成本
About 0.65 gas per ±1 multiply-add and 6.1 per int8 one (measured, unoptimised). Storing a model costs about 0.0105 BNB per MiB at 0.05 gwei (estimate).每次 ±1 乘加约 0.65 gas,int8 约 6.1 gas(实测,未优化)。存一个模型每 MiB 约 0.0105 BNB(按 0.05 gwei 估算)。
Where it runs在哪里运行
BSC testnet only. Nothing is deployed on mainnet yet, and the toolchain is not public yet.只在 BSC 测试网。主网上还没有部署任何东西,工具链也还没有公开。