104 lignes
5.0 KiB
Go
104 lignes
5.0 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"math"
|
|
"os"
|
|
"time"
|
|
)
|
|
|
|
type Offer struct {
|
|
ID string `json:"id"`
|
|
Date int `json:"date"`
|
|
OwnerNodeAddress NodeAddress `json:"ownerNodeAddress"`
|
|
Direction string `json:"direction"`
|
|
Price int `json:"price"`
|
|
MarketPriceMargin float64 `json:"marketPriceMargin"`
|
|
UseMarketBasedPrice bool `json:"useMarketBasedPrice"`
|
|
Amount int64 `json:"amount"`
|
|
MinAmount int64 `json:"minAmount"`
|
|
BaseCurrencyCode string `json:"baseCurrencyCode"`
|
|
CounterCurrencyCode string `json:"counterCurrencyCode"`
|
|
ArbitratorNodeAddresses []NodeAddress `json:"arbitratorNodeAddresses"`
|
|
MediatorNodeAddress []NodeAddress `json:"mediatorNodeAddresses"`
|
|
PaymentMethodId string `json:"paymentMethodId"`
|
|
MakerPaymentAccountId string `json:"makerPaymentAccountId"`
|
|
OfferFeePaymentTxId string `json:"offerFeePaymentTxId"`
|
|
VersionNR string `json:"versionNr"`
|
|
BlockHeightAtOfferCreation int `json:"blockHeightAtOfferCreation"`
|
|
TxFee int `json:"txFee"`
|
|
MakerFee int `json:"makerFee"`
|
|
IsCurrencyForMakerFeeBtc bool `json:"isCurrencyForMakerFeeBtc"`
|
|
BuyerSecurityDeposit int `json:"buyerSecurityDeposit"`
|
|
SellerSecurityDeposit int `json:"sellerSecurityDeposit"`
|
|
MaxTradeLimit int `json:"maxTradeLimit"`
|
|
MaxTradePeriod int `json:"maxTradePeriod"`
|
|
UseAutoClose bool `json:"useAutoClose"`
|
|
UseReOpenAfterAutoClose bool `json:"useReOpenAfterAutoClose"`
|
|
LowerClosePrice int `json:"lowerClosePrice"`
|
|
UpperClosePrice int `json:"upperClosePrice"`
|
|
IsPrivateOffer bool `json:"isPrivateOffer"`
|
|
ExtraDataMap map[string]string `json:"extraDataMap"`
|
|
ProtocolVersion int `json:"protocolVersion"`
|
|
}
|
|
|
|
type NodeAddress struct {
|
|
HostName string `json:"hostName"`
|
|
Port int `json:"port"`
|
|
}
|
|
|
|
type AccountPayload struct {
|
|
Address string `json:"address"`
|
|
PaymentMethodId string `json:"paymentMethodId"`
|
|
ID string `json:"id"`
|
|
MaxTradePeriod int `json:"maxTradePeriod"`
|
|
}
|
|
|
|
type BisqContract struct {
|
|
OfferPayload Offer `json:"offerPayload"`
|
|
TradeAmount int `json:"tradeAmount"`
|
|
TradePrice int `json:"tradePrice"`
|
|
TakerFeeTXID string `json:"takerFeeTxID"`
|
|
BuyerNodeAddress NodeAddress `json:"buyerNodeAddress"`
|
|
SellerNodeAddress NodeAddress `json:"sellerNodeAddress"`
|
|
MediatorNodeAddress NodeAddress `json:"mediatorNodeAddress"`
|
|
IsBuyerMakerAndSellerTaker bool `json:"isBuyerMakerAndSellerTaker"`
|
|
MakerAccountId string `json:"makerAccountId"`
|
|
TakerAccountId string `json:"takerAccountId"`
|
|
MakerPaymentAccountPayload AccountPayload `json:"makerPaymentAccountPayload"`
|
|
TakerPaymentAccountPayload AccountPayload `json:"takerPaymentAccountPayload"`
|
|
MakerPayoutAddressString string `json:"makerPayoutAddressString"`
|
|
TakerPayoutAddressString string `json:"takerPayoutAddressString"`
|
|
LockTime int `json:"lockTime"`
|
|
RefundAgentNodeAddress NodeAddress `json:"refundAgentNodeAddress"`
|
|
}
|
|
|
|
// Ideally this should be 10 minutes, but realistically...
|
|
const AverageBlockTime = 9.465
|
|
const BisqLockTime = 6 * 24 * 10 // 6 blocks an hour * 24 hours a day * 10 days (for alt coin trades)
|
|
|
|
func EstimateBlockHeightTime(blockHeight int) time.Time {
|
|
loc, _ := time.LoadLocation("America/Vancouver")
|
|
return time.Date(2009, 01, 03, 18, 15, 00, 00, loc).Add(time.Minute * time.Duration(int64(math.Round(float64(blockHeight)*AverageBlockTime))))
|
|
}
|
|
|
|
func main() {
|
|
contractBytes, _ := ioutil.ReadFile(os.Args[1])
|
|
contract := new(BisqContract)
|
|
err := json.Unmarshal(contractBytes, contract)
|
|
if err == nil {
|
|
// Deal with general formatting weirdness. The canonical Bisq hash output is over the contract
|
|
// when it has been formatted to separated fields by newlines, and with an indent of 2 spaces
|
|
contractOut, _ := json.MarshalIndent(contract, "", " ")
|
|
fmt.Printf("Successfully Validated Contract\n")
|
|
fmt.Printf("Contract Offer Date: %s\n", time.Unix(int64(contract.OfferPayload.Date/1000), 0))
|
|
fmt.Printf("Contract Block Height %d (estimated) / %s (estimated)\n", contract.LockTime-BisqLockTime, EstimateBlockHeightTime(contract.LockTime-BisqLockTime))
|
|
fmt.Printf("Contract Hash: %x\n", sha256.Sum256(contractOut))
|
|
} else {
|
|
fmt.Printf("Error %v", err)
|
|
}
|
|
}
|