bitcoinrb 1.6.0 → 1.7.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/lib/bitcoin/block.rb +27 -0
- data/lib/bitcoin/descriptor/combo.rb +1 -1
- data/lib/bitcoin/descriptor/key_expression.rb +7 -0
- data/lib/bitcoin/descriptor/pk.rb +1 -1
- data/lib/bitcoin/descriptor/pkh.rb +1 -1
- data/lib/bitcoin/descriptor/raw_tr.rb +20 -0
- data/lib/bitcoin/descriptor/wpkh.rb +1 -1
- data/lib/bitcoin/descriptor.rb +10 -0
- data/lib/bitcoin/message_sign.rb +2 -1
- data/lib/bitcoin/script_witness.rb +1 -0
- data/lib/bitcoin/silent_payment.rb +5 -0
- data/lib/bitcoin/sp/addr.rb +55 -0
- data/lib/bitcoin/tx.rb +13 -0
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin.rb +1 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81a899ff49ba8888d3479e7f0c93c2124098c07c68dfd293349881d724c9393b
|
4
|
+
data.tar.gz: '052092011357a7abb68ec74bbbd5939b74d75aa83d5561ce088fc80c152b3341'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce9d912ba951f85c95dd30b29f1f2d0330a168e6fdd119296186fc6e651ba92ab838c90b7d31cf1a99e17def444c6bcb9784eff6ceab0816b210428fbc77b36a
|
7
|
+
data.tar.gz: bc9f7c2e34f9f47def957b549e5c33f5a4940fb56ad2fb379f717811aedd0b5f1cc4089c0f67ff7ad1363eb9a7d7b4a4ea4405124a06b20a1674d02802720cfe
|
data/lib/bitcoin/block.rb
CHANGED
@@ -4,11 +4,38 @@ module Bitcoin
|
|
4
4
|
attr_accessor :header
|
5
5
|
attr_accessor :transactions
|
6
6
|
|
7
|
+
# Constructor
|
8
|
+
# @param [Bitcoin::BlockHeader] header
|
9
|
+
# @param [Array] transactions An array of transaction.
|
10
|
+
# @raise [ArgumentError]
|
7
11
|
def initialize(header, transactions = [])
|
12
|
+
raise ArgumentError, "header must be Bitcoin::BlockHeader." unless header.is_a?(Bitcoin::BlockHeader)
|
13
|
+
raise ArgumentError, "transactions must be an Array." unless transactions.is_a?(Array)
|
8
14
|
@header = header
|
9
15
|
@transactions = transactions
|
10
16
|
end
|
11
17
|
|
18
|
+
# Create genesis block.
|
19
|
+
# @param [String] msg Message embedded in coinbase transaction.
|
20
|
+
# @param [Bitcoin::Script] script Coinbase transaction scriptPubkey.
|
21
|
+
# @param [Integer] time Block time.
|
22
|
+
# @param [Integer] nonce nonce.
|
23
|
+
# @param [Integer] bits nBits
|
24
|
+
# @param [Integer] version nVersion.
|
25
|
+
# @param [Integer] rewards Block rewards(satoshi).
|
26
|
+
def self.create_genesis(msg, script, time, nonce, bits, version, rewards = 50 * 100000000)
|
27
|
+
coinbase = Bitcoin::Tx.create_coinbase(msg, script, rewards)
|
28
|
+
header = BlockHeader.new(
|
29
|
+
version,
|
30
|
+
'00' * 32,
|
31
|
+
MerkleTree.build_from_leaf([coinbase.txid]).merkle_root.rhex,
|
32
|
+
time,
|
33
|
+
bits,
|
34
|
+
nonce
|
35
|
+
)
|
36
|
+
Block.new(header, [coinbase])
|
37
|
+
end
|
38
|
+
|
12
39
|
def self.parse_from_payload(payload)
|
13
40
|
Bitcoin::Message::Block.parse_from_payload(payload).to_block
|
14
41
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Descriptor
|
3
|
+
# rawtr() expression
|
4
|
+
class RawTr < KeyExpression
|
5
|
+
include Bitcoin::Opcodes
|
6
|
+
|
7
|
+
def type
|
8
|
+
:rawtr
|
9
|
+
end
|
10
|
+
|
11
|
+
def top_level?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_script
|
16
|
+
Bitcoin::Script.new << OP_1 << extract_pubkey(key).xonly_pubkey
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/bitcoin/descriptor.rb
CHANGED
@@ -19,6 +19,7 @@ module Bitcoin
|
|
19
19
|
autoload :Tr, 'bitcoin/descriptor/tr'
|
20
20
|
autoload :MultiA, 'bitcoin/descriptor/multi_a'
|
21
21
|
autoload :SortedMultiA, 'bitcoin/descriptor/sorted_multi_a'
|
22
|
+
autoload :RawTr, 'bitcoin/descriptor/raw_tr'
|
22
23
|
autoload :Checksum, 'bitcoin/descriptor/checksum'
|
23
24
|
|
24
25
|
module_function
|
@@ -104,6 +105,13 @@ module Bitcoin
|
|
104
105
|
Tr.new(key, tree)
|
105
106
|
end
|
106
107
|
|
108
|
+
# Generate taproot output script descriptor.
|
109
|
+
# @param [String] key
|
110
|
+
# @return [Bitcoin::Descriptor::RawTr]
|
111
|
+
def rawtr(key)
|
112
|
+
RawTr.new(key)
|
113
|
+
end
|
114
|
+
|
107
115
|
# Generate tapscript multisig output for given keys.
|
108
116
|
# @param [Integer] threshold the threshold of multisig.
|
109
117
|
# @param [Array[String]] keys an array of keys.
|
@@ -169,6 +177,8 @@ module Bitcoin
|
|
169
177
|
else
|
170
178
|
tr(key, parse(rest, false))
|
171
179
|
end
|
180
|
+
when 'rawtr'
|
181
|
+
rawtr(args_str)
|
172
182
|
else
|
173
183
|
raise ArgumentError, "Parse failed: #{string}"
|
174
184
|
end
|
data/lib/bitcoin/message_sign.rb
CHANGED
@@ -71,7 +71,8 @@ module Bitcoin
|
|
71
71
|
tx.in[0].script_witness = Bitcoin::ScriptWitness.parse_from_payload(sig)
|
72
72
|
script_pubkey = Bitcoin::Script.parse_from_addr(address)
|
73
73
|
tx_out = Bitcoin::TxOut.new(script_pubkey: script_pubkey)
|
74
|
-
|
74
|
+
flags = Bitcoin::STANDARD_SCRIPT_VERIFY_FLAGS
|
75
|
+
interpreter = Bitcoin::ScriptInterpreter.new(flags: flags, checker: Bitcoin::TxChecker.new(tx: tx, input_index: 0, prevouts: [tx_out]))
|
75
76
|
interpreter.verify_script(Bitcoin::Script.new, script_pubkey, tx.in[0].script_witness)
|
76
77
|
else
|
77
78
|
raise ArgumentError, "This address unsupported."
|
@@ -11,6 +11,7 @@ module Bitcoin
|
|
11
11
|
|
12
12
|
def self.parse_from_payload(payload)
|
13
13
|
buf = payload.is_a?(StringIO) ? payload : StringIO.new(payload)
|
14
|
+
return self.new if buf.eof?
|
14
15
|
size = Bitcoin.unpack_var_int_from_io(buf)
|
15
16
|
stack = size.times.map do
|
16
17
|
buf.read(Bitcoin.unpack_var_int_from_io(buf))
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module SilentPayment
|
3
|
+
class Addr
|
4
|
+
|
5
|
+
HRP_MAINNET = 'sp'
|
6
|
+
HRP_TESTNET = 'tsp'
|
7
|
+
MAX_CHARACTERS = 1023
|
8
|
+
|
9
|
+
attr_reader :version
|
10
|
+
attr_reader :scan_key
|
11
|
+
attr_reader :spend_key
|
12
|
+
|
13
|
+
# Constructor.
|
14
|
+
# @param [Bitcoin::Key] scan_key
|
15
|
+
# @param [Bitcoin::Key] spend_key
|
16
|
+
def initialize(version, scan_key:, spend_key:)
|
17
|
+
raise ArgumentError, "version must be integer." unless version.is_a?(Integer)
|
18
|
+
raise ArgumentError, "scan_key must be Bitcoin::Key." unless scan_key.is_a?(Bitcoin::Key)
|
19
|
+
raise ArgumentError, "spend_key must be Bitcoin::Key." unless spend_key.is_a?(Bitcoin::Key)
|
20
|
+
raise ArgumentError, "version '#{version}' is unsupported." unless version.zero?
|
21
|
+
|
22
|
+
@version = version
|
23
|
+
@scan_key = scan_key
|
24
|
+
@spend_key = spend_key
|
25
|
+
end
|
26
|
+
|
27
|
+
# Parse silent payment address.
|
28
|
+
# @param [String] A silent payment address.
|
29
|
+
# @return [Bitcoin::SilentPayment::Addr]
|
30
|
+
def self.from_string(addr)
|
31
|
+
raise ArgumentError, "addr must be string." unless addr.is_a?(String)
|
32
|
+
hrp, data, spec = Bech32.decode(addr, MAX_CHARACTERS)
|
33
|
+
unless hrp == Bitcoin.chain_params.mainnet? ? HRP_MAINNET : HRP_TESTNET
|
34
|
+
raise ArgumentError, "The specified hrp is different from the current network HRP."
|
35
|
+
end
|
36
|
+
raise ArgumentError, "spec must be bech32m." unless spec == Bech32::Encoding::BECH32M
|
37
|
+
|
38
|
+
ver = data[0]
|
39
|
+
payload = Bech32.convert_bits(data[1..-1], 5, 8, false).pack("C*")
|
40
|
+
scan_key = Bitcoin::Key.new(pubkey: payload[0...33].bth, key_type: Bitcoin::Key::TYPES[:compressed])
|
41
|
+
spend_key = Bitcoin::Key.new(pubkey: payload[33..-1].bth, key_type: Bitcoin::Key::TYPES[:compressed])
|
42
|
+
Addr.new(ver, scan_key: scan_key, spend_key: spend_key)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Get silent payment address.
|
46
|
+
# @return [String]
|
47
|
+
def to_s
|
48
|
+
hrp = Bitcoin.chain_params.mainnet? ? HRP_MAINNET : HRP_TESTNET
|
49
|
+
payload = [scan_key.pubkey + spend_key.pubkey].pack("H*").unpack('C*')
|
50
|
+
Bech32.encode(hrp, [version] + Bech32.convert_bits(payload, 8, 5), Bech32::Encoding::BECH32M)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/bitcoin/tx.rb
CHANGED
@@ -33,6 +33,19 @@ module Bitcoin
|
|
33
33
|
alias_method :in, :inputs
|
34
34
|
alias_method :out, :outputs
|
35
35
|
|
36
|
+
# Create coinbase transaction.
|
37
|
+
# @param [String] msg Message embedded in coinbase transaction.
|
38
|
+
# @param [Bitcoin::Script] script Coinbase transaction scriptPubkey.
|
39
|
+
# @param [Integer] rewards Coinbase Transaction Rewards
|
40
|
+
# @return [Bitcoin::Tx] Coinbase transaction.
|
41
|
+
def self.create_coinbase(msg, script, rewards = 50 * 100000000)
|
42
|
+
coinbase = Tx.new
|
43
|
+
script_sig = Bitcoin::Script.new << 486604799 << "04" << msg.bth
|
44
|
+
coinbase.in << TxIn.new(out_point: OutPoint.create_coinbase_outpoint, script_sig: script_sig)
|
45
|
+
coinbase.out << TxOut.new(value: rewards, script_pubkey: script)
|
46
|
+
coinbase
|
47
|
+
end
|
48
|
+
|
36
49
|
def self.parse_from_payload(payload, non_witness: false, strict: false)
|
37
50
|
buf = payload.is_a?(String) ? StringIO.new(payload) : payload
|
38
51
|
tx = new
|
data/lib/bitcoin/version.rb
CHANGED
data/lib/bitcoin.rb
CHANGED
@@ -61,6 +61,7 @@ module Bitcoin
|
|
61
61
|
autoload :SigHashGenerator, 'bitcoin/sighash_generator'
|
62
62
|
autoload :MessageSign, 'bitcoin/message_sign'
|
63
63
|
autoload :Taproot, 'bitcoin/taproot'
|
64
|
+
autoload :SilentPayment, 'bitcoin/silent_payment'
|
64
65
|
autoload :BIP324, 'bitcoin/bip324'
|
65
66
|
|
66
67
|
require_relative 'bitcoin/constants'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitcoinrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ecdsa_ext
|
@@ -360,6 +360,7 @@ files:
|
|
360
360
|
- lib/bitcoin/descriptor/pk.rb
|
361
361
|
- lib/bitcoin/descriptor/pkh.rb
|
362
362
|
- lib/bitcoin/descriptor/raw.rb
|
363
|
+
- lib/bitcoin/descriptor/raw_tr.rb
|
363
364
|
- lib/bitcoin/descriptor/script_expression.rb
|
364
365
|
- lib/bitcoin/descriptor/sh.rb
|
365
366
|
- lib/bitcoin/descriptor/sorted_multi.rb
|
@@ -469,10 +470,12 @@ files:
|
|
469
470
|
- lib/bitcoin/secp256k1/rfc6979.rb
|
470
471
|
- lib/bitcoin/secp256k1/ruby.rb
|
471
472
|
- lib/bitcoin/sighash_generator.rb
|
473
|
+
- lib/bitcoin/silent_payment.rb
|
472
474
|
- lib/bitcoin/slip39.rb
|
473
475
|
- lib/bitcoin/slip39/share.rb
|
474
476
|
- lib/bitcoin/slip39/sss.rb
|
475
477
|
- lib/bitcoin/slip39/wordlist/english.txt
|
478
|
+
- lib/bitcoin/sp/addr.rb
|
476
479
|
- lib/bitcoin/store.rb
|
477
480
|
- lib/bitcoin/store/chain_entry.rb
|
478
481
|
- lib/bitcoin/store/db.rb
|