func (a *AuctionOrder) GenerateExecutionFromPrice(orderID *OrderID, execPrice float64, amountToFill uint64) (orderExec OrderExecution, setExecs []*SettlementExecution, fillRemainder uint64, err error) {
	var amountWantToFill uint64
	var debitAsset Asset
	var creditAsset Asset
	if a.IsBuySide() {
		debitAsset = a.TradingPair.AssetHave
		creditAsset = a.TradingPair.AssetWant
	} else if a.IsSellSide() {
		debitAsset = a.TradingPair.AssetWant
		creditAsset = a.TradingPair.AssetHave
	} else {
		err = fmt.Errorf("Error generating execution from price, order is not buy or sell side, it's %s side", a.Side.String())
		return
	}
	amountWantToFill = uint64(float64(amountToFill) * execPrice)
	if amountWantToFill >= a.AmountHave {
		fillRemainder = amountWantToFill - a.AmountHave
		if orderExec, setExecs, err = a.GenerateOrderFill(orderID, execPrice); err != nil {
			err = fmt.Errorf("Error generating order fill while generating exec for price: %s", err)
			return
		}
	} else {
		orderExec = OrderExecution{
			OrderID:       *orderID,
			NewAmountWant: a.AmountWant - amountToFill,
			NewAmountHave: a.AmountHave - amountWantToFill,
			Filled:        false,
		}
		debitSetExec := SettlementExecution{
			Amount: amountToFill,
			Asset:  debitAsset,
			Type:   Debit,
		}
		creditSetExec := SettlementExecution{
			Amount: amountWantToFill,
			Asset:  creditAsset,
			Type:   Credit,
		}
		copy(debitSetExec.Pubkey[:], a.Pubkey[:])
		copy(creditSetExec.Pubkey[:], a.Pubkey[:])
		setExecs = append(setExecs, &debitSetExec)
		setExecs = append(setExecs, &creditSetExec)
	}
	return
}
GenerateExecutionFromPrice generates a trade execution from a price and an amount to fill. This is intended to be
used by the matching engine when a price is determined for this order to execute at.
amountToFill refers to the amount of AssetWant that can be filled. So the other side's "AmountHave" can be passed
in as a parameter. The order ID will be filled in, as it's being passed as a parameter.
This returns a fillRemainder, which is the amount that is left over from amountToFill after
filling orderID at execPrice and amountToFill
package match
import (
	"encoding/binary"
	"encoding/json"
	"fmt"
	"github.com/mit-dci/opencx/crypto/timelockencoders"
)
type OrderPuzzleResult struct {
	Encrypted *EncryptedAuctionOrder
	Auction   *AuctionOrder
	Err       error
}
type AuctionOrder struct {
	Pubkey      [33]byte `json:"pubkey"`
	Side        Side     `json:"side"`
	TradingPair Pair     `json:"pair"`
	AmountHave uint64 `json:"amounthave"`
	AmountWant uint64 `json:"amountwant"`
	AuctionID AuctionID `json:"auctionid"`
	Nonce     [2]byte `json:"nonce"`
	Signature []byte  `json:"signature"`
}
func (a *AuctionOrder) TurnIntoEncryptedOrder(t uint64) (encrypted *EncryptedAuctionOrder, err error) {
	encrypted = new(EncryptedAuctionOrder)
	if encrypted.OrderCiphertext, encrypted.OrderPuzzle, err = timelockencoders.CreateRSW2048A2PuzzleRC5(t, a.Serialize()); err != nil {
		err = fmt.Errorf("Error creating puzzle from auction order: %s", err)
		return
	}
	encrypted.IntendedAuction = a.AuctionID
	encrypted.IntendedPair = a.TradingPair
	return
}
func (a *AuctionOrder) IsBuySide() bool {
	return a.Side == Buy
}
func (a *AuctionOrder) IsSellSide() bool {
	return a.Side == Sell
}
func (a *AuctionOrder) OppositeSide() (sideStr Side) {
	if a.IsBuySide() {
		sideStr = Sell
	} else if a.IsSellSide() {
		sideStr = Buy
	}
	return
}
func (a *AuctionOrder) Price() (price float64, err error) {
	if a.AmountWant == 0 || a.AmountHave == 0 {
		err = fmt.Errorf("The amount requested in the order is 0, so no price can be calculated")
		return
	}
	price = float64(a.AmountWant) / float64(a.AmountHave)
	return
}
func (a *AuctionOrder) GenerateOrderFill(orderID *OrderID, execPrice float64) (orderExec OrderExecution, setExecs []*SettlementExecution, err error) {
	if a.AmountHave == 0 {
		err = fmt.Errorf("Error generating order fill: empty order, the AmountHave cannot be 0")
		return
	}
	if execPrice == float64(0) {
		err = fmt.Errorf("Error generating order fill: price cannot be zero")
		return
	}
	var amountToDebit uint64
	var debitAsset Asset
	var creditAsset Asset
	if a.IsBuySide() {
		debitAsset = a.TradingPair.AssetWant
		creditAsset = a.TradingPair.AssetHave
	} else if a.IsSellSide() {
		debitAsset = a.TradingPair.AssetHave
		creditAsset = a.TradingPair.AssetWant
	} else {
		err = fmt.Errorf("Error generating order fill from price, order is not buy or sell side, it's %s side", a.Side.String())
		return
	}
	amountToDebit = uint64(float64(a.AmountHave) * execPrice)
	orderExec = OrderExecution{
		OrderID:       *orderID,
		NewAmountWant: 0,
		NewAmountHave: 0,
		Filled:        true,
	}
	debitSetExec := SettlementExecution{
		Amount: amountToDebit,
		Asset:  debitAsset,
		Type:   Debit,
	}
	creditSetExec := SettlementExecution{
		Amount: a.AmountHave,
		Asset:  creditAsset,
		Type:   Credit,
	}
	copy(debitSetExec.Pubkey[:], a.Pubkey[:])
	copy(creditSetExec.Pubkey[:], a.Pubkey[:])
	setExecs = append(setExecs, &debitSetExec)
	setExecs = append(setExecs, &creditSetExec)
	return
}