Telegram Channel
记录和分享有趣的信息。

Record and share interesting information.

contact: [email protected]
前阵子 Bybit 价值 1.4B 的资产被盗,堪称史上最大金额的盗窃案。黑客所使用的盗窃技术其实并不复杂,某种意义上更说明整个区块链业界的安全观念仍然非常欠缺。

区块链的本质就是保存不可修改的数据块,Ethereum 的 EVM 就是运行在这些 append-only 的数据存储层之上的计算机。其中可以被运行的程序称为合约(Contract)。因为合约一旦被部署上链后,它的调用地址、代码就无法修改,只有数据可以被修改。为了让合约能够在不变更地址的前提下实现升级,人们想出了一个办法就是 proxy-Implementation 模式。也就是部署两个独立的合约,逻辑代码通过 implemenation 合约部署,然后再部署一个保存用户数据的 proxy 合约,proxy 合约作为面向用户的入口层,一旦部署就永久使用,以保证调用地址的稳定。proxy 合约中有一个 master 变量,可以理解为是一个指针,指向 implementation 合约的地址,实际的逻辑代码都是通过调用 implementation 合约来完成的。

从函数调用的角度来考虑,这相当于是 proxy 函数调用了 implementation 函数的代码,但是修改的却是 proxy 函数的数据。这种特殊的调用在 EVM 中称为 delegateCall,即在调用者的上下文中执行被调用者的代码逻辑。这一设计通过对数据和逻辑的拆分,让每个面向用户的 proxy 合约保持了地址和数据的一致性,而实现逻辑的 implementation 合约可以像插件一样随时更替。

然而,这次出事的就是这个 proxy-implementation 的设计。黑客部署了一个恶意的合约,这个合约有一个伪装成转账接口的方法,虽然看上去像是转账 transfer(address,uint256) ,但是其实际功能是替换 proxy 合约中的 master 属性,也就是替换其所指向的 implementation 合约地址。然后黑客生成了一个对这个恶意合约的调用 transfer("0xbDd077f651EBe7f7b3cE16fe5F2b025BE2969516", "0"),这个交易看上去像是一个无害的零额转账,但是因为设置了 operation=1 即启动了 delegateCall,实际上是执行了恶意合约的修改 proxy 合约中 master 属性的逻辑。很可惜,因为 Safe 的网站前端代码被黑客替换,Bybit 的三位管理员都没能注意到这次调用中的 operation=1 这个高度危险的设置,可能误以为是一次零额转账而签署了交易,黑客从而成功将 proxy 合约所指向的 implementation 修改为指向到自己的恶意合约,完全替换了 proxy 合约的逻辑,最终完成了对 1.4B 资产的盗窃。

Update: Safe 已经承认了,是因 Safe 的前端文件被黑客替换,导致了这一事件。 #blockchain

ref:

* 我曾写过一篇 web3 的简易入门,可以搜索 Upgradable 一节
* 关于 safe-wallet 被黑的分析
Laisky's Notes
最近都在学习 TON 开发,积累了一些经验。TON 有很多独特的设计和开发范式,值得先记个小笔记,主要以 Ethereum/EVM 作对比。这是基于我目前的理解,不一定正确,有兴趣欢迎讨论。 1. 所有的调用都是消息,所有的消息都是异步的。也就是说,你没法同步取得跨合约调用的结果。 2. 每次调用的费用是非确定性的,而且因为整个调用是异步的,没法预知调用的总费用。所以只能先给一个相对较高的手续费,然后等合约执行完后退还余款。TON 的费用的精确控制非常困难,我花了很多时间在这上面,这个以后可以单独讲一…
终于学会相对精确的控制 TON 的 value flow 了,先记个小笔记防止忘了。这也只是我目前的理解,不一定正确,欢迎讨论或指正。

有三个主要费用 network、computing、action。network 包含消息发送的费用,一般由 sender 付,钱包里一般消息的 value 和 network fee 是分别支付的,而合约中默认是从消息的 value 中支付的。computing 是执行合约的费用,action 是合约发送 external message 的费用,主要就是 emit。(此外还有 storage fee 先不管了)

ctx.value 代表的是 inflow msg 携带的 value,sender 已经付过了 network fee,还没支付 computing 和 action。合约执行后会扣除 computing,执行完成后如果有需要发送的 outflow 消息,那么再扣除 action fee。

可以把 ctx.value 理解为税前收入,而且你无法知道会收多少税(computing & action fees)。

补充:FunC 里是可以精确计算 fwd_fee 的,但是感觉 tact 不太行,可参考:
* https://docs.ton.org/develop/smart-contracts/fee-calculation
* https://github.com/ton-blockchain/stablecoin-contract/blob/main/contracts/gas.fc
* https://tonviewer.com/config#24

