coin-op 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -3
- data.tar.gz.sig +0 -0
- data/lib/coin-op/bit/fee.rb +43 -26
- data/lib/coin-op/bit/transaction.rb +23 -29
- data/lib/coin-op/encodings.rb +1 -1
- data/lib/coin-op/version.rb +1 -1
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: daa2b1357a473f001974e80e34fcdd52358f906e
|
4
|
+
data.tar.gz: a0da314f07e56ad68d776de5234ddbbb8e49d4aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e076e686da9b9dc3a6212df1a21757317bd20792d4e9c342c6afaaa19d9acd41e60fb058f0e2b2859ea1ccf50b2f9a22c4ba2e4ac8e5945b42950be96b62c2ae
|
7
|
+
data.tar.gz: 4ff3f5c89ebb5d8e6ae0294904b9db02545bc3d2c1fe8b3598e20d293ebb518e86db9293170b609b862101fbc1865a831098a1cbb5f9d056d6e04d0ed7b0d3f6
|
checksums.yaml.gz.sig
CHANGED
@@ -1,3 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
�h��U��
|
1
|
+
�.ˤ'-<��DmW
|
2
|
+
��ɂ1 %�dvJQ/�$�1ſ��� ��.��@�nY�C
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/coin-op/bit/fee.rb
CHANGED
@@ -3,59 +3,76 @@ module CoinOp::Bit
|
|
3
3
|
|
4
4
|
module Fee
|
5
5
|
|
6
|
+
# From http://bitcoinfees.com
|
7
|
+
AVG_P2PKH_BYTES = 148
|
8
|
+
AVG_OUTPUT_SIZE = 34
|
9
|
+
|
10
|
+
# From rough tests of Gem p2sh txs on 2015-09-08
|
11
|
+
AVG_P2SH_BYTES = 300
|
12
|
+
|
6
13
|
module_function
|
7
14
|
|
8
15
|
# Given an array of unspent Outputs and an array of Outputs for a
|
9
16
|
# Transaction, estimate the fee required for the transaction to be
|
10
|
-
# included in a block.
|
11
|
-
#
|
12
|
-
#
|
17
|
+
# included in a block.
|
18
|
+
#
|
19
|
+
# Optionally takes an Integer tx_size specifying the transaction size in bytes
|
20
|
+
# This is useful if you have the scriptSigs for the unspents, because
|
21
|
+
# you can get a more accurate size than the estimate which is generated
|
22
|
+
# here by default
|
23
|
+
#
|
24
|
+
# Optionally takes an Integer fee_per_kb specifying the chosen cost per 1000
|
25
|
+
# bytes to use
|
13
26
|
#
|
14
27
|
# Returns the estimated fee in satoshis.
|
15
|
-
def estimate(unspents, payees, tx_size
|
28
|
+
def estimate(unspents, payees, network:, tx_size: nil, fee_per_kb: nil)
|
16
29
|
# https://en.bitcoin.it/wiki/Transaction_fees
|
17
30
|
|
18
31
|
# dupe because we'll need to add a change output
|
19
32
|
payees = payees.dup
|
20
33
|
|
21
|
-
unspent_total = unspents.inject(0) {|sum, output| sum += output.value}
|
22
|
-
payee_total = payees.inject(0) {|sum, payee| sum += payee.value}
|
34
|
+
unspent_total = unspents.inject(0) { |sum, output| sum += output.value }
|
35
|
+
payee_total = payees.inject(0) { |sum, payee| sum += payee.value }
|
36
|
+
|
23
37
|
nominal_change = unspent_total - payee_total
|
24
|
-
payees << Output.new(value: nominal_change, network: network)
|
38
|
+
payees << Output.new(value: nominal_change, network: network) if nominal_change > 0
|
25
39
|
|
26
|
-
tx_size ||= estimate_tx_size(unspents
|
27
|
-
min = payees.min_by {|payee| payee.value }
|
40
|
+
tx_size ||= estimate_tx_size(unspents, payees)
|
28
41
|
|
42
|
+
# conditions for 0-fee transactions
|
29
43
|
small = tx_size < 1000
|
30
|
-
big_outputs = min.value > 1_000_000
|
31
44
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
45
|
+
min_payee = payees.min_by { |payee| payee.value }
|
46
|
+
big_outputs = min_payee.value > 1_000_000
|
47
|
+
high_priority = priority(
|
48
|
+
size: tx_size,
|
49
|
+
unspents: unspents.map { |output| { value: output.value, age: output.confirmations } }
|
50
|
+
) > PRIORITY_THRESHOLD
|
36
51
|
|
37
|
-
|
38
|
-
|
39
|
-
else
|
40
|
-
fee_for_bytes(tx_size, network: network)
|
41
|
-
end
|
52
|
+
# 0-fee requirements met
|
53
|
+
return 0 if small && big_outputs && high_priority
|
42
54
|
|
55
|
+
# Otherwise, calculate the fee by size
|
56
|
+
fee_for_bytes(tx_size, network: network, fee_per_kb: fee_per_kb)
|
43
57
|
end
|
44
58
|
|
45
|
-
def fee_for_bytes(bytes, network:)
|
59
|
+
def fee_for_bytes(bytes, network:, fee_per_kb: nil)
|
46
60
|
# https://en.bitcoin.it/wiki/Transaction_fees
|
47
61
|
# > the reference implementation will round up the transaction size to the
|
48
62
|
# > next thousand bytes and add a fee of 0.1 mBTC (0.0001 BTC) per thousand bytes
|
49
63
|
size = (bytes / 1000) + 1
|
64
|
+
return size * fee_per_kb if fee_per_kb
|
50
65
|
CoinOp.syncbit(network) { Bitcoin.network[:min_tx_fee] * size }
|
51
66
|
end
|
52
67
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
68
|
+
def estimate_tx_size(inputs, outputs)
|
69
|
+
# tx overhead
|
70
|
+
10 +
|
71
|
+
# outputs don't vary much in size
|
72
|
+
(AVG_OUTPUT_SIZE * outputs.size) +
|
73
|
+
# p2sh outputs are usually larger than p2pkh outputs, which don't vary much
|
74
|
+
inputs.inject(0) { |sum, input|
|
75
|
+
sum += input.script.type == :script_hash ? AVG_P2SH_BYTES : AVG_P2PKH_BYTES }
|
59
76
|
end
|
60
77
|
|
61
78
|
|
@@ -10,8 +10,7 @@ module CoinOp::Bit
|
|
10
10
|
transaction
|
11
11
|
end
|
12
12
|
|
13
|
-
# Construct a Transaction from a data structure of nested Hashes
|
14
|
-
# and Arrays.
|
13
|
+
# Construct a Transaction from a data structure of nested Hashes and Arrays.
|
15
14
|
def self.data(data, network:)
|
16
15
|
version, lock_time, fee, inputs, outputs, confirmations =
|
17
16
|
data.values_at :version, :lock_time, :fee, :inputs, :outputs, :confirmations
|
@@ -25,20 +24,17 @@ module CoinOp::Bit
|
|
25
24
|
)
|
26
25
|
|
27
26
|
outputs.each do |output_hash|
|
28
|
-
transaction.add_output(
|
27
|
+
transaction.add_output(output_hash, network: network)
|
29
28
|
end
|
30
29
|
|
31
30
|
#FIXME: we're not handling sig_scripts for already signed inputs.
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
inputs.each_with_index do |input_hash, index|
|
36
|
-
transaction.add_input(input_hash, network: network)
|
32
|
+
inputs.each do |input_hash|
|
33
|
+
transaction.add_input(input_hash, network: network)
|
37
34
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
35
|
+
## FIXME: verify that the supplied and computed sig_hashes match
|
36
|
+
#puts :sig_hashes_match => (data[:sig_hash] == input.sig_hash)
|
37
|
+
end if inputs
|
42
38
|
|
43
39
|
transaction
|
44
40
|
end
|
@@ -160,17 +156,14 @@ module CoinOp::Bit
|
|
160
156
|
# * an instance of Output
|
161
157
|
# * a Hash describing an Output
|
162
158
|
#
|
163
|
-
def add_input(input, network:)
|
159
|
+
def add_input(input, network: @network)
|
164
160
|
# TODO: allow specifying prev_tx and index with a Hash.
|
165
161
|
# Possibly stop using SparseInput.
|
166
162
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
network: network
|
172
|
-
)
|
173
|
-
end
|
163
|
+
input = Input.new(input.merge(transaction: self,
|
164
|
+
index: @inputs.size,
|
165
|
+
network: network)
|
166
|
+
) unless input.is_a?(Input)
|
174
167
|
|
175
168
|
@inputs << input
|
176
169
|
self.update_native do |native|
|
@@ -180,15 +173,15 @@ module CoinOp::Bit
|
|
180
173
|
end
|
181
174
|
|
182
175
|
# Takes either an Output or a Hash describing an output.
|
183
|
-
def add_output(output)
|
184
|
-
|
185
|
-
output
|
176
|
+
def add_output(output, network: @network)
|
177
|
+
if output.is_a?(Output)
|
178
|
+
output.set_transaction(self, @outputs.size)
|
179
|
+
else
|
180
|
+
output = Output.new(output.merge(transaction: self,
|
181
|
+
index: @outputs.size),
|
182
|
+
network: network)
|
186
183
|
end
|
187
184
|
|
188
|
-
index = @outputs.size
|
189
|
-
# TODO: stop using set_transaction and just pass self to Output.new
|
190
|
-
# Then remove output.set_transaction
|
191
|
-
output.set_transaction self, index
|
192
185
|
@outputs << output
|
193
186
|
self.update_native do |native|
|
194
187
|
native.add_out(output.native)
|
@@ -301,10 +294,11 @@ module CoinOp::Bit
|
|
301
294
|
# Estimate the fee in satoshis for this transaction. Takes an optional
|
302
295
|
# tx_size argument because it is impossible to determine programmatically
|
303
296
|
# the size of the scripts used to create P2SH outputs.
|
304
|
-
# Rough testing of the size of a 2of3 multisig p2sh input: 297
|
305
|
-
def estimate_fee(tx_size
|
297
|
+
# Rough testing of the size of a 2of3 multisig p2sh input: 297 +/- 40 bytes
|
298
|
+
def estimate_fee(tx_size: nil, network: @network, fee_per_kb: nil)
|
306
299
|
unspents = inputs.map(&:output)
|
307
|
-
Fee.estimate(unspents, outputs,
|
300
|
+
Fee.estimate(unspents, outputs,
|
301
|
+
network: network, tx_size: tx_size, fee_per_kb: fee_per_kb)
|
308
302
|
end
|
309
303
|
|
310
304
|
# Returns the transaction fee computed from the actual input and output
|
data/lib/coin-op/encodings.rb
CHANGED
data/lib/coin-op/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coin-op
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew King
|
@@ -32,7 +32,7 @@ cert_chain:
|
|
32
32
|
tdc4VS7IlSRxlZ3dBOgiigy9GXpJ+7F831AqjxL39EPwdr7RguTNz+pi//RKaT/U
|
33
33
|
IlpVB+Xfk0vQdP7iYfjGxDzUf0FACMjsR95waJmadKW1Iy6STw2hwPhYIQz1Hu1A
|
34
34
|
-----END CERTIFICATE-----
|
35
|
-
date: 2015-
|
35
|
+
date: 2015-09-09 00:00:00.000000000 Z
|
36
36
|
dependencies:
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: bitcoin-ruby
|
metadata.gz.sig
CHANGED
Binary file
|