質問編集履歴

3

元に戻しました。

2018/12/19 06:26

投稿

nekoooo
nekoooo

スコア10

test CHANGED
File without changes
test CHANGED
@@ -1,17 +1,345 @@
1
1
  ### 前提・実現したいこと
2
2
 
3
+ BitcoinまたはLitecoinの送金をPay-to-PubkeyHashで行いたいのですが。
4
+
5
+ 1つのUTXOからの送金を
6
+
7
+ https://en.bitcoin.it/wiki/Transaction#Pay-to-PubkeyHash
8
+
9
+ https://github.com/shirriff/bitcoin-code/blob/master/txnUtils.py
10
+
11
+ を参考に送金を行うことができました。
12
+
13
+ しかし
14
+
15
+ 2つ3つの同じアドレスのUTXOから送金をしたいと思っています。
16
+
3
17
 
4
18
 
5
19
  ### 発生している問題・エラーメッセージ
6
20
 
21
+ https://github.com/shirriff/bitcoin-code/blob/master/txnUtils.py
22
+
23
+ のソースコードを元に以下のソースコードを作成実行したところAPI側から
24
+
25
+ Non-canonical signature: S value is unnecessarily high
26
+
27
+ とエラーが発生してしまいます。
28
+
7
29
 
8
30
 
9
31
  ### 該当のソースコード
10
32
 
