bitcoin 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- metadata +17 -288
- data/.rspec +0 -1
- data/.rvmrc +0 -1
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -98
- data/Guardfile +0 -38
- data/README.markdown +0 -24
- data/Rakefile +0 -1
- data/bin/rbcoin +0 -8
- data/bitcoin.gemspec +0 -40
- data/config/cucumber.yml +0 -5
- data/config/darcs.boring +0 -121
- data/doc/DEFINITION_OF_DONE.markdown +0 -12
- data/doc/HISTORY.markdown +0 -19
- data/doc/LICENCE.markdown +0 -25
- data/doc/TODO.markdown +0 -31
- data/doc/UBIQUITOUS_LANGUAGE.markdown +0 -15
- data/features/descriptions/command_help.feature +0 -31
- data/features/descriptions/satoshi_wallet/add_address.feature +0 -49
- data/features/descriptions/satoshi_wallet/show_addresses.feature +0 -18
- data/features/descriptions/satoshi_wallet/show_version.feature +0 -17
- data/features/descriptions/satoshi_wallet/subcommand_help.feature +0 -20
- data/features/fixtures/ABOUT_FIXTURES.markdown +0 -6
- data/features/fixtures/addressbook_wallet.dat +0 -0
- data/features/fixtures/new_wallet.dat +0 -0
- data/features/step_definitions/command_steps.rb +0 -3
- data/features/step_definitions/wallet_steps.rb +0 -11
- data/features/support/env.rb +0 -9
- data/lib/bitcoin.rb +0 -5
- data/lib/bitcoin/cli.rb +0 -35
- data/lib/bitcoin/commands.rb +0 -3
- data/lib/bitcoin/commands/help_command.rb +0 -32
- data/lib/bitcoin/commands/satoshi_wallet.rb +0 -11
- data/lib/bitcoin/commands/satoshi_wallet/add_address_command.rb +0 -61
- data/lib/bitcoin/commands/satoshi_wallet/show_addresses_command.rb +0 -16
- data/lib/bitcoin/commands/satoshi_wallet/show_version_command.rb +0 -15
- data/lib/bitcoin/commands/satoshi_wallet_command.rb +0 -37
- data/lib/bitcoin/commands/satoshi_wallet_command_environment.rb +0 -28
- data/lib/bitcoin/console/capturing_stream_bundle.rb +0 -42
- data/lib/bitcoin/console/stream_bundle.rb +0 -21
- data/lib/bitcoin/data_access/satoshi/bdb_satoshi_wallet_repository.rb +0 -155
- data/lib/bitcoin/data_access/satoshi/satoshi_version.rb +0 -58
- data/lib/bitcoin/data_access/satoshi/satoshi_wallet.rb +0 -39
- data/lib/bitcoin/domain/address_book.rb +0 -19
- data/lib/bitcoin/domain/bitcoin_address.rb +0 -33
- data/lib/bitcoin/filesystem/empty_temp_dir.rb +0 -74
- data/lib/bitcoin/rspec/argument_matchers.rb +0 -1
- data/lib/bitcoin/rspec/argument_matchers/block_evaluating_to_matcher.rb +0 -23
- data/lib/bitcoin/rspec/directory_helpers.rb +0 -22
- data/lib/bitcoin/version.rb +0 -3
- data/spec/bitcoin/cli_spec.rb +0 -128
- data/spec/bitcoin/commands/help_command_spec.rb +0 -53
- data/spec/bitcoin/commands/satoshi_wallet/add_address_command_spec.rb +0 -149
- data/spec/bitcoin/commands/satoshi_wallet/show_addresses_command_spec.rb +0 -26
- data/spec/bitcoin/commands/satoshi_wallet/show_version_command_spec.rb +0 -26
- data/spec/bitcoin/commands/satoshi_wallet_command_environment_spec.rb +0 -76
- data/spec/bitcoin/commands/satoshi_wallet_command_spec.rb +0 -73
- data/spec/bitcoin/console/_contracts/stream_bundle_contract.rb +0 -29
- data/spec/bitcoin/console/capturing_stream_bundle_spec.rb +0 -74
- data/spec/bitcoin/console/stream_bundle_spec.rb +0 -13
- data/spec/bitcoin/data_access/satoshi/bdb_satoshi_wallet_repository_spec.rb +0 -78
- data/spec/bitcoin/data_access/satoshi/satoshi_version_spec.rb +0 -112
- data/spec/bitcoin/data_access/satoshi/satoshi_wallet_spec.rb +0 -102
- data/spec/bitcoin/domain/address_book_spec.rb +0 -63
- data/spec/bitcoin/domain/bitcoin_address_spec.rb +0 -52
- data/spec/bitcoin/filesystem/empty_temp_dir_spec.rb +0 -170
- data/spec/bitcoin/rspec/argument_matchers/block_evaluating_to_matcher_spec.rb +0 -36
- data/spec/spec_helper.rb +0 -29
Binary file
|
Binary file
|
@@ -1,11 +0,0 @@
|
|
1
|
-
module Fixtures
|
2
|
-
def fixture_file_data(filename)
|
3
|
-
File.read(File.join(PROJECT_ROOT, "features", "fixtures", filename))
|
4
|
-
end
|
5
|
-
end
|
6
|
-
|
7
|
-
World(Fixtures)
|
8
|
-
|
9
|
-
Given %r/^a new Satoshi Wallet "([^"]*)"$/ do |wallet_filename|
|
10
|
-
write_file(wallet_filename, fixture_file_data(wallet_filename))
|
11
|
-
end
|
data/features/support/env.rb
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
Bundler.setup
|
3
|
-
|
4
|
-
PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), "..", "..")).freeze
|
5
|
-
|
6
|
-
# So Aruba can find the binary
|
7
|
-
ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
8
|
-
|
9
|
-
require 'aruba/cucumber'
|
data/lib/bitcoin.rb
DELETED
data/lib/bitcoin/cli.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'bitcoin/commands'
|
2
|
-
|
3
|
-
module Bitcoin
|
4
|
-
class CLI
|
5
|
-
class CommandError < RuntimeError; end
|
6
|
-
|
7
|
-
def initialize(stream_bundle)
|
8
|
-
@stream_bundle = stream_bundle
|
9
|
-
end
|
10
|
-
|
11
|
-
def run(args)
|
12
|
-
command_name, *remaining_args = *args
|
13
|
-
dispatch_command(command_name, remaining_args)
|
14
|
-
rescue CommandError => error
|
15
|
-
1
|
16
|
-
else
|
17
|
-
0
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def dispatch_command(command_name, remaining_args)
|
23
|
-
case command_name
|
24
|
-
when nil, "help"
|
25
|
-
Commands::HelpCommand.new(@stream_bundle).show_help
|
26
|
-
when "satoshi-wallet"
|
27
|
-
command_environment = Commands::SatoshiWalletCommandEnvironment.new(@stream_bundle)
|
28
|
-
Commands::SatoshiWalletCommand.new(@stream_bundle, command_environment).run(remaining_args)
|
29
|
-
else
|
30
|
-
Commands::HelpCommand.new(@stream_bundle).show_unknown_command_help(command_name)
|
31
|
-
raise CommandError.new
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/bitcoin/commands.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'lstrip-on-steroids'
|
2
|
-
|
3
|
-
module Bitcoin
|
4
|
-
module Commands
|
5
|
-
class HelpCommand
|
6
|
-
def initialize(stream_bundle)
|
7
|
-
@stream_bundle = stream_bundle
|
8
|
-
end
|
9
|
-
|
10
|
-
def show_help
|
11
|
-
@stream_bundle.puts_output(
|
12
|
-
-%{
|
13
|
-
Usage: rbcoin COMMAND ...
|
14
|
-
|
15
|
-
Commands:
|
16
|
-
help Display help about rbcoin and rbcoin commands
|
17
|
-
satoshi-wallet Manipulate the wallet.dat file of the original client
|
18
|
-
|
19
|
-
Use "rbcoin COMMAND --help" or "rbcoin help COMMAND" for help on a single command
|
20
|
-
Use "rbcoin --version" to see the rbcoin version number
|
21
|
-
Use "rbcoin --exact-version" to see the all version details (with dependencies)
|
22
|
-
}
|
23
|
-
)
|
24
|
-
end
|
25
|
-
|
26
|
-
def show_unknown_command_help(command_name)
|
27
|
-
@stream_bundle.puts_output(%'rbcoin failed: No such command "#{command_name}"')
|
28
|
-
@stream_bundle.puts_output("Try: `rbcoin help`")
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'bitcoin/cli' # For CommandError
|
2
|
-
|
3
|
-
require 'bitcoin/domain/bitcoin_address'
|
4
|
-
|
5
|
-
module Bitcoin
|
6
|
-
module Commands
|
7
|
-
module SatoshiWallet
|
8
|
-
class AddAddressCommand
|
9
|
-
def initialize(stream_bundle)
|
10
|
-
@stream_bundle = stream_bundle
|
11
|
-
end
|
12
|
-
|
13
|
-
def run(wallet, options)
|
14
|
-
assert_valid_args(options[:args])
|
15
|
-
|
16
|
-
address, name = *options[:args]
|
17
|
-
|
18
|
-
assert_valid_name(name)
|
19
|
-
|
20
|
-
wallet.add_address(Domain::BitcoinAddress.new(address), name: name)
|
21
|
-
@stream_bundle.puts_output("Address added successfully")
|
22
|
-
rescue Domain::BitcoinAddress::InvalidBitcoinAddressError => error
|
23
|
-
@stream_bundle.puts_error(error.message)
|
24
|
-
@stream_bundle.puts_error("The address was not added to the wallet")
|
25
|
-
raise CLI::CommandError.new
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def assert_valid_args(args)
|
31
|
-
if args.length < 2
|
32
|
-
@stream_bundle.puts_error("You must provide both a Bitcoin address and a name to add to a wallet")
|
33
|
-
@stream_bundle.puts_error("No changes were made to the wallet")
|
34
|
-
raise CLI::CommandError.new
|
35
|
-
elsif args.length > 2
|
36
|
-
@stream_bundle.puts_error(
|
37
|
-
-%{
|
38
|
-
Received too many arguments
|
39
|
-
|
40
|
-
To make sure the name is formatted correctly we ask you to use use quotes
|
41
|
-
around the name, e.g.: "#{args.drop(1).join(" ")}"
|
42
|
-
|
43
|
-
No changes were made to the wallet
|
44
|
-
}
|
45
|
-
)
|
46
|
-
raise CLI::CommandError.new
|
47
|
-
end
|
48
|
-
|
49
|
-
def assert_valid_name(name)
|
50
|
-
if name.bytesize > 252
|
51
|
-
@stream_bundle.puts_error(%'The address name "#{name}" is too long\n')
|
52
|
-
@stream_bundle.puts_error("Currently we do not allow address names over 252 bytes long\n")
|
53
|
-
@stream_bundle.puts_error("The address was not added to the wallet\n")
|
54
|
-
raise CLI::CommandError.new
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module Bitcoin
|
2
|
-
module Commands
|
3
|
-
module SatoshiWallet
|
4
|
-
class ShowAddressesCommand
|
5
|
-
def initialize(stream_bundle)
|
6
|
-
@stream_bundle = stream_bundle
|
7
|
-
end
|
8
|
-
|
9
|
-
def run(wallet, options)
|
10
|
-
@stream_bundle.puts_output("# All addresses in #{options[:wallet_filename]}")
|
11
|
-
@stream_bundle.puts_output(wallet.addresses)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Bitcoin
|
2
|
-
module Commands
|
3
|
-
module SatoshiWallet
|
4
|
-
class ShowVersionCommand
|
5
|
-
def initialize(stream_bundle)
|
6
|
-
@stream_bundle = stream_bundle
|
7
|
-
end
|
8
|
-
|
9
|
-
def run(wallet, options = { })
|
10
|
-
@stream_bundle.puts_output(wallet.version)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'tmpdir'
|
2
|
-
|
3
|
-
require 'bitcoin/cli' # circular dependency on CLI for CommandError
|
4
|
-
require 'bitcoin/commands/satoshi_wallet'
|
5
|
-
require 'bitcoin/data_access/satoshi/satoshi_wallet'
|
6
|
-
require 'bitcoin/domain/bitcoin_address'
|
7
|
-
require 'bitcoin/filesystem/empty_temp_dir'
|
8
|
-
|
9
|
-
module Bitcoin
|
10
|
-
module Commands
|
11
|
-
class SatoshiWalletCommand
|
12
|
-
TEMP_DB_PATH = "bitcoinrb_db_tmp"
|
13
|
-
|
14
|
-
def initialize(stream_bundle, command_environment)
|
15
|
-
@stream_bundle = stream_bundle
|
16
|
-
@command_environment = command_environment
|
17
|
-
end
|
18
|
-
|
19
|
-
def run(args)
|
20
|
-
command_name, *remaining_args = *args
|
21
|
-
command_class =
|
22
|
-
case command_name
|
23
|
-
when "add-address"
|
24
|
-
SatoshiWallet::AddAddressCommand
|
25
|
-
when "show-addresses"
|
26
|
-
SatoshiWallet::ShowAddressesCommand
|
27
|
-
when "show-version"
|
28
|
-
SatoshiWallet::ShowVersionCommand
|
29
|
-
else
|
30
|
-
@stream_bundle.puts_error(%'Unknown satoshi-wallet subcommand: "#{command_name}"')
|
31
|
-
raise CLI::CommandError.new
|
32
|
-
end
|
33
|
-
@command_environment.run_command(command_class.new(@stream_bundle), remaining_args)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'bitcoin/filesystem/empty_temp_dir'
|
2
|
-
|
3
|
-
module Bitcoin
|
4
|
-
module Commands
|
5
|
-
class SatoshiWalletCommandEnvironment
|
6
|
-
def initialize(stream_bundle)
|
7
|
-
@stream_bundle = stream_bundle
|
8
|
-
end
|
9
|
-
|
10
|
-
def run_command(command, arguments)
|
11
|
-
wallet_filename, *remaining_args = *arguments
|
12
|
-
|
13
|
-
if !File.exist?(wallet_filename)
|
14
|
-
@stream_bundle.puts_error("Couldn't find wallet file: #{wallet_filename}")
|
15
|
-
raise CLI::CommandError.new
|
16
|
-
end
|
17
|
-
|
18
|
-
absolute_wallet_path = File.expand_path(wallet_filename)
|
19
|
-
|
20
|
-
FileSystem::EmptyTempDir.open(with_name: "bitcoinrb_db_tmp", parallel_to: absolute_wallet_path) do |temp_dir|
|
21
|
-
DataAccess::Satoshi::SatoshiWallet.open(wallet_filename: absolute_wallet_path, db_dirname: temp_dir.absolute_path) do |wallet|
|
22
|
-
command.run(wallet, wallet_filename: wallet_filename, args: remaining_args)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
require_relative 'stream_bundle'
|
2
|
-
|
3
|
-
module Bitcoin
|
4
|
-
module Console
|
5
|
-
# CapturingStreamBundles are StreamBundles that record the data written to them
|
6
|
-
# for easy inspection later. They are useful for testing purposes.
|
7
|
-
class CapturingStreamBundle
|
8
|
-
class << self
|
9
|
-
def test_bundle
|
10
|
-
new(StringIO.new, StringIO.new, StringIO.new)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def initialize(input, output, error)
|
15
|
-
@stream_bundle = StreamBundle.new(input, output, error)
|
16
|
-
|
17
|
-
@captured_output = StringIO.new
|
18
|
-
@captured_error = StringIO.new
|
19
|
-
end
|
20
|
-
|
21
|
-
def puts_output(stringlike)
|
22
|
-
@stream_bundle.puts_output(stringlike)
|
23
|
-
@captured_output.puts(stringlike)
|
24
|
-
end
|
25
|
-
|
26
|
-
def puts_error(stringlike)
|
27
|
-
@stream_bundle.puts_error(stringlike)
|
28
|
-
@captured_error.puts(stringlike)
|
29
|
-
end
|
30
|
-
|
31
|
-
def captured_output
|
32
|
-
@captured_output.rewind
|
33
|
-
@captured_output.read
|
34
|
-
end
|
35
|
-
|
36
|
-
def captured_error
|
37
|
-
@captured_error.rewind
|
38
|
-
@captured_error.read
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Bitcoin
|
2
|
-
module Console
|
3
|
-
# StreamBundles are objects that encapsulate the standard unix pipes
|
4
|
-
# (STDIN, STDOUT, STDERR)
|
5
|
-
class StreamBundle
|
6
|
-
def initialize(input, output, error)
|
7
|
-
@input = input
|
8
|
-
@output = output
|
9
|
-
@error = error
|
10
|
-
end
|
11
|
-
|
12
|
-
def puts_output(stringlike)
|
13
|
-
@output.puts(stringlike)
|
14
|
-
end
|
15
|
-
|
16
|
-
def puts_error(stringlike)
|
17
|
-
@error.puts(stringlike)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,155 +0,0 @@
|
|
1
|
-
require 'sbdb'
|
2
|
-
require 'bdb/base'
|
3
|
-
|
4
|
-
module Bitcoin
|
5
|
-
module DataAccess
|
6
|
-
module Satoshi
|
7
|
-
# Raw Berkeley DB access (thin wrapper around SBDB) for wallet data
|
8
|
-
# WARNING! This code is in really bad shape. It works, but is verbose
|
9
|
-
# and full of duplication. It needs massive refactoring.
|
10
|
-
class BDBSatoshiWalletRepository
|
11
|
-
def initialize(db_filename, options)
|
12
|
-
@db_filename = db_filename
|
13
|
-
@db_dirname = options[:db_dirname]
|
14
|
-
end
|
15
|
-
|
16
|
-
def bdb_bytes_to_utf8_string(bytes)
|
17
|
-
bytes.pack("C*").force_encoding("UTF-8")
|
18
|
-
end
|
19
|
-
|
20
|
-
def get_value_immediate_uint32le(key_name)
|
21
|
-
with_bdb_db do |db|
|
22
|
-
db[make_key(key_name)].unpack("V").first
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def set_value_immediate_uint32le(key_name, value_data)
|
27
|
-
with_bdb_db do |db|
|
28
|
-
db[make_key(key_name)] = [ value_data ].pack("V")
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def get_key_and_value_data_string_utf8(key_name)
|
33
|
-
with_bdb_db do |db|
|
34
|
-
db_records(db).select { |record|
|
35
|
-
record.first == key_name
|
36
|
-
}.map { |name, data_hash|
|
37
|
-
data_hash
|
38
|
-
}.map { |data_hash|
|
39
|
-
[ data_hash[:key_data], data_hash[:value_data] ].map { |value|
|
40
|
-
bdb_bytes_to_utf8_string(value)
|
41
|
-
}
|
42
|
-
}
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def get_value_with_key_data_string_utf8(key_name, key_data)
|
47
|
-
with_bdb_db do |db|
|
48
|
-
value_data = db[make_key_with_data(key_name, key_data)]
|
49
|
-
return unless value_data
|
50
|
-
value_bytes = value_data.unpack("C*")
|
51
|
-
value_bytes.shift(read_compact_size(value_bytes)).pack("C*")
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def set_value_with_key_data_string_utf8(key_name, key_data, value_data)
|
56
|
-
with_bdb_db do |db|
|
57
|
-
db[make_key_with_data(key_name, key_data)] = make_key(value_data)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def make_key(key_name)
|
62
|
-
key = [ ]
|
63
|
-
key << write_compact_size(key_name)
|
64
|
-
key.concat(key_name.unpack("C*"))
|
65
|
-
key.pack("C*")
|
66
|
-
end
|
67
|
-
|
68
|
-
def make_key_with_data(key_name, key_data)
|
69
|
-
make_key(key_name) + make_key(key_data)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Maybe allow changing read/write & read-only when calling this?
|
73
|
-
def with_bdb_env(&block)
|
74
|
-
# This doesn't yet exactly mirror the DB setup in CWalletDB::LoadWallet
|
75
|
-
SBDB::Env.new(
|
76
|
-
dir: File.expand_path(@db_dirname),
|
77
|
-
lg_max: 10_000_000,
|
78
|
-
flags: Bdb::DB_CREATE | # Create the environment if it does not already exist.
|
79
|
-
Bdb::DB_INIT_LOCK | # Initialize locking.
|
80
|
-
Bdb::DB_INIT_LOG | # Initialize logging
|
81
|
-
Bdb::DB_INIT_MPOOL | # Initialize the in-memory cache.
|
82
|
-
Bdb::DB_INIT_TXN | # Initialize transactions
|
83
|
-
Bdb::DB_THREAD | # TODO: What?
|
84
|
-
Bdb::DB_RECOVER # TODO: What?
|
85
|
-
) do |env|
|
86
|
-
yield env
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def with_bdb_db(&block)
|
91
|
-
with_bdb_env do |env|
|
92
|
-
bitcoin_logical_database_name = "main"
|
93
|
-
# Leaving this here for reference: we could offer a read-only mode if we wanted (see Env flags though)
|
94
|
-
read_write_flags = Bdb::DB_CREATE | Bdb::DB_AUTO_COMMIT
|
95
|
-
read_only_flags = Bdb::DB_RDONLY
|
96
|
-
env.open(SBDB::Btree, File.expand_path(@db_filename), name: bitcoin_logical_database_name, flags: read_write_flags) do |db|
|
97
|
-
yield db
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def db_records(db)
|
103
|
-
db.to_hash.map { |key, value|
|
104
|
-
# Key name
|
105
|
-
key_bytes = key.bytes.to_a
|
106
|
-
key_name_length = read_compact_size(key_bytes)
|
107
|
-
key_name = key_bytes.shift(key_name_length).pack("C*").force_encoding("UTF-8")
|
108
|
-
|
109
|
-
# Key data
|
110
|
-
key_data_length = read_compact_size(key_bytes)
|
111
|
-
key_data_raw = key_bytes.shift(key_data_length)
|
112
|
-
|
113
|
-
# Value data
|
114
|
-
value_bytes = value.bytes.to_a
|
115
|
-
value_data_raw =
|
116
|
-
case key_name
|
117
|
-
when "version" # values that don't start with a length
|
118
|
-
value_bytes
|
119
|
-
else # variable-length values
|
120
|
-
value_length = read_compact_size(value_bytes)
|
121
|
-
value_bytes.shift(value_length)
|
122
|
-
end
|
123
|
-
|
124
|
-
[ key_name, { key_data: key_data_raw, value_data: value_data_raw } ]
|
125
|
-
}
|
126
|
-
end
|
127
|
-
|
128
|
-
def write_compact_size(string)
|
129
|
-
string.bytesize
|
130
|
-
end
|
131
|
-
|
132
|
-
def read_compact_size(byte_array)
|
133
|
-
# The Satoshi client throws an error here if the determined length is greater
|
134
|
-
# than (uint64)MAX_SIZE - I don't know if we need to worry about it
|
135
|
-
|
136
|
-
byte_1 = byte_array.shift
|
137
|
-
if byte_1.nil?
|
138
|
-
0
|
139
|
-
elsif byte_1 < 253
|
140
|
-
byte_1
|
141
|
-
elsif byte_1 == 253
|
142
|
-
# Little-endian 16-bit
|
143
|
-
byte_array.shift(2).pack("C*").unpack("v").first
|
144
|
-
elsif byte_1 == 254
|
145
|
-
# Little-endian 32-bit int
|
146
|
-
byte_array.shift(4).pack("C*").unpack("V").first
|
147
|
-
else
|
148
|
-
# 64-bit int (is this little-endian or native?)
|
149
|
-
byte_array.shift(8).pack("C*").unpack("Q").first
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|