Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
IPFS 安装, [7 Z1 T8 c) @, S
7 n/ \$ W* v. C/ X# n
要使用IPFS, 第一步肯定是先把IPFS安装好,IPFS在Mac OS X 、Linux及Window平台均有提供, 可以通过这个链接下载对应平台可执行文件的压缩包。
2 v  Z# w4 r( @: P$ B
8 Q6 c. z# |+ J1 E9 n$ W对于Mac OS X 及 Linux 平台,使用一下命令进行安装:
8 h1 q5 [# y# {4 D$ ]5 S* D( F' d+ O; f% H3 h. ]  p" V
$ tar xvfz go-ipfs.tar.gz" }7 f/ g0 C, k

7 V7 s) Q% w# |' ?9 C8 S; o$ cd go-ipfs
0 h7 q5 K9 |, ?' d6 A2 k6 }; c* _3 n# P# B' S
$ ./install.sh
' W  t# d3 J; w4 h
9 m, t  ?9 m1 E" k, h上面先使用tar 对压缩包进行解压,然后执行install.sh 进行安装,安装脚本install.sh其实就是把可执行文件ipfs移动到$PATH目录下。安装完成之后,可以在命令行终端敲入ipfs试试看,如果显示一堆命令说明,则说明IPFS安装成功。+ {5 _: @; y5 ], J9 r( h

$ b$ {* x, I8 H: f在Windows平台也是类似,把ipfs.exe移动到环境变量%PATH%指定的目录下。
& S+ H6 @+ h4 v% H- P  [9 }7 J4 G  O! l$ T! j6 I
IPFS 基本用法
9 k) _3 |( ^8 j' ?) H* X8 l9 D$ o/ ~
  F% m! n. E- r# j' \+ MIPFS初始化; Y$ K$ P" X# e. S( G& A0 `. s
+ ^6 ~! n! ^, G* z) R
安装完成之后,要使用IPFS第一步是要对IPFS进行初始化,使用ipfs init进行初始化7 K# r8 a2 t0 |4 }' t