myBalance() - ctx.value 代表合约执行前的余额。可以用 nativeReserve(myBalance() - ctx.value, ReserveExact); 来保护合约余额不被用户消息所消耗。

但是你在合约代码中极难通过控制 ctx.value 来计算你能操作的 inflow 余额,因为 computing 和 action 的开销是很难计算的。比如如果你想要把剩余的 inflow value 全部转走,可行的办法是用 nativeReserve 锁定不想转走的余额,然后再用 SendRemainingBalance mode 发送一条 value 为 0 的消息。

SendRemainingBalance 会转走未被 nativeReserve 锁定的全部金额,按照上文描述,也就是所有剩余的 ctx.value注意 send 的 value 并不会支付 action fee,而仅会包含 network fee。也就是说,当你在代码中 send 一个消息,这个消息的 network fee 会从 send 的 value 中扣除,但是 action fee 会从合约余额中扣除。这其中有一个坑,emit 的费用是在 action 阶段计算的,如果你的代码中使用了 emit,那么就需要记住在 action 阶段合约余额会被扣钱,你最好在 nativeReserve 的锁定中包含 emit 的费用。
经过多次测试,nativeReserve 锁定余额后,仅有 storage_fee 是从 balance 扣除的,其他都是从 send 的 value 里扣除的。

但是 emit 具体花多少钱?我还不知道怎么算,目前是估计一个经验值,测试网是 0.007,你可以多锁定 0.01 给 emit。 #blockchain

Ps. 我真是行业冥灯,搞啥啥死

prev: https://t.me/laiskynotes/318
next: https://t.me/laiskynotes/324 Fees calculation | The Open Network
最近都在学习 TON 开发,积累了一些经验。TON 有很多独特的设计和开发范式,值得先记个小笔记,主要以 Ethereum/EVM 作对比。这是基于我目前的理解,不一定正确,有兴趣欢迎讨论。

1. 所有的调用都是消息,所有的消息都是异步的。也就是说,你没法同步取得跨合约调用的结果。

2. 每次调用的费用是非确定性的,而且因为整个调用是异步的,没法预知调用的总费用。所以只能先给一个相对较高的手续费,然后等合约执行完后退还余款。TON 的费用的精确控制非常困难,我花了很多时间在这上面,这个以后可以单独讲一篇,简而言之就是整个调用链应该有一个唯一的起点和唯一的终点。唯一的起点是因为交易发起者只有一个人,唯一的终点是因为要汇集所有消息的余额。
注意,交易执行的总费用是很可能超过用户支付的 input value 的,换言之合约在用自己的余额给用户交易付费,要特别小心!

3. 合约在链上不会永久存在,部署 code 和 data 后状态会成为 active,但是同时会开始计费缴纳租金。租金从合约余额扣除,扣完后经过一段时间后合约的数据会被删除,仅保留哈希。用户可以重新上传数据恢复合约。如果一段时间后未恢复,所有的链上数据都会被销毁。之所以这样做是因为 TON 链上交互非常依赖子合约,子合约的数量会随着用户量倍增,必须通过限制合约存活时间来控制链上数据量。

4. 合约不会直接和用户交互,而是会用用户的钱包地址给用户部署一个子合约,然后主合约和这个子合约交互。子合约里会有两个属性,master 指向主合约,owner 指向用户的钱包合约地址。这样做的好处是,因为子合约代码是主合约部署的,那么子合约的行为就是确定性的。所以 TON 的合约开发类似于工厂模式,你首先需要编写一个主合约,然后需要给你所有的交互对象各自编写一个子合约。

5. 主合约内不保存任何用户数据,仅保留必须的全局变量。这是和 EVM 最显著的一个区别。拿 ERC-20 代币来说,EVM 合约需要存储一个巨大的用户账本。而 TON 的主合约什么都不存,只需要给用户部署一个子合约,然后将用户持有的代币信息保存在子合约里即可。因为子合约的代码是主合约部署的,所以行为完全可控和可信。用户间转账只需要子合约间互相通信即可,双方可以通过校验对方的地址来确定合约代码的完整性,毕竟合约地址本质上就是合约代码和初始化数据的哈希,而初始化参数往往就是 master 和 owner 的地址。

6. 我目前的开发组合是 blueprint + tact + tonkeeper。开发体验非常痛苦,缺乏必要的文档和示例,等我有空整理一篇博客。 #blockchain

