惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
有赞技术团队
有赞技术团队
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Recent Announcements
Recent Announcements
Y
Y Combinator Blog
Vercel News
Vercel News
Martin Fowler
Martin Fowler
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
L
LangChain Blog
云风的 BLOG
云风的 BLOG
H
Hackread – Cybersecurity News, Data Breaches, AI and More
aimingoo的专栏
aimingoo的专栏
G
Google Developers Blog
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
Google DeepMind News
Google DeepMind News
雷峰网
雷峰网
阮一峰的网络日志
阮一峰的网络日志
F
Fortinet All Blogs

smallyu的博客

RISC-V 虚拟机无法代替 EVM 虚拟机 Polkadot 的 Existential Deposit 机制错在哪里 利息,套利,交易策略,金融市场 LayerZero 从来不挑战比特币的地位 默认参数引起的以太坊节点运行错误 硬件钱包与资产安全 预测市场比币圈更赌场 为什么去中心化的跨链桥不可能实现 我对于 AI 时代的答案 不要投资任何隐私币 区块链技术世界的三大真理 以太坊 AA 钱包的致命问题是什么 基于 AI 语义执行的 MCP 区块链的设计 一个集成 Geth 和 CometBFT 的兼容层 我的加密货币定投策略(二) DeFi 基础: 理解 AMM 定价机制 Go 语言 GMP 调度器的原理是什么 Web3 项目分析计划 对 Psyche Network 项目的分析 continuation 教程: 理解 CPS 如何开发一个比特币符文(Runes)协议 比特币脚本开发教程 我从王垠的计算机科学视频班学到了什么 区块链技术面试题(2025年版) Rust 语言容易让新手困惑的一个“过度优化” Solana 智能合约开发教程 (1) 尝试开发一个最小 EVM 虚拟机 基于 ZK 的链上身份系统设计 一个 Web3 打赏系统的设计 鼓吹 Cursor 的人技术能力都差
半年的工作回顾
2023-05-06 · via smallyu的博客

半年的工作回顾

2023-05-06

前几年关于工作内容方面的回顾:

回顾一下最近半年的工作。从半年前开始,我就迷茫了,因为知道 Filecoin 在做 EVM 的适配,存储赛道已经倒向计算赛道的一边。我们又无法超越 Filecoin。

不过我还是有收获的,主要集中在对文件证明的进一步理解,以及对项目中代码细节的进一步熟悉,这一块是我之前没了解的。

扇区证明

扇区证明一直存在个问题,就是证明会失败。一开始认为是合约进行证明检查的时候,根本没有带上文件列表的信息,导致过期文件没有被删掉。后来发现不止这一个问题,因为在修复代码后,如果文件只存到一个存储节点,是正常的,如果有多个存储节点,证明仍然会失败。

最后查到的原因是,当一个文件被存到多个节点,其他节点提交证明到合约,如果发现文件过期了,就会在合约里删掉节点对应的文件信息,同时广播给其他节点,要删掉这个文件。而其他节点收到通知后,只删除了本地的问题,没有删除合约里的文件信息,就导致本地的文件经常会少于合约里记录的文件,证明就失败了。

这个问题解决的过程中,相当于把证明相关的代码看了一遍。

EVM 合约

在去年 一年的工作回顾 中提到,我在做一件把 Go 语言合约用 Solidity 重写的事情,也就是把原有的合约移植到以太坊上运行。

其中让项目支持以太坊账户的事情早就完成了,存储节点可以顺利地使用以太坊节点,通过以太坊的智能合约实现文件的上传下载。但是合约对文件的证明一直空着,因为项目使用了 Bulletproof 的零知识证明,用 Solidity 写一遍 Bulletproof 的证明太费力了。

现在的做法是 POA 的方式,在合约里本该进行证明的地方,换成提交证明参数,把证明参数记录到合约中。然后验证节点从合约里把证明参数拿下来,在本地进行零知识证明的验证,再把证明结果提交回合约里。

因为把证明相关的代码看了一遍,所以现在能够完成 EVM 合约中,证明相关的这一部分。

为什么忽略 Layer2

之前有一个想法是,把证明放到 Layer2 的节点上做。我在这个方向上没什么进度,有两个原因:

  1. Layer2 的定位是 EVM 完备,本身不具备额外的功能
  2. Layer2 也很难进行验证

第一点的意思是,对于用户或者开发者来说,Layer2 存在的意义是降低手续费,如果能在使用效果上和 Layer1 一模一样,那就了不得了。给 Layer2 增加一些额外的功能,是不是 Layer2 这种项目的本意呢?

第二点的意思是,Layer2 的项目也是拿着 Layer1 的节点改了改区块的头信息之类。想要实现文件的验证,需要在虚拟机的字节码层面,识别出一笔交易是调用了某个合约的某个函数,然后把这个函数要操作的变量拿出来,对参数进行一次零知识证明的验证,再把验证结果在字节码层面写入回变量中。这样做的难度很大。不过要真的能搞成,相当于搞了一个业务专用的 EVM 虚拟机,技术门槛挺高,挺能用来炫耀的。

与之相比,相对简单的做法就是,用一个客户端对证明参数做验证,再把结果提交回去。如果是这样,那就无所谓客户端在 Layer2 的节点上还是其他什么节点上了。 我就选择了这种简单的方式去做,虽然不够酷,但是有生之年能完成,能看到结果,现在确实完成了。

Solidity 合约

稍微总结一下 Go 合约迁移到 Solidity 合约遇到的问题。

合约大小不能超过 24 KB,否则会编译失败。对于业务型的合约,24 KB 是不够用的,需要拆分为两个甚至多个合约,合约之间再通过调用完成相应的功能。拆起来也不难,就是注意在功能上拆明白,哪些是对外的,哪些是内部的。

storage 的结构体不能包含列表,因为列表不是固定长度的。合约不好计算占用了多少空间。这就需要把原先结构体里面的列表拆出来,用的时候单独用。当然如果对业务逻辑熟悉,这一点不是什么问题,如果对业务逻辑不熟悉,看到一堆陌生的变量名称,还是挺烦的。我就因为当时偷懒,合约里没把逻辑写全,查了两天才查明白问题。

mapping 不能迭代。原先简单的写法,需要用 library 改为挺复杂的写法。

mapping 元素不存在会返回默认值。无法判断 mapping 是否包含某个 key,如果业务中类型的默认值有含义,可能会出现意想不到的情况。

这几点不算什么大问题,但可能会给写代码的过程带来一点麻烦,因为需要用不一样的写法,写出完全一样的逻辑。