bsv-sdk 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +62 -0
- data/README.md +4 -2
- data/lib/bsv/kv_store/entry.rb +15 -0
- data/lib/bsv/kv_store/global.rb +210 -0
- data/lib/bsv/kv_store/interpreter.rb +109 -0
- data/lib/bsv/kv_store/token.rb +10 -0
- data/lib/bsv/kv_store.rb +10 -0
- data/lib/bsv/mcp/tools/helpers.rb +3 -3
- data/lib/bsv/overlay/admin_token_template.rb +2 -2
- data/lib/bsv/overlay/historian.rb +118 -0
- data/lib/bsv/overlay/topic_broadcaster.rb +1 -1
- data/lib/bsv/overlay.rb +1 -0
- data/lib/bsv/primitives/digest.rb +107 -13
- data/lib/bsv/primitives/ecies.rb +12 -3
- data/lib/bsv/registry/client.rb +43 -1
- data/lib/bsv/script/bip276.rb +143 -0
- data/lib/bsv/script/interpreter/error.rb +2 -0
- data/lib/bsv/script/interpreter/interpreter.rb +226 -7
- data/lib/bsv/script/interpreter/operations/flow_control.rb +30 -13
- data/lib/bsv/script/push_drop_template.rb +2 -2
- data/lib/bsv/script/script.rb +21 -2
- data/lib/bsv/script.rb +1 -0
- data/lib/bsv/storage/downloader.rb +174 -0
- data/lib/bsv/storage/errors.rb +8 -0
- data/lib/bsv/storage/utils.rb +90 -0
- data/lib/bsv/storage.rb +16 -0
- data/lib/bsv/transaction/beef.rb +168 -14
- data/lib/bsv/transaction/beef_party.rb +119 -0
- data/lib/bsv/transaction/chain_tracker.rb +1 -1
- data/lib/bsv/transaction/fee_model.rb +1 -1
- data/lib/bsv/transaction/fee_models/live_policy.rb +1 -1
- data/lib/bsv/transaction/fee_models/satoshis_per_kilobyte.rb +1 -1
- data/lib/bsv/transaction/merkle_path.rb +1 -1
- data/lib/bsv/transaction/p2pkh.rb +1 -1
- data/lib/bsv/transaction/transaction_input.rb +78 -14
- data/lib/bsv/transaction/transaction_output.rb +46 -6
- data/lib/bsv/transaction/tx.rb +370 -39
- data/lib/bsv/transaction/unlocking_script_template.rb +2 -2
- data/lib/bsv/transaction.rb +1 -0
- data/lib/bsv/version.rb +1 -1
- data/lib/bsv-sdk.rb +2 -0
- metadata +13 -2
- data/lib/bsv/secp256k1_native.bundle +0 -0
|
@@ -14,19 +14,42 @@ module BSV
|
|
|
14
14
|
# @return [Integer] index of the output within the previous transaction
|
|
15
15
|
attr_reader :prev_tx_out_index
|
|
16
16
|
|
|
17
|
-
#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
#
|
|
21
|
-
|
|
17
|
+
# @!attribute [rw] sequence
|
|
18
|
+
# @return [Integer] sequence number (default: 0xFFFFFFFF)
|
|
19
|
+
# @note Setting this invalidates the owning Tx's wire cache and the
|
|
20
|
+
# hash_sequence component of the sighash cache. See
|
|
21
|
+
# {file:docs/reference/sighash-cache.md}.
|
|
22
|
+
attr_reader :sequence
|
|
23
|
+
|
|
24
|
+
# @!attribute [rw] unlocking_script
|
|
25
|
+
# @return [Script::Script, nil] the unlocking script (set after signing)
|
|
26
|
+
# @note Setting this invalidates the owning Tx's wire cache only.
|
|
27
|
+
# The unlocking script does not enter the BIP-143 preimage, so the
|
|
28
|
+
# sighash component caches are not touched. See
|
|
29
|
+
# {file:docs/reference/sighash-cache.md}.
|
|
30
|
+
attr_reader :unlocking_script
|
|
22
31
|
|
|
23
32
|
# @return [Integer, nil] satoshi value of the source output (needed for sighash)
|
|
33
|
+
# @note Enters the BIP-143 preimage at step 6 but no current cache layer
|
|
34
|
+
# memoises the per-input preimage, so no invalidator is required. If a
|
|
35
|
+
# future change adds preimage or per-input digest memoisation, add a
|
|
36
|
+
# setter override here that invalidates the relevant cache slice. See
|
|
37
|
+
# {file:docs/reference/sighash-cache.md}.
|
|
24
38
|
attr_accessor :source_satoshis
|
|
25
39
|
|
|
26
40
|
# @return [Script::Script, nil] locking script of the source output (needed for sighash)
|
|
41
|
+
# @note Enters the BIP-143 preimage as scriptCode (step 5) when no
|
|
42
|
+
# subscript override is supplied. Same caveat as {#source_satoshis}:
|
|
43
|
+
# no current cache layer depends on this field, but a future preimage
|
|
44
|
+
# cache would need a setter override here. See
|
|
45
|
+
# {file:docs/reference/sighash-cache.md}.
|
|
27
46
|
attr_accessor :source_locking_script
|
|
28
47
|
|
|
29
|
-
# @return [Tx, nil] the full source transaction (for BEEF wiring)
|
|
48
|
+
# @return [Transaction::Tx, nil] the full source transaction (for BEEF wiring)
|
|
49
|
+
# @note Source data is lazily resolved from this Tx during {Tx#verify}
|
|
50
|
+
# and {Tx#sighash_preimage}. Mutation of this field after resolution
|
|
51
|
+
# has occurred has no effect on caches because no current cache layer
|
|
52
|
+
# depends on resolved source data.
|
|
30
53
|
attr_accessor :source_transaction
|
|
31
54
|
|
|
32
55
|
# @return [UnlockingScriptTemplate, nil] template for deferred signing
|
|
@@ -38,23 +61,60 @@ module BSV
|
|
|
38
61
|
# @param sequence [Integer] sequence number
|
|
39
62
|
def initialize(prev_wtxid:, prev_tx_out_index:, unlocking_script: nil, sequence: 0xFFFFFFFF)
|
|
40
63
|
BSV::Primitives::Hex.validate_wtxid!(prev_wtxid, name: 'prev_wtxid')
|
|
41
|
-
|
|
64
|
+
# Defensively copy + freeze so external mutation of the caller's String
|
|
65
|
+
# cannot stale the cached outpoint_binary / to_binary.
|
|
66
|
+
@prev_wtxid = prev_wtxid.b.dup.freeze
|
|
42
67
|
@prev_tx_out_index = prev_tx_out_index
|
|
43
68
|
@unlocking_script = unlocking_script
|
|
44
69
|
@sequence = sequence
|
|
70
|
+
@owning_tx = nil
|
|
45
71
|
BSV.logger&.debug { "[TransactionInput] prev_wtxid set: #{dtxid_hex}:#{@prev_tx_out_index}" }
|
|
46
72
|
end
|
|
47
73
|
|
|
74
|
+
# Called by +#dup+ and +#clone+. Clears the owning-Tx backref so that the
|
|
75
|
+
# cloned input does not belong to any transaction until it is explicitly
|
|
76
|
+
# added via +Tx#add_input+.
|
|
77
|
+
def initialize_copy(other)
|
|
78
|
+
super
|
|
79
|
+
@owning_tx = nil
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Sets the sequence number and invalidates the L1 binary memo and any
|
|
83
|
+
# owning-Tx slice caches that incorporate sequence (BIP-143 preimage
|
|
84
|
+
# and wire format).
|
|
85
|
+
#
|
|
86
|
+
# @param value [Integer] new sequence number
|
|
87
|
+
def sequence=(value)
|
|
88
|
+
@sequence = value
|
|
89
|
+
@to_binary = nil
|
|
90
|
+
@owning_tx&.send(:invalidate_sequence_components_cache)
|
|
91
|
+
@owning_tx&.send(:invalidate_wire_cache)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Sets the unlocking script and invalidates the L1 binary memo and the
|
|
95
|
+
# owning-Tx wire cache. Unlocking script does not enter the BIP-143
|
|
96
|
+
# preimage, so the sequence/outputs components caches are not touched.
|
|
97
|
+
#
|
|
98
|
+
# @param value [Script::Script, nil] new unlocking script
|
|
99
|
+
def unlocking_script=(value)
|
|
100
|
+
@unlocking_script = value
|
|
101
|
+
@to_binary = nil
|
|
102
|
+
@owning_tx&.send(:invalidate_wire_cache)
|
|
103
|
+
end
|
|
104
|
+
|
|
48
105
|
# Serialise the input to its binary wire format.
|
|
49
106
|
#
|
|
107
|
+
# @note Memoised; see {file:docs/reference/sighash-cache.md} for the invalidation contract.
|
|
50
108
|
# @return [String] binary input (outpoint + varint + script + sequence)
|
|
51
109
|
def to_binary
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
110
|
+
@to_binary ||= begin
|
|
111
|
+
script_bytes = @unlocking_script ? @unlocking_script.to_binary : ''.b
|
|
112
|
+
(@prev_wtxid +
|
|
113
|
+
[@prev_tx_out_index].pack('V') +
|
|
114
|
+
VarInt.encode(script_bytes.bytesize) +
|
|
115
|
+
script_bytes +
|
|
116
|
+
[@sequence].pack('V')).freeze
|
|
117
|
+
end
|
|
58
118
|
end
|
|
59
119
|
|
|
60
120
|
# Deserialise a transaction input from binary data.
|
|
@@ -113,9 +173,13 @@ module BSV
|
|
|
113
173
|
|
|
114
174
|
# Serialise the outpoint (prev_wtxid + output index) as binary.
|
|
115
175
|
#
|
|
176
|
+
# Memoised: outpoint components are +attr_reader+ only so the value is
|
|
177
|
+
# immutable after construction. Returns a frozen binary string.
|
|
178
|
+
#
|
|
179
|
+
# @note Memoised; see {file:docs/reference/sighash-cache.md} for the invalidation contract.
|
|
116
180
|
# @return [String] 36-byte outpoint
|
|
117
181
|
def outpoint_binary
|
|
118
|
-
@prev_wtxid + [@prev_tx_out_index].pack('V')
|
|
182
|
+
@outpoint_binary ||= (@prev_wtxid + [@prev_tx_out_index].pack('V')).freeze
|
|
119
183
|
end
|
|
120
184
|
|
|
121
185
|
# The previous transaction ID in display-order hex.
|
|
@@ -8,11 +8,17 @@ module BSV
|
|
|
8
8
|
# Outputs are consumed by transaction inputs that provide matching
|
|
9
9
|
# unlocking scripts.
|
|
10
10
|
class TransactionOutput
|
|
11
|
-
#
|
|
12
|
-
|
|
11
|
+
# @!attribute [rw] satoshis
|
|
12
|
+
# @return [Integer] the output value in satoshis
|
|
13
|
+
# @note Setting this invalidates the owning Tx's outputs-components
|
|
14
|
+
# and wire caches. See {file:docs/reference/sighash-cache.md}.
|
|
15
|
+
attr_reader :satoshis
|
|
13
16
|
|
|
14
|
-
#
|
|
15
|
-
|
|
17
|
+
# @!attribute [rw] locking_script
|
|
18
|
+
# @return [Script::Script] the locking script (spending conditions)
|
|
19
|
+
# @note Setting this invalidates the owning Tx's outputs-components
|
|
20
|
+
# and wire caches. See {file:docs/reference/sighash-cache.md}.
|
|
21
|
+
attr_reader :locking_script
|
|
16
22
|
|
|
17
23
|
# @return [Boolean] whether this output receives change
|
|
18
24
|
attr_accessor :change
|
|
@@ -24,14 +30,48 @@ module BSV
|
|
|
24
30
|
@satoshis = satoshis
|
|
25
31
|
@locking_script = locking_script
|
|
26
32
|
@change = change
|
|
33
|
+
@owning_tx = nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Called by +#dup+ and +#clone+. Clears the owning-Tx backref so that the
|
|
37
|
+
# cloned output does not belong to any transaction until it is explicitly
|
|
38
|
+
# added via +Tx#add_output+.
|
|
39
|
+
def initialize_copy(other)
|
|
40
|
+
super
|
|
41
|
+
@owning_tx = nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Sets the satoshi value and invalidates the L1 binary memo and the
|
|
45
|
+
# owning-Tx outputs-components and wire caches.
|
|
46
|
+
#
|
|
47
|
+
# @param value [Integer] new satoshi value
|
|
48
|
+
def satoshis=(value)
|
|
49
|
+
@satoshis = value
|
|
50
|
+
@to_binary = nil
|
|
51
|
+
@owning_tx&.send(:invalidate_outputs_components_cache)
|
|
52
|
+
@owning_tx&.send(:invalidate_wire_cache)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Sets the locking script and invalidates the L1 binary memo and the
|
|
56
|
+
# owning-Tx outputs-components and wire caches.
|
|
57
|
+
#
|
|
58
|
+
# @param value [Script::Script] new locking script
|
|
59
|
+
def locking_script=(value)
|
|
60
|
+
@locking_script = value
|
|
61
|
+
@to_binary = nil
|
|
62
|
+
@owning_tx&.send(:invalidate_outputs_components_cache)
|
|
63
|
+
@owning_tx&.send(:invalidate_wire_cache)
|
|
27
64
|
end
|
|
28
65
|
|
|
29
66
|
# Serialise the output to its binary wire format.
|
|
30
67
|
#
|
|
68
|
+
# @note Memoised; see {file:docs/reference/sighash-cache.md} for the invalidation contract.
|
|
31
69
|
# @return [String] binary output (8-byte LE satoshis + varint + script)
|
|
32
70
|
def to_binary
|
|
33
|
-
|
|
34
|
-
|
|
71
|
+
@to_binary ||= begin
|
|
72
|
+
script_bytes = @locking_script.to_binary
|
|
73
|
+
([@satoshis].pack('Q<') + VarInt.encode(script_bytes.bytesize) + script_bytes).freeze
|
|
74
|
+
end
|
|
35
75
|
end
|
|
36
76
|
|
|
37
77
|
# Deserialise a transaction output from binary data.
|