1 | /**
|
2 | * PubKey Map
|
3 | * ==========
|
4 | *
|
5 | * A map from (transaction hash, output number) to (script chunk index, pubKey).
|
6 | * Whening signing a bitcoin transaction, we need to be able to sign an input
|
7 | * with the correct key and also we need to know where to put signature when we
|
8 | * get it. This mapping allows us to find the key for an associated input (which
|
9 | * is identified by tx output hash and number) with which to sign the
|
10 | * transaction and then also to know where to insert the signature into the
|
11 | * input script. This gets us the public key, and we need a different method to
|
12 | * get the private key. That is because we often know the public key to be used
|
13 | * but may not have access to the private key until the entire tx is sent to
|
14 | * where the private keys are.
|
15 | */
|
16 |
|
17 |
|
18 | import { Struct } from './struct'
|
19 | import { Sig } from './sig'
|
20 |
|
21 | class SigOperations extends Struct {
|
22 | constructor (map = new Map()) {
|
23 | super({ map })
|
24 | }
|
25 |
|
26 | toJSON () {
|
27 | const json = {}
|
28 | this.map.forEach((arr, label) => {
|
29 | json[label] = arr.map(obj => ({
|
30 | nScriptChunk: obj.nScriptChunk,
|
31 | type: obj.type, // 'sig' or 'pubKey'
|
32 | addressStr: obj.addressStr,
|
33 | nHashType: obj.nHashType,
|
34 | log: obj.log
|
35 | }))
|
36 | })
|
37 | return json
|
38 | }
|
39 |
|
40 | fromJSON (json) {
|
41 | Object.keys(json).forEach(label => {
|
42 | this.map.set(label, json[label].map(obj => ({
|
43 | nScriptChunk: obj.nScriptChunk,
|
44 | type: obj.type,
|
45 | addressStr: obj.addressStr,
|
46 | nHashType: obj.nHashType,
|
47 | log: obj.log
|
48 | })))
|
49 | })
|
50 | return this
|
51 | }
|
52 |
|
53 | /**
|
54 | * Set an address to in the map for use with single-sig.
|
55 | *
|
56 | * @param {Buffer} txHashBuf The hash of a transsaction. Note that this is
|
57 | * *not* the reversed transaction id, but is the raw hash.
|
58 | * @param {Number} txOutNum The output number, a.k.a. the "vout".
|
59 | * @param {Number} nScriptChunk The index of the chunk of the script where
|
60 | * we are going to place the signature.
|
61 | * @param {String} addressStr The addressStr coresponding to this (txHashBuf,
|
62 | * txOutNum, nScriptChunk) where we are going to sign and insert the
|
63 | * signature or public key.
|
64 | * @param {Number} nHashType Usually = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID
|
65 | */
|
66 | setOne (txHashBuf, txOutNum, nScriptChunk, type = 'sig', addressStr, nHashType = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID) {
|
67 | const label = txHashBuf.toString('hex') + ':' + txOutNum
|
68 | const obj = { nScriptChunk, type, addressStr, nHashType }
|
69 | this.map.set(label, [obj])
|
70 | return this
|
71 | }
|
72 |
|
73 | /**
|
74 | * Set a bunch of addresses for signing an input such as for use with multi-sig.
|
75 | *
|
76 | * @param {Buffer} txHashBuf The hash of a transsaction. Note that this is
|
77 | * *not* the reversed transaction id, but is the raw hash.
|
78 | * @param {Number} txOutNum The output number, a.k.a. the "vout".
|
79 | * @param {Array} arr Must take the form of [{nScriptChunk, type, addressStr, nHashType}, ...]
|
80 | */
|
81 | setMany (txHashBuf, txOutNum, arr) {
|
82 | const label = txHashBuf.toString('hex') + ':' + txOutNum
|
83 | arr = arr.map(obj => ({
|
84 | type: obj.type || 'sig',
|
85 | nHashType: obj.nHashType || Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID,
|
86 | ...obj
|
87 | }))
|
88 | this.map.set(label, arr)
|
89 | return this
|
90 | }
|
91 |
|
92 | addOne (txHashBuf, txOutNum, nScriptChunk, type = 'sig', addressStr, nHashType = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID) {
|
93 | const arr = this.get(txHashBuf, txOutNum) || []
|
94 | arr.push({
|
95 | nScriptChunk,
|
96 | type,
|
97 | addressStr,
|
98 | nHashType
|
99 | })
|
100 | this.setMany(txHashBuf, txOutNum, arr)
|
101 | return this
|
102 | }
|
103 |
|
104 | /**
|
105 | * Get an address from the map
|
106 | *
|
107 | * @param {Buffer} txHashBuf The hash of a transction. Note that this is *not*
|
108 | * the reversed transaction id, but is the raw hash.
|
109 | * @param {Number} txOutNum The output number, a.k.a. the "vout".
|
110 | * @param {Number} nScriptChunk The index of the chunk of the script where
|
111 | * we are going to place the signature.
|
112 | * @returns {PubKey}
|
113 | */
|
114 | get (txHashBuf, txOutNum) {
|
115 | const label = txHashBuf.toString('hex') + ':' + txOutNum
|
116 | return this.map.get(label)
|
117 | }
|
118 | }
|
119 |
|
120 | export { SigOperations }
|