-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.xml
403 lines (352 loc) · 63.9 KB
/
index.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
<?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>Qiao's Blog</title>
<link>https://qiaopengjun5162.github.io/</link>
<description>Recent content on Qiao's Blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<lastBuildDate>Sat, 06 Apr 2024 22:21:23 +0800</lastBuildDate><atom:link href="https://qiaopengjun5162.github.io/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>React 学习之 Hello World</title>
<link>https://qiaopengjun5162.github.io/posts/react_hello_world/</link>
<pubDate>Sat, 06 Apr 2024 22:21:23 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/react_hello_world/</guid>
<description>React 学习之 Hello World React 简介 React是一个用于构建用户界面的JavaScript库,由Facebook开发并维护。React通过声明式的方式来构建UI,使得代码更易于理解和测试。React的核心概念包括组件(Component)和虚拟DOM(Virtual DOM)。
组件:在React中,UI被构建为组件的集合。组件是封装了HTML、CSS和JavaScript代码的可重用单元。它们可以是函数或类,接受输入(称为“props”)并返回React元素树,这些元素树描述了用户界面在某一时刻的外观。
虚拟DOM:React使用虚拟DOM来提高性能。当组件的状态或属性发生变化时,React会创建一个新的虚拟DOM树,并将其与之前的树进行比较。然后,React计算出差异并仅将这些差异应用到实际的DOM中,从而实现高效的UI更新。
React的生态系统非常丰富,包括React Native(用于构建原生移动应用的框架)、Redux(用于管理应用状态的库)以及许多其他工具和库。这使得React成为构建复杂Web和移动应用的强大工具。
React的优点包括:
组件化:通过将UI拆分为独立的、可重用的组件,可以提高代码的可维护性和可测试性。 声明式:React使用声明式语法来描述UI,这使得代码更易于阅读和理解。 高效性能:虚拟DOM和React的更新策略使得应用能够高效地响应状态变化。 灵活性:React可以与多种其他库和工具配合使用,以满足不同项目的需求。 然而,React也有其局限性,例如学习曲线较陡峭,需要一定的JavaScript基础才能有效使用。此外,对于大型项目,可能需要额外的工具和库来管理状态和路由等复杂问题。
总之,React是一个强大的JavaScript库,适用于构建各种规模和复杂度的Web和移动应用。通过掌握React的核心概念和生态系统中的工具,开发者可以创建出高效、可维护且用户友好的界面。
React的核心概念是什么 React的核心概念主要包括以下几个方面:
组件(Components): React中构建用户界面的基本单位是组件。组件可以看作是一个独立的、可复用的代码块,它接受输入(通常是以“props”形式传递的数据)并返回React元素树,这些元素树描述了用户界面的一部分。 组件可以是函数组件或类组件。函数组件接受props并返回JSX元素;类组件则继承自React.Component类,具有更多的生命周期方法和状态管理功能。 JSX(JavaScript XML): JSX是React中用于描述用户界面的一种语法扩展。它允许我们在JavaScript代码中编写类似HTML的结构,并在编译时转换成React元素。JSX使得组件的代码更加直观和易于理解。 虚拟DOM(Virtual DOM): React使用虚拟DOM来提高应用的性能。当组件的状态或属性发生变化时,React会创建一个新的虚拟DOM树,并与之前的虚拟DOM树进行比较。通过比较这两个树,React能够计算出最小的DOM操作来更新实际的DOM,从而实现高效的UI更新。 状态(State)和属性(Props): 状态是组件内部的数据,它决定了组件的渲染输出。状态是私有的,并且只能通过组件内部的方法(如setState)来更新。 属性是父组件传递给子组件的数据。子组件通过props接收这些数据,并使用它们来渲染输出。属性是只读的,子组件不能修改它们。 生命周期方法(Lifecycle Methods): 类组件具有一系列的生命周期方法,这些方法在组件的不同阶段(如挂载、更新、卸载)被调用。生命周期方法允许开发者在组件的不同阶段执行特定的逻辑,如数据获取、副作用处理等。 钩子(Hooks): Hooks是React 16.8版本中引入的新特性,它们允许开发者在不编写类的情况下使用state以及其他的React特性。通过使用钩子,函数组件可以拥有与类组件相同的功能,同时保持代码的简洁和可维护性。 这些核心概念共同构成了React的基础,使得开发者能够高效地构建出复杂且响应式的用户界面。通过掌握这些概念,开发者可以充分利用React的优势来创建出高质量的Web应用。
React 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 &lt;!DOCTYPE html&gt; &lt;html lang=&#34;en&#34;&gt; &lt;head&gt; &lt;meta charset=&#34;UTF-8&#34;&gt; &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt; &lt;title&gt;Hello World&lt;/title&gt; &lt;!-- 引入React 的核心库 --&gt; &lt;script src=&#34;script/react.development.js&#34;&gt;&lt;/script&gt; &lt;!-- 引入React 的DOM库 --&gt; &lt;script src=&#34;script/react-dom.development.js&#34;&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;div id=&#34;root&#34;&gt;&lt;/div&gt; &lt;script&gt; /* https://unpkg.com/[email protected]/umd/react.development.js https://unpkg.com/[email protected]/umd/react-dom.development.js */ // React 就是用来代替DOM的 // // 通过DOM向页面中添加一个div // // 创建一个div // const div = document.</description>
</item>
<item>
<title>Substrate 区块链开发之本地网络启动</title>
<link>https://qiaopengjun5162.github.io/posts/substrate_study/</link>
<pubDate>Sun, 17 Mar 2024 10:38:21 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/substrate_study/</guid>
<description>Substrate 区块链开发之本地网络启动 What is Substrate? Substrate 是一个软件开发工具包 (SDK),它使用基于 Rust 的库和工具,使您能够从模块化和可扩展的组件构建特定于应用程序的区块链。使用 Substrate 构建的特定于应用程序的区块链可以作为独立服务运行,也可以与其他链并行运行,以利用 Polkadot 生态系统提供的共享安全性。Substrate 包含区块链基础设施核心组件的默认实现,让您能够专注于应用程序逻辑。
安装 https://docs.substrate.io/install/macos/ 本地网络启动实操 https://docs.substrate.io/tutorials/build-a-blockchain/build-local-blockchain/ https://github.com/substrate-developer-hub/substrate-node-template 克隆仓库 1 git clone [email protected]:substrate-developer-hub/substrate-node-template.git 切换目录 1 cd substrate-node-template 创建一个新分支 1 git switch -c my-learning-branch-2024-03-16 编译 1 cargo build --release 启动本地 Substrate 节点 1 ./target/release/node-template --dev --tmp 启动第一个区块链节点 alice 1 ./target/release/node-template --chain local --alice --tmp 启动第二个区块链节点 bob 1 ./target/release/node-template --chain local --bob --tmp 将链规范转换为原始格式 Convert the chain specification to raw format https://docs.substrate.io/tutorials/build-a-blockchain/add-trusted-nodes/ 1 ./target/release/node-template build-spec --chain=local --raw &gt; spec.json 读取spec.json文件的内容,搜索包含“boot”的行,并显示这些行以及它们前后各两行的内容 1 cat spec.json | grep boot -C 2 启动第二个区块链节点,此命令包含--bootnodes选项并指定单个引导节点,即由 启动的节点alice 1 ./target/release/node-template --chain local --bob --tmp --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWBGJ3YcEgqt2BjFmWDv2fkqWPkKrDreWiGyreA7z72UnW polkadot.js. 查看 https://polkadot.js.org/apps/#/explorer polkadot.js 查看出块信息 交易之前查询 交易 提交交易 交易之后 查询交易后的值 </description>
</item>
<item>
<title>Solana 开发学习之与Solana合约交互</title>
<link>https://qiaopengjun5162.github.io/posts/solana_study03/</link>
<pubDate>Thu, 22 Feb 2024 17:19:05 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/solana_study03/</guid>
<description>Solana 开发学习之与Solana合约交互 Solana的Web3.js 相关链接 https://github.com/web3/web3.js https://github.com/solana-labs/solana-web3.js https://solana-labs.github.io/solana-web3.js/ 安装 solana-web3.js 1 $ npm install --save @solana/web3.js 通过 WalletAdatper 与钱包交互 https://github.com/anza-xyz/wallet-adapter
https://bobbyhadz.com/blog/module-not-found-cant-resolve-crypto</description>
</item>
<item>
<title>Solana 开发学习之通过RPC与Solana交互</title>
<link>https://qiaopengjun5162.github.io/posts/solana_study02/</link>
<pubDate>Thu, 22 Feb 2024 12:42:01 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/solana_study02/</guid>
<description>Solana 开发学习之通过RPC与Solana交互 相关链接 https://solana.com/docs/rpc/http https://www.jsonrpc.org/specification https://www.json.org/json-en.html JSON-RPC 2.0 规范 JSON-RPC 是一种无状态、轻量级远程过程调用 (RPC) 协议。该规范主要定义了几种数据结构及其处理规则。它与传输无关,因为这些概念可以在同一进程中、通过套接字、通过 http 或在许多不同的消息传递环境中使用。它使用JSON ( RFC 4627 ) 作为数据格式。
接口RPC 节点相关接口 获取集群节点信息 通过getClusterNodes方法可以获得当前网络内,集群节点的相关信息,比如验证者的key,节点IP,节点版本等。
1 2 3 4 5 6 7 8 9 10 11 curl https://api.devnet.solana.com -X POST -H &#34;Content-Type: application/json&#34; -d &#39; { &#34;jsonrpc&#34;: &#34;2.0&#34;, &#34;id&#34;: 1, &#34;method&#34;: &#34;getClusterNodes&#34; } &#39; {&#34;jsonrpc&#34;:&#34;2.0&#34;,&#34;result&#34;:[{&#34;featureSet&#34;:3580551090,&#34;gossip&#34;:&#34;67.209.54.90:8001&#34;,&#34;pubkey&#34;:&#34;7pbH563fFai2Gm8aXGi27Toj1i7x55rGp7QQ8ZQt6C7i&#34;,&#34;pubsub&#34;:null,&#34;rpc&#34;:null,&#34;shredVersion&#34;:503,&#34;tpu&#34;:&#34;67.209.54.90:8004&#34;,&#34;tpuQuic&#34;:&#34;67.209.54.90:8010&#34;,&#34;version&#34;:&#34;1.17.21&#34;},{&#34;featureSet&#34;:3580551090,&#34;gossip&#34;:&#34;37.27.61.250:8000&#34;,&#34;pubkey&#34;:&#34;HPpYXZ944SXpJB3Tb7Zzy2K7YD45zGREsGqPtEP43xBx&#34;,&#34;pubsub&#34;:null,&#34;rpc&#34;:null,&#34;shredVersion&#34;:503,&#34;tpu&#34;:&#34;37.27.61.250:8003&#34;,&#34;tpuQuic&#34;:&#34;37.27.61.250:8009&#34;,&#34;version&#34;:&#34;1.17.22&#34;}, ...... {&#34;featureSet&#34;:3011420684,&#34;gossip&#34;:&#34;69.197.5.60:8001&#34;,&#34;pubkey&#34;:&#34;FKizb2faoz57ym1bTWcZhei3aUZu7eU5AiY1EYoZsok6&#34;,&#34;pubsub&#34;:null,&#34;rpc&#34;:null,&#34;shredVersion&#34;:503,&#34;tpu&#34;:null,&#34;tpuQuic&#34;:null,&#34;version&#34;:&#34;1.17.5&#34;}],&#34;id&#34;:1} 区块相关接口 获取当前区块高度 通过getBlockHeight可以获取当前的区块高度
https://solana.com/docs/rpc/http/getblockheight 1 2 3 4 5 6 7 curl https://api.devnet.solana.com -X POST -H &#34;Content-Type: application/json&#34; -d &#39; { &#34;jsonrpc&#34;:&#34;2.0&#34;,&#34;id&#34;:1, &#34;method&#34;:&#34;getBlockHeight&#34; } &#39; {&#34;jsonrpc&#34;:&#34;2.0&#34;,&#34;result&#34;:268621259,&#34;id&#34;:1} 获取最近的Block Hash https://solana.com/docs/rpc/http/getlatestblockhash 1 2 3 4 5 6 7 8 9 10 11 12 13 curl https://api.devnet.solana.com -X POST -H &#34;Content-Type: application/json&#34; -d &#39; { &#34;id&#34;:1, &#34;jsonrpc&#34;:&#34;2.0&#34;, &#34;method&#34;:&#34;getLatestBlockhash&#34;, &#34;params&#34;:[ { &#34;commitment&#34;:&#34;processed&#34; } ] } &#39; {&#34;jsonrpc&#34;:&#34;2.0&#34;,&#34;result&#34;:{&#34;context&#34;:{&#34;apiVersion&#34;:&#34;1.17.21&#34;,&#34;slot&#34;:280325472},&#34;value&#34;:{&#34;blockhash&#34;:&#34;9ebRPaCY2pcKAPhWzjDtmLArbSzAH1Mb5n8PZzXKbW8X&#34;,&#34;lastValidBlockHeight&#34;:268622097}},&#34;id&#34;:1} 获取指定高度block的信息 https://solana.com/docs/rpc/http/getblock 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 curl https://api.devnet.solana.com -X POST -H &#34;Content-Type: application/json&#34; -d &#39; { &#34;jsonrpc&#34;: &#34;2.</description>
</item>
<item>
<title>Solana 开发学习之Solana 基础知识</title>
<link>https://qiaopengjun5162.github.io/posts/solana_study/</link>
<pubDate>Tue, 20 Feb 2024 14:28:01 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/solana_study/</guid>
<description>Solana 开发学习之Solana 基础知识 Install the Solana CLI 相关链接 https://docs.solanalabs.com/cli/install https://solanacookbook.com/zh/getting-started/installation.html#%E5%AE%89%E8%A3%85%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7 https://www.solanazh.com/course/1-4 https://solana.com/zh/developers/guides/getstarted/setup-local-development 实操 安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 sh -c &#34;$(curl -sSfL https://release.solana.com/v1.18.2/install)&#34; downloading v1.18.2 installer ✨ 1.18.2 initialized Adding export PATH=&#34;/Users/qiaopengjun/.local/share/solana/install/active_release/bin:$PATH&#34; to /Users/qiaopengjun/.profile Adding export PATH=&#34;/Users/qiaopengjun/.local/share/solana/install/active_release/bin:$PATH&#34; to /Users/qiaopengjun/.zprofile Adding export PATH=&#34;/Users/qiaopengjun/.local/share/solana/install/active_release/bin:$PATH&#34; to /Users/qiaopengjun/.bash_profile Close and reopen your terminal to apply the PATH changes or run the following in your existing shell: export PATH=&#34;/Users/qiaopengjun/.local/share/solana/install/active_release/bin:$PATH&#34; 配置环境变量 1 2 3 4 vim .zshrc # 复制并粘贴下面命令以更新 PATH export PATH=&#34;/Users/qiaopengjun/.local/share/solana/install/active_release/bin:$PATH&#34; 通过运行以下命令确认您已安装了所需的 Solana 版本: 1 2 3 4 5 solana --version # 实操 solana --version solana-cli 1.18.2 (src:13656e30; feat:3352961542, client:SolanaLabs) 切换版本 1 solana-install init 1.16.4 设置网络环境 官方RPC地址分别是:
DevNet: https://api.devnet.solana.com TestNet: https://api.testnet.solana.com MainNet: https://api.mainnet-beta.solana.com 相关链接 https://solana.com/zh/rpc 实操 1 2 3 4 5 6 7 solana config set --url https://api.devnet.solana.com Config File: /Users/qiaopengjun/.config/solana/cli/config.yml RPC URL: https://api.devnet.solana.com WebSocket URL: wss://api.</description>
</item>
<item>
<title>Rust学习之Diesel setup报错解决</title>
<link>https://qiaopengjun5162.github.io/posts/rust_diesel/</link>
<pubDate>Sun, 28 Jan 2024 17:02:08 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/rust_diesel/</guid>
<description>Diesel setup报错解决 Diesel 是一个安全、可扩展的Rust ORM 和查询生成器。 Diesel 是 Rust 中与数据库交互最高效的方式,因为它对查询进行了安全且可组合的抽象。
1. 报错信息 1 2 3 4 5 6 diesel_demo on master [?] via 🦀 1.75.0 via 🅒 base ➜ diesel setup Creating migrations directory at: /Users/qiaopengjun/Code/rust/diesel_demo/migrations Creating database: postgres could not translate host name &#34;db&#34; to address: nodename nor servname provided, or not known 2. 解决方案 检查数据库是否正常运行 检查数据库连接配置是否正确 检查数据库用户名和密码是否正确 1 2 sudo vim /etc/hosts 127.0.0.1 db 3. 参考文档 https://diesel.rs/ https://github.com/diesel-rs/diesel </description>
</item>
<item>
<title>Rust 所有权和 Move 语义</title>
<link>https://qiaopengjun5162.github.io/posts/rust_owner/</link>
<pubDate>Sat, 20 Jan 2024 14:28:09 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/rust_owner/</guid>
<description>Rust 所有权和 Move 语义 所有权和生命周期是 Rust 和其它编程语言的主要区别,也是 Rust 其它知识点的基础。
动态数组因为大小在编译期无法确定,所以放在堆上,并且在栈上有一个包含了长度和容量的胖指针指向堆上的内存。
恰到好处的限制,反而会释放无穷的创意和生产力。
Rust 所有权规则 一个值只能被一个变量所拥有,这个变量被称为所有者。 一个值同一时刻只能有一个所有者,也就是说不能有两个变量拥有相同的值。所以对应变量赋值、参数传递、函数返回等行为,旧的所有者会把值的所有权转移给新的所有者,以便保证单一所有者的约束。 当所有者离开作用域,其拥有的值被丢弃,内存得到释放。 这三条规则很好理解,核心就是保证单一所有权。其中第二条规则讲的所有权转移是 Move 语义,Rust 从 C++ 那里学习和借鉴了这个概念。
第三条规则中的作用域(scope)指一个代码块(block),在 Rust 中,一对花括号括起来的代码区就是一个作用域。举个例子,如果一个变量被定义在 if {} 内,那么 if 语句结束,这个变量的作用域就结束了,其值会被丢弃;同样的,函数里定义的变量,在离开函数时会被丢弃。
所有权规则,解决了谁真正拥有数据的生杀大权问题,让堆上数据的多重引用不复存在,这是它最大的优势。 但是,它也有一个缺点,就是每次赋值、参数传递、函数返回等行为,都会导致旧的所有者把值的所有权转移给新的所有者,这会导致一些性能上的问题。
Rust 提供了两种解决方案:
如果你不希望值的所有权被转移,在 Move 语义外,Rust 提供了 Copy 语义。如果一个数据结构实现了 Copy trait,那么它就会使用 Copy 语义。这样,在你赋值或者传参时,值会自动按位拷贝(浅拷贝)。 如果你不希望值的所有权被转移,又无法使用 Copy 语义,那你可以“借用”数据。 Rust 生命周期 生命周期(lifetime)是 Rust 中的一个概念,它描述了一个引用(reference)的生命周期。
在 Rust 中,生命周期可以用来解决引用(reference)的悬垂(dangling)问题。
Rust 中的引用 在 Rust 中,引用(reference)是一个特殊的指针,它指向一个特定的数据,并且可以被用来访问该数据。
Rust 中的引用(reference)分为两种:
不可变引用(immutable reference):不可变引用是指指向不可变数据的引用,即不能修改被引用的数据。 可变引用(mutable reference):可变引用是指指向可变数据的引用,即可以修改被引用的数据。 Rust 中的引用(reference)是借用(borrow)的语法糖,它使得 Rust 中的数据更加安全。 Rust 中的生命周期 在 Rust 中,生命周期(lifetime)是引用(reference)的一个属性,它描述了一个引用(reference)的生命周期。
Rust 中的生命周期(lifetime)分为两种:
静态生命周期(&lsquo;static):静态生命周期是指引用(reference)的生命周期直到程序结束。 动态生命周期(&lsquo;a):动态生命周期是指引用(reference)的生命周期由其作用域(scope)决定。 Rust 中的借用检查器 在 Rust 中,借用检查器(borrow checker)是一个工具,它用于检查引用(reference)的合法性。
在 Rust 中,借用检查器会检查引用的生命周期,以确保引用的有效性。如果引用的生命周期不合法,那么编译器会给出错误提示。
Rust 中的所有权和借用规则 在 Rust 中,所有权和借用规则是 borrow checker 的基础。
Rust 的所有权规则规定,每个值都有一个所有者(owner),并且每个值只能有一个所有者。当所有者离开作用域时,该值将被丢弃。
Rust 的借用规则规定,当一个值被借出时,不能被再次借出。
Rust 中的生命周期规则 在 Rust 中,生命周期规则规定,当一个值被借出时,其生命周期必须大于等于所有者的生命周期。
如果一个值的生命周期小于所有者的生命周期,那么编译器会给出错误提示。
Rust 中的生命周期省略规则 在 Rust 中,生命周期省略规则规定,当一个值被借出时,其生命周期可以被省略。
如果编译器能够根据上下文推断出该值的生命周期,那么编译器会自动将其生命周期省略。
Rust 中的生命周期标注规则 在 Rust 中,生命周期标注规则规定,当一个值被借出时,其生命周期必须被标注。
如果编译器无法推断出该值的生命周期,那么编译器会给出错误提示。</description>
</item>
<item>
<title>Dojoup 安装问题解决</title>
<link>https://qiaopengjun5162.github.io/posts/dojo/</link>
<pubDate>Thu, 18 Jan 2024 18:24:19 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/dojo/</guid>
<description>Dojoup 安装问题解决 Install Dojoup https://book.dojoengine.org/getting-started/quick-start.html 1 curl -L https://install.dojoengine.org | bash 安装失败 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 dojoup ═════════════════════════════════════════════════════════════════════════ ██████╗ ██████╗ ██╗ ██████╗ ██╔══██╗██╔═══██╗ ██║██╔═══██╗ ██║ ██║██║ ██║ ██║██║ ██║ ██║ ██║██║ ██║██ ██║██║ ██║ ██████╔╝╚██████╔╝╚█████╔╝╚██████╔╝ ╚═════╝ ╚═════╝ ╚════╝ ╚═════╝ Repo : https://github.com/dojoengine/dojo Book : https://book.dojoengine.org/ Chat : https://discord.gg/dojoengine https://t.me/dojoengine ═════════════════════════════════════════════════════════════════════════ dojoup: installing dojo (version , tag ) https://github.com/dojoengine/dojo/releases/download//dojo__darwin_arm64.tar.gz dojoup: downloading latest dojo ########################################################################################################################################################## 100.0% tar: Error opening archive: Unrecognized archive format dojoup: command failed: tar -xzC /Users/qiaopengjun/.</description>
</item>
<item>
<title>Starknet开发实战</title>
<link>https://qiaopengjun5162.github.io/posts/starknet/</link>
<pubDate>Wed, 10 Jan 2024 12:06:44 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/starknet/</guid>
<description>Starknet开发实战 以太坊网络架构 以太坊有共识、数据可用性、结算、执行四个模块。
共识层
共识层指的是节点就区块链上哪些数据可以被验证为真实和准确达成协议的机制。 共识协议决定了交易如何排序,以及新区块如何被添加到链上。 执行层
执行层是区块链上的节点如何处理交易,以在不同状态之间过渡区块链。 参与共识的节点必须使用他们的区块链副本执行交易,以便在验证区块之前进行证明。 数据可用性
区块提议者发布区块的所有交易数据并且交易数据可供其他网络参与者使用的保证。 简单来讲,数据可用性是一个通信标准,以保证某个节点的数据可被另一个节点所接收并验证为正确,从而保证安全。 区块链执行的规则要求交易数据的可用性。这意味着区块生产者必须为每个区块发布数据,供网络对等者下载和存储;这些数据必须应要求提供。 结算层
区块链提供了 &ldquo;最终性&rdquo;&ndash;保证已经提交到链的历史的交易是不可逆的(或 &ldquo;不可改变的&rdquo;)。 要做到这一点,区块链必须确信交易的有效性。因此,结算功能需要链来验证交易,验证证明,并仲裁争端。 安装 https://foundry-rs.github.io/starknet-foundry/getting-started/installation.html https://book.cairo-lang.org/ch01-01-installation.html 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 curl -L https://raw.githubusercontent.com/foundry-rs/starknet-foundry/master/scripts/install.sh | sh % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1616 100 1616 0 0 691 0 0:00:02 0:00:02 --:--:-- 691 Installing snfoundryup... ######################################################################## 100.0% Detected your preferred shell is zsh and added snfoundryup to PATH. Run &#39;source /Users/qiaopengjun/.zshenv&#39; or start a new terminal session to use snfoundryup. Then, simply run &#39;snfoundryup&#39; to install Starknet-Foundry. ~ via 🅒 base took 3.3s ➜ snfoundryup starknet-foundry-install: retrieving latest version from https://github.com/foundry-rs/starknet-foundry... starknet-foundry-install: downloading starknet-foundry-v0.</description>
</item>
<item>
<title>计算机网络原理之计算机网络概述</title>
<link>https://qiaopengjun5162.github.io/posts/computer_network_code/</link>
<pubDate>Sat, 09 Dec 2023 18:29:45 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/computer_network_code/</guid>
<description>计算机网络原理之计算机网络概述 一、计算机网络基本概念 计算机网络的定义 计算机网络(Computer Network)是若干结点(Host)通过通信设备连接起来的计算机系统,这些计算机通过通信设备进行信息交换。 从技术范畴来看,计算机网络是计算机技术与通信技术相互融合的产物。 计算机网络是互连的、自治的计算机的集合,这些计算机通过通信设备进行信息交换。 ISP 网络由许多有线或无线通信链路互连分组交换设置构成。 分组交换设备可以实现数据分组的接收与转发,是构成 Internet 的重要基础,存在多种形式,最典型的是路由器和交换机。 协议的定义 协议(Protocol)是计算机网络中,计算机之间通信必须遵守的规则,这些规则将数据划分为具有特定含义的组件,并通过这些组件在计算机之间传递数据。 协议是计算机网络中,计算机之间进行通信时所必须遵守的规则的集合。 协议三要素 语法:语法是用来规定语言的规则,计算机网络协议的语法就是对数据包中数据的组织格式进行定义。 语义:语义是用来规定语言的含意,计算机网络协议的语义是对数据包中数据的含意进行定义。 同步:同步就是对发送和接收双方的数据发送和接收速率进行协调。 计算机网络的功能 硬件资源共享 软件资源共享 信息资源共享 计算机网络的分类 按覆盖范围分类 广域网 WAN(Wide Area Network):覆盖范围很广的计算机网络,通常跨接很大的地理距离,所覆盖的范围从几十公里到几千公里,甚至全球。 城域网 MAN(Metropolitan Area Network):覆盖范围较小的计算机网络,通常覆盖一个城市,也可以覆盖一个城市里的几个区 局域网 LAN(Local Area Network):覆盖范围较小的计算机网络,通常覆盖一个校园,一个公司,或者一个单位。 个人区域网 PAN(Personal Area Network):覆盖范围极小的计算机网络,通常覆盖一个家庭,一个宿舍或一个办公室。 按拓扑结构分类 总线型拓扑结构 环型拓扑结构 星型拓扑结构 网状拓扑结构 树形拓扑结构 混合拓扑结构 按交换方式分类 电路交换(Circuit Switching):在通信开始前,通信双方需要先建立一个通信电路,然后通信双方通过这个电路进行通信。通信的结束也通过释放这个通信电路来结束。 报文交换(Message Switching):报文交换的交换节点即交换机,交换机中存储着大量报文,报文交换机根据报文中的地址信息将报文转发到下一个交换机。报文交换的交换节点即交换机,交换机中存储着大量报文,报文交换机根据报文中的地址信息将报文转发到下一个交换机。 分组交换(Packet Switching):分组交换的交换节点即交换机,交换机中存储着大量分组,分组交换机根据分组中的地址信息将分组转发到下一个交换机。 按传输介质分类 无线传输介质 有线传输介质 按网络模型分类 OSI 七层模型 TCP/IP 四层模型 客户-服务器模型 按网络用户属性分类 公用网 私有网 二、计算机网络结构 网络边缘 终端系统(End System):终端系统也称为用户终端(User Equipment),直接连到网络的计算机,是网络边缘设备,是计算机用户访问网络的入口。 边缘路由器(Edge Router):边缘路由器也称为网络接入设备(Network Access Device),是网络边缘设备,是终端系统接入互联网的网关,是网络边缘的入口。 接入网络 常见的接入网络包括以下几类:
电话拨号接入 非对称数字用户线路 ADSL 混合光纤同轴电缆 HFC 接入网络 局域网 移动接入网络 网络核心 三、数据交换技术 数据交换的概念 电路交换 建立电路 传输数据 拆除电路 报文交换 报文交换机 报文 存储转发 分组交换 分组交换的基本原理 分组交换的优点 交换设备存储容量要求低 交换速度快 可靠传输效率高 更加公平 分组长度的确定 分组长度与延迟时间 分组长度与误码率 四、计算机网络性能 速率与带宽 时延 结点处理时延 排队时延 传输时延 传播时延 时延带宽积 丢包率 吞吐量 五、计算机网络体系结构 计算机网络分层体系结构 OSI 参考模型 TCP/IP 参考模型 五层参考模型 计算机网络与因特网发展简史 </description>
</item>
<item>
<title>Python 中 import 的使用说明</title>
<link>https://qiaopengjun5162.github.io/posts/code_import/</link>
<pubDate>Sat, 09 Dec 2023 18:16:48 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/code_import/</guid>
<description>Python 中 import 的使用说明 1. 导入模块 1.1 导入模块 1 import module1, module2 1.2 导入模块时给模块指定别名 1 2 import module1 as m1 import module2 as m2 1.3 导入模块时给模块指定别名,并指定模块的路径 1 2 3 4 import module1 as m1 import module2 as m2 from module1 import func1 from module2 import func2 2. import的格式说明 Python官方给出的建议是这样的,把import分为三个类型:
官方标准库,比如sys, os 第三方库,比如numpy 本地库
每一组import都要用空格区分开。
在每一组import内,每个import只import一个库,不要出现 import os, sys 这样的用法。如果用from,可以import多个内容,比如 from subprocess import Popen, PIPE 。尽量避免使用 from XX import * ,以防命名冲突。
在每一组import内,先写import完整库的,再写使用from的。每一类再按照字典序排序。
3. 导入模块的顺序 Python的import语句是可以在程序中多次使用的,所以,如果导入的模块过多,那么导入顺序就显得尤为重要。
3.1 导入顺序 标准库 第三方库 本地库 3.2 导入顺序示例 1 2 3 4 5 6 7 8 9 10 11 12 import os import sys import time import datetime import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import xlrd import xlwt import xlsxwriter import openpyxl </description>
</item>
<item>
<title>如果我们要打印一个class的signature(比如使用help命令的时候),我们是应该优先__new__,还是__init__?</title>
<link>https://qiaopengjun5162.github.io/posts/code_init_new/</link>
<pubDate>Sat, 09 Dec 2023 18:08:19 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/code_init_new/</guid>
<description><h1 id="如果我们要打印一个class的signature比如使用help命令的时候我们是应该优先__new__还是__init__">如果我们要打印一个class的signature(比如使用help命令的时候),我们是应该优先__new__,还是__init__?</h1>
<p>如果这个class同时自定义了__new__和__init__,按照现在的实现,是先打印__new__的。</p>
<p>任何一个类,如果同时定义了__new__和__init__,只有__new__在instantiate的时候是一定会被运行的,因为__new__可以返回一个其他类型(衍生类甚至是完全无关的类型)的object,导致这个类的__init__压根没有被调用。也就是说,__new__是比__init__更稳定的signature。</p></description>
</item>
<item>
<title>Python中自带的 assert 的使用</title>
<link>https://qiaopengjun5162.github.io/posts/code_assert/</link>
<pubDate>Sat, 09 Dec 2023 17:57:50 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/code_assert/</guid>
<description>Python中自带的 assert 的使用 1. 概述 assert 语句用于判断一个表达式,在表达式条件为 false 的时候触发异常。
2. 语法 assert expression [, arguments]
3. 实例 1 2 # 判断一个变量是否为空 assert a is not None 4. 注意事项 assert 语句只在调试模式开启时起作用,在发布模式时,assert 语句将被忽略。
5. 断言的用法 5.1 断言表达式为真 1 assert 1 == 1 5.2 断言表达式为假 1 assert 1 == 2 5.3 断言表达式为假,并抛出异常 1 assert 1 == 2, &#34;1 is not equal to 2&#34; 5.4 断言表达式为假,并抛出异常,并附加额外的参数 1 assert 1 == 2, &#34;1 is not equal to 2&#34;, 100 5.5 断言表达式为假,并抛出异常,并附加额外的参数,并附加额外的参数 1 assert 1 == 2, &#34;1 is not equal to 2&#34;, 100, 200 6. 断言的执行 assert 语句只在调试模式开启时起作用,在发布模式时,assert 语句将被忽略。
7. 断言的执行过程 断言的执行过程如下:
执行 assert 语句 如果断言失败,则触发 AssertionError 异常 异常被触发时,assert 语句后面的语句将不会执行 8. 断言的使用说明 首先,在python中,assert expression 在不开-O(即使用debug mode)的情况下,等价于if not expression: raise AssertionError 。python里的assert就是raise了一个exception而已。但是我们看待assert的时候,要从语言的层面去理解,背后的实现反而没那么重要。
assert的语义其实是非常清晰的——这个事情它压根不该发生。你永远不应该用assert处理任何错误,如果你能想到一个当前情况下assert不成立的可能性,你这里就不应该写这个assert。你不应该依赖assert的任何behavior,任何assert不成立的时候,你就应该接受你的程序可能发生任何事情。事实上,在使用-O(production mode)的时候,所有的assert都会被变成noop,也就是没有任何行为。
那为什么要写assert?当然还是有原因的。
第一,当你在对程序进行开发的时候,可以更快地发现一些程序的错误。比如你这个函数是个内部函数,只有自己的代码调用,你觉得传进来的都应该是int,你不需要对传入数据进行类型判断,这里可以加一个assert isinstance(arg, int) ,万一你在开发的时候出了一些比较蠢的错误,可以及时发现。这个用法其实大家相对熟悉一些,有的人在开发的时候会用这个方式调试。
第二,是一个被很多人忽略的点——assert是有注释含义的。它可以提醒后来的开发者(和一周后的你自己),这个地方我确认某个事情是成立的,你不需要去思考其他的可能性。这样的assert在开发时起到一个测试的作用,而在开发后维护的时候起到一个注释的作用。在assert起注释作用的时候,它的可信度是更高的。我相信大家都会有读代码的时候看到一段注释,不知道该不该信的时候(可能时间久远了)。但是如果是assert,说服力明显就更强。
最后再次强调一下,不要把assert当成一个正常的exception来用!不要去catch AssertionError!尽管在Python实现的层面上它就是一个exception,但是大家一定要习惯把语义和实现区分开这个事情,因为你写的代码在被别人阅读的时候是有隐含意的。</description>
</item>
<item>
<title>开发中 PR 注意事项</title>
<link>https://qiaopengjun5162.github.io/posts/code_pr/</link>
<pubDate>Sat, 09 Dec 2023 17:52:06 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/code_pr/</guid>
<description>开发中 PR 注意事项 提交PR 在提交PR的时候,需要先在本地创建一个分支,然后在这个分支上开发,开发完成后,再将这个分支合并到主分支
代码规范 大家提交PR的时候,要注意一下代码规范,不要提交一些不符合规范的代码,比如空格、换行。 在拉PR的时候要注意一下,不要去轻易地动和你的PR无关的代码,什么随手改一个空格或者括号的位置啥的,这是非常不可取的。把自己的代码保持和源代码的style一致,只去专心做feature,额外的空行都不要多加。养成好习惯!</description>
</item>
<item>
<title>测试的几个基本原则</title>
<link>https://qiaopengjun5162.github.io/posts/code_test/</link>
<pubDate>Sat, 09 Dec 2023 17:43:50 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/code_test/</guid>
<description>写测试的一些基本原则 测试的核心只有一个——确认你的代码运行结果和期待结果是一致的。
因此,当你写测试的时候,你脑子里只需要考虑两个事情
我如何得到这段代码的运行结果 我这段代码的期待结果是什么? 根据得到运行结果方式的不同,我们有很多的测试分类,比如黑盒或者白盒。不需要去对这些分类死记硬背,你脑海中其实只需要想我怎么拿到结果。 比如在Python中,你可以通过直接调用你写的函数求值。如果用这种方法,你就会发现,你写的代码好坏,很大程度上影响了你测试的难易。side effect越小的代码,越好测试。比如一个函数,它一个输入永远对应一个输出,这代码就非常好测试。这个函数是个method,它依赖instance的一些属性,就难测一些,需要建立一个instance。它依赖一些全局变量,更难测了。依赖远端的数据库之类的,那就难测炸了。一段代码,依赖的东西越多越复杂,测试就越困难。所以很多人会发现,只有自己开始写测试了,才能意识到自己的代码写的有什么毛病。
除了直接调用,也可以通过subprocess去开一个新的进程。有时候这是必须的,比如viztracer这种命令行工具,你是不能通过完全的直接调用去做测试的。那这里你就需要对怎么开一个新进程做一个了解,或许还需要自己整理一个小小的framework来测试你的工具。
得到了实际运行结果之后,就要和期待结果进行比对。你的程序一定得有个期待结果才能去测试,不然你光跑一下程序是几乎没有意义的(倒是能确认不报错)。
在设计期待结果的时候,要注意一下这个结果是不是稳定的。比如我去读我的stdout打印某一串字符串——那它未来的输出是不是可能变?我在写pdb的代码的时候,经常会涉及测试中显示代码在文件中行数的问题,这就是一个很重要的考量。你把测试写死了,后面就总得调整,改一下代码就得改测试,你的测试就失去了价值。
既然聊到了测试的价值,我们就说一下——为什么要写测试? 测试当然是确认此时此刻,你的程序是正常工作的。但是它更大的意义在于——增强了未来你对程序做修改的时候你对程序还工作的信心。
在你刚开始开发某个功能的时候,可能手动做了非常多的测试,一步一步地把它弄得正常工作。这时候你可能觉得我为什么要写那些我已经做过的测试?浪费时间啊。但这些自动化测试的意义在于,在未来你改动代码的时候,随时保证你之前的那些功能还正常工作。因为你不会在未来修改代码的时候再这么详细地测试你之前开发的功能了。
如果你的代码缺少测试,你会很快陷入一个开发瓶颈——完全不敢重构和做大型的修改,只敢做新功能。因为根本不知道改之后我这东西还工作不工作。随着你项目复杂度的增加,各个模块之间耦合度变大,任何一个部分的修改都可能影响到很多内容,你就没法接着写了,然后项目就烂尾了。
所以,如果你想做一个相对长期稳定维护的项目,测试是不可少的。具体的测试上的技术细节,其实并没有那么重要。就像我前面说的,无非就是想办法运行你的代码,再和期待值做比较。测试的代码经常没那么“漂亮”,甚至有不少冗余,这都完全是可被接受的。甚至很多时候,要适度减少测试代码中的抽象,以保证每个单独的测试的完整性(读测试代码的时候不用几个函数之间来回切)。</description>
</item>
<item>
<title>量化学习之 jupyter notebook 环境配置</title>
<link>https://qiaopengjun5162.github.io/posts/jupyter_notebook/</link>
<pubDate>Sat, 09 Dec 2023 11:05:59 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/jupyter_notebook/</guid>
<description>量化学习之 jupyter notebook 环境配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 # 安装 anaconda conda create -n jupyter python=3.8 conda activate jupyter # 安装 jupyter notebook pip install jupyter # 安装 jupyter lab pip install jupyterlab # 安装 jupyter lab extensions jupyter labextension install @jupyterlab/toc jupyter labextension install @jupyterlab/git jupyter labextension install @jupyter-widgets/jupyterlab-manager jupyter labextension install @jupyterlab/plotly-extension jupyter labextension install @jupyterlab/celltags jupyter labextension install @jupyterlab/toc jupyter labextension install @jupyterlab/launcher jupyter labextension install @jupyterlab/shortcuts jupyter labextension install @jupyterlab/debugger jupyter labextension install @jupyterlab/running jupyter labextension install @jupyterlab/vega5-extension jupyter labextension install @jupyterlab/hub-extension jupyter labextension install @jupyterlab/vdom jupyter labextension install @jupyterlab/theme-dark-extension jupyter labextension install @jupyterlab/theme-light-extension jupyter labextension install @jupyterlab/virtual-gl jupyter labextension install @jupyterlab/fasta-extension jupyter labextension install @jupyterlab/geojson-extension jupyter labextension install @jupyterlab/mathjax3-extension jupyter labextension install @jupyterlab/vega5-extension jupyter labextension install @jupyterlab/toc jupyter labextension install @jupyterlab/celltags jupyter labextension install @jupyterlab/plotly-extension jupyter labextension install @jupyterlab/celltags # 安装 jupyter notebook conda install jupyter notebook # 创建虚拟环境 conda create -n quantify_python_3_12 python=3.</description>
</item>
<item>
<title>零知识证明 PLONK</title>
<link>https://qiaopengjun5162.github.io/posts/plonk/</link>
<pubDate>Tue, 17 Oct 2023 01:07:08 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/plonk/</guid>
<description>零知识证明 PLONK https://eprint.iacr.org/2019/953.pdf
PLONK 背景 FFT(Fast Fourier transform): 将一个用系数表示的多项式转换成它的点值表示的算法,O(n log n)
作用在有限域上,多项式相乘(也叫求卷积)
IFFT(Inverse Fast Fourier transform): 将一个用点值表示的多项式转换成它的系数表示的算法
n 次单位元的性质
Polynomial 承诺(Kate): 结论:
任意程序可转化为电路(Circuit) 电路可转化成多项式表示 多项式可承诺并证明 P 向 V 证明拥有多项式(or 函数) f(x):
f(s) = z =&gt; f(s) -z = 0 =&gt; f&rsquo;(x) = f(x) - z root x = s =&gt; f&rsquo;(x) = (x-s)*h(x)
z 可作为多项式承诺(Schwartz-zippel lemma d &laquo; P)
PLONK-Circuit 加法门 乘法门 布尔门
检查满足电路的关系
PLONK-Lagrange 从几何上看,n 次插值多项式 Pn(x),是一条n 次代数曲线,它通过曲线 y = f(x) 上的 n + 1 个点
y = f(x)
y = Pn(x)
PLonk 优势 整个方案只设置一个单独的可信设置 多方可参与的可信设置 用多项式承诺代替原先的零知识验证步骤 PLONK-Prove Set up SRS (Structure Reference String) Build Circuit (Selector) Preprocess Build Proof PLONK-Verify Set up SRS (Structure Reference String) Validate proof range (Selector) Compute opening evaluation ECC Pairing check Polymoial equation 更多请查看:https://www.youtube.com/watch?v=ypilwXBXATM
门约束
算术化是指把计算转换成数学对象,然后进行零知识证明。 Plonkish 算术化是 Plonk 证明系统特有的算术化方法,在 Plonkish 出现之前,主流的电路表达形式为 R1CS,被 Pinocchio,Groth16,Bulletproofs 等广泛采用。
一个算术电路包含若干个乘法门与加法门。每一个门都有「两个输入」引脚和一个「输出」引脚,任何一个输出引脚可以被接驳到多个门的输入引脚上。
所有的加法门都会被展开成多个变量的相加(或线性组合)。
并不是任何一个电路都存在赋值向量。凡是存在合法的赋值向量的电路,被称为可被满足的电路。判断一个电路是否可被满足,是一个 NP-Complete 问题,也是一个 NP 困难问题。
请注意,通常「赋值向量」中需要一个固定赋值为 1 的变量,这是为了处理加法门中的常量输入。</description>
</item>
<item>
<title>零知识证明学习笔记</title>
<link>https://qiaopengjun5162.github.io/posts/zkp/</link>
<pubDate>Sun, 15 Oct 2023 18:19:53 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/zkp/</guid>
<description>零知识证明学习笔记 零知识和证明 零知识证明是构建信任的重要技术,也是区块链这个有机体中不可缺少的一环。
零知识证明是打通链上数据与链下计算的关键技术,也是实现链上数据隐私保护的重要途径。
古希腊:「证明」 == 「洞见」 二十世纪初:「证明」 == 「符号推理」 六十年代:「证明」 == 「程序」 八十年代:「证明」 == 「交互」 交互式证明系统的概念:通过构造两个图灵机进行「交互」而不是「推理」,来证明一个命题在概率上是否成立。
交互证明的表现形式是两个(或者多个图灵机)的「对话脚本」,或者称为 Transcript。而这个对话过程,其中有一个显式的「证明者」角色,还有一个显式的「验证者」。其中证明者向验证者证明一个命题成立,同时还「不泄露其他任何知识」。这种就被称为「零知识证明」。
证明凝结了「知识」,但是证明过程确可以不泄露「知识」,同时这个证明验证过程仍然保持了简单、机械,并且有限性。
零知识证明技术可以解决数据的信任问题,计算的信任问题!
零知识证明技术可以「模拟」出一个第三方,来保证某一个论断是可信的
零知识证明的用处:
数据的隐私保护 计算压缩与区块链扩容 端到端的通讯加密 身份认证 去中心化存储 信用记录 构造完全公平的线上数字化商品的交易协议 更多的例子,可以是任何形式的数据共享,数据处理与数据传输。 举例:地图三染色问题 信息 vs. 知识 信息 「Information」 知识 「Knowledge」 「知识」是与「计算难度」相关,而「信息」则不是 「知识」是与公共所知的东西有关,而「信息」主要与部分公开的东西有关 可验证计算与电路可满足性问题 我们平时跑的(没有死循环)代码,都可以用算术电路来表示。
所谓的电路可满足性就是指,存在满足电路的一个解。如果这个解的输出值等于一个确定值,那么这个解就能「表示」电路的计算过程。
「零知识的电路可满足性证明协议」提供了一种最直接的保护隐私/敏感数据的技术
所有的证明都体现了「证明」与「验证」的「不对称性」。
模拟 安全的定义与不可区分性 「安全」需要有一个数学意义上的严格定义
完美安全:假设你是一个攻击者,你通过密文获取不到任何有价值的信息,破解的唯一手段就是靠瞎蒙。
语义安全:假设你是一个攻击者,你通过密文在多项式时间内计算不出来任何有价值的信息。
注:不可区分性是概率意义上的不可区分;在学术上,它可以分为「完全不可区分」,「统计不可区分」,还有「计算不可区分」
证明的零知识过程,等价于构造(寻找)一个「模拟」算法,这个算法能够让模拟器来模拟出一个「没有知识」的理想世界。如果这个算法存在,而且两个世界不可区分,那么就证明完毕。
模拟器其实只是一个图灵机。
证明零知识的过程,就是要寻找一个算法,或者更通俗点说,写出一段代码,它运行在外部计算机系统中,但是实现了虚拟机的功能。而且在虚拟机中,需要有一个不带有「知识」作为输入的 Zlice,可以骗过放入虚拟机运行的 Bob。
计算机科学中有两个方法论至关重要,第一个是「抽象」,第二个是「模拟」
知识 「零知识证明」并不是通过给出一个不允许发生的事件列表来定义,而是直接给出了一个最极致的「模拟条件」。
所谓「模拟条件」是指,通过「模拟」方法来实现一个「理想世界」,使之与「现实世界」不可区分;而由于在理想世界中不存在知识,所以可以推导出结论:现实世界满足「零知识」。
只有「知识」在存在的前提下,保证「零知识」才有意义
弱一些的「零知识」性质——「SHVZK」
可靠性
完备性
零知性
注:并不是所有的可靠性都必须要求存在抽取器算法。采用抽取器来证明可靠性的证明系统被称为「Proof of Knowledge」。
If you would be a real seeker after truth, it is necessary that at least once in your life you doubt, as far as possible, all things. 如果你是一个真正的真理探求者,在你人生中至少要有一次,尽可能地质疑所有的事情。 —— 笛卡尔
大体上说,plonk和很多零知识证明的概念基本上都是把一个逻辑的问题变成多项式,通过多项式的代数方法来完成证明。
1 电路 -&gt; 多项式
2 多项式承诺
证明多项式满足关系式
零知识证明是证明数学的一个运算。
加法门 乘法门 常数门
有限域
挑战 通过随机数挑战是交互式零知识证明的「信任根基」。
非交互式零知识证明,英文是 Non-Interactive Zero Knowledge,简称 NIZK。它意味整个证明被编码为一个「字符串」,它可以写到一张纸上,通过邮件、聊天工具等各种方式随意发送给任何验证者,字符串甚至可以放在 Github 上随时供大家下载验证。
交互式证明,只能取信于一个验证者;而 NIZK 可以取信于多个验证者,以至所有人。 交互式证明,只能在交互的那个时刻有效;而 NIZK 将始终有效。 NIZK 不仅可以跨越空间,还能跨越时间
不严格地说,数字签名方案相当于在证明(1)我拥有私钥,并且(2)私钥和消息进行了关联计算。
而采用 Hash 函数的方法来把一个交互式的证明系统变成非交互式的方法被称为 Fiat-Shamir 变换[5],它由密码学老前辈 Amos Fiat 和 Adi Shamir 两人在 1986 年提出。</description>
</item>
<item>
<title>Rust 学习之 flod</title>
<link>https://qiaopengjun5162.github.io/posts/rust_fold/</link>
<pubDate>Thu, 12 Oct 2023 20:01:17 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/rust_fold/</guid>
<description>Rust 学习之 flod 在 Rust 中,fold 是一个常见的方法,通常用于对集合(例如,向量、列表或数组)中的元素进行迭代,并通过一个累加器(accumulator)将元素组合起来。fold 方法通常与闭包(closure)一起使用,闭包定义了如何将每个元素与累加器结合起来。
fold 方法的基本语法如下:
1 2 3 fn fold&lt;B, F&gt;(self, init: B, f: F) -&gt; B where F: FnMut(B, Self::Item) -&gt; B, 这里的参数解释如下:
self:表示要进行迭代的集合。 init:累加器的初始值。 f:一个闭包,接受累加器和集合中的一个元素作为参数,并返回新的累加器值。 下面是一个简单的例子,演示如何使用 fold 方法计算一个向量中所有元素的和:
1 2 3 4 5 fn main() { let numbers = vec![1, 2, 3, 4, 5]; let sum = numbers.iter().fold(0, |acc, &amp;x| acc + x); println!(&#34;Sum: {}&#34;, sum); // 输出:Sum: 15 } 在这个例子中,我们使用了 iter() 方法来获取一个包含向量中所有元素的迭代器。然后,我们使用 fold 方法来迭代这些元素,并使用闭包 |acc, &amp;x| acc + x 来将每个元素与累加器相加。最终,我们得到了所有元素的和,并将其存储在 sum 变量中。
需要注意的是,在闭包中,我们使用了可变的引用 &amp;mut acc 来修改累加器的值。这是因为在闭包中,f 参数被标记为 FnMut,这意味着它可以修改它的参数。</description>
</item>
<item>
<title>Rust Quiz 学习之 #1</title>
<link>https://qiaopengjun5162.github.io/posts/rust_quiz_001/</link>
<pubDate>Thu, 12 Oct 2023 19:43:17 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/rust_quiz_001/</guid>
<description>Rust Quiz 学习之第一题 文档链接 https://dtolnay.github.io/rust-quiz/1
实操 问题: What is the output of this Rust program?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 macro_rules! m { ($($s:stmt)*) =&gt; { $( { stringify!($s); 1 } )&lt;&lt;* }; } fn main() { print!( &#34;{}{}{}&#34;, m! { return || true }, m! { (return) || true }, m! { {return} || true }, ); } The program exhibits undefined behavior
The program does not compile
The program is guaranteed to output:
回答 这个问题围绕着 Rust 语法在哪里放置语句边界。
宏的输入规则m!是$($s:stmt)*匹配零个或多个 Rust 语句。规则的$(&hellip;)*部分是一个重复,它匹配重复零次或多次的内容,并且 是$s:stmt一个片段说明符,匹配stmt符合 Rust 语法规则的 Rust 语句 ( )。匹配的语句在扩展代码中可以作为片段变量使用$s。
语句是函数体内允许的顶级语法单元。以下所有内容均为陈述示例。函数体的语法要求某些类型的语句后跟分号,但出于宏语法的目的,分号不是语句的一部分。
1 2 3 4 5 6 7 8 // Items are statements. struct S { x: u64 } // Let-bindings are statements. let mut s = S { x: 1 } // Expressions are statements. s.x + 1 该宏m!扩展为零个或多个{ stringify!</description>
</item>
<item>
<title>MacBookPro 16 M2 使用Parallels Desktop 安装 Ubuntu-22.04.3及相关配置</title>
<link>https://qiaopengjun5162.github.io/posts/ubuntu_settings/</link>
<pubDate>Wed, 11 Oct 2023 14:17:45 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/ubuntu_settings/</guid>
<description>MacBookPro 16 M2 使用Parallels Desktop 安装 Ubuntu-22.04.3及相关配置 适用于 ARM 的 Ubuntu 服务器 https://ubuntu.com/download/server/arm
安装搜狗输入法 https://shurufa.sogou.com/linux/guide
1 2 sudo apt-get install fcitx sudo apt-get install fonts-wqy-microhei 安装谷歌浏览器 1 2 3 sudo apt install chromium-browser sudo tzselect 更改系统时区为亚洲/上海 1 2 3 4 5 6 7 8 9 10 11 12 # 复制时区文件 sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # 安装ntp时间服务器 sudo apt install ntpdate # 同步ntp时间服务器 sudo ntpdate time.windows.com # 将系统时间与网络同步 sudo ntpdate cn.pool.ntp.org # 将时间写入硬件 sudo hwclock --systohc # 重启Ubuntu reboot https://github.com/Dreamacro/clash/blob/master/docs/logo.png
1 sudo snap remove --purge firefox </description>
</item>
<item>
<title>安装rustlings报错解决</title>
<link>https://qiaopengjun5162.github.io/posts/githubusercontentfix/</link>
<pubDate>Sun, 08 Oct 2023 22:54:09 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/githubusercontentfix/</guid>
<description>安装rustlings报错解决 相关文档 https://github.com/LearningOS/rust-rustlings-2023-autumn-qiaopengjun5162
安装rustlings 报错: 1 2 3 4 5 6 7 8 ~/Code/rust via 🅒 base took 53.7s ➜ curl -L https://raw.githubusercontent.com/rust-lang/rustlings/main/install.sh | bash % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- 0:01:15 --:--:-- 0 curl: (28) Failed to connect to raw.githubusercontent.com port 443 after 75005 ms: Couldn&#39;t connect to server 解决: 访问https://sites.ipaddress.com/raw.githubusercontent.com/网站,获取最新IP地址。
修改hosts文件
sudo vim /etc/hosts
编辑 hosts 文件,新增下列内容
185.199.108.133 raw.githubusercontent.com</description>
</item>
<item>
<title>First</title>
<link>https://qiaopengjun5162.github.io/posts/first/</link>
<pubDate>Sat, 07 Oct 2023 13:00:03 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/first/</guid>
<description>This is a heading one This is a heading two This is a paragraph.
graph TD; A-->B; A-->C; B-->D; C-->D; </description>
</item>
<item>
<title>Rust 学习之所有权 Rc</title>
<link>https://qiaopengjun5162.github.io/posts/rust_rc_arc/</link>
<pubDate>Sat, 07 Oct 2023 13:00:03 +0800</pubDate>
<guid>https://qiaopengjun5162.github.io/posts/rust_rc_arc/</guid>
<description>Rust 学习笔记之所有权 Rc Rust 处理很多问题时的思路:
编译时,处理大部分使用场景,保证安全性和效率; 运行时,处理无法在编译时处理的场景,会牺牲一部分效率,提高灵活性。 Rust具体如何在运行时做动态检查呢?运行时的动态检查又如何与编译时的静态检查自洽呢?
Rust 的答案是使用引用计数的智能指针:Rc(Reference counter) 和 Arc(Atomic reference counter)。这里要特别说明一下,Arc 和 ObjC/Swift 里的 ARC(Automatic Reference Counting)不是一个意思,不过它们解决问题的手段类似,都是通过引用计数完成的。
Rc 对某个数据结构 T,我们可以创建引用计数 Rc,使其有多个所有者。 Rc 会把对应的数据结构创建在堆上。 堆是唯一可以让动态创建的数据被到处使用的内存。 1 2 3 4 use std::rc::Rc; fn main() { let a = Rc::new(1); } 如果想对数据创建更多的所有者,我们可以通过 clone() 来完成。 clone() 方法会创建一个新引用计数,并把新引用计数指向的数据的所有者数量加 1。 1 2 3 4 5 use std::rc::Rc; fn main() { let a = Rc::new(1); let b = a.clone(); } 如果我们把数据的所有者数量减到 0,那么数据就会被销毁。 对一个 Rc 结构进行 clone(),不会将其内部的数据复制,只会增加引用计数。 当一个 Rc 结构离开作用域被 drop() 时,也只会减少其引用计数,直到引用计数为零,才会真正清除对应的内存。 1 2 3 4 5 6 use std::rc::Rc; fn main() { let a = Rc::new(1); let b = a.clone(); let c = a.clone(); } 上面的代码我们创建了三个 Rc,分别是 a、b 和 c。它们共同指向堆上相同的数据,也就是说,堆上的数据有了三个共享的所有者。在这段代码结束时,c 先 drop,引用计数变成 2,然后 b drop、a drop,引用计数归零,堆上内存被释放。
a 是 Rc::new(1) 的所有者,b 和 c 是 a 的 clone() 所有者。 引用计数是 3,因为 a 有三个所有者,b 和 c 各有一个。 引用计数归零,a 离开作用域,a 的所有者变成 2,a 的内存被释放。 b 和 c 离开作用域,引用计数减 1,b 和 c 的内存被释放。 从编译器的角度,abc 都各自拥有一个 Rc,所以编译器不会报错。 Rc 的 clone() 函数的实现 Rc 的 clone() 函数的实现很简单,就是增加引用计数:</description>
</item>
<item>
<title>About</title>
<link>https://qiaopengjun5162.github.io/about/</link>
<pubDate>Fri, 06 Oct 2023 15:00:00 +0700</pubDate>
<guid>https://qiaopengjun5162.github.io/about/</guid>
<description>About Me I&rsquo;m a frontend and backend ethusiast.
My Skills and Interests As a programmer, I possess a diverse skill set, including but not limited to:
Front-end Development: I am proficient in HTML, CSS, and JavaScript and have extensive experience building user-friendly front-end interfaces across different platforms.
Back-end Development: I am skilled in multiple programming languages and frameworks, including Python, Go, Rust, and Django, for creating robust back-end systems.
Database: I have a deep understanding of database design and management, covering both SQL and NoSQL databases.
Team Collaboration: I excel at working in teams, collaborating closely with designers, project managers, and other developers to achieve project goals.
Continuous Learning: I believe that knowledge in the tech field is boundless, so I actively pursue continuous learning and regularly update my skills.
Conclusion As a programmer, my journey has been filled with challenges and opportunities.</description>
</item>
</channel>
</rss>