33
+ ```python
34
+
35
+ class BitcoinTransaction():
36
+
37
+ def __init__(self,type="insight",APIURL="https://insight.litecore.io",txversion="01000000",iVersion=48,iWIFVersion=176):
38
+
39
+ if type == "insight":
40
+
41
+ self.APIRapper = insight(APIURL)
42
+
43
+ elif type == "dogechain":
44
+
45
+ self.APIRapper = dogechain()
46
+
47
+
48
+
49
+ self.txversion = txversion
50
+
51
+
52
+
53
+ self.util = BitcoinUtil(iVersion,iWIFVersion)
54
+
55
+
56
+
57
+
58
+
59
+ def varstr(self,s):
60
+
61
+ return self.varint(len(s)) + s
62
+
63
+
64
+
65
+
66
+
67
+ def varint(self,n):
68
+
69
+ if n < 0xfd:
70
+
71
+ return struct.pack('<B', n)
72
+
73
+ elif n < 0xffff:
74
+
75
+ return struct.pack('<cH', '\xfd', n)
76
+
77
+ elif n < 0xffffffff:
78
+
79
+ return struct.pack('<cL', '\xfe', n)
80
+
81
+ else:
82
+
83
+ return struct.pack('<cQ', '\xff', n)
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+ def GetScriptPubKeyFromAddress(self,address):
92
+
93
+ pubkeyhash = self.util.GetPubkeyhashFromAddress(address)
94
+
95
+ return '76a914' + pubkeyhash + '88ac'
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+ def CreateRawInputs(self,address):
104
+
105
+ utxos = self.APIRapper.utxo(address)
106
+
107
+
108
+
109
+ inputs_text = ""
110
+
111
+ inputs_text = inputs_text + "%02x" % len(utxos)
112
+
113
+
114
+
115
+ for index,utxo in enumerate(utxos):
116
+
117
+ utxoTx = binascii.unhexlify(utxo["txid"])
118
+
119
+ utxoTx = utxoTx[::-1]
120
+
121
+ utxoTx = binascii.hexlify(utxoTx)
122
+
123
+ utxoTx = utxoTx.decode('utf-8')
124
+
125
+
126
+
127
+ utxoIndex = utxo["vout"]
128
+
129
+ utxoIndex = struct.pack('<L', utxoIndex)
130
+
131
+ utxoIndex = binascii.hexlify(utxoIndex)
132
+
133
+ utxoIndex = utxoIndex.decode('utf-8')
134
+
135
+
136
+
137
+ scriptPubKey = utxo["scriptPubKey"]
138
+
139
+ scriptPubKey_size = len(binascii.unhexlify(scriptPubKey))
140
+
141
+ scriptPubKey_size = "%02x" % scriptPubKey_size
142
+
143
+
144
+
145
+ sequence = "ffffffff"
146
+
147
+
148
+
149
+ inputs_text = inputs_text + (utxoTx + utxoIndex + scriptPubKey_size + scriptPubKey + sequence)
150
+
151
+
152
+
153
+ return inputs_text
154
+
155
+
156
+
157
+
158
+
159
+
160
+
161
+ def CreateSignInputs(self,privkey,datas):
162
+
163
+ address = self.util.GetKeysFromPrivkey(privkey)["address"]
164
+
165
+ utxos = self.APIRapper.utxo(address)
166
+
167
+
168
+
169
+ sk = SigningKey.from_string(binascii.unhexlify(privkey), curve=SECP256k1)
170
+
171
+
172
+
173
+
174
+
175
+
176
+
177
+ inputs_text = ""
178
+
179
+ inputs_text = inputs_text + "%02x" % len(utxos)
180
+
181
+
182
+
183
+ for index,utxo in enumerate(utxos):
184
+
185
+ utxoTx = binascii.unhexlify(utxo["txid"])
186
+
187
+ utxoTx = utxoTx[::-1]
188
+
189
+ utxoTx = binascii.hexlify(utxoTx)
190
+
191
+ utxoTx = utxoTx.decode('utf-8')
192
+
193
+
194
+
195
+ utxoIndex = utxo["vout"]
196
+
197
+ utxoIndex = struct.pack('<L', utxoIndex)
198
+
199
+ utxoIndex = binascii.hexlify(utxoIndex)
200
+
201
+ utxoIndex = utxoIndex.decode('utf-8')
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+ RawTransaction = self.CreateRawTransaction(address,datas)
210
+
211
+ txhash = hashlib.sha256(hashlib.sha256(binascii.unhexlify(RawTransaction)).digest()).digest()
212
+
213
+
214
+
215
+ sig = sk.sign_digest(txhash, sigencode=ecdsa.util.sigencode_der) + binascii.unhexlify('01') # 01 is hashtype
216
+
217
+ pubKey = binascii.unhexlify(self.util.GetPubkeyFromPrivkey(privkey))
218
+
219
+ scriptSig = binascii.hexlify(self.varstr(sig)).decode('utf-8') + binascii.hexlify(self.varstr(pubKey)).decode('utf-8')
220
+
221
+
222
+
223
+ scriptSig_size = len(binascii.unhexlify(scriptSig))
224
+
225
+ scriptSig_size = "%02x" % scriptSig_size
226
+
227
+
228
+
229
+
230
+
231
+ sequence = "ffffffff"
232
+
233
+
234
+
235
+ inputs_text = inputs_text + (utxoTx + utxoIndex + scriptSig_size + scriptSig + sequence)
236
+
237
+
238
+
239
+ return inputs_text
240
+
241
+
242
+
243
+
244
+
245
+
246
+
247
+
248
+
249
+ def CreateOutputs(self,datas):
250
+
251
+ outputs_text = ""
252
+
253
+ outputs_text = outputs_text + "%02x" % len(datas)
254
+
255
+ for data in datas:
256
+
257
+ redemptionSatoshis, address = data
258
+
259
+
260
+
261
+ rspack = struct.pack("<Q", redemptionSatoshis)
262
+
263
+ rspack = binascii.hexlify(rspack).decode('utf-8')
264
+
265
+
266
+
267
+ outputScript = self.GetScriptPubKeyFromAddress(address)
268
+
269
+ outputScript_size = len(binascii.unhexlify(outputScript))
270
+
271
+ outputScript_size = "%02x" % outputScript_size
272
+
273
+
274
+
275
+ outputs_text = outputs_text + (rspack + outputScript_size + outputScript)
276
+
277
+
278
+
279
+ outputs_text = outputs_text + "00000000"
280
+
281
+
282
+
283
+ return outputs_text
284
+
285
+
286
+
287
+
288
+
289
+
290
+
291
+ def CreateRawTransaction(self,inputaddress,datas):
292
+
293
+ RawTransaction = ""
294
+
295
+ RawTransaction = RawTransaction + self.txversion
296
+
297
+ RawTransaction = RawTransaction + self.CreateRawInputs(inputaddress)
298
+
299
+ RawTransaction = RawTransaction + self.CreateOutputs(datas)
300
+
301
+
302
+
303
+ RawTransaction = RawTransaction + "01000000"
304
+
305
+
306
+
307
+ return RawTransaction
308
+
309
+
310
+
311
+
312
+
313
+
314
+
315
+ def CreateSignTransaction(self,privkey,datas):
316
+
317
+ SignTransaction = ""
318
+
319
+ SignTransaction = SignTransaction + self.txversion
320
+
321
+ SignTransaction = SignTransaction + self.CreateSignInputs(privkey,datas)
322
+
323
+ SignTransaction = SignTransaction + self.CreateOutputs(datas)
324
+
325
+
326
+
327
+ return SignTransaction
328
+
329
+ ```
330
+
11
331
 
12
332
 
13
333
  ### 試したこと
14
334
 
335
+ ```python
336
+
337
+ scriptSig = binascii.hexlify(self.varstr(sig)).decode('utf-8') + binascii.hexlify(self.varstr(pubKey)).decode('utf-8')
338
+
339
+ ```
340
+
341
+ sigの元のtxhashの元のrawTransactionの中を変更したりしました。
342
+
15
343
 
16
344
 
17
345
  ### 補足情報(FW/ツールのバージョンなど)

2

編集