prev: https://t.me/laiskynotes/296
next: https://t.me/laiskynotes/319
总算把 TON, The Open Network 的白皮书看完了。这个白皮书里描写了一个非常具有野心的技术架构,可以认为它把目前还处于计划中的区块链技术都全部作为基础设施实现了,提供了目前业界最高性能和兼容性的基建。我在这里先简单记个笔记,之后有空写篇博客水文。

当我们提到 TON 时,指的不是一个链,而是一系列链在不同维度组合。首先 TON 有一个扮演全局状态的 master chain,但是这个链只负责状态,不负责具体的 COIN 和账本。在 master chain 之上,可以支持 2^32 个 work chain,每一个 work chain 都可以有自己独立的 COIN 和 protocol,只要这个 work chain 定期将自己的状态提交到 master chain 即可。目前 TON 有一个 work chain,就是 TON coin chain。我们可以认为,TON 天生就自带 layer-2 结构,而且这个 layer-2 还是无限扩展的。

每一个 work chain 还可以根据负载继续动态拆分,最多拆分为 2^60 个 shard chain。理论上每一个账户都可以独占一个 shard chain,每一个账户独立维护自己的 COIN/TOKEN 余额,每一个账户间的交易都可以完全并行。账户与账户间通过异步消息进行传递,消息在 shard chain 间传递的路径为 log_16(N) - 1,其中 N 为 shard chain 的数量。假设目前有 4000 个 shard chains,最多中转两次就能完成消息传递。shard chain 为 TON 提供了近乎无限的并行度,使其成为目前市面上最快的 layer-1,吞吐量理论无上限

TON 采用 PoS 共识,work chain 的区块经过所有 validators 的校验后可以进入 master chain。validators 还会拆分成小组,构成 shard chain 的 validators。任何一个 validator 可能会被分配给多个 shard chains,这些校验工作可以完全并行运行。除此外还有 fisherman 可以对历史区块提出挑战。

为了尽可能避免硬分叉,TON 所有链上的区块实际上也是一个称为 vertical chain 的子链,只是正常情况下它们是只有一个区块的链。当需要对历史进行矫正时,无需硬分叉,而是在对应的区块上再提交一个新区块即可。

可以看出 TON 提供了近乎无限的并行度和兼容性,难怪称之为 Blockchain of Blockchains。甚至理论上说,目前业界所有的区块链,都可以作为 work chain 运行在 TON 的网络之上。 #blockchain

prev: https://t.me/laiskynotes/281
next: https://t.me/laiskynotes/318
Laisky's Notes
https://x.com/LaiskyCai/status/1797491021565378737 给 AO 的官方视频搞了个机翻字幕,有兴趣的可以看看,我认为对背景介绍的比较全面了。 如果你是后端程序员,那么其实一句话就可以解释:就是 DDD 里的 event-sourcing,不过现在所有的 event 都上链持久化了。 #blockchain prev: https://t.me/laiskynotes/239 next: https://t.me/laiskynotes/281
我之前介绍过 Arweave 的 AO 项目,并且认为 AO 是区块链世界的一次重要的技术进步,因为它利用类似于 event-sourcing 的技术架构,提供了传统 Ethereum 无法比拟的扩展性。

最近几天我一直在学习 TON(The Open Network)。这也是一个基于 actor 消息模型的去中心化网络,和 AO 有异曲同工之妙。但是深入了解后我发现,TON 显然比 AO 的成熟度更高,扩展性更强,隐私性也更好。就目前看来,TON 代表着一个更令人兴奋的未来技术架构。

TON 中有很多非常有意思的独特设计:

1. 基于消息的 Actor 模型,这点和 AO 的 processes 大同小异,此处不再重复。
2. 基于租约的 smart contract。合约需要支付租金让自己在链上存活,欠租后会删除代码仅保留签名,欠租超过 1 年后会被完全删除。
3. Jetton wallets。智能合约不再维护账本,而是由用户自己的子钱包自行维护余额。提供了更好的隐私性,和最强的可扩展性。
4. base & master 双链设计,有效解决了消息系统中的正确性问题。被 validators 验证过的状态才会上 master chain。

特别值得一提的当属 Jetton wallets,我认为这是一个非常伟大的设计,可以理解为在区块链世界实现了现金。每个用户持有可信的现金,不同用户间可以直接交易,而不需要通过中心化的合约账本,这样不仅提高了隐私性,也提供了无限的可扩展性。

