Fabric命令行工具及运行思路(二)

Orderer

配置信息

关于orderer的配置如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MLdZoFpb-1628858687761)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155239125.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZjZoWh0j-1628858687763)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155245216.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VHkHPChs-1628858687765)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155249895.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-necG8FQb-1628858687768)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155259441.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XqyBVBU3-1628858687770)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155304101.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ofTxPskO-1628858687771)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155308645.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pT2HZE2s-1628858687772)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155313115.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-668ydbP7-1628858687773)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155318777.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zgADAhOd-1628858687774)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155359263.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BFiVq5H0-1628858687775)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155403334.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-voXUqnHO-1628858687775)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155407524.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ctxAA31u-1628858687776)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155413443.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MEPSJAFO-1628858687776)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155416872.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k6GbwyGo-1628858687777)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155421205.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1VkDVaBZ-1628858687778)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155424491.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TjtpGPgj-1628858687778)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155428877.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jFKRLjUy-1628858687779)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155432295.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eXQodAfP-1628858687780)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155436306.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hC9FJo5s-1628858687781)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155440505.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Fd3VabE-1628858687781)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155444601.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nRZqhM9v-1628858687782)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155449285.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DheU2WVt-1628858687783)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155452398.png)]

默认设置如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ioWDpSXj-1628858687784)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155505524.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VbtirjWc-1628858687784)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155510144.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KOPt1hxH-1628858687785)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155516244.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lyHrEmp7-1628858687786)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155521327.png)]

主要流程

  1. 加载orderer配置

    1. 将cache中的使用过的配置序列化,即获取cache
    2. 对错误进行处理
    3. 根据filepath,使用过的配置文件的路径来完成初始化。若字段为空,则以默认值赋值,最后返回配置。
  2. 初始化日志

    1. 获取FABRIC_LOGGING_SPEC,FABRIC_LOGGING_FORMAT环境变量
    2. 将环境变量放入flogging的配置文件,根据配置文件将其应用在日志系统当中并生成日志
  3. 将配置中的结构体进行打印

  4. 再生成一个长期的BCCSP,cryptoprovider,即密码算法模块

  5. 根据生成的配置文件conf,来获得签名的身份

  6. 创建操作系统,其参数如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zLEPCTwa-1628858687786)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155529175.png)]

  1. 再生成metricsProvider

    1. 根据生成的metricsProvider与conf来生成severconfig
  2. 根据severconfig与conf来生成grpcsever

  3. 创建camanager,其参数如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZP24rLgJ-1628858687787)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155603021.png)]

  1. 根据conf与metricsprovider来生成ledgerfactory类型的lf

  2. 根据conf.general.bootstrapmethod中定义的创世块生成方法,来创建创世块与通道

    1. 如果方法为file,则判断是否存在当前通道ID的通道了,不存在才能继续

    2. 根据conf.general.bootstapfile来生成创世块bootstrapblock

    3. 再用cryptoprovider来对其进行验证

    4. 再根据lf与创世块来初始化创世通道

    5. 如果方法为none,则根据conf,cryptoprovider,lf来直接创建系统通道并将区块加入

  3. 根据lf与cryptoprovider来获得系统通道中的最后一个配置区块作为syschanconfigblock

  4. 根据bootstrapblock,syschanconfigblock来生成clusterbootblock,规则如下:

    1. 如果syschanlastconfig为空,则返回bootstrapblock
    2. 如果bootstrapblock为空,则返回syschanconfigblock
    3. 如果两个都有,则返回区块头号较大的那个
  5. 接着判断orderer是否是集群类型的,规则如下:

    1. 如果clusterbootblock为空,则为集群类型
    2. 如果不为空,则从clusterbootblock获得channelid,,再根据clusterbootblock与cryptoprovider获得共识类型,再根据共识类型来判断orderer是否为集群类型
  6. 若orderer为集群类型,则配置一下参数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QUkaPpoK-1628858687788)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155614014.png)]

  1. 启动集群

    1. 根据conf来获得clusterclientconfig与reusegrpclistener
    2. 根据clusterclientconfig来生成clusterdialer
    3. 若reusegrpclistener不为空,则根据conf与severconfig生成clusterseverconfig与clustergrpcsever
    4. 将clustergrpcsever加入需要更新的服务器列表中,即需要更新TLS ca 证书池
    5. 若clusterbootblock不为空,则根据lf,clusterbootblock,conf,clusterclientconfig.secopts, signer,cryptoprovider来对所有的通道进行replicate,要求为:clusterbootblock的区块号大于系统通道高度
    6. 若创世块生成方法为None且bootstrapblock不为空,从文件仓库中丢弃系统通道的join-block
  2. 序列化签名身份

  3. 生成experiationlogger,终结日志

  4. 启动crypto中的跟踪终结功能,在日志终结前一周来进行提醒,参数设置如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MZKMLSky-1628858687788)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155624796.png)]

  1. 对重复使用的grpcsever,将其添加入serversToUpdate中,再根据bundle与serversToUpdate来对信任根进行更新,如果是集群类型,还要对clusterdialer来进行更新。Bundle为

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gUHfnQFa-1628858687789)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155631315.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PLxeyQrR-1628858687790)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155634195.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-celVTCZz-1628858687790)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155639118.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FOarWVOj-1628858687791)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155642996.png)]

  1. 再对多通道注册者进行初始化manager,参数为clusterbootblock,repinitator,clusterdialer,clusterserverconfig,clusterGRPCServer, conf, signer, metricsProvider, opsSystem, lf, cryptoProvider, tlsCallback。 其中会根据共识类型对共识服务进行初始化,最后将该注册者的共识进行初始化,并开启通道

  2. 根据conf.admin来创建adminserver

  3. 开始admin server

  4. 生成mutualTLS

  5. 生成Server,参数为manager,metricsprovider,conf.config, conf.general.authentication.timewindow,mutualtls,conf.general. authentication.noexpirationchecks

  6. 开始处理信号,并在clustergrpcserver.address端口上进行监听,

  7. 若profile是enable的,则开始profile服务

  8. 然后开始响应服务请求

