【Filecoin相关】Filecoin之propose-deal客户端逻辑

【Filecoin相关】Filecoin之propose-deal客户端逻辑

【Filecoin相关】Filecoin之propose-deal客户端逻辑 
     命令解析

【Filecoin相关】Filecoin之propose-deal客户端逻辑

// Propose a storage deal with a storage miner

$ go-filecoin client propose-storage-deal <miner> <data> <ask> <duration>

miner-矿工ID,指的是接收处理客户发起文件的节点miner;

data-本地数据cid,将本地文件传到filecoin local node后生成的cid,其命令如下:

$ go-filecoin client import [–] <file>

【Filecoin相关】Filecoin之propose-deal客户端逻辑

ask-矿工挂单id,挂单指的是矿工公示在网络中告知其他节点存储区块所需的报酬信息,可以通过如下命令进行查询:

$ go-filecoin client list-asks | grep <cid>

【Filecoin相关】Filecoin之propose-deal客户端逻辑

duration-时间参数,存储多久.计算方式:

Filecoin假设每30秒产生一个区块,用产生的区块个数代表存储的期限,如一天的代表就是:

2*60*24=2880

下单命令举例:

$ go-filecoin client propose-storage-deal t2d6cp6uui6ggewux5kksfc5beqwe6633dvq7niky QmPbD9yJo3EZF698KW2TiU4WqeanyRA9J87q8XLmac5HPR 000 2880

    代码解读
【Filecoin相关】Filecoin之propose-deal客户端逻辑

(1)获取矿工对应节点pid;

(2)启动goroutine,测试能否连接上对方节点;

(3)解析参数构造Proposal对象并判断订单正确性;

(4)创建支付渠道;

(5)创建订单请求,进行数据交换

// ProposeDeal proposes a storage deal to a miner. Pass allowDuplicates = true to

// allow duplicate proposals without error.

func (smc *Client) ProposeDeal(ctx context.Context, miner address.Address, data cid.Cid, askID uint64, duration uint64, allowDuplicates bool) (*storagedeal.Response, error) {

    ctxSetup, cancel := context.WithTimeout(ctx, 30*smc.node.GetBlockTime()) // 5

    defer cancel()

    pid, err := smc.api.MinerGetPeerID(ctxSetup, miner)

    if err != nil {

        return nil, err

    }

    minerAlive := make(chan error, 1)

    go func() {

        defer close(minerAlive)

        minerAlive <- smc.pingMiner(ctxSetup, pid, 15*time.Second)

    }()

    size, err := smc.api.DAGGetFileSize(ctxSetup, data)

    if err != nil {

        return nil, errors.Wrap(err, “failed to determine the size of the data”)

    }

    ask, err := smc.api.MinerGetAsk(ctxSetup, miner, askID)

    if err != nil {

        return nil, errors.Wrap(err, “failed to get ask price”)

    }

    price := ask.Price

    chainHeight, err := smc.api.ChainBlockHeight(ctxSetup)

    if err != nil {

        return nil, err

    }

    fromAddress, err := smc.api.WalletDefaultAddress()

    if err != nil {

        return nil, err

    }

    minerOwner, err := smc.api.MinerGetOwnerAddress(ctxSetup, miner)

    if err != nil {

        return nil, err

    }

    totalPrice := price.MulBigInt(big.NewInt(int64(size * duration)))

    proposal := &storagedeal.Proposal{

        PieceRef: data,

        Size: types.NewBytesAmount(size),

        TotalPrice: totalPrice,

        Duration: duration,

        MinerAddress: miner,

    }

    if smc.isMaybeDupDeal(proposal) && !allowDuplicates {

        return nil, Errors[ErrDuplicateDeal]

    }

    // see if we managed to connect to the miner

    select {

    case err := <-minerAlive:

        if err != nil {

            return nil, err

        }

    case <-ctxSetup.Done():

        return nil, ctxSetup.Err()

    }

    // create payment information

    cpResp, err := smc.api.CreatePayments(ctxSetup, porcelain.CreatePaymentsParams{

        From: fromAddress,

        To: minerOwner,

        Value: *price.MulBigInt(big.NewInt(int64(size * duration))),

        Duration: duration,

        PaymentInterval: VoucherInterval,

        ChannelExpiry: *chainHeight.Add(types.NewBlockHeight(duration + ChannelExpiryInterval)),

        GasPrice: *types.NewAttoFIL(big.NewInt(CreateChannelGasPrice)),

        GasLimit: types.NewGasUnits(CreateChannelGasLimit),

    })

    if err != nil {

        return nil, errors.Wrap(err, “error creating payment”)

    }

    proposal.Payment.Channel = cpResp.Channel

    proposal.Payment.PayChActor = address.PaymentBrokerAddress

    proposal.Payment.Payer = fromAddress

    proposal.Payment.ChannelMsgCid = &cpResp.ChannelMsgCid

    proposal.Payment.Vouchers = cpResp.Vouchers

    signedProposal, err := proposal.NewSignedProposal(fromAddress, smc.api)

    if err != nil {

        return nil, err

    }

    // send proposal

    var response storagedeal.Response

    // We reset the context to not timeout to allow large file transfers

    // to complete.

    err = smc.node.MakeProtocolRequest(ctx, makeDealProtocol, pid, signedProposal, &response)

    if err != nil {

        return nil, errors.Wrap(err, “error sending proposal”)

    }

    if err := smc.checkDealResponse(ctx, &response); err != nil {

        return nil, errors.Wrap(err, “response check failed”)

    }

    // Note: currently the miner requests the data out of band

    if err := smc.recordResponse(&response, miner, proposal); err != nil {

        return nil, errors.Wrap(err, “failed to track response”)

    }

    return &response, nil

}

【Filecoin相关】Filecoin之propose-deal客户端逻辑

 

【IPFS原力区】

总部位于上海,深耕IPFS社区发展与商业生态建设

Force系列产品布局IPFS商业应用,贯通视频娱乐、文件共享、浏览器入口、数据加密管理等服务,为企业与个人的使用提供一站式服务。

旗下IPFS原力区是IPFS顶级价值生态社区,聚集了众多技术大咖和IPFS爱好者,通过持续输出全面、精细、优质的IPFS咨询和技术支持,将生态中的爱好者转化为IPFS支持者和参与者,推动IPFS生态的健康发展。

【Filecoin相关】Filecoin之propose-deal客户端逻辑

原创文章,作者:IPFSforce,如若转载,请注明出处:http://ipfser.org/2019/05/07/%e3%80%90filecoin%e7%9b%b8%e5%85%b3%e3%80%91filecoin%e4%b9%8bpropose-deal%e5%ae%a2%e6%88%b7%e7%ab%af%e9%80%bb%e8%be%91-2/

发表评论

登录后才能评论

联系我们

在线咨询:点击这里给我发消息

邮件:ipfsforce@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code