具体来说,当你要发行一个类似 ERC-20 的 layer-2 Token 时,不再需要在合约里记录所有用户的账本,而是仅需要提供一个可供所有用户独立运行的子合约模版。每个用户可以运行任意数量的子合约,子合约中记录有该用户持有的余额。当用户 Sender 向用户 Receiver 转账时,转账消息会携带上 Sender 合约的签名和金额,Receiver 通过验证签名得知 Sender 的合约是可信的,即 Sender 的合约会同时扣除相应的转账金额,Receiver 同意接收消息并增加自己的余额,转账完成,整个过程中不需要第三方参与,尤其不需要中心化的合约账本参与。因为用户的子合约(Jetton wallets)也是完全运行于链上的,所以 TON protocol 会保证消息中的 Sender 合约签名是真实可信的,可信的合约也会诚实地执行和转账相对应的余额操作。

上述操作仅仅只发生于转账的双方,也就是即使是同一种代币,不同人间的转账也可以完全并行运行,而不受制于中心化合约,这一点使其可扩展性达到了最大,提供近乎无限的吞吐量。同时,用户的余额和转账交易也不再那么容易被外界观察到,极大提高了隐私性。 #blockchain

prev: https://t.me/laiskynotes/249
next: https://t.me/laiskynotes/296
- https://docs.attest.org/docs/welcome

简单学习了一下 Ethereum Attestation Service(EAS)。根据宣传,这是一个使用标准化接口统一诸多认证的服务,用于简化开发者和用户的认证流程。

实际上,看下来感觉原理其实很简单,说白了就是个在链上存储和展示 JSON 的服务。开发者首先提交一个 schema,也就是这个 JSON 的字段的定义。然后用户(attester)选择一个 schema,填写内容,用自己的私钥签名,发送上链,就完成了认证。

EAS 并不保证这个 attestation 是正确的,只保证它是被签名的,同时提供一个链上的存储,然后用户还可以随时撤销这个 attestation。验证这个 attestation 是否正确是开发者的责任,我觉得可惜的是,EAS 的设计并没有留出给 attestation 标记 verified 属性的地方,导致它并没有完成 attest -> verify 这个完整的流程。

可以看出,实际上 EAS 的逻辑非常简单,一个简单的合约就能实现。 #blockchain
这几天在看 cross chain bridge,顺带简单了解了一下 cosmos 的 IBC(Inter-Blokchain Communication Protocol)。

前文介绍过,跨链桥的作用是跨链转移资产,其根本原理就是在 source chain 质押资产,然后在 target chain 取出新的资产。这一流程最大的挑战,就在于 source 和 target 两个chain 之间无法直接通信,而间接通信的可靠性和可信度都很成问题,使得质押和取款这两个操作很难具有原子性。

IBC 的解决办法很直观,甚至说有点简单粗暴。既然间接通信不可靠,那就让它们直接通信好了。通信的方式就是在 target chain 的底层协议中,支持运行 source chain 的 light client。用户在 source chain 完成资产质押后,将质押交易和 block header 通过 Relayers 转发给 target chain,target chain 通过 light client 验证 block header 的真实性,从而确认质押交易的有效性。简而言之,就是将确认第三方链上交易真实性的 Oracle,以轻客户端的方式直接集成进了链的底层协议之中。

注:light client 就是某个链的客户端,但是只下载 block headers,可以验证链的完整性,但是不包含具体的交易信息,相对 full-client 要轻量得多。

注:前文提到的这个 Relayers 仅负责监听和转发,不需要信任它,所以 IBC 是不需要引入可信第三方(Trusted Third Party)的。

这样做一个问题是,如果你想要和尽可能多的链桥接,那么你的协议中就得同步运行很多的轻客户端,这会使得协议的复杂度和资源消耗都大大增加。为了缓解这个问题,cosmos 提供了一个集成了很多轻客户端的中转链 cosmos hub。你可以将自己的链桥接到 cosmos hub,然后再从 cosmos hub 上接入其他链,这样就可以大大减少你自己的链上所需要维护的轻客户端的数量。

这个做法我感觉蛮奇葩的,我觉得仅利用 Oracle 就可以很轻量地实现类似的功能。 #blockchain

refs:
- https://laisky.notion.site/ELI5-What-is-IBC-ea3aa65210c545a6ab63b4ec43d8ee26?pvs=4
- https://laisky.notion.site/IBC-Getting-Started-With-IBC-Understanding-the-Interchain-Stack-and-the-Main-IBC-Implementations-996375ac5fa04dc5a538e1fb238c2ead?pvs=4
最近简单学习了一下区块链中的 cross chain bridge。

它的功能类似于传统金融机构中的自动清算银行 (ACH, Automated Clearing House),ACH 就是负责跨行转账的中转机构。Bridge 就是区块链世界力求去中心化的 ACH。

区块链中的每一个链都是一个自成体系的网络,链与链之间是无法直接通讯的,当链上的资产希望跨链流通时,有两个转换途径:

