It was the Bitcointalk forum that inspired us to create Bitcointalksearch.org - Bitcointalk is an excellent site that should be the default page for anybody dealing in cryptocurrency, since it is a virtual gold-mine of data. However, our experience and user feedback led us create our site; Bitcointalk's search is slow, and difficult to get the results you need, because you need to log in first to find anything useful - furthermore, there are rate limiters for their search functionality.
The aim of our project is to create a faster website that yields more results and faster without having to create an account and eliminate the need to log in - your personal data, therefore, will never be in jeopardy since we are not asking for any of your data and you don't need to provide them to use our site with all of its capabilities.
We created this website with the sole purpose of users being able to search quickly and efficiently in the field of cryptocurrency so they will have access to the latest and most accurate information and thereby assisting the crypto-community at large.
pkey = pubkey[::-1] + "0042030a0004812b050601023dce48862a070610305630".decode("hex")
pkey = M2Crypto.EC.pub_key_from_der(pkey[::-1])
from pyasn1.codec.der import encoder
from pyasn1.type.univ import Sequence, ObjectIdentifier, BitString
# http://www.oid-info.com/get/1.2.840.10045.2.1
OID_EC_PUBLIC_KEY = "1.2.840.10045.2.1"
# http://www.oid-info.com/get/1.3.132.0.10
OID_SECP256K1 = "1.3.132.0.10"
def ec_public_key_in_der(xy_curve):
"Create the DER public key part using the XY curve values"
oid = Sequence()
oid.setComponentByPosition(0, ObjectIdentifier(OID_EC_PUBLIC_KEY))
oid.setComponentByPosition(1, ObjectIdentifier(OID_SECP256K1))
xyc = BitString("'%s'H" % xy_curve.encode('hex'))
tmp = Sequence()
tmp.setComponentByPosition(0, oid)
tmp.setComponentByPosition(1, xyc)
return(encoder.encode(tmp))
if __name__ == '__main__':
XY_CURVE = "0447d490561f396c8a9efc14486bc198884ba18379bcac2e0be2d8525134" +\
"ab742f301a9aca36606e5d29aa238a9e2993003150423df6924563642d4afe9bf4fe28"
XY_CURVE = XY_CURVE.decode('hex')
PUBLIC_KEY = "3056301006072a8648ce3d020106052b8104000a0342000447d490561f" +\
"396c8a9efc14486bc198884ba18379bcac2e0be2d8525134ab742f301a9aca36606e5d2" +\
"9aa238a9e2993003150423df6924563642d4afe9bf4fe28"
PUBLIC_KEY = PUBLIC_KEY.decode('hex')
if ec_public_key_in_der(XY_CURVE) == PUBLIC_KEY:
print(True)
else:
print(False)
import binascii
import hashlib
import M2Crypto
import structures
#Transaction 2 uses an output from Transaction 1
#Transaction 1: http://blockexplorer.com/tx/945691940e0ccd9f526ee1edd57a77ce170804915749702f5564c49b1f70f330
#Transaction 2: http://blockexplorer.com/tx/ff954e099764d192c5bb531c9c14c18c230b0c0a63f02cd168a4ea94548c890f#i325189
tx1raw= '\x01\x00\x00\x00\x02\x0f{\x7f\xb8mL\xf6F\x05\x8eA\xd3\xb0\x07\x18?\xdfysn\xd1\x9b*th\xab\xc5\xbd\x04\xb1n\x91\x00\x00\x00\x00\x8cI0F\x02!\x00\xb2\xee9\xd2\xfc\xc2\xe5TJW\xc3\x0f{NI\xcf\xb8""fm\x03O\xb9\x0e"4\x8e\x17\xe2\x8e\x0f\x02!\x00\xdb\x91\xc3\x19\x9c\xc7\xb4\x1dMz\xfc\xe0\xcc\xb4\xce\xb4$\xb9GmQ\xc0aBX=\xafS\xce\n\x9bf\x01A\x04\xc3"\x15\xa9\t0\x11\xbd\xfb\xd8-\x149\xbe\x01A\x04\xc3"\x15\xa9\t0\x11\xbdtx2raw= "\x01\x00\x00\x00\x030\xf3p\x1f\x9b\xc4dU/pIW\x91\x04\x08\x17\xcewz\xd5\xed\xe1nR\x9f\xcd\x0c\x0e\x94\x91V\x94\x00\x00\x00\x00\x8cI0F\x02!\x00\xf5tk\x0b%OZ7\xe7RQE\x9cz#\xb6\xdf\xcb\x86\x8a\xc7F~\xdd\x9ao\xdd\x1d\x96\x98q\xbe\x02!\x00\x88\x94\x8a\xea)\xb6\x91a\xca4\x1cI\xc0&\x86\xa8\x1d\x8c\xbbs\x94\x0f\x91\x7f\xa0\xedqThm>[\x01A\x04G\xd4\x90V\x1f9l\x8a\x9e\xfc\x14Hk\xc1\x98\x88K\xa1\x83y\xbc\xac.\x0b\xe2\xd8RQ4\xabt/0\x1a\x9a\xca6`n])\xaa#\x8a\x9e)\x93\x001PB=\xf6\x92Ecd-J\xfe\x9b\xf4\xfe(\xff\xff\xff\xffr\x14+\xf7hl\xe9,m\xe5\xb73e\xbf\xb9\xd5\x9b\xb6\x0c,\x80\x98-YX\xc1\xe6\xa3\xb0\x8e\xa6\x89\x00\x00\x00\x00JI0F\x02!\x00\xbc\xe4:\xd3\xac\xbcy\xb0$~T\xc8\xc9\x1e\xac\x1c\xf9\x03u\x05\x00\x0e\x01\xd1\xfd\x81\x18T\xd8[\xc2\x1a\x02!\x00\x99*oo/\xebob\xd3po;\x9a\xaa\xb8\x8d\x9f\x112\x95j\x1d\xff\xa9&\xcdUn\xd5S`\xdf\x01\xff\xff\xff\xff\xd2\x81(\xbb\xb6 |\x1c=\nc\x0c\xc6\x19\xdc~{\xeaV\xac\x19\xa1\xda\xb1'\xc6,x\xfa\x1bc,\x00\x00\x00\x00IH0E\x02 \x97W6\x81aSw\x08\xfd)\xd8\x9b\xb1\xe9\xd6H\x00yI\xec\xfd\xedx\x9bQ\xa9c$\xcbe\x18\x02!\x00\xcd\x0f|0!9\x16H+n\x16m\x8aO+\x98\x1fw~\xb1\x84\xcd\x8aI_\x1b=6\x90\xfb\xbf-\x01\xff\xff\xff\xff\x01\x00\xa6\xf7_\x02\x00\x00\x00\x19v\xa9\x14\x9e5\xd9
tx1 = structures.Tx.deserialize(tx1raw)[0]
tx2 = structures.Tx.deserialize(tx2raw)[0]
#We're going to check that the first input of Tx2 is correctly redeemed
def run_script(script, stack):
while script:
opcode = ord(script.pop(0))
if opcode <= 75:
value = ""
for x in xrange(0, opcode):
value += script.pop(0)
stack.append(value)
elif opcode == 118:
#OP_DUP
stack.append(stack[-1])
elif opcode == 169:
#OP_HASH160
#The input is hashed twice: first with SHA-256 and then with RIPEMD-160.
value = stack.pop()
value = hashlib.sha256(value).digest()
ripemd = hashlib.new('ripemd160')
ripemd.update(value)
value = ripemd.digest()
stack.append(value)
elif opcode == 136:
#OP_EQUALVERIFY
v1 = stack.pop()
v2 = stack.pop()
if v1 != v2:
raise Exception()
elif opcode == 172:
#OP_CHECKSIG
#1. the public key and the signature are popped from the stack, in that order.
pubkey = stack.pop()
signature = stack.pop()
#2. A new subscript is created from the instruction from the most recent OP_CODESEPARATOR to the end of the script. If there is no OP_CODESEPARATOR the entire script becomes the subscript (hereby referred to as subScript)
#(we don't do the OP_CODESEPARATOR thing yet...)
subscript = tx1.txout[0].script
#3. the signature is deleted from subscript
subscript = subscript.replace(chr(len(signature)) + signature, "")
#4. The hashtype is removed from the last byte of the sig and stored
hashtype = signature[-1]
signature = signature[:-1]
#5. A deep copy is made of the current transaction (hereby referred to txCopy)
#(we do this by serializing and deserialing this transaction again...)
txCopy = structures.Tx.deserialize(tx2.serialize())[0]
#6. All OP_CODESEPARATORS are removed from subScript
#(we don't do this yet...)
#7. The scripts for all transaction inputs in txCopy are set to empty scripts
for txin in txCopy.txins:
txin.script = ""
#8. The script for the current transaction input in txCopy is set to subScript
#We're checking the first input
txCopy.txins[0].script = subscript
#An array of bytes is constructed from the serialized txCopy + four bytes for the hash type.
#This array is sha256 hashed twice, then the public key is used to to check the supplied
#signature against the hash.
#Load the public key. I have no idea what this magical string does...
pkey = pubkey[::-1] + "0042030a0004812b050601023dce48862a070610305630".decode("hex")
pkey = M2Crypto.EC.pub_key_from_der(pkey[::-1])
#Serialize the transaction and add the hashtype to the end as an int
txhash = txCopy.serialize() + "\x01\x00\x00\x00"
#And sha256 it twice
txhash = hashlib.sha256(hashlib.sha256(txhash).digest()).digest()
if pkey.verify_dsa_asn1(txhash, signature):
stack.append(True)
else:
stack.append(False)
stack = []
run_script(list(tx2.txins[0].script), stack)
run_script(list(tx1.txout[0].script), stack)
print stack
pkey = pubkey[::-1] + "0042030a0004812b050601023dce48862a070610305630".decode("hex")
pkey = M2Crypto.EC.pub_key_from_der(pkey[::-1])