Я пытаюсь извлечь параметры сигнатуры ECDSA, используемые в биткойнах для запуска некоторых тестов. Для этого мне нужно получить:
--- r and s , i.e., the ECDSA signature
--- H(m) , the hash of the message used to generate the ECDSA signature
--- the random integer k used in ECDSA signature generation,
this is, the k such that s = k*(H(m) + x*r) mod q where x is
the private key
Я уже смог получить r и s очень специфического типа блока, где len (inp.script_sig) == 214).
Поэтому мне нужно получить эти параметры для всех блоков, а также знать, как это сделать для Ethereum и LiteCoin.
from blockchain import blockexplorer
from binascii import unhexlify
from pyasn1.codec.der import decoder as asn1der
import time, os, codecs
import numpy as np
from bitcoin_tools.bitcoin_tools.core.transaction import TX
# returns the blocks of given day
# if day = 0 , returns blocks of today
# if day = 1 , returns blocks of yesterday , and so on ....
def getBlocksofDay( day ):
# get blocks from blockchain from given day
# if we want the day before just subtract 86400000
return blockexplorer.get_blocks(int(round(time.time() * 1000)) - 86400000*day)
# print SimpleBlock
def printSimpleBlock( block ):
print("\nHeight : ", block.height )
print("Hash : ", block.hash )
print("Time : ", block.time)
print("Main Chain :", block.main_chain, "\n" )
# print Block
def printBlock( block ):
print("\nHash : ", block.hash )
print("Version : ", block.version )
print("Previous Block : ", block.previous_block )
print("Merkle Root : ", block.merkle_root )
print("Time : ", block.time)
print("Bits : ", block.bits)
print("Fee : ", block.fee)
print("Nonce : ", block.nonce)
print("Number of transaction : ", block.n_tx)
print("Size : ", block.size )
print("Block Index : " , block.block_index )
print("Main Chain :", block.main_chain )
print("Height : ", block.height )
print("Received Time : ", block.received_time )
print("Relayed By : ", block.relayed_by )
if( block.n_tx > 50):
print("Transactions : NOT PRINTING TX TOO MANY \n" )
else:
print("Transactions : ", block.transactions )
# print Transaction
def printTransaction( tx ):
print("\nDouble Spend : ", tx.double_spend )
print("Block height : ", tx.block_height )
print("Time : ", tx.time )
print("Relayed By : ", tx.relayed_by )
print("Hash : ", tx.hash )
print("Tx Index : " , tx.tx_index )
print("Version : ", tx.version )
print("Size : ", tx.size )
print("Inputs : ", tx.inputs )
print("Outputs : ", tx.outputs, "\n" )
# print Input
def printInput( inp ):
try:
if( len(inp.script_sig) == 214 ):
'''
print("\nN : ", inp.n )
print("Value : ", inp.value )
print("Address : ", inp.address )
print("Tx_Index : ", inp.tx_index )
print("Type : ", inp.type )
print("Script : ", inp.script )
print("Script_Sig : ", inp.script_sig )
print("Sequence : ", inp.sequence )
'''
return 0
except:
return -1
# print XPub
def printXPub( xpub ):
print("\nAddress : ", xpub.address)
print("Number of Transaction : ", xpub.n_tx )
print("Total Received : ", xpub.total_received / 100000000, "BTC" )
print("Total Sent : ", xpub.total_sent / 100000000, "BTC" )
print("Final Balance : ", xpub.final_balance )
print("Change Index : ", xpub.change_index )
print("Account Index : ", xpub.account_index, "\n\n" )
for tx in xpub.transactions:
printTransaction(tx)
def printR_S_PK(script_sig_hex):
#script_sig_hex is the scriptsig hex
values = asn1der.decode(unhexlify(script_sig_hex)[1:])
'''
#R Value in int form
print( "\nR value:", values[0][0] )
#S Value in int form
print( "S value:", values[0][1] )
# X coordinate of Public Key
print( "X coordinate of PK:", int(values[1].hex()[4:],16) )
'''
return [ int(values[1].hex()[6:],16), int(values[1].hex()[4:6],16), int(values[0][0]), int(values[0][1]) ]
#if __name__ == "__main__":
def getThemBlocks(day):
simpleBlocksofDay = getBlocksofDay(day)
pubKeys = np.array([[-1], [-1], [-1], [-1], [-1], [-1]])
print("LEN : ", len(simpleBlocksofDay), "\n")
# run through all blocks of this day
for block in [simpleBlocksofDay[0]]:
blocksofDay = blockexplorer.get_block( block.hash )
txs = blocksofDay.transactions
# run through all tx of this day
for txofDay in txs:
inpofTx = txofDay.inputs
# run through all inputs of this day
for inp in inpofTx:
# if input has format we want
if( printInput(inp) == 0 ):
numLines, numColumns = len(pubKeys), pubKeys[0].size
script_sig_hex = inp.script_sig
xC, sig, r, s = printR_S_PK(script_sig_hex)
aux = np.where(pubKeys[2]==xC)
columnToAdd = [ -1 for i in range(0,numLines) ]
columnToAdd[0], columnToAdd[1], columnToAdd[2], columnToAdd[3] = 6, 1, xC, sig
columnToAdd[4], columnToAdd[5] = r, s
lineToAdd = [ -1 for i in range(0,numColumns) ]
# xC it's not repeated
if( aux[0].size == 0 ):
pubKeys = np.c_[pubKeys, np.array(columnToAdd)]
# again xC it's not repeated
elif( (aux[0].size == 1) and (pubKeys[3][aux[0][0]] != sig) ):
pubKeys = np.c_[pubKeys, np.array(columnToAdd)]
# xC it's repeated
else:
if( pubKeys[3][aux[0][0]] == sig ):
column = aux[0][0]
else:
column = aux[0][1]
# need to add 2 new lines
if( pubKeys[0][column]+1 > numLines ):
aux = np.array(lineToAdd)
pubKeys = np.r_[pubKeys, [aux]]
pubKeys = np.r_[pubKeys, [aux]]
pubKeys = np.r_[pubKeys, [aux]]
line = pubKeys[0][column]
pubKeys[line][column] = r
pubKeys[line+1][column] = s
pubKeys[line+2][column] = txofDay.hash
# increase the number of elements in that columns by 2
pubKeys[0][column] += 3
# increase the number of signatures by 1
pubKeys[1][column] += 1
for j in range(1, pubKeys[0].size):
if(pubKeys[1][j] > 40):
for i in range(0, len(pubKeys)):
print(pubKeys[i][j])
print("\n\n")
if __name__ == "__main__":
'''
for i in range(0,3):
getThemBlocks(i)
'''
# First a transaction object is created (through the deserialize constructor) by deserializing the hex transaction we have selected.
hex_tx = "01000000013ca58d2f6fac36602d831ee0cf2bc80031c7472e80a322b57f614c5ce9142b71000000006b483045022100f0331d85cb7f7ec1bedc41f50c695d654489458e88aec0076fbad5d8aeda1673022009e8ca2dda1d6a16bfd7133b0008720145dacccb35c0d5c9fc567e52f26ca5f7012103a164209a7c23227fcd6a71c51efc5b6eb25407f4faf06890f57908425255e42bffffffff0241a20000000000001976a914e44839239ab36f5bc67b2079de00ecf587233ebe88ac74630000000000001976a914dc7016484646168d99e49f907c86c271299441c088ac00000000"
tx = TX.deserialize(hex_tx)
# Then, the transaction can be displayed using the display method to analyze how it's been constructed.
tx.display()