bitcoinrb 1.6.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|