1. 通过中心化的交易所(CEX),将资产从一条链上提现,然后在另一条链上取款;
2. 通过跨链桥,将资产从一条链上锁定,然后在另一条链上解锁。

跨链桥从功能上来说和 CEX 有相似之处,但它旨在实现更高的去中心化和减少信任假设。一般通过一套自动运行的 DAO(Decentralized Autonomous Organization)来管理跨链桥的运行。跨链桥在两个链(来源链和目标链)上都有部署合约,在目标链上会有自己的代币。用户在来源链上将资产转账给跨链桥的合约,然后跨链桥会在目标链上发行相应数量的代币给用户。在目标合约放款前,会运行一些列的自动化检测和审计程序,这些程序可以分布式部署和运行,然后共同维护一个多签名钱包,当所有的检查程序都通过后,各自用自己的私钥生成一个多签名,然后使用该多签名让目标链上的合约通过 mint 为用户生成新的目标代币。

上面只是描述了多签名跨链桥这一种形式,其他还有各式各样的很多实现形式。但是就目前来说,依赖一个可信第三方(custodian)仍然是无法避免的,本质上跨链桥仍然是一个中心化的,存在信任风险的工具,未来也许有可能通过零知识证明等技术来实现完全去中心化的跨链桥。

美国货币总核查办公室(OCC)的代理审计长 Michael J. Hsu 在 2022 年时也曾发言提到,cross chain bridge 是加密货币世界的基石(尤其各种稳定币都通过跨链桥实现跨链流通),而其对于黑客攻击非常脆弱,需要加强监管。 #blockchain

next: https://t.me/laiskynotes/258
论文: https://arxiv.org/abs/2401.17555
论文作者的视频讲解: https://youtu.be/_AdCIphFZzk?si=U0ETt9-zRddZyGOE

学习了一下号称可以链上证明 AI 推理的 opML。

首先介绍一下使用场景,比如说有一个 AI 聚合平台,服务商可以在上面发布自己的 AI 推理接口,用户可以付费使用这些接口服务。那么就会出现两个问题:

1. 我怎么知道服务商真的运行了推理,而不是随便给我编了个结果?
2. 我怎么知道服务商真的是用它声称的模型执行的推理,而不是用廉价模型,或者用别家的强力模型来刷分?

这两个问题可以概括为,真实算力问题,和模型的一致性问题。

对于真实算力问题,以前介绍过的 BitTensor 也曾试图解决这个问题,但是解决办法比较粗糙,它让一大群矿工同时运行推理,然后从推理结果中择优选取。这样确实可以大幅提高推理结果的真实性,但是会导致非常严重的计算资源浪费,而且也无法对模型和数据提供任何隐私保护。

opML 将推理的计算步骤,转换为虚拟机(FPVM)的状态变化,那么就可以形成一个状态链,这个状态链的每一个节点都是当前推理步骤时,整个虚拟机数据的 merkel-tree root。然后将最终状态的 merkle root 上链持久化存储,作为本次推理的 Proof。

乐观(Optimism)的意思就是,所有的结果直接上链,默认正确,但是服务商需要在一个挑战期内质押一定量的 token。在这个挑战期内,任何人都可以扮演 challenger 发起挑战,链上也会有固定的挑战者发起随机挑战。挑战者可以提供自己的状态链,证明服务商上链的状态链是错误的,通过二分查找,可以找到双方链上的一个分歧点。然后根据分歧点的前一个状态,重算分歧点的状态,就可以知道哪个链是正确的。如果服务商的链是正确的,那么挑战者会被罚款,如果服务商的链是错误的,那么服务商会被罚款。这样可以实现相对低成本线上证明和验证。

但是我没理解的一点是,挑战者该如何知道正确的状态链是什么呢,除非他自己本地重算一遍推理?而且随机挑战实际上也不一定能发现伪造吧,恶意供应商完全可以伪造一个虚假但是可验证的状态链,你的任何抽检都不会发现问题。

最后,看上去 opML 这篇论文是为了推 HyperOracle 他们家的 LLM Oracle 产品,所以他们需要试图证明他们的 Oracle 提供的 off-chain 推理结果是真实可信的。 #blockchain
https://mirror.xyz/firstfan.eth/kGa6jFpYm9qvW3tdlEAdwSEa841xS8DEEvrEyR3uUmI

币圈餐具,老哥用 ArConnect 使用的密码库批量生成 AR 地址转账,转飞了价值 10 万 USDT 的 AR。