Osnadmin

参数如下:

名称功能
ordererOsn的admin端点
Cafile包含pem编码后的OSN的TLS,CA证书的路径
clientCert包含pem编码后的用于TLS通信的X509公钥
clientKey包含pem编码后的用于TLS通信的X509私钥
noStatus删除回显信息中的HTTP状态信息

命令行如下:

名称功能参数帮助
Channel.join将一个OSN加入通道,如果通道不存在,则创建Joinchannelid通道ID
configBlockPath包含一个为通道更新配置的区块的文件的路径
Channel.list列出这个OSN所在的通道的详细信息Listchannelid要列出的通道ID
Channel.remove从通道中移除OSNremovechannelid要移除的通道id
  1. 先定义变量,osurl,cacertpool,tlsclientcert,其中私钥被定义在tlsclientcert中,其余各参数为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KZWlt8qH-1628858725554)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155658210.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q2a9wAdf-1628858725555)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155702399.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4msei6kc-1628858725559)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155706695.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jztuuU5u-1628858725561)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155713587.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lDrJh5ii-1628858725561)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155718522.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8o05XPPu-1628858725562)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155723849.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EqYCMhIo-1628858725563)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210812155730093.png)]

  1. 若Ca文件不为空

    1. 根据orderer生成osnurl
    2. 生成Ca证书池
    3. 读取ca文件来生成cafilepem
    4. 将cafilepem放入ca证书池
    5. 根据clientkey和clientcert来生成tlsclientcert,即加载证书密钥对

    若为空,就生成osnurl

  2. 根据读取configblockpath来获得整理过的配置区块marshaledconfigblock,即读取其信息

  3. 根据加入的channelid与marshaledconfigblock来对区块的通道ID进行验证

  4. 根据command来进行操作

Join

Command为join:

  1. 根据osnurl,marshaledconfigblock,cacertpool,tlsclientcert来生成加入已存在通道的请求req
  2. 根据req,cacertpool,tlsclientcert来进行httpdo指令

list

Command为list:

  1. 如果listchannelid字段不为空,则要获得特定通道的信息

    1. 根据osnurl,listchannelid,cacertpool,tlsclientcert来生成对应的url
    2. 调用httpget,参数为url,cacertpool,tlsclientcert来获得所属OSN的单个通道的http响应
  2. 如果为空,则要获得所有通道的信息:

    1. 根据osnurl,listchannelid,cacertpool,tlsclientcert来生成对应的url
    2. 调用httpget,参数为url,cacertpool,tlsclientcert来获得所属OSN的所有通道的http响应