2018/12/19 06:26

投稿

nekoooo
nekoooo

スコア10

test CHANGED
File without changes
test CHANGED
@@ -2,33 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- BitcoinまたはLitecoinの送金をPay-to-PubkeyHashで行いたいのですが。
6
-
7
- 1つのUTXOからの送金を
8
-
9
- https://en.bitcoin.it/wiki/Transaction#Pay-to-PubkeyHash
10
-
11
- https://github.com/shirriff/bitcoin-code/blob/master/txnUtils.py
12
-
13
- を参考に送金を行うことができました。
14
-
15
- しかし
16
-
17
- 2つ3つの同じアドレスのUTXOから送金をしたいと思っています。
18
-
19
-
20
-
21
5
  ### 発生している問題・エラーメッセージ
22
-
23
- https://github.com/shirriff/bitcoin-code/blob/master/txnUtils.py
24
-
25
- のソースコードを元に以下のソースコードを作成実行したところAPI側から
26
-
27
- Non-canonical signature: S value is unnecessarily high
28
-
29
- とエラーが発生してしまいます。
30
-
31
-
32
6
 
33
7
 
34
8
 
@@ -40,6 +14,4 @@
40
14
 
41
15
 
42
16
 
43
-
44
-
45
17
  ### 補足情報(FW/ツールのバージョンなど)

1

編集

2018/12/05 10:08

投稿

nekoooo
nekoooo

スコア10

test CHANGED
File without changes
test CHANGED
@@ -36,317 +36,7 @@
36
36
 
37
37
 
38
38
 