原因是密码库有 BUG,首次调用没问题,连续多次调用的话,会因为脏数据而产生不一致的输出。必须每次调用都重新初始化。(以后各位测试密码库 SDK 的时候,要注意多写个 case 测试批量调用下的一致性)

好消息是,因为暴跌,现在只值 8 万 U 了… #blockchain
- blog: https://blog.laisky.com/amend/web3-101/
- slides: https://s3.laisky.com/public/slides/web3-101.slides.html#/

做了一个面向新人的 Blockchain/Web3 技术入门分享,内容很浅,主要是相关概念的介绍,希望能帮助新人快速入门。各位有兴趣的话可以看看,有什么疑问或建议也欢迎在评论里讨论。 #blockchain
花了两天时间总算看懂了 KZG 证明😢

如果你熟悉 Merkel-tree 的话,那么可以很容易理解,KZG 的功能完全一致,试图利用一个很小的承诺(Commitment)保证一大堆数据的完整性。在 Merkel-tree 中,Commitment 就是它的树根(Root)。

KZG 的优点在于,当你需要验证消息的完整性,比如某个点确实存在于这个数据集之中时,它所需的计算是常量级,而 Merkel-tree 需要提供所有相关路径的 HASH 值,计算复杂度为 O(logN)。所以在数据量较大时,KZG 会更有优势。

具体的证明过程就不在这里细说了,详见笔记 https://laisky.notion.site/Kate-Zaverucha-Goldberg-KZG-Constant-Sized-Polynomial-Commitments-Alin-Tomescu-30c1406d97fa4ecaa5190827d65faa9b?pvs=4

#blockchain #crypto
读完这本币圈圣经《货币的非国家化》(Denationalisation of Money)。这本书的出版时间正好与RSA算法发表的同一年,1978年。此前也分享过一片介绍加密货币起源的文章

自二战以来,世界范围内的政策和舆论深受凯恩斯主义的影响。凯恩斯主义认为央行可以通过货币政策进行逆周期调节,以维持金融稳定,并相信温和通胀对经济发展是有利的。

然而,哈耶克则驳斥了上述观点。他认为政府对货币的垄断是一切金融危机的根源,通胀无论程度如何都是有害的。逆周期调节只能使危机延迟并恶化,而不能真正解决危机,甚至认为危机本身就是法币通胀导致的。哈耶克进一步指出,亚当·斯密在论述国家职责时,根本没有提及货币发行权。事实上,国家对货币的垄断是一件相对比较新鲜的事情,但如今法币的垄断已经成为政府最重要的权力之一。

哈耶克主张货币的发行应当是市场驱动,而不是政府控制的。他认为,货币发行应当是竞争性的,而非垄断性的,去中心化而不是集权化。所有金融机构都可以提出一篮子货物作为价值锚点,发行自己的货币,而市场将自然选择最优质的货币。当人们以某种货币签署合同时,计算的是其所代表的真实价值。如果一个合同因为通胀不断贬值,债务人可以通过时间化解债务,这对于债权人是不公平的,也动摇了市场稳定的契约基础。

哈耶克的这些理论在加密货币世界得到了实践。然而,天然通缩的货币似乎必然导致财富的集中。比如,早期持有BTC的人富可敌国,而晚入场的人只能望洋兴叹。可惜的是,哈耶克对此问题并未作出论述。 我又考虑了一下,BTC 是天然通缩的,但是哈耶克设想的货币是锚定真实商品,应该是既不通缩也不通胀的,BTC 实际上并没能实现哈耶克的设想。
#blockchain
https://laisky.notion.site/Solidity-delegatecall-usage-and-pitfalls-3833eadc06ae4528bfa23d194ea8d3cb?pvs=4

前文介绍了 solidity 中变量的持久化存储方式。而我们之所以关心变量的存储位置(slot),就是因为在使用 Proxy 模式时,需要在合约间共享变量,而合约间变量的共享方式就是通过 slot 对齐的。

合约一旦发布就是只读不可更改的,如果想要修复 bug 或升级功能而发布一个新的合约,那么就会得到一个新的地址。为了在保持地址不变的同时更改合约的代码,最常见的实现方法就是使用 Proxy-Implementation 模式。发布一个 Proxy 合约作为接口,地址永远不变。但是实际的业务代码指向 Implementation 合约,implementation 合约可以不断地升级迭代,只要同步更新 Proxy 合约的指向即可。

实现 Proxy 这一功能,依赖于 solidity 的 delegatecall(),这个函数可以让 Implementation 使用 Proxy 的上下文,即内存数据和存储。而这个数据共享的前提,就要求 Proxy 和 Implementation 的变量声明按照 slot 进行严格的对齐。

