前面一番操作,从小程序前端到Rust跨平台通用算法逻辑library,基本搞通。再增加其他功能的话,照虎画猫也不难。
给加密钱包写个二维码实现,历时...20分钟
就算是Paper wallet,也还得有两个二维码才能用(总不能每次手敲几十位无法记忆的数字吧?) - 一个是钱包地址,接受支付或者查自己的资产时用;另一个是私钥,在交易时使用。
感谢Rust开源世界的大神们,要给我们的钱包加个生成二维码的功能,真是唾手可得。再把我们在前面已经玩熟了的FinClip小程序+Rust的套路拿出来弄一次,顺便还能额外试试SVG在小程序里面怎么搞:
- 首先我们找个能生成二维码的代码库。选择当然是很多了,但是我们希望它是跨平台的,二维码本身的生成是纯算法逻辑,哪都一样
- 其次,二维码的渲染展示,最好不依赖于任何平台。二维码图形其实用println都能打印出来(也就是把'█'这个字符排列一下嘛)。我们选择SVG,因为它的格式实际上就一XML文本。这样我们就不用去搞什么PNG、JPG,引入一些不必要的库
- 最后,我们要把生成的二维码SVG展示在FinClip小程序中
有了上述“指导思想”,我们选择了以下的方案:
- 使用qrcodegen这个Rust crate,帮助实现QR code生成
- 按照SVG的规范,把生成的QR code输出为XML
- 使用base64这个Rust crate,把SVG文本转化成一串base64编码的字符串
- 把这串字符,在小程序中作为变量值绑定到页面渲染
下面我们把之前介绍的从Rust到FinClip小程序的流程又“机械”的走一次。
Rust部分
首先,改一下Rust部分的代码:
finclip-rust
|---- ios
|---- mini-app
|---- rust <==== 修订对象
在rust子项目的根目录下,对Cargo.toml编辑,增加两个库:
[dependencies]
...
qrcodegen = "1.8.0"
base64 = "0.13.0"
然后编辑修订src/lib.rs,增加一个QR Code的生成函数,因为是打算给小程序调用的,所以也需要输出为C函数。QR code生成部分特别简单,'QrCode::encode_text(&str, ECC-level)'即可生成,其中ECC为Error correction,即当二维码损毁的时候,视乎损毁程度,二维码中浓缩的数据的程度(四级)以支持容错。我们选个medium即可:
#[no_mangle]
pub unsafe extern "C" fn generate_qrcode_svg(input: *const c_char) -> *const c_char {
let s = CStr::from_ptr(input);
let sp = s.to_str().unwrap();
let qr = QrCode::encode_text(sp, QrCodeEcc::Medium).unwrap();
let svg = to_svg_string_base64(&qr, 4);
let result = CString::new(svg).unwrap();
let c_result: *mut c_char