39
- ```python
40
-
41
- class BitcoinTransaction():
42
-
43
- def __init__(self,type="insight",APIURL="https://insight.litecore.io",txversion="01000000",iVersion=48,iWIFVersion=176):
44
-
45
- if type == "insight":
46
-
47
- self.APIRapper = insight(APIURL)
48
-
49
- elif type == "dogechain":
50
-
51
- self.APIRapper = dogechain()
52
-
53
-
54
-
55
- self.txversion = txversion
56
-
57
-
58
-
59
- self.util = BitcoinUtil(iVersion,iWIFVersion)
60
-
61
-
62
-
63
-
64
-
65
- def varstr(self,s):
66
-
67
- return self.varint(len(s)) + s
68
-
69
-
70
-
71
-
72
-
73
- def varint(self,n):
74
-
75
- if n < 0xfd:
76
-
77
- return struct.pack('<B', n)
78
-
79
- elif n < 0xffff:
80
-
81
- return struct.pack('<cH', '\xfd', n)
82
-
83
- elif n < 0xffffffff:
84
-
85
- return struct.pack('<cL', '\xfe', n)
86
-
87
- else:
88
-
89
- return struct.pack('<cQ', '\xff', n)
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
- def GetScriptPubKeyFromAddress(self,address):
98
-
99
- pubkeyhash = self.util.GetPubkeyhashFromAddress(address)
100
-
101
- return '76a914' + pubkeyhash + '88ac'
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
- def CreateRawInputs(self,address):
110
-
111
- utxos = self.APIRapper.utxo(address)
112
-
113
-
114
-
115
- inputs_text = ""
116
-
117
- inputs_text = inputs_text + "%02x" % len(utxos)
118
-
119
-
120
-
121
- for index,utxo in enumerate(utxos):
122
-
123
- utxoTx = binascii.unhexlify(utxo["txid"])
124
-
125
- utxoTx = utxoTx[::-1]
126
-
127
- utxoTx = binascii.hexlify(utxoTx)
128
-
129
- utxoTx = utxoTx.decode('utf-8')
130
-
131
-
132
-
133
- utxoIndex = utxo["vout"]
134
-
135
- utxoIndex = struct.pack('<L', utxoIndex)
136
-
137
- utxoIndex = binascii.hexlify(utxoIndex)
138
-
139
- utxoIndex = utxoIndex.decode('utf-8')
140
-
141
-
142
-
143
- scriptPubKey = utxo["scriptPubKey"]
144
-
145
- scriptPubKey_size = len(binascii.unhexlify(scriptPubKey))
146
-
147
- scriptPubKey_size = "%02x" % scriptPubKey_size
148
-
149
-
150
-
151
- sequence = "ffffffff"
152
-
153
-
154
-
155
- inputs_text = inputs_text + (utxoTx + utxoIndex + scriptPubKey_size + scriptPubKey + sequence)
156
-
157
-
158
-
159
- return inputs_text
160
-
161
-
162
-
163
-
164
-
165
-
166
-
167
- def CreateSignInputs(self,privkey,datas):
168
-
169
- address = self.util.GetKeysFromPrivkey(privkey)["address"]
170
-
171
- utxos = self.APIRapper.utxo(address)
172
-
173
-
174
-
175
- sk = SigningKey.from_string(binascii.unhexlify(privkey), curve=SECP256k1)
176
-
177
-
178
-
179
-
180
-
181
-
182
-
183
- inputs_text = ""
184
-
185
- inputs_text = inputs_text + "%02x" % len(utxos)
186
-
187
-
188
-
189
- for index,utxo in enumerate(utxos):
190
-
191
- utxoTx = binascii.unhexlify(utxo["txid"])
192
-
193
- utxoTx = utxoTx[::-1]
194
-
195
- utxoTx = binascii.hexlify(utxoTx)
196
-
197
- utxoTx = utxoTx.decode('utf-8')
198
-
199
-
200
-
201
- utxoIndex = utxo["vout"]
202
-
203
- utxoIndex = struct.pack('<L', utxoIndex)
204
-
205
- utxoIndex = binascii.hexlify(utxoIndex)
206
-
207
- utxoIndex = utxoIndex.decode('utf-8')
208
-
209
-
210
-
211
-
212
-
213
-
214
-
215
- RawTransaction = self.CreateRawTransaction(address,datas)
216
-
217
- txhash = hashlib.sha256(hashlib.sha256(binascii.unhexlify(RawTransaction)).digest()).digest()
218
-
219
-
220
-
221
- sig = sk.sign_digest(txhash, sigencode=ecdsa.util.sigencode_der) + binascii.unhexlify('01') # 01 is hashtype
222
-
223
- pubKey = binascii.unhexlify(self.util.GetPubkeyFromPrivkey(privkey))
224
-
225
- scriptSig = binascii.hexlify(self.varstr(sig)).decode('utf-8') + binascii.hexlify(self.varstr(pubKey)).decode('utf-8')
226
-
227
-
228
-
229
- scriptSig_size = len(binascii.unhexlify(scriptSig))
230
-
231
- scriptSig_size = "%02x" % scriptSig_size
232
-
233
-
234
-
235
-
236
-
237
- sequence = "ffffffff"
238
-
239
-
240
-
241
- inputs_text = inputs_text + (utxoTx + utxoIndex + scriptSig_size + scriptSig + sequence)
242
-
243
-
244
-
245
- return inputs_text
246
-
247
-
248
-
249
-
250
-
251
-
252
-
253
-
254
-
255
- def CreateOutputs(self,datas):
256
-
257
- outputs_text = ""
258
-
259
- outputs_text = outputs_text + "%02x" % len(datas)
260
-
261
- for data in datas:
262
-
263
- redemptionSatoshis, address = data
264
-
265
-
266
-
267
- rspack = struct.pack("<Q", redemptionSatoshis)
268
-
269
- rspack = binascii.hexlify(rspack).decode('utf-8')
270
-
271
-
272
-
273
- outputScript = self.GetScriptPubKeyFromAddress(address)
274
-
275
- outputScript_size = len(binascii.unhexlify(outputScript))
276
-
277
- outputScript_size = "%02x" % outputScript_size
278
-
279
-
280
-
281
- outputs_text = outputs_text + (rspack + outputScript_size + outputScript)
282
-
283
-
284
-
285
- outputs_text = outputs_text + "00000000"
286
-
287
-
288
-
289
- return outputs_text
290
-
291
-
292
-
293
-
294
-
295
-
296
-
297
- def CreateRawTransaction(self,inputaddress,datas):
298
-
299
- RawTransaction = ""
300
-
301
- RawTransaction = RawTransaction + self.txversion
302
-
303
- RawTransaction = RawTransaction + self.CreateRawInputs(inputaddress)
304
-
305
- RawTransaction = RawTransaction + self.CreateOutputs(datas)
306
-
307
-
308
-
309
- RawTransaction = RawTransaction + "01000000"
310
-
311
-
312
-
313
- return RawTransaction
314
-
315
-
316
-
317
-
318
-
319
-
320
-
321
- def CreateSignTransaction(self,privkey,datas):
322
-
323
- SignTransaction = ""
324
-
325
- SignTransaction = SignTransaction + self.txversion
326
-
327
- SignTransaction = SignTransaction + self.CreateSignInputs(privkey,datas)
328
-
329
- SignTransaction = SignTransaction + self.CreateOutputs(datas)
330
-
331
-
332
-
333
- return SignTransaction
334
-
335
- ```
336
-
337
-
338
-
339
39
  ### 試したこと
340
-
341
- ```python
342
-
343
- scriptSig = binascii.hexlify(self.varstr(sig)).decode('utf-8') + binascii.hexlify(self.varstr(pubKey)).decode('utf-8')
344
-
345
- ```
346
-
347
- をscriptSig = sig + pubkey + pubkeyにしたり
348
-
349
- sigの元のtxhashの元のrawTransactionの中を変更したりしました。
350
40
 
351
41
 
352
42