按照目前最推荐使用的 UUPS Proxy 模式(UUPS 简而言之就是将升级 Implementation 的 upgrade() method 也放在 Implementation 内定义),为了减少 Proxy 和 Implementation 间的变量冲突,一个最佳实践就是不要在 Proxy 内声明任何非必需的变量,理论上 Proxy 内仅需要定义 owner(设置管理者) 和 implementation(设置 Implementation 的地址) 两个变量即可。所有的业务数据,全部仅在 Implementation 内定义。当 Proxy 使用 delegatecall() 调用 Implementation 时,Proxy 的存储空间会被共享给 Implementation,所以虽然变量仅定义在 Implementation 内,但实际上全部存储于 Proxy 的存储空间内。当 Implementation 迭代升级时,新版本的 Implementation 内的变量声明必须严格对齐于旧版本,仅允许在尾部添加新变量,不允许修改或删除旧变量(append-only)。

此文详细介绍了 delegatecall() 时,Proxy 和 Implementation 间变量对齐的注意事项和案例。 #blockchain #evm Solidity delegatecall usage and pitfalls | Notion
https://laisky.notion.site/Bitcoin-s-UTXO-Model-What-Is-It-and-How-to-Manage-UTXOs-River-d92673a0172841429ec5f998d49f101f?pvs=4

区块链的分布式账本有两个主流实现方式:账户模式(account model)和 UTXO model。

Ethereum 和传统金融(如银行)都采用账户模式,也就是在持久化的数据中,存储账户和余额。这样做的优点是更简单,但是要追踪每一笔钱的去向就变得比较困难。

BTC 采用的是 Unspent Transaction Outputs(UTXOs)模式,每个地址下记录的是尚未消费的入账记录(UTXO),每一个 UTXO 都包含一个金额和其源自的交易(Transaction ID)。每一个交易都由若干个 inputs 和 outputs 组成,其中 inputs 就是付款方支付的 UTXOs,outputs 就是收款方收到的 UTXOs。每一笔交易都会销毁输入的 UTXOs 同时诞生一些新的输出的 UTXOs。通过回溯交易历史,每个 UTXO 最终可以追溯到其由矿工挖出时产生的 coinbase 交易(coinbase transaction)。

综上所述,实际上每个人账户中的每一笔 BTC 都不是完全同质化的,它们可以通过 coinbase 交易 ID 和输出编号(output number)进行唯一识别。正是利用这一点,构建了 BRC-20/BRC-100/BRC-420 等 FT/NFT/铭文生态。

BTC 的每一笔交易的转账费用也通过其中所包含的 UTXO 数量来确定。因此,作为私人钱包管理者,应该尽量避免持有大量小额 UTXO。在网络转账费较低的时候,可以通过将小额 UTXO 批量转账给自己的方式,以较低成本将其融合成一个大额的 UTXO。如果一个 UTXO 的面额小于转账所需的费用,那么这个 UTXO 实际上已经失去了价值,被称为比特币尘埃(bitcoin dust)。 #blockchain Bitcoin’s UTXO Model: What Is It and How to Manage UTXOs | River | Notion
https://laisky.notion.site/Protocol-Specification-of-the-ao-Computer-9226ca385cd74a2c8716efb64704ac19?pvs=4

学习了 Arweave 生态的新项目 AO,我觉得这轮牛市大浪淘金能够看到给世界带来真正进步的技术,可能只有 ZK 和 AO。

L1 基于 Arweave,这是一种能够永久存储大量数据的区块链(区块纺)协议,具体细节这里不多说了。

AO 是基于 Arweave 的二层应用,在永久存储的基础上,构建起了一个消息的分发和处理机制。AO 负责消息的分发和存储,而不负责提供计算,它对计算节点只有一个要求:确定性。

所以这东西很像是微服务领域的 event-driven,每一个计算节点就相当于一个微服务业务节点,AO 网络会永久存储下所有的消息,而且每一个计算节点的消息都是有序的。所以每一个计算节点的任务,就是按照顺序处理完所有的消息,并且进行相应的输出,输出也是消息,也会被永久存储。

AO 的强大之处就在于,计算节点是分布式 + 并行的,每个人都可以运行自己的计算节点,每一个计算节点会有一个唯一的 process id,然后以这个 process id 为地址进行消息传输。这就为网络提供了近乎无限的并行计算能力。

从 Ethereum 的角度来说,它虽然也有无数个 EVM 在并行运行,但是最终能上链的数据实际上只来自一个 EVM,换句话说,你可以把整个 Ethereum 网络视为一个单线程的程序,这一特性为 EVM 提供了确定性和一致性,但恶果就是运算效率和吞吐极其低下。

