diff --git a/src/main/java/io/bitsquare/btc/WalletFacade.java b/src/main/java/io/bitsquare/btc/WalletFacade.java
index 51a76816a9..ca85ed96ab 100644
--- a/src/main/java/io/bitsquare/btc/WalletFacade.java
+++ b/src/main/java/io/bitsquare/btc/WalletFacade.java
@@ -33,6 +33,8 @@ import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN;
+
/**
* TODO: use walletextension (with protobuffer) instead of saving addressEntryList via storage
* TODO: use HD wallet features instead of addressEntryList
@@ -605,9 +607,8 @@ public class WalletFacade
Transaction tx = new Transaction(params);
- //TODO priv key is null, use other signing key or find out why it is null at that moment
- //byte[] data = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationAddressInfo().getKey(), stringifiedBankAccounts);
- //tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, new ScriptBuilder().op(OP_RETURN).data(data).build());
+ byte[] data = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationAddressInfo().getKey(), stringifiedBankAccounts);
+ tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, new ScriptBuilder().op(OP_RETURN).data(data).build());
Coin fee = FeePolicy.ACCOUNT_REGISTRATION_FEE.subtract(Transaction.MIN_NONDUST_OUTPUT).subtract(FeePolicy.TX_FEE);
log.trace("fee: " + fee.toFriendlyString());
diff --git a/src/main/java/io/bitsquare/crypto/CryptoFacade.java b/src/main/java/io/bitsquare/crypto/CryptoFacade.java
index 082dc82339..c0edb4db58 100644
--- a/src/main/java/io/bitsquare/crypto/CryptoFacade.java
+++ b/src/main/java/io/bitsquare/crypto/CryptoFacade.java
@@ -1,12 +1,18 @@
package io.bitsquare.crypto;
import com.google.bitcoin.core.ECKey;
+import com.google.bitcoin.core.Sha256Hash;
import com.google.bitcoin.core.Utils;
+import com.google.bitcoin.crypto.KeyCrypterException;
import com.google.common.base.Charsets;
+import java.nio.charset.Charset;
import java.security.SignatureException;
+import javax.annotation.Nullable;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.util.encoders.Base64;
/**
* That facade delivers crypto functionality from the bitcoinJ library
@@ -21,16 +27,42 @@ public class CryptoFacade
{
}
+ // DeterministicKey does not support signMessage yet.
+ private String signMessage(ECKey key, String message, @Nullable KeyParameter aesKey) throws KeyCrypterException
+ {
+ byte[] data = Utils.formatMessageForSigning(message);
+ Sha256Hash hash = Sha256Hash.createDouble(data);
+ ECKey.ECDSASignature sig = key.sign(hash, aesKey);
+ // Now we have to work backwards to figure out the recId needed to recover the signature.
+ int recId = -1;
+ for (int i = 0; i < 4; i++)
+ {
+ ECKey k = ECKey.recoverFromSignature(i, sig, hash, key.isCompressed());
+ if (k != null && k.getPubKeyPoint().equals(key.getPubKeyPoint()))
+ {
+ recId = i;
+ break;
+ }
+ }
+ if (recId == -1)
+ throw new RuntimeException("Could not construct a recoverable key. This should never happen.");
+ int headerByte = recId + 27 + (key.isCompressed() ? 4 : 0);
+ byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S
+ sigData[0] = (byte) headerByte;
+ System.arraycopy(Utils.bigIntegerToBytes(sig.r, 32), 0, sigData, 1, 32);
+ System.arraycopy(Utils.bigIntegerToBytes(sig.s, 32), 0, sigData, 33, 32);
+ return new String(Base64.encode(sigData), Charset.forName("UTF-8"));
+ }
public byte[] getEmbeddedAccountRegistrationData(ECKey registrationKey, String stringifiedBankAccounts)
{
- String signedBankAccountIDs = registrationKey.signMessage(stringifiedBankAccounts);
+ String signedBankAccountIDs = signMessage(registrationKey, stringifiedBankAccounts, null);
return Utils.sha256hash160(concatenateChunks(stringifiedBankAccounts, signedBankAccountIDs).getBytes(Charsets.UTF_8));
}
public String signContract(ECKey key, String contractAsJson)
{
- return key.signMessage(contractAsJson);
+ return signMessage(key, contractAsJson, null);
}
// registration
@@ -38,7 +70,7 @@ public class CryptoFacade
{
try
{
- ECKey key = new ECKey(null, pubKey, true);
+ ECKey key = ECKey.fromPublicOnly(pubKey);
key.verifyMessage(msg, sig);
return true;
} catch (SignatureException e)
diff --git a/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationView.fxml b/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationView.fxml
index b041edc628..0ddd7ffff5 100644
--- a/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationView.fxml
+++ b/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationView.fxml
@@ -26,19 +26,19 @@
-
+
-
+
-
+
diff --git a/src/main/java/io/bitsquare/gui/market/createOffer/CreateOfferController.java b/src/main/java/io/bitsquare/gui/market/createOffer/CreateOfferController.java
index 479017c4c3..bfce9fcc83 100644
--- a/src/main/java/io/bitsquare/gui/market/createOffer/CreateOfferController.java
+++ b/src/main/java/io/bitsquare/gui/market/createOffer/CreateOfferController.java
@@ -214,7 +214,7 @@ public class CreateOfferController implements Initializable, ChildController, Hi
if (user.getCurrentBankAccount() != null)
{
Coin amountAsCoin = BitSquareFormatter.parseBtcToCoin(getAmountString());
- Coin minAmountAsCoin = BitSquareFormatter.parseBtcToCoin(getAmountString());
+ Coin minAmountAsCoin = BitSquareFormatter.parseBtcToCoin(getMinAmountString());
offer = new Offer(user.getMessagePublicKey(),
direction,
@@ -354,6 +354,18 @@ public class CreateOfferController implements Initializable, ChildController, Hi
}
}
+ private String getMinAmountString()
+ {
+ try
+ {
+ BitSquareValidator.textFieldsHasPositiveDoubleValueWithReset(minAmountTextField);
+ return minAmountTextField.getText();
+ } catch (BitSquareValidator.ValidationException e)
+ {
+ return "0";
+ }
+ }
+
private double getCollateral()
{
// TODO
diff --git a/src/main/java/io/bitsquare/gui/market/createOffer/CreateOfferView.fxml b/src/main/java/io/bitsquare/gui/market/createOffer/CreateOfferView.fxml
index 7bb299d324..6db240da5e 100644
--- a/src/main/java/io/bitsquare/gui/market/createOffer/CreateOfferView.fxml
+++ b/src/main/java/io/bitsquare/gui/market/createOffer/CreateOfferView.fxml
@@ -24,7 +24,7 @@
-
+
diff --git a/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookListItem.java b/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookListItem.java
index 0f4354b037..81007d93f2 100644
--- a/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookListItem.java
+++ b/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookListItem.java
@@ -20,7 +20,7 @@ public class OrderBookListItem
this.offer = offer;
this.price.set(BitSquareFormatter.formatPrice(offer.getPrice()));
this.amount.set(BitSquareFormatter.formatCoinToBtc(offer.getAmount()) + " (" + BitSquareFormatter.formatCoinToBtc(offer.getMinAmount()) + ")");
- this.volume.set(BitSquareFormatter.formatVolumeWithMinVolume(offer.getVolume(), offer.getMinVolume()));
+ this.volume.set(BitSquareFormatter.formatVolumeWithMinVolume(offer.getOfferVolume(), offer.getMinOfferVolume()));
}
diff --git a/src/main/java/io/bitsquare/gui/market/trade/TakeOfferView.fxml b/src/main/java/io/bitsquare/gui/market/trade/TakeOfferView.fxml
index 4f5c17dd21..21753333e7 100644
--- a/src/main/java/io/bitsquare/gui/market/trade/TakeOfferView.fxml
+++ b/src/main/java/io/bitsquare/gui/market/trade/TakeOfferView.fxml
@@ -18,7 +18,7 @@
-
+
@@ -122,7 +122,7 @@
-
+
@@ -133,7 +133,7 @@
-
+
diff --git a/src/main/java/io/bitsquare/gui/market/trade/TakerOfferController.java b/src/main/java/io/bitsquare/gui/market/trade/TakerOfferController.java
index 595d658ac4..30b8ef143b 100644
--- a/src/main/java/io/bitsquare/gui/market/trade/TakerOfferController.java
+++ b/src/main/java/io/bitsquare/gui/market/trade/TakerOfferController.java
@@ -200,8 +200,9 @@ public class TakerOfferController implements Initializable, ChildController
public void onPayoutTxPublished(Trade trade, String payoutTxId)
{
accordion.setExpandedPane(summaryTitledPane);
+
summaryPaidTextField.setText(BitSquareFormatter.formatCoinToBtcWithCode(trade.getTradeAmount()));
- summaryReceivedTextField.setText(BitSquareFormatter.formatVolume(trade.getOffer().getPrice() * trade.getTradeAmount().value));
+ summaryReceivedTextField.setText(BitSquareFormatter.formatVolume(trade.getTradeVolume()));
summaryFeesTextField.setText(BitSquareFormatter.formatCoinToBtcWithCode(FeePolicy.TAKE_OFFER_FEE.add(FeePolicy.TX_FEE)));
summaryCollateralTextField.setText(BitSquareFormatter.formatCoinToBtcWithCode(trade.getCollateralAmount()));
summaryDepositTxIdTextField.setText(depositTxId);
diff --git a/src/main/java/io/bitsquare/gui/orders/offer/OfferListItem.java b/src/main/java/io/bitsquare/gui/orders/offer/OfferListItem.java
index 231e1001f5..10ff9a8760 100644
--- a/src/main/java/io/bitsquare/gui/orders/offer/OfferListItem.java
+++ b/src/main/java/io/bitsquare/gui/orders/offer/OfferListItem.java
@@ -23,7 +23,7 @@ public class OfferListItem
this.price.set(BitSquareFormatter.formatPrice(offer.getPrice()));
this.amount.set(BitSquareFormatter.formatCoinToBtc(offer.getAmount()) + " (" + BitSquareFormatter.formatCoinToBtc(offer.getMinAmount()) + ")");
- this.volume.set(BitSquareFormatter.formatVolumeWithMinVolume(offer.getVolume(), offer.getMinVolume()));
+ this.volume.set(BitSquareFormatter.formatVolumeWithMinVolume(offer.getOfferVolume(), offer.getMinOfferVolume()));
this.offerId = offer.getId();
}
diff --git a/src/main/java/io/bitsquare/gui/orders/pending/PendingTradeController.java b/src/main/java/io/bitsquare/gui/orders/pending/PendingTradeController.java
index 632901a80e..ea9079102f 100644
--- a/src/main/java/io/bitsquare/gui/orders/pending/PendingTradeController.java
+++ b/src/main/java/io/bitsquare/gui/orders/pending/PendingTradeController.java
@@ -292,16 +292,13 @@ public class PendingTradeController implements Initializable, ChildController, H
txTitleLabel.setText("Payout transaction ID:");
bankAccountDetailsHeaderLabel.setText("Summary");
- bankAccountTypeTitleLabel.setText("You have bought (BTC):");
+ bankAccountTypeTitleLabel.setText("You have bought:");
holderNameTitleLabel.setText("You have payed (" + trade.getOffer().getCurrency() + "):");
primaryBankAccountIDTitleLabel.setText("Total fees (offer fee + tx fee):");
secondaryBankAccountIDTitleLabel.setText("Refunded collateral:");
- //TODO
- String fiatPayed = BitSquareFormatter.formatVolume(trade.getOffer().getPrice() * trade.getTradeAmount().value);
-
bankAccountTypeTextField.setText(BitSquareFormatter.formatCoinToBtcWithCode(trade.getTradeAmount()));
- holderNameTextField.setText(fiatPayed);
+ holderNameTextField.setText(BitSquareFormatter.formatVolume(trade.getTradeVolume()));
primaryBankAccountIDTextField.setText(BitSquareFormatter.formatCoinToBtcWithCode(FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE)));
secondaryBankAccountIDTextField.setText(BitSquareFormatter.formatCoinToBtcWithCode(trade.getCollateralAmount()));
diff --git a/src/main/java/io/bitsquare/trade/Offer.java b/src/main/java/io/bitsquare/trade/Offer.java
index 52bd41e767..968b99b4af 100644
--- a/src/main/java/io/bitsquare/trade/Offer.java
+++ b/src/main/java/io/bitsquare/trade/Offer.java
@@ -5,6 +5,7 @@ import io.bitsquare.bank.BankAccountType;
import io.bitsquare.locale.Country;
import io.bitsquare.user.Arbitrator;
import java.io.Serializable;
+import java.math.BigDecimal;
import java.security.PublicKey;
import java.util.*;
@@ -23,6 +24,7 @@ public class Offer implements Serializable
private final double price;
private final Coin amount;
private final Coin minAmount;
+ //TODO use hex string
private final PublicKey messagePublicKey;
private final BankAccountType bankAccountType;
private final Country bankAccountCountry;
@@ -137,14 +139,21 @@ public class Offer implements Serializable
return acceptedLanguageLocales;
}
- public double getVolume()
+ public double getVolumeForCoin(Coin coin)
{
- return price * amount.value;
+ BigDecimal amountBD = BigDecimal.valueOf(coin.longValue());
+ BigDecimal volumeBD = amountBD.multiply(BigDecimal.valueOf(price));
+ return volumeBD.divide(BigDecimal.valueOf(Coin.COIN.value)).doubleValue();
}
- public double getMinVolume()
+ public double getOfferVolume()
{
- return price * minAmount.value;
+ return getVolumeForCoin(amount);
+ }
+
+ public double getMinOfferVolume()
+ {
+ return getVolumeForCoin(minAmount);
}
public String getOfferFeePaymentTxID()
diff --git a/src/main/java/io/bitsquare/trade/Trade.java b/src/main/java/io/bitsquare/trade/Trade.java
index 097963abe9..bcd7168d50 100644
--- a/src/main/java/io/bitsquare/trade/Trade.java
+++ b/src/main/java/io/bitsquare/trade/Trade.java
@@ -38,6 +38,10 @@ public class Trade implements Serializable
_stateChangedProperty = new SimpleStringProperty();
}
+ public double getTradeVolume()
+ {
+ return offer.getVolumeForCoin(tradeAmount);
+ }
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
diff --git a/src/main/java/io/bitsquare/trade/protocol/offerer/VerifyAndSignContract.java b/src/main/java/io/bitsquare/trade/protocol/offerer/VerifyAndSignContract.java
index 77a44bc32c..3cfddd18e3 100644
--- a/src/main/java/io/bitsquare/trade/protocol/offerer/VerifyAndSignContract.java
+++ b/src/main/java/io/bitsquare/trade/protocol/offerer/VerifyAndSignContract.java
@@ -39,16 +39,13 @@ public class VerifyAndSignContract
// log.trace("Offerers contractAsJson: " + contractAsJson);
// log.trace("Takers contractAsJson: " + sharedModel.peersContractAsJson);
- //TODO not matching yet due refactoring...
- /* if (contractAsJson.equals(peersContractAsJson))
- { */
- log.trace("The 2 contracts as json does match");
- //String signature = cryptoFacade.signContract(registrationKey, contractAsJson);
- String signature = "TODO";
- //log.trace("signature: " + signature);
-
- resultHandler.onResult(contract, contractAsJson, signature);
- /* }
+ if (contractAsJson.equals(peersContractAsJson))
+ {
+ log.trace("The 2 contracts as json does match");
+ String signature = cryptoFacade.signContract(registrationKey, contractAsJson);
+ //log.trace("signature: " + signature);
+ resultHandler.onResult(contract, contractAsJson, signature);
+ }
else
{
// TODO use diff output as feedback ?
@@ -57,7 +54,7 @@ public class VerifyAndSignContract
log.error("Takers contractAsJson: " + peersContractAsJson);
faultHandler.onFault(new Exception("Contracts are not matching"));
- } */
+ }
}
public interface ResultHandler
diff --git a/src/main/java/io/bitsquare/trade/protocol/taker/CreateAndSignContract.java b/src/main/java/io/bitsquare/trade/protocol/taker/CreateAndSignContract.java
index 983cd2055c..cec5a3a1ac 100644
--- a/src/main/java/io/bitsquare/trade/protocol/taker/CreateAndSignContract.java
+++ b/src/main/java/io/bitsquare/trade/protocol/taker/CreateAndSignContract.java
@@ -36,9 +36,7 @@ public class CreateAndSignContract
Contract contract = new Contract(offer, tradeAmount, takeOfferFeeTxId, peersAccountId, accountId, peersBankAccount, bankAccount, peersMessagePublicKey, messagePublicKey);
String contractAsJson = Utilities.objectToJson(contract);
- //TODO priv key is null, use other signing key or find out why it is null at that moment
- // String signature = cryptoFacade.signContract(registrationKey, contractAsJson);
- String signature = "TODO priv key is null, use other signing key or find out why it is null at that moment";
+ String signature = cryptoFacade.signContract(registrationKey, contractAsJson);
resultHandler.onResult(contract, contractAsJson, signature);
} catch (Throwable t)
{