Module: Bitcoin::Descriptor

Includes:
Opcodes
Defined in:
lib/bitcoin/descriptor.rb

Constant Summary

Constants included from Opcodes

Opcodes::DUPLICATE_KEY, Opcodes::NAME_MAP, Opcodes::OPCODES_MAP, Opcodes::OP_0, Opcodes::OP_0NOTEQUAL, Opcodes::OP_1, Opcodes::OP_10, Opcodes::OP_11, Opcodes::OP_12, Opcodes::OP_13, Opcodes::OP_14, Opcodes::OP_15, Opcodes::OP_16, Opcodes::OP_1ADD, Opcodes::OP_1NEGATE, Opcodes::OP_1SUB, Opcodes::OP_2, Opcodes::OP_2DIV, Opcodes::OP_2DROP, Opcodes::OP_2DUP, Opcodes::OP_2MUL, Opcodes::OP_2OVER, Opcodes::OP_2ROT, Opcodes::OP_2SWAP, Opcodes::OP_3, Opcodes::OP_3DUP, Opcodes::OP_4, Opcodes::OP_5, Opcodes::OP_6, Opcodes::OP_7, Opcodes::OP_8, Opcodes::OP_9, Opcodes::OP_ABS, Opcodes::OP_ADD, Opcodes::OP_AND, Opcodes::OP_BOOLAND, Opcodes::OP_BOOLOR, Opcodes::OP_CAT, Opcodes::OP_CHECKMULTISIG, Opcodes::OP_CHECKMULTISIGVERIFY, Opcodes::OP_CHECKSIG, Opcodes::OP_CHECKSIGADD, Opcodes::OP_CHECKSIGVERIFY, Opcodes::OP_CODESEPARATOR, Opcodes::OP_DEPTH, Opcodes::OP_DIV, Opcodes::OP_DROP, Opcodes::OP_DUP, Opcodes::OP_ELSE, Opcodes::OP_ENDIF, Opcodes::OP_EQUAL, Opcodes::OP_EQUALVERIFY, Opcodes::OP_FROMALTSTACK, Opcodes::OP_GREATERTHAN, Opcodes::OP_GREATERTHANOREQUAL, Opcodes::OP_HASH160, Opcodes::OP_HASH256, Opcodes::OP_IF, Opcodes::OP_IFDUP, Opcodes::OP_INVALIDOPCODE, Opcodes::OP_INVERT, Opcodes::OP_LEFT, Opcodes::OP_LESSTHAN, Opcodes::OP_LESSTHANOREQUAL, Opcodes::OP_LSHIFT, Opcodes::OP_MAX, Opcodes::OP_MIN, Opcodes::OP_MOD, Opcodes::OP_MUL, Opcodes::OP_NEGATE, Opcodes::OP_NIP, Opcodes::OP_NOP, Opcodes::OP_NOP1, Opcodes::OP_NOP10, Opcodes::OP_NOP2, Opcodes::OP_NOP3, Opcodes::OP_NOP4, Opcodes::OP_NOP5, Opcodes::OP_NOP6, Opcodes::OP_NOP7, Opcodes::OP_NOP8, Opcodes::OP_NOP9, Opcodes::OP_NOT, Opcodes::OP_NOTIF, Opcodes::OP_NUMEQUAL, Opcodes::OP_NUMEQUALVERIFY, Opcodes::OP_NUMNOTEQUAL, Opcodes::OP_OR, Opcodes::OP_OVER, Opcodes::OP_PICK, Opcodes::OP_PUBKEY, Opcodes::OP_PUBKEYHASH, Opcodes::OP_PUSHDATA1, Opcodes::OP_PUSHDATA2, Opcodes::OP_PUSHDATA4, Opcodes::OP_RESERVED, Opcodes::OP_RESERVED1, Opcodes::OP_RESERVED2, Opcodes::OP_RETURN, Opcodes::OP_RIGHT, Opcodes::OP_RIPEMD160, Opcodes::OP_ROLL, Opcodes::OP_ROT, Opcodes::OP_RSHIFT, Opcodes::OP_SHA1, Opcodes::OP_SHA256, Opcodes::OP_SIZE, Opcodes::OP_SUB, Opcodes::OP_SUBSTR, Opcodes::OP_SUCCESSES, Opcodes::OP_SWAP, Opcodes::OP_TOALTSTACK, Opcodes::OP_TUCK, Opcodes::OP_VER, Opcodes::OP_VERIF, Opcodes::OP_VERIFY, Opcodes::OP_VERNOTIF, Opcodes::OP_WITHIN, Opcodes::OP_XOR

Instance Method Summary collapse

Methods included from Opcodes

defined?, name_to_opcode, op_success?, opcode_to_name, opcode_to_small_int, small_int_to_opcode

Instance Method Details

#combo(key) ⇒ Array[Bitcoin::Script]