, @( {4 V. h0 Z7 T1 x# N5 F> ipfs init8 T) d; o: _$ o# y; q' {* E
) {# ]1 V7 p& a+ A6 Z
initializing ipfs node at /Users/Emmett/.ipfs6 s/ M. d2 f6 S; g6 W7 Z
* w" m! H8 i0 O+ \" f
generating 2048-bit RSA keypair...done
6 D6 F0 C  G: S7 T* F/ l0 X4 T( v9 r. }7 G/ L' g. u
peer identity: QmYM36s4ut2TiufVvVUABSVWmx8VvmDU7xKUiVeswBuTva' O5 H3 i& h! s2 i9 u

) V) S7 L( @( l& M7 p" \to get started, enter:/ O8 [$ B9 t  L- D' @! V" d: Q
: X' l1 _6 Z6 v) W% \6 V7 a
  ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme
7 C1 C) r. D3 x3 a/ `) G
% _( A7 E- s' m. Y& C* S9 C上面是执行命令即对应输出,在执行ipfs init进行初始化时,会有一下行为:
/ l% g* `& }* B0 Y5 s
( Q- F7 S5 j# a/ I生成一个秘钥对并产生对应的节点id, 即命令提示:peer identity后面的hash值。$ s7 U9 g# s7 B8 g8 M
3 _4 T/ Y2 T: M# G0 D1 [
节点的id用来标识和连接一个节点,每个节点的id是独一无二的, 因此大家看到的提示也会和我的不一样。& h! T  s" E. s' K
6 z- O& G0 J% [( M$ o
在当前用户的主目录(~ 目录)下产生一个.ipfs 的隐藏目录,这个目录称之为库(repository)目录,ipfs 所有相关的数据都会放在这个目录下。4 `8 W& y& o* A6 \) W. u. ~0 `8 G
. ?# K: }6 W( `) {8 A# ?
如同步文件数据块放在.ipfs/blocks 目录,秘钥在.ipfs/keystore 目录,ipfs配置文件为:.ipfs/config。, F. I& O4 k/ r6 c6 a! C! \4 k

* x+ n/ Q4 T1 U! v) `8 OIPFS 配置修改& |. h/ A1 A. l' ?# a6 [
# d3 {0 @/ M6 [8 [3 W! l9 D
在IPFS初始化之后,可以根据需要修改配置(可选),修改方法如下:
5 v! s. j  p9 |$ l2 N# ~) c6 w1 D4 G* N& K
cd ~/.ipfs
# {; h. R4 W1 S( U+ j
: W7 t4 ^' o% S& d2 v$ D2 k: a0 Iexport EDITOR=/usr/bin/vim
8 y* B# A" P) s9 h
; `: C% _9 L( O7 Y0 D! Eipfs config edit( H1 m. j/ x* S

* O# _) p- \4 |0 I  S或者直接编辑 ~/.ipfs/config 文件。5 U; k# y1 H4 V3 {# Q

6 j" y% F! [4 _! X: V& e; k上传文件到IPFS
2 z3 Y1 G9 x0 o5 w# v: e6 [  p0 J. _6 }8 s7 f, F) Q$ G* k2 G
我们先创建一个upchain.pro.txt文件,可以使用如下方式:  F  a8 L9 ]; Y/ J

5 _! _2 j& G2 v5 A> echo "比特池塘:www.bitmere.com" >> upchain.pro.txt& G, f$ c( x9 l
1 \& U9 x5 m0 z# o
ipfs 使用add 命令来添加内容到节点中,  在命令行输入:
- j0 m2 A7 {: y1 h3 W! Q7 R! I3 _3 u( i! [, D
> ipfs add upchain.pro.txt% r% m& \+ T8 `7 F, A

7 E+ V$ u2 Y3 Q# q. Radded QmQgMZKqHzyEdyJja5ioF8WaXrbUDVjqhJDoaUKDymgioi upchain.pro.txt
$ M! b3 G  N" `& `
: l9 Z* U/ N% l43 B / 43 B [=====================================================] 100%
5 g! p  O5 u( ?3 o, l$ R
$ Z, ~- d1 I3 ?5 I9 W4 N* ?当它文件添加到节点时,会为文件生成唯一的hash: QmQgMZKqHzyEdyJja5ioF8WaXrbUDVjqhJDoaUKDymgioi, 可以使用ipfs cat 查看文件的内容:  N$ o6 g9 U" R' [! D0 l

" z" i+ |+ K6 K& B/ q> ipfs cat QmQgMZKqHzyEdyJja5ioF8WaXrbUDVjqhJDoaUKDymgioi
$ y6 g6 X* |+ D
: l7 V* h) G. d1 x. K) @, v2 J8 G' x" ?! p$ Z4 ^
注意,此时文件仅仅是上传在本地的IPFS节点中,如果需要把文件同步到网络,就需要开启 daemon 服务, 使用命令:) X9 G! N( D4 e. C, B1 I& X
8 n$ r  Z6 i4 i" f  h
> ipfs daemon
+ o. J) w" f6 k; I" F6 g& M/ A# K3 H, R* P6 S
Initializing daemon...
1 v/ z- X% p4 p6 M% v4 u
+ j4 `8 K/ V- T& ^) T4 ^6 pgo-ipfs version: 0.4.18-8 N: I1 L. G+ {8 @- o( A( s
1 a" k$ p- b) k- B" j8 t# |! d& _  r
Repo version: 7: w# i4 R* t5 Q' R% v9 q& U' U
8 z! C# C# L7 V+ I
System version: amd64/darwin1 \$ L3 l. C* K9 h$ @' g2 [
! u* f+ F4 @6 X# F
Golang version: go1.11.10 l7 T( L' z  w" j% _3 F

& `: T: M2 X3 R' ]" ^. @# \$ [Swarm listening on /ip4/127.0.0.1/tcp/4001
# N, p0 q* Y" Q3 ]( Z# U" ]: R, |+ z
Swarm listening on /ip4/192.168.8.105/tcp/4001
  U  \4 R, |; A2 N  w$ [& |) }% h: N: K: Z, T: `0 S
Swarm listening on /ip6/2408:84f3:82e:cfcd:409:fee2:e261:4dc3/tcp/4001
) o4 Q- U9 t  @9 Z
. V% e# {# d0 W) ?: tSwarm listening on /ip6/2408:84f3:82e:cfcd:a9c6:116b:349f:8c2b/tcp/40016 a# }) J" v4 \' [) B

% v0 S4 J1 r. s4 nSwarm listening on /ip6/2408:84f3:82e:cfcd:ec89:145d:cf27:4/tcp/40014 m( S* b- T; S
7 s; N# X3 A; ~* g3 o! r4 F7 K
Swarm listening on /ip6/::1/tcp/4001- n4 b1 P2 V9 R2 c* O! ?0 o* ^0 X
8 v7 |1 E5 C* z+ @
Swarm listening on /ip6/fd1d:43b:e89b:eb9b:c405:56af:8f52:67df/tcp/4001
4 q/ q+ ^. f2 |7 ~% O1 n# C4 E! g) \( ^
Swarm listening on /p2p-circuit
' g. w; d6 m$ \1 Y* |9 M2 E  l
. [- N$ o( W) R  L* ySwarm announcing /ip4/127.0.0.1/tcp/4001, t/ \. E2 X5 `$ `' _( w7 O
" m6 U( r* }1 x$ {: U$ q9 h8 H! m
Swarm announcing /ip4/192.168.8.105/tcp/4001  Y3 A) K" E0 \! p8 R4 `

( Q6 g; u! G/ [8 s0 S7 wSwarm announcing /ip6/2408:84f3:82e:cfcd:409:fee2:e261:4dc3/tcp/4001
6 K: w8 e! i" i: ^% [$ Z) A
1 J) Q3 c" \# Y$ GSwarm announcing /ip6/2408:84f3:82e:cfcd:a9c6:116b:349f:8c2b/tcp/4001+ C/ t% i6 l' M; D
5 ^7 {* b% z& N3 [3 e. n& K: L8 i
Swarm announcing /ip6/2408:84f3:82e:cfcd:ec89:145d:cf27:4/tcp/4001
$ _* t3 _3 n* L! D! x4 K$ ~2 z0 }/ q  s3 h, l  T. I3 }
Swarm announcing /ip6/::1/tcp/4001
# r* f( f" p8 F1 [. L+ I0 y
+ c. X  ]4 n. C3 G- Y% eSwarm announcing /ip6/fd1d:43b:e89b:eb9b:c405:56af:8f52:67df/tcp/4001; F9 F5 ^) P7 [' P& h; `
, q& Y- F6 e2 z; ]4 }5 L9 X" D
API server listening on /ip4/127.0.0.1/tcp/5001
" u- _7 c& R+ _$ i* t6 D0 l. l* {- a0 W; C8 Q; e5 O* Z
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
' `; h( V" h) _1 t8 Z1 `, W3 T: g& o/ m. g9 T! q% X
Daemon is ready
2 B" Q& V! w7 L7 `3 E; M' X
% U2 O0 z7 s6 M' i% X开启 daemon 之后,Swarm 就会尝试连接其他的节点,同步数据,同时在本地还会开启两个服务:API服务及Web网关服务,下面分别介绍下:
9 r# I# m+ k& x+ L3 F% h2 K" p  @- p" q: x
API服务,默认在5001端口,可以通过 http://localhost:5001/webui 进行访问,界面如:4 d$ \, z! B- U  f8 Y8 _
: l( Y: @5 L' L# f) U) Z' ^) b
这也是IPFS的一个Web版的管理控制台, 可以通过这个控制台添加文件,查看节点连接情况等等。
( _; N- F% F+ [) \6 V, f7 R: \- z" w; t7 {5 y
网关服务,默认在8080端口, 由于当前浏览器还不支持通过IPFS协议(ipfs://)来访问文件,如果我们要在浏览器里访问文件的话,就需要借助于IPFS 提供的网关服务,由浏览器先访问到网关,网关去获取IPFS网络杀过了的文件。 有了网关服务,就可以通过这个链接:http://localhost:8080/ipfs/QmQgMZKqHzyEdyJja5ioF8WaXrbUDVjqhJDoaUKDymgioi 来访问刚刚上传到ipfs 的文件。/ I+ h4 A' d9 {
+ \; M( S. m( g' E/ [+ ^* w
ipfs 也提供了官方的网关服务:https://ipfs.io/, 因此也可以通过 https://ipfs.io/ipfs/QmQgMZKqHzy ... UDVjqhJDoaUKDymgioi (需要翻墙)来访问刚刚上传到ipfs 的文件。5 H  X; U8 X9 ^5 f" t
3 r; v! `5 @( s- ?4 s" G2 x
上传目录到IPFS$ ~4 k  J- c# {3 ]/ t
, R0 q7 o( t8 s) Z
我们先创建一个文件夹upchain, 并把之前的 upchain.pro.txt 放进目录。
$ w8 g4 v$ T1 Y! ^+ M0 g* b- \- |- M% J
4 E* y6 [  c  d, e+ R> mkdir upchain
$ ?# k  k2 j- h+ O$ @
' o  \1 t+ f" l* `5 d  I> mv upchain.pro.txt  upchain0 N) G: @% ^4 `' U$ ]

9 H% l( q; E5 n& V上传目录到IPFS 需要在使用 add 命令时加上 -r ,如下:  E% z2 I3 L, P1 n- |4 Q0 N6 h* u. j

) N  P% L) H% \4 U1 g7 R1 q6 N> ipfs add -r upchain
9 T( I! b9 o9 f9 V
$ z7 h% P6 l! v4 Cadded QmQgMZKqHzyEdyJja5ioF8WaXrbUDVjqhJDoaUKDymgioi upchain/upchain.pro.txt
- L; @! q6 _0 K: H1 J
1 _- r) v. @6 u5 e& G- oadded QmQYpGRFBpHVzoShpwU5C3XgGAxJKqY83X8VXfMbyktdbP upchain
8 y+ Y7 G( k7 \" @, J1 U7 H" h/ |8 t9 f  K8 M& Q" N
43 B / 43 B [===========================================================================] 100.00%
7 [. [5 }9 t/ c) w% P" g# f4 M! f0 B8 x6 |7 V3 l; y) X" d% P
在上传时文件夹,文件夹也会生成一个对应的hash,可以通过hash后接文件名来进行访问, 如:
" C# |+ y/ x& _& M2 O  b. p: m( u1 M  v9 o
>ipfs cat QmQYpGRFBpHVzoShpwU5C3XgGAxJKqY83X8VXfMbyktdbP/upchain.pro.txt
/ w9 h4 H$ I: q  J
' B9 S5 i; P3 j
2 X' T& C! h9 e3 l在浏览器可以链接:http://127.0.0.1:8080/ipfs/QmQYp ... dbP/upchain.pro.txt 来访问。
) w; c. @4 [, z' m5 J9 p! m* T9 \6 V* x* \
通过上传目录的方式,可以把整个静态网站的根目录上传到IPFS网络,这样就可以省去托管服务器,例如可以直接通过以下链接访问深入浅出区块链博客:' l: ^) M% u) E3 W6 x% m7 j

6 @! Z/ b  y1 V: s; {% \https://ipfs.io/ipfs/QmaFWgfpRNz ... uCphq2ua/index.html1 [' g- `$ ~0 E. m) X

) M  l1 p& l  d6 m使用IPNS解决文件更新问题
# t- h+ V  y5 \4 ~
1 R; E0 e$ T/ R0 L. @/ ]因为IPFS在IPFS中,对一个文件的内容修改后(如升级),会生成一个完全不同的新Hash,使用IPNS就可以利用同一个链接总是指向更新的内容,其实使用也很简单,只需要每次在内容更新之后使用ipfs name publish hash 发布到节点。
) p9 S* Q) |& p
3 r5 v! K+ t) i$ b8 @/ [例如把upchain.pro.txt发布到节点,使用下面的命令:3 t7 E& p1 I* z( k* p/ d

4 {! F2 y/ V+ g1 v6 l. t, E> ipfs name publish QmQgMZKqHzyEdyJja5ioF8WaXrbUDVjqhJDoaUKDymgioi$ `0 m% a* b. j" p% X( U, `& C

8 X3 {; M: _- O& h1 NPublished to QmYM36s4ut2TiufVvVUABSVWmx8VvmDU7xKUiVeswBuTva: /ipfs/QmQgMZKqHzyEdyJja5ioF8WaXrbUDVjqhJDoaUKDymgioi
$ n  o% J. x/ {1 S+ ?) j) j0 m3 w: n( C3 ~3 ~
命令中的QmQgMZKqHzyEdyJja5ioF8WaXrbUDVjqhJDoaUKDymgioi是upchain.pro.txt的hash, 命令提示中的QmYM36s4ut2TiufVvVUABSVWmx8VvmDU7xKUiVeswBuTva是当前节点id(大家可以回看一个前面ipfs init 的输出)。
$ d4 @. W* A7 C
$ H, r5 E- A  J1 [6 X: j0 f1 j+ Z发布之后就可以使用http://127.0.0.1:8080/ipns/QmYM3 ... VvmDU7xKUiVeswBuTva 或 https://ipfs.io/ipns/QmYM36s4ut2 ... VvmDU7xKUiVeswBuTva 来访问upchain.pro.txt的内容,如图:/ q* ~/ m! Z# f' R0 H
3 K/ B% t  b! B9 x* f7 u* U
其实理想下是使用 ipns://QmYM36s4ut2TiufVvVUABSVWmx8VvmDU7xKUiVeswBuTva 来访问,通过网站还是前面提到的浏览器暂不支持ipfs协议。' G4 |  J! r! R8 p0 ]

/ i1 v$ C: C$ D( w现在我们来更新一下upchain.pro.txt 加入文字:“创办人:Tiny熊”
) S9 j, D; ?6 v2 l1 _
2 m( x! K# a  B; y8 x> echo "创办人:Tiny熊" >>  upchain.pro.txt- ?8 p5 f8 i* R, Z, r) s; C# `
( z  |* m8 U9 K* R; @7 m7 s5 p
> ipfs add upchain.pro.txt3 @0 c& l+ `; a5 o2 p
- L, W; m  a4 H9 s
added QmUUiDN6tWtj89xmUw1iCK2NczBqE6m3zH9QnbhHoMvZ5S upchain.pro.txt! N$ A  Y! A' m

4 q7 r6 A6 r2 c. j2 ~: W+ t63 B / 63 B [=============================================================] 100.00%
7 O  b- u. W0 t1 N; W, E* B7 n% k
! F1 ~% ]7 I5 e5 f7 [- h! C重新发布一下:5 r: |) }& u" k& P

* q8 w1 y: W  G, R& c( E  K# h! B' I' q) x> ipfs name publish QmUUiDN6tWtj89xmUw1iCK2NczBqE6m3zH9QnbhHoMvZ5S
- g. h! A2 j: Z
9 S- ~; u' {, I+ p2 G" }% V. v# i( WPublished to QmYM36s4ut2TiufVvVUABSVWmx8VvmDU7xKUiVeswBuTva: /ipfs/QmUUiDN6tWtj89xmUw1iCK2NczBqE6m3zH9QnbhHoMvZ5S8 u( b& }0 @' L' f, x

9 p) Z; U$ l4 |+ e2 \- {8 A+ w, M再次访问 http://127.0.0.1:8080/ipns/QmYM3 ... VvmDU7xKUiVeswBuTva (这个链接和上面的链接一样)可以看到内容更新了。# K  B; A# Y1 P& j8 C2 Z
' h) S% y  ~# J: j5 O" P# M
如果我们要查询 节点id 指向的hash 可以使用 ipfs name resolve  进行查询:2 _# Y% H! W( s7 c3 K6 ~2 d7 g

3 |& R, a" [( X( k4 w> ipfs name resolve- {1 f# i8 g( G5 J2 V% `3 a

, Y. y! e* m. ^$ W, p/ipfs/QmUUiDN6tWtj89xmUw1iCK2NczBqE6m3zH9QnbhHoMvZ5
; u/ ?6 j1 v& x
% G2 m; O7 z4 w+ W/ @- R7 f8 g有一点值得大家注意: 节点id其实是公钥的hash,它的关联信息是需要经过私钥签名才可以发布,因此只有我们自己才可以更新节点的指向。+ T: Y' _6 t# e) M3 a! d+ X; q0 X, W
* m! t1 E+ {, g6 y) o
如果我们有多个站点需要更新,可以新产生一个秘钥对,使用新的key 发布,如:
; W  Y8 ^4 C. w6 W& ^3 g' p8 N
" d' s2 A8 g/ ]0 J/ y6 n! v> ipfs key gen --type=rsa --size=2048 mykey
# @4 y" i) u3 v' E" n7 z
) Z4 J5 U% @  s1 V. v7 }, t' O1 s$ EQmVZvdYEsdfHSR43Qm1fY8eDFrhB3UNZ2oVyEuVUH3VHrg
' M. y/ h; }1 g# d. o
, M% y: P4 h5 q" H& \( e> ipfs name publish --key=mykey  hashxxx  q0 j9 l& L! W# q1 n' K/ v

7 _% b' S, J% y! RPinning
& O: M( N( X& t
+ `$ S) ]& s( W. nPinning 在IPFS里是一个很重要的概念,当我们每次请求一个网络上的内容的时候,IPFS总是会把内容先同步的本地提供服务,而为了防止 IPFS 存储空间不停增长,实际上使用cache 机制来处理文件, 如果文件在一段时间内没有被使用,文件会被”回收“。 Pinning 的作用就是把文件”钉“住,确保文件在本地不被”回收“。 如果是重要的文件,就可以使用 Pinning 防止文件被删除。  u5 O! J& t9 F, i

8 ~) A. {8 {7 ?, _当我们使用ipfs add 添加文件时,默认会进行Pinning(使用其他命令获取的文件不会进行pinning),
: [4 h3 p0 C2 w7 l
. q$ R& |" \" ^1 _8 g- l8 G# M& KIPFS 提供了pin命令进行Pinning操作, 比如我们查询下某一个hash 是否被pin:& `' A! B* M; X8 _& i
: w- r2 _5 `9 j. F2 ~
> ipfs pin ls QmUUiDN6tWtj89xmUw1iCK2NczBqE6m3zH9QnbhHoMvZ5S  U- N1 t- L( c, Q

7 j1 z3 D- p& u. m4 \: sQmUUiDN6tWtj89xmUw1iCK2NczBqE6m3zH9QnbhHoMvZ5S recursive
7 R; Y  ^  ]( B1 j. x' E, N9 u9 B# `& h3 X' S5 i7 }
> ipfs pin ls QmWnrAEKyDVUQ1jh9vDtQhtBSNEgUnQhAJyMmo3JjwJZK7
$ @0 n% a' t( F- w  U
! D; l' k& o4 x& L- y; P0 lError: path 'QmWnrAEKyDVUQ1jh9vDtQhtBSNEgUnQhAJyMmo3JjwJZK7' is not pinned( @+ G, Y+ G' A$ q( p  N# z( j, m
! ~1 P" F2 m9 V% w
可以使用 pin add 手动钉住一个文件,如:
" w5 e' r# y( S3 X( a2 [8 C% u- l3 T
> ipfs pin add QmWnrAEKyDVUQ1jh9vDtQhtBSNEgUnQhAJyMmo3JjwJZK7  C( X/ m3 q# i, F9 P1 M. s  j! o8 D

& D3 j& a: d& O( Y2 Bpinned QmWnrAEKyDVUQ1jh9vDtQhtBSNEgUnQhAJyMmo3JjwJZK7 recursively% D6 _0 M+ X6 p+ |, G7 o

& ?; F$ b6 V0 R% b! _如果要删除pin的状态,使用pin rm , 如:5 c& ^9 G- v9 ?* {1 ^

% O- L$ `- E: u> ipfs pin rm -r QmWnrAEKyDVUQ1jh9vDtQhtBSNEgUnQhAJyMmo3JjwJZK7
# J$ D  a; Q! H* Z% L/ O$ X) c% R' ^2 s6 e  D/ U; w. ]
unpinned QmWnrAEKyDVUQ1jh9vDtQhtBSNEgUnQhAJyMmo3JjwJZK7# u9 l5 W9 {9 Q9 g  d3 m- ]
4 g: o1 C8 e- D: L
pin rm 的参数 -r 表示递归的删除pin 状态,对于没有pin住的文件, 如果执行GC操作 ipfs repo gc 文件会被删除。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

在冰雪中的玫瑰 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    2