lib/mastercoin-wallet/builder.rb in mastercoin-wallet-0.0.5 vs lib/mastercoin-wallet/builder.rb in mastercoin-wallet-0.0.6
- old
+ new
@@ -53,14 +53,14 @@
tr("Could not send payment, wrong password."))
return
end
begin
key = Bitcoin::Key.from_base58(priv_key)
- rescue ArgumentError
+ rescue ArgumentError, RuntimeError
begin
key = Bitcoin::Key.new(priv_key)
- rescue ArgumentError, OpenSSL::BNError
+ rescue ArgumentError, OpenSSL::BNError, RuntimeError
Qt::MessageBox.information(self, tr("Could not send payment."),
tr("Could not send payment, wrong password."))
return
end
end
@@ -101,30 +101,45 @@
s.recipient Mastercoin::EXODUS_ADDRESS
end
end
end
- tx = Bitcoin::Protocol::Tx.new( tx.to_payload )
+ transmit!(tx)
+ end
- MastercoinWallet.log.debug("TX Made: #{tx.to_hash}")
+ def pick_outputs(required_amount)
+ used_outputs = MastercoinWallet.config.created_transactions.collect{|x| x["in"][0]["prev_out"] }
+ usuable_outputs = MastercoinWallet.config.spendable_outputs.find{|x| BigDecimal.new(x[:value]) > BigDecimal.new(required_amount.to_s) }
- transaction_hash = tx.to_payload.unpack("H*").first
+ #puts "Found these total: #{usuable_outputs}"
+ #puts "These are used #{used_outputs}"
- MastercoinWallet.log.debug("If you want to send it by Bitcoind use this")
- MastercoinWallet.log.debug(transaction_hash)
- MastercoinWallet.log.debug("Required fee: #{tx.calculate_minimum_fee} - Multisig size: #{tx.outputs.last.script.bytesize}")
+ usuable_outputs = [usuable_outputs] if usuable_outputs.is_a?(Hash)
+ usuable_outputs.reject!{|x| puts x; used_outputs.include?(x["prev_out"])}
+ #puts "Left with these: #{usuable_outputs}"
- remote_transaction = Transaction.new(tx.to_hash["hash"], tx.to_json)
- response = remote_transaction.create!
- if response.parsed_response.keys.include?("error")
- Qt::MessageBox.critical(self, tr("Could not relay transaction"),
- tr("The remote server could not transmit your transaction at this moment. #{response.parsed_response}"))
- return
+ if usuable_outputs.empty?
+ # Outputs are saved in order so the last output should always the one that's unused, make sure it's an output for thist address and that it's big enough
+ if MastercoinWallet.config.created_transactions.last["out"].first["address"] == MastercoinWallet.config.address && MastercoinWallet.config.created_transactions.last["out"].first["value"].to_f >= BigDecimal.new(required_amount)
+ # We are taking an full transaction and building a spendable output based on the details we have
+ output = MastercoinWallet.config.created_transactions.last["out"].first.reverse_merge({prev_out: {hash: MastercoinWallet.config.created_transactions.last["hash"], n: 0}})
+ tx = MastercoinWallet.config.created_transactions.last
+ return output,tx
else
- Qt::MessageBox.information(self, tr("Transaction send"),
- tr("Your transaction with hash #{tx.to_hash["hash"]} has been offered to the relay server, it should show up within 10 minutes."))
+ return nil, nil
end
+ else
+ if usuable_outputs.is_a?(Array)
+ usuable_outputs = usuable_outputs[0]
+ end
+
+ tx = MastercoinWallet.config.bitcoin_transactions.find{|x| x["hash"] == usuable_outputs["prev_out"]["hash"]}
+ if tx.is_a?(Array)
+ tx = tx[0]
+ end
+ return usuable_outputs, tx
+ end
end
def create_transaction_with_keys(data_keys, options = {})
public_keys = []
public_keys << data_keys
@@ -134,52 +149,52 @@
self.set_fee(BigDecimal.new(options[:force_fee]))
else
self.set_fee
end
- valid_output = MastercoinWallet.config.spendable_outputs.find{|x| BigDecimal.new(x[:value]) > (self.fee + self.mastercoin_tx)}
+ required_amount = (self.fee + self.mastercoin_tx)
+ output, tx = pick_outputs(required_amount)
- if valid_output.is_a?(Array)
- ouput = valid_output[0]
- else
- output = valid_output
- end
+# puts "Using output: #{output} and Tx: #{tx}"
unless output
Qt::MessageBox.critical(self, tr("Could not send transaction"),
tr("It appears there are no spendable outputs for this address that are big enough to transmit this transaction. Please consolidate some coins and send them to your Mastercoin address."))
return
end
change_amount = BigDecimal.new(output["value"]) - fee - mastercoin_tx
- tx = MastercoinWallet.config.bitcoin_transactions.find{|x| x["hash"] == output["prev_out"]["hash"]}
- if tx.is_a?(Array)
- tx = tx[0]
- end
begin
priv_key = MastercoinWallet.config.get_encrypted_key(:private_key, @password)
rescue ArgumentError
Qt::MessageBox.information(self, tr("Could not send payment."),
tr("Could not send payment, wrong password."))
return
end
begin
key = Bitcoin::Key.from_base58(priv_key)
- rescue ArgumentError
+ rescue ArgumentError, RuntimeError
begin
key = Bitcoin::Key.new(priv_key)
- rescue ArgumentError, OpenSSL::BNError
+ rescue ArgumentError, OpenSSL::BNError, RuntimeError
Qt::MessageBox.information(self, tr("Could not send payment."),
tr("Could not send payment, wrong password."))
return
end
end
- public_keys.insert(0, key.pub_compressed)
+ begin
+ public_keys.insert(0, key.pub_compressed)
+ rescue RuntimeError => e
+ Qt::MessageBox.information(self, tr("Could not send payment."),
+ tr("Something went wrong while trying to generate your public key. Please report this: #{e}"))
+ return
+ end
+
tx = build_tx do |t|
t.input do |i|
i.prev_out Bitcoin::Protocol::Tx.from_hash(tx)
i.prev_out_index output["prev_out"]["n"]
i.signature_key key
@@ -225,11 +240,14 @@
s.type :multisig
s.recipient 1, *public_keys
end
end
end
+ transmit!(tx)
+ end
+ def transmit!(tx)
tx = Bitcoin::Protocol::Tx.new( tx.to_payload )
MastercoinWallet.log.debug("TX Made: #{tx.to_hash}")
transaction_hash = tx.to_payload.unpack("H*").first
@@ -243,9 +261,21 @@
if response.parsed_response.keys.include?("error")
Qt::MessageBox.critical(self, tr("Could not relay transaction"),
tr("The remote server could not transmit your transaction at this moment. #{response.parsed_response}"))
return
else
+ sent_transactions = MastercoinWallet.config.get_key("created_transactions")
+ sent_transactions ||= []
+ sent_transactions << tx.to_hash(with_address: true)
+
+ #transactions = MastercoinWallet.config.get_key("bitcoin_transactions")
+ #transactions ||= []
+ #transactions << tx
+ #transactions = MastercoinWallet.config.set_key!("bitcoin_transactions", transactions)
+
+
+ MastercoinWallet.config.set_key!(:created_transactions, sent_transactions)
+
Qt::MessageBox.information(self, tr("Transaction send"),
tr("Your transaction with hash #{tx.to_hash["hash"]} has been offered to the relay server, it should show up within 10 minutes."))
end
end