예제 #1
0
func (n *OpenBazaarNode) Purchase(data *PurchaseData) error {
	// TODO: validate the purchase data is formatted properly
	contract := new(pb.RicardianContract)
	order := new(pb.Order)
	order.RefundAddress = n.Wallet.GetCurrentAddress(bitcoin.REFUND).EncodeAddress()

	order.Shipping.ShipTo = data.shipTo
	order.Shipping.Address = data.address
	order.Shipping.City = data.city
	order.Shipping.State = data.state
	order.Shipping.PostalCode = data.postalCode
	order.Shipping.Country = pb.CountryCode(pb.CountryCode_value[data.countryCode])

	// TODO: Add blockchain ID to order
	order.BuyerID.Guid = n.IpfsNode.Identity.Pretty()
	pubkey, err := n.IpfsNode.PrivateKey.GetPublic().Bytes()
	if err != nil {
		return err
	}
	order.BuyerID.Pubkeys.Guid = pubkey
	order.BuyerID.Pubkeys.Bitcoin = n.Wallet.GetMasterPublicKey().Key

	order.Timestamp = uint64(time.Now().Unix())

	for _, item := range data.items {
		i := new(pb.Order_Item)
		b, err := ipfs.Cat(n.Context, item.listingHash)
		if err != nil {
			return err
		}
		rc := new(pb.RicardianContract)
		err = jsonpb.UnmarshalString(string(b), rc)
		if err != nil {
			return err
		}
		// TODO: validate signatures on this contract before we purchase it
		contract.VendorListings = append(contract.VendorListings, rc.VendorListings[0])
		contract.Signatures = append(contract.Signatures, rc.Signatures[0])
		ser, err := proto.Marshal(rc.VendorListings[0])
		if err != nil {
			return err
		}
		h := sha256.Sum256(ser)
		i.ListingHash = h[:]
		i.Quantity = uint32(item.quantity)

		for _, option := range item.options {
			o := new(pb.Order_Item_Option)
			o.Name = option.name
			o.Value = option.value
			i.Options = append(i.Options, o)
		}
		order.Items = append(order.Items, i)
	}

	// TODO: create payment obj
	// TODO: send to vendor
	return nil
}
예제 #2
0
// Add our identity to the listings and sign it
func (n *OpenBazaarNode) SignListing(listing *pb.Listing) (*pb.RicardianContract, error) {
	c := new(pb.RicardianContract)
	if err := validate(listing); err != nil {
		return c, err
	}
	id := new(pb.ID)
	id.Guid = n.IpfsNode.Identity.Pretty()
	pubkey, err := n.IpfsNode.PrivateKey.GetPublic().Bytes()
	if err != nil {
		return c, err
	}
	//TODO: add blockchain ID to listing
	p := new(pb.ID_Pubkeys)
	p.Guid = pubkey
	p.Bitcoin = n.Wallet.GetMasterPublicKey().Key
	id.Pubkeys = p
	listing.VendorID = id
	s := new(pb.Signatures)
	s.Section = pb.Signatures_LISTING
	serializedListing, err := proto.Marshal(listing)
	if err != nil {
		return c, err
	}
	guidSig, err := n.IpfsNode.PrivateKey.Sign(serializedListing)
	if err != nil {
		return c, err
	}
	priv, _ := ec.PrivKeyFromBytes(ec.S256(), n.Wallet.GetMasterPrivateKey().Key)
	hashed := sha256.Sum256(serializedListing)
	bitcoinSig, err := priv.Sign(hashed[:])
	if err != nil {
		return c, err
	}
	s.Guid = guidSig
	s.Bitcoin = bitcoinSig.Serialize()
	c.VendorListings = append(c.VendorListings, listing)
	c.Signatures = append(c.Signatures, s)
	return c, nil
}