def address_p2sh_p2wpkh(version, pubkey): assert pubkey[0] != 4, "uncompressed pubkey" prefix_bytes = version_to_bytes(version) pubkey_bytes = hash_160(pubkey) witness = b"\x00\x14" + pubkey_bytes witness_bytes = hash_160(witness) return b58check_encode(prefix_bytes + witness_bytes)
def get_subnode(node, i): # Public Child key derivation (CKD) algorithm of BIP32 i_as_bytes = struct.pack(">L", i) if i & HARDENED_FLAG: raise ValueError("Prime derivation not supported") # Public derivation data = node.public_key + i_as_bytes I64 = hmac.HMAC(key=node.chain_code, msg=data, digestmod=hashlib.sha512).digest() I_left_as_exponent = int.from_bytes(I64[:32], "big") # BIP32 magic converts old public key to new public point point = SEC1Encoder.decode_public_key(node.public_key, secp256k1) result = I_left_as_exponent * secp256k1.G + point if point == Point.IDENTITY_ELEMENT: raise ValueError("Point cannot be INFINITY") # Convert public point to compressed public key public_key = SEC1Encoder.encode_public_key(result) return HDNodeType( depth=node.depth + 1, child_num=i, chain_code=I64[32:], fingerprint=hash_160(node.public_key)[:4], public_key=public_key, )
def fingerprint(pubkey): return string_to_number(tools.hash_160(pubkey)[:4])
def create_inputs(self, numinputs, txsize): idx = 0 sum = 0 self.inputs = [] self.txs = {} for nr in range(numinputs): t = proto_types.TransactionType() t.version = 1 t.lock_time = 0 i = t.inputs.add() i.prev_hash = os.urandom(32) i.prev_index = random.randint(0, 4) i.script_sig = os.urandom(100) i.sequence = 0xffffffff if nr % 50 == 0: print(nr) myout = random.randint(0, txsize - 1) segwit = random.randint(0, 2) for vout in range(txsize): o = t.bin_outputs.add() o.amount = random.randint(10000, 1000000) if vout == myout: amount = o.amount sum = sum + o.amount node = self.node path = [0, idx] node = bip32.public_ckd(node, path) idx = idx + 1 pubkey = tools.hash_160(node.public_key) else: pubkey = os.urandom(20) if segwit == 2: # p2sh segwit o.script_pubkey = b'\xa9\x14' + hash160(b'\x00\x14' + pubkey) + b'\x87' elif segwit == 1: o.script_pubkey = b'\x00\x14' + pubkey else: o.script_pubkey = b'\x76\xa9\x14' + pubkey + b'\x88\xac' txser = self.serialize_tx(t) txhash = tools.Hash(txser)[::-1] outi = self.inputs.append( proto_types.TxInputType( address_n=self.client.expand_path("44'/0'/0'/0/%d" % idx), script_type=(proto_types.SPENDWITNESS if segwit == 1 else proto_types.SPENDP2SHWITNESS if segwit == 2 else proto_types.SPENDADDRESS), prev_hash=txhash, prev_index=myout, amount=amount if segwit > 0 else 0)) # print(binascii.hexlify(txser)) # print(binascii.hexlify(txhash)) self.txs[binascii.hexlify(txhash)] = t self.outputs = [ proto_types.TxOutputType( amount=sum, script_type=proto_types.PAYTOADDRESS, address_n=self.client.expand_path("44'/0'/0'/1/0")) ]
def create_inputs(self, numinputs, txsize): idx = 0 sum = 0 self.inputs = [] self.txs = {} for nr in range(numinputs): t = proto_types.TransactionType() t.version = 1 t.lock_time = 0 i = t.inputs.add() i.prev_hash = os.urandom(32) i.prev_index = random.randint(0,4) i.script_sig = os.urandom(100) i.sequence = 0xffffffff if (nr % 50 == 0): print(nr) myout = random.randint(0, txsize-1) segwit = 1 #random.randint(0,1) for vout in range(txsize): o = t.bin_outputs.add() o.amount = random.randint(10000,1000000) if vout == myout: amount = o.amount sum = sum + o.amount node = self.node path = [0, idx] node = bip32.public_ckd(node, path) idx = idx + 1 pubkey = tools.hash_160(node.public_key) else: pubkey = os.urandom(20) if (segwit): o.script_pubkey = binascii.unhexlify('0014') + pubkey else: o.script_pubkey = binascii.unhexlify('76a914') + pubkey + binascii.unhexlify('88ac') txser = self.serialize_tx(t) txhash = tools.Hash(txser)[::-1] if (segwit): outi = self.inputs.append( proto_types.TxInputType( address_n=self.client.expand_path("44'/0'/0'/0/"+str(idx)), script_type = proto_types.SPENDWADDRESS, prev_hash=txhash, prev_index = myout, amount = amount )) else: outi = self.inputs.append( proto_types.TxInputType( address_n=self.client.expand_path("44'/0'/0'/0/"+str(idx)), script_type = proto_types.SPENDADDRESS, prev_hash=txhash, prev_index = myout )) #print(binascii.hexlify(txser)) #print(binascii.hexlify(txhash)) self.txs[binascii.hexlify(txhash)] = t self.outputs = [ proto_types.TxOutputType( amount=sum, script_type=proto_types.PAYTOADDRESS, address_n=self.client.expand_path("44'/0'/0'/1/0") )]
def script_sig_p2sh_p2wpkh(address, signature): script_sig = b"\x16\x00\x14" + hash_160(address.public_key) return script_sig, [signature, address.public_key]
def address_p2wpkh(version, pubkey): assert pubkey[0] != 4, "uncompressed pubkey" witver = 0 witprog = hash_160(pubkey) return bech32.encode(version, witver, witprog)
def address_p2pkh(version, pubkey): assert pubkey[0] != 4, "uncompressed pubkey" prefix_bytes = version_to_bytes(version) pubkey_bytes = hash_160(pubkey) return b58check_encode(prefix_bytes + pubkey_bytes)