AO 的每一个计算节点是并行计算的,而且计算节点是无状态的(计算任务是可以有状态的),并不需要存储,所以回避了分布式下的数据一致性问题。实际上计算机节点的任何时刻的状态,都可以用同一段代码和消息输入进行重现,所以计算节点根本不需要持久化存储任何中间数据。

可以期待,在 Arweave 大存储和 AO 大计算的加持下,AR 生态将会给区块链世界带来飞跃性的基础设施进步。 #blockchain

next: https://t.me/laiskynotes/249 Protocol Specification of the ao Computer. | Notion
https://taresky.com/crypto-arbitrage

虽然我不是从这篇文章入行的,但是 Taresky 这篇文章写得很好值得推荐。

自从开始套利后,感觉眼界都打开了。以前我对金融市场的理解是很肤浅的,只知道那些低买高卖,高风险高收益的交易者(traders),这些人是市场上的明星。我总是暗暗揣度自己,自认不能承受那么大的风险,也没那么聪明,这钱不是我能赚的。

但实际上金融市场上除了交易者外还有另外一帮人,称为套利者(Arbitrageurs)。交易者会用自己的本金持有商品,并且赌商品的价值会上涨;或者做空头,反正都是用自己的本金去赌商品价值的波动。但是套利者是完全另一个思路,套利者不能接受本金的损失,而只是把本金当着抵押品,去尽可能地赚取手续费或差价等一切蝇头小利。

拿文中所提到的做空对冲套利来说,其实逻辑很简单:

1. 你把自己的本金分成两半,一半做空,另一半购币
2. 如果币价上涨,你的做空合约亏本,但是购入的币价值上涨,本金不变
3. 如果币价下跌,你的做空合约赚钱,但是购入的币价值下跌,本金不变

只要币价的波动没有剧烈到让你的做空被爆仓,你的本金就是安全的,不亏不赚。你实际上赚取的,是期货交易中,做多方付给做空方的手续费,这个手续费会随着市场的交易热度动态调整,一般来说实现 10~40% 的年化收益是比较容易的。15% 的年化如果能持续五年,那就是翻一番,耐心,不要激动,做时间的朋友。

类似的套利逻辑还有很多,套利也不是没有风险的,比如交易所跑路、稳定币发行方跑路、剧烈波动导致爆仓等等,但是这个风险的概率远远小于交易者所承受的风险,比如你可以通过多交保证金以降低本金收益的方式减少爆仓风险,而长期收益可能会比大多数交易者都高。

此外,我感觉,币圈主流币的套利风险可能比传统金融更小。我认为 BTC 的存在是有客观需求的,而且 BTC 的币价在可预期的未来里是不会归零的,即使腰斩,只要耐心等待几年,总能等来下一波的牛市。而传统金融市场上的股票、期货、债券,有可能真的就原地破产,本金归零。而 shitcoins 也是真的可能随时归零的,所以我不会持有小币。

以上不构成投资建议,只是分享一些个人的感想。 #blockchain
https://laisky.notion.site/Solidity-layout-and-access-of-storage-state-variables-simply-explained-6fb8c4eaca0d4004b361e4358257fa92?pvs=4

详细介绍了 solidity storage 的存储结构。每一个 smart contract 都有独立的 storage,由 2^{256}-1 个 slots 组成,每个 slot 的长度为 32 bytes。

在 solidity 中声明的 variables 都会在 slot 中从头开始逐一存放,它们存储的位置称为 slot index。

比较奇葩的是 dynamic variables,如 array、mapping 和长度超过 32 bytes 的 string。拿 array 来说,其 slot 内存放的只是其长度,它的成员数据实际上是连续存放在另外一组随机的 slots 里的,这组 slots 的首地址由 keccak256(slot index) 计算而来。

理论上,dynamic variables 是有可能和其他的数据的 slot 发生冲突的,但是考虑到 2^256 是一个足够巨大的空间,一般认为超过 2^100 就足够满足密码学的碰撞安全性要求了,ECC-256 的安全等级也就是 2^128,如果你不担心自己的私钥被别人碰撞出来,那么也不需要担心 dynamic variables 和其他 slot 碰撞。

#blockchain #evm
next: https://t.me/laiskynotes/245 Solidity layout and access of storage state variables simply explained | Notion
https://laisky.notion.site/Solidity-c48cc6d6c9924dd5a912e19edaef756c?pvs=4 最近学习 solidity 的一些简单笔记,作为一个 Web2 开发者,主要是厘清很多基础概念,实际的代码是不难的。 #blockchain Solidity | Notion
 
 
Telegram Channel