remove

Command为remove:

  1. 根据OSNURL,removechannelid,cacertpool,tlsclientcert来生成url

  2. 根据http.methoddelete,url来生成对应的请求

  3. 根据req,cacertpool,tlsclientcert来通过httpdo来获得http响应

  4. 将响应resp的body读取为二进制的形式bodybytes

  5. 根据bodybytes,resp.statuscode来生成output

  6. 返回output并将其读取

Peer

  1. 设置并预处理环境变量

  2. 从factory中获得cryptoprovider

  3. 根据cryptoprovider,将version,node,chaincode,channel,lifecycle,snaptshot的命令加入peer命令,最后生成peer父命令集,生成的Peer父命令集如下:

名称子命令参数帮助
NodeStartchaincodeDevMode 是否以链码开发模式启动节点启动与网络交互的节点
ResetConfig.rootfspath Ledger数据根目录重置创世区块的所有通道,Peer需处于离线状态
RollbackChannelid 要回滚的通道 \\Blocknumber 要回滚到的区块号回滚通道至一个特定的区块,Peer必须处于离线状态
pauseChannelid 要停止的通道暂停通道
ResumeChannelid 要继续运行的通道继续通道
RebuilddbsLedgerconfig删除所有通道的数据库,并在peer重启时重新构建它们
UpgradedbsLedgerconfig通过直接更新数据库格式或删除数据库来升级数据库
chaincode(1.4)installLang Ctor, Path, Name, Version, Peeraddress, Tlsrootcertfiles, Connectionprofile, Cryptoprovider 安装链码
Instantiate"lang", "ctor", "name", "channelID", "version", "policy", "escc", "vscc", "collections-config", "peerAddresses", "tlsRootCertFiles", "connectionProfile", 实例化链码
invokeCname", "ctor", "isInit", "channelID", "peerAddresses", "tlsRootCertFiles", "connectionProfile", "waitForEvent", "waitForEventTimeout" 调用链码函数,会提交一个背书交易
Package"lang", "path", "ctor", "name", "version", "cc-package", "sign", "instantiate-policy", 打包一个链码
Query"ctor", "name", "channelID", "peerAddresses", "tlsRootCertFiles", "connectionProfile",根据链码名及函数来调用并打印,不会生成交易
SignpackageIpackagefile 输入链码文件// Opackagefile 输出链码文件 对一个特定的链码包进行签名
Upgrade"lang", "ctor", "path", "name", "channelID", "version", "policy", "escc", "vscc", "peerAddresses", "tlsRootCertFiles", "connectionProfile", "collections-config",更新一个链码,新链码会立即替代旧链码
List"channelID", "installed", "instantiated", "peerAddresses", "tlsRootCertFiles", "connectionProfile", 获得在通道上实例化的链码或获得安装在peer上的链码
channelCreate"channelID", "file", "outputBlock", "timeout", Connectionprofile Cryptoprovider创建一个通道且将创世块写入文件
Fetch"channelID", "bestEffort" 获取一个特定的区块,并将它写入文件
Joinblockpath"将peer加入通道
Joinbysnapshotsnapshotpath 通过特定的快照将Peer加入通道
joinBySnapshotStatus查询joinbysnaptshot是否运行在任何通道上
List列出加入通道的peer节点
Upgrade"channelID", "file", 签名并将提供的configtx更新文件发送到通道
Signconfigtxfile 对文件系统上提供的configtx更新文件进行签名
GetinfoChannelid 获得特定通道上的区块链信息
SnaptshotSubmitrequest"channelID", "blockNumber", "peerAddress", "tlsRootCertFile", 在指定的块上提交一个快照请求
Cancelrequest"channelID", "blockNumber", "peerAddress", "tlsRootCertFile",取消对指定块的快照请求
listpending"channelID", "peerAddress", "tlsRootCertFile",列出快照挂起的请求
Lifecycle(2.0+)package"lang", "path", "ctor", "name", "version", "cc-package", "sign", "instantiate-policy",打包链码
Install"peerAddresses", "tlsRootCertFiles", "connectionProfile", "targetPeer",安装一个链码
Queryinstalled"peerAddresses", "tlsRootCertFiles", "connectionProfile", "targetPeer", "output",查询在peer上安装的链码
GetInstalledPackage"peerAddresses", "tlsRootCertFiles", "connectionProfile", "targetPeer", "package-id", "output-directory", 从一个Peer节点上获得安装的链码
ApproveForMyOrg "channelID", "name", "version", "package-id", "sequence", "endorsement-plugin", "validation-plugin", "signature-policy", "channel-config-policy", "init-required", "collections-config", "peerAddresses", "tlsRootCertFiles", "connectionProfile", "waitForEvent", "waitForEventTimeout", 支持链码定义
queryapproved "channelID", "name", "sequence", "peerAddresses", "tlsRootCertFiles", "connectionProfile", "output", 支从一个组织的peer上获得approved的链码定义
checkcommitreadiness "channelID", "name", "version", "sequence", "endorsement-plugin", "validation-plugin", "signature-policy", "channel-config-policy", "init-required", "collections-config", "peerAddresses", "tlsRootCertFiles", "connectionProfile", "output", 查看一个链码定义是否可以提交至通道
Commit "channelID", "name", "version", "sequence", "endorsement-plugin", "validation-plugin", "signature-policy", "channel-config-policy", "init-required", "collections-config", "peerAddresses", "tlsRootCertFiles", "connectionProfile", "waitForEvent", "waitForEventTimeout",向通道提交链码定义
Querrycommit "channelID", "name", "peerAddresses", "tlsRootCertFiles", "connectionProfile", "output",查询提交的链码定义

