<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>WebAssembly on 豆子技术站</title><link>https://blog.91demo.top/tags/webassembly/</link><description>Recent content in WebAssembly on 豆子技术站</description><generator>Hugo -- 0.155.1</generator><language>zh-cn</language><lastBuildDate>Sun, 24 May 2026 06:40:16 +0800</lastBuildDate><atom:link href="https://blog.91demo.top/tags/webassembly/index.xml" rel="self" type="application/rss+xml"/><item><title>从 wasm-bindgen 到 C-ABI 写微信小程序WASM：一次真实的 WASM 落地复盘</title><link>https://blog.91demo.top/wx-wasm/</link><pubDate>Sun, 24 May 2026 06:40:16 +0800</pubDate><guid>https://blog.91demo.top/wx-wasm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;在写完 ESP8266 IoT 架构之后，我就在想一件事情：既然代码开源，IoT 网关岂不是谁都能连？&lt;br&gt;
于是我试图在微信小程序端做文章。但开源的小程序不能硬编码密钥，也不能仅靠接口鉴权。&lt;br&gt;
我想到了很早之前预研的 WebAssembly（WASM）。配合后端防护，可以大幅提升攻击者的成本。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="一背景与目标"&gt;一、背景与目标&lt;/h2&gt;
&lt;p&gt;实现的功能非常简单：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;传入 &lt;strong&gt;小程序 APPID + 设备 ID + 时间戳&lt;/strong&gt;，使用 &lt;strong&gt;Ed25519&lt;/strong&gt; 签名，返回 Token。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以前在微信小程序调通过 &lt;code&gt;WxWebAssembly&lt;/code&gt;（简称 wxwasm），但当时主要处理 Int 类型，这次需要返回字符串。&lt;/p&gt;
&lt;p&gt;当我拿出以前的预研代码进行修改时，我才意识到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“能用 Rust 写 WASM”&lt;/strong&gt; 和 &lt;strong&gt;“能在微信小程序里稳定运行”&lt;/strong&gt;，完全是两回事。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="二第一阶段理想很丰满--rust--wasm-bindgen"&gt;二、第一阶段：理想很丰满 —— Rust + wasm-bindgen&lt;/h2&gt;
&lt;p&gt;最初的环境是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rust &lt;strong&gt;1.95&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wasm-bindgen&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wasm-pack&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="cargotoml"&gt;Cargo.toml&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[&lt;span style="color:#a6e22e"&gt;dependencies&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;wasm-bindgen&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;0.2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ed25519-dalek&lt;/span&gt; = { &lt;span style="color:#a6e22e"&gt;version&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;2.1&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;features&lt;/span&gt; = [&lt;span style="color:#e6db74"&gt;&amp;#34;rand_core&amp;#34;&lt;/span&gt;] }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;hex&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;0.4&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="librs"&gt;lib.rs&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[wasm_bindgen]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;pub&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;fn&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;generate_token&lt;/span&gt;(appid: &lt;span style="color:#66d9ef"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;str&lt;/span&gt;, device_id: &lt;span style="color:#66d9ef"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;str&lt;/span&gt;, timestamp: &lt;span style="color:#66d9ef"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;str&lt;/span&gt;) -&amp;gt; Result&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String, JsValue&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Ed25519 签名逻辑
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;编译很顺利（就是有点慢 😭），本地 &lt;code&gt;test.html&lt;/code&gt; 测试一切正常。&lt;/p&gt;</description></item></channel></rss>