an alias for the collection of ‘pk(KEY)` and `pkh(KEY)`. If the key is compressed, it also includes `wpkh(KEY)` and `sh(wpkh(KEY))`.

Parameters:

  • key (String)

    private key or public key with hex format.

Returns:



53
54
55
56
57
58
59
60
61
# File 'lib/bitcoin/descriptor.rb', line 53

def combo(key)
  result = [pk(key), pkh(key)]
  pubkey = extract_pubkey(key)
  if compressed_key?(pubkey)
    result << wpkh(key)
    result << sh(result.last)
  end
  result
end

#multi(threshold, *keys, sort: false) ⇒ Bitcoin::Script

generate multisig output for given keys.

Parameters:

  • threshold (Integer)

    the threshold of multisig.

  • keys (Array[String])

    an array of keys.

Returns:

Raises:

  • (ArgumentError)


67
68
69
70
71
72
73
74
# File 'lib/bitcoin/descriptor.rb', line 67

def multi(threshold, *keys, sort: false)
  raise ArgumentError, 'Multisig threshold is not valid.' unless threshold.is_a?(Integer)
  raise ArgumentError, 'Multisig threshold cannot be 0, must be at least 1.' unless threshold > 0
  raise ArgumentError, 'Multisig threshold cannot be larger than the number of keys.' if threshold > keys.size
  raise ArgumentError, 'Multisig must have between 1 and 16 keys, inclusive.' if keys.size > 16
  pubkeys = keys.map{|key| extract_pubkey(key) }
  Bitcoin::Script.to_multisig_script(threshold, pubkeys, sort: sort)
end

#pk(key) ⇒ Bitcoin::Script

generate P2PK output for the given public key.

Parameters:

  • key (String)

    private key or public key with hex format

Returns:



10
11
12
# File 'lib/bitcoin/descriptor.rb', line 10

def pk(key)
  Bitcoin::Script.new << extract_pubkey(key) << OP_CHECKSIG
end

#pkh(key) ⇒ Bitcoin::Script

generate P2PKH output for the given public key.

Parameters:

  • key (String)

    private key or public key with hex format.

Returns:



17
18
19
# File 'lib/bitcoin/descriptor.rb', line 17

def pkh(key)
  Bitcoin::Script.to_p2pkh(Bitcoin.hash160(extract_pubkey(key)))
end

#sh(script) ⇒ Bitcoin::Script

generate P2SH embed the argument.

Parameters:

Returns:

Raises:

  • (ArgumentError)


33
34
35
36
37
# File 'lib/bitcoin/descriptor.rb', line 33

def sh(script)
  script = script.to_hex if script.is_a?(Bitcoin::Script)
  raise ArgumentError, "P2SH script is too large, 547 bytes is larger than #{Bitcoin::MAX_SCRIPT_ELEMENT_SIZE} bytes." if script.htb.bytesize > Bitcoin::MAX_SCRIPT_ELEMENT_SIZE
  Bitcoin::Script.to_p2sh(Bitcoin.hash160(script))
end

#sortedmulti(threshold, *keys) ⇒ Bitcoin::Script

generate sorted multisig output for given keys.

Parameters:

  • threshold (Integer)

    the threshold of multisig.

  • keys (Array[String])

    an array of keys.

Returns:



80
81
82
# File 'lib/bitcoin/descriptor.rb', line 80

def sortedmulti(threshold, *keys)
  multi(threshold, *keys, sort: true)
end

#wpkh(key) ⇒ Bitcoin::Script

generate P2PKH output for the given public key.

Parameters:

  • key (String)

    private key or public key with hex format.

Returns:

Raises:

  • (ArgumentError)


24
25
26
27
28
# File 'lib/bitcoin/descriptor.rb', line 24

def wpkh(key)
  pubkey = extract_pubkey(key)
  raise ArgumentError, "Uncompressed key are not allowed." unless compressed_key?(pubkey)
  Bitcoin::Script.to_p2wpkh(Bitcoin.hash160(pubkey))
end

#wsh(script) ⇒ Bitcoin::Script

generate P2WSH embed the argument.

Parameters:

Returns:

Raises:

  • (ArgumentError)


42
43
44
45
46
47
# File 'lib/bitcoin/descriptor.rb', line 42

def wsh(script)
  script = Bitcoin::Script(script.htb) if script.is_a?(String)
  raise ArgumentError, "P2SH script is too large, 547 bytes is larger than #{Bitcoin::MAX_SCRIPT_ELEMENT_SIZE} bytes." if script.to_payload.bytesize > Bitcoin::MAX_SCRIPT_ELEMENT_SIZE
  raise ArgumentError, "Uncompressed key are not allowed." if script.get_pubkeys.any?{|p|!compressed_key?(p)}
  Bitcoin::Script.to_p2wsh(script)
end