Idemixgen

名称功能参数帮助
Node创建ca密钥HostnameREST服务器将侦听的主机名或IP
PortREST服务器将侦听的端口
Cors 允许的cors域
Gensignerconfig为MSP创建一个默认的签名者Gencainput储存ca的文件夹
genCredOU默认组织者的签名单元
genCredIsAdmin创建默认的签名者admin
genCredEnrollmentId默认签名者的注册id
genCredRevocationHandle用来撤销签名

对不同的命令做出相应的响应:

gensisuerkey

命令为genissuerkey:

  1. 随机生成一个seed
  2. 根据msp中的attributenameou,attributenamerole,attributeenrollmentid,attributenamerevocationhandle来生成attributename
  3. 根据attributename和随机seed rng来生成key
  4. 将key的ipk整理后得到ipkserialized,即byte的形式
  5. 返回key.isk, ipkserialized
  6. 生成revocationkey
  7. 将revocationkey进行整理,获得encodedrevocationsk
  8. 根据encodedrevocationsk来生成私钥pemencodedrevocationsk
  9. 按照3-4生成公钥pemencodedrevocationpk,只不过将3中的revocationkey换为revocationkey.Public
  10. 将isk,pemencodedrevocationsk,ipk, pemencodedrevocationpk,ipk证书文件写入对应路径

gensignerconfig

命令为gensignerconfig:

  1. 对不同的身份admin与member来生成rolemask
  2. 如果gencainput为空,则将其设为outputdir
  3. 从issuerkey中获取获取ipk,ipkraw,相应的,获取私钥与公钥rsk,spk
  4. 根据rolemask,gencredou,genenrollmentid,gencredrevocationhandle,ipk,isk生成signerconfig
  5. 将该MSP配置写入文件

version

命令为version:打印version信息

Ledgerutil

名称功能参数帮助
Compare通过快照来比较两个账本快照路径1REST服务器将侦听的主机名或IP
快照路径2REST服务器将侦听的端口
输出路径允许的cors域
Troubleshoot确定可能存在分歧的交易
  1. 首先确定result json文件的路径

  2. 在该路径下生成结果文件

  3. 对不同的命令做出不同的响应:

compare

如果命令为比较:

  1. 比较两个文件的哈希

  2. 创建output文件

  3. 创建snaptshotreaders去读取snapshots

  4. 通过snaptshotreaders获得相应的命名空间和记录内容

  5. 如果记录项都没有缺失,则根据键值的大小来进行比较,键值为命名空间和记录内容生成的结构体:

    1. 如果键值相等内容不等,将比较的差异写入output中
    2. 如果键值不等,则表明有缺,则将缺的内容写入output中,并将缺的snaptshop快进,重新获得命名空间和记录项
  6. 如果记录项有缺失,则将缺失的内容写入output中,并将缺失的镜像进行加速快进

  7. 返回生成的json文件

troubleshoot

如果命令为troubleshoot,则打印command TBD

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值