示例#1
0
 def verify_input(self, input_index):
     tx_in = self.tx_ins[input_index]
     script_pubkey = tx_in.script_pubkey(testnet=self.testnet)
     if script_pubkey.is_p2sh_script_pubkey():
         cmd = tx_in.script_sig.cmds[-1]
         raw_redeem = int_to_little_endian(len(cmd), 1) + cmd
         redeem_script = Script.parse(BytesIO(raw_redeem))
         if redeem_script.is_p2wpkh_script_pubkey():
             z = self.sig_hash_bip143(input_index, redeem_script)
             witness = tx_in.witness
         elif redeem_script.is_p2wsh_script_pubkey():
             cmd = tx_in.witness[-1]
             raw_witness = encode_varint(len(cmd)) + cmd
             witness_script = Script.parse(BytesIO(raw_witness))
             z = self.sig_hash_bip143(input_index, witness_script=witness_script)
             witness = tx_in.witness
         else:
             z = self.sig_hash(input_index, redeem_script)
             witness = None
     else:
         if script_pubkey.is_p2wpkh_script_pubkey():
             z = self.sig_hash_bip143(input_index)
             witness = tx_in.witness
         elif script_pubkey.is_p2wsh_script_pubkey():
             cmd = tx_in.witness[-1]
             raw_witness = encode_varint(len(cmd)) + cmd
             witness_script = Script.parse(BytesIO(raw_witness))
             z = self.sig_hash_bip143(input_index, witness_script=witness_script)
             witness = tx_in.witness
         else:
             z = self.sig_hash(input_index)
             witness = None
     combined = tx_in.script_sig + script_pubkey
     return combined.evaluate(z, witness)
示例#2
0
 def serialize_legacy(self):
     result = int_to_little_endian(self.version, 4)
     result += encode_varint(len(self.tx_ins))
     for tx_in in self.tx_ins:
         result += tx_in.serialize()
     result += encode_varint(len(self.tx_outs))
     for tx_out in self.tx_outs:
         result += tx_out.serialize()
     result += int_to_little_endian(self.locktime, 4)
     return result
示例#3
0
 def filterload(self, flag=1):
     payload = encode_varint(self.size)
     payload += self.filter_bytes()
     payload += int_to_little_endian(self.function_count, 4)
     payload += int_to_little_endian(self.tweak, 4)
     payload += int_to_little_endian(flag, 1)
     return GenericMessage(b"filterload", payload)
示例#4
0
 def serialize_segwit(self):
     result = int_to_little_endian(self.version, 4)
     result += b"\x00\x01"
     result += encode_varint(len(self.tx_ins))
     for tx_in in self.tx_ins:
         result += tx_in.serialize()
     result += encode_varint(len(self.tx_outs))
     for tx_out in self.tx_outs:
         result += tx_out.serialize()
     for tx_in in self.tx_ins:
         result += int_to_little_endian(len(tx_in.witness), 1)
         for item in tx_in.witness:
             if type(item) == int:
                 result += int_to_little_endian(item, 1)
             else:
                 result += encode_varint(len(item)) + item
     result += int_to_little_endian(self.locktime, 4)
     return result
示例#5
0
 def sig_hash(self, input_index, redeem_script=None):
     s = int_to_little_endian(self.version, 4)
     s += encode_varint(len(self.tx_ins))
     for i, tx_in in enumerate(self.tx_ins):
         if i == input_index:
             if redeem_script:
                 script_sig = redeem_script
             else:
                 script_sig = tx_in.script_pubkey(self.testnet)
         else:
             script_sig = None
         s += TxIn(
             prev_tx=tx_in.prev_tx,
             prev_index=tx_in.prev_index,
             script_sig=script_sig,
             sequence=tx_in.sequence,
         ).serialize()
     s += encode_varint(len(self.tx_outs))
     for tx_out in self.tx_outs:
         s += tx_out.serialize()
     s += int_to_little_endian(self.locktime, 4)
     s += int_to_little_endian(SIGHASH_ALL, 4)
     h256 = hash256(s)
     return int.from_bytes(h256, "big")
示例#6
0
 def serialize(self):
     result = int_to_little_endian(self.version, 4)
     result += int_to_little_endian(self.services, 8)
     result += int_to_little_endian(self.timestamp, 8)
     result += int_to_little_endian(self.receiver_services, 8)
     result += b"\x00" * 10 + b"\xff\xff" + self.receiver_ip
     result += self.receiver_port.to_bytes(2, "big")
     result += int_to_little_endian(self.sender_services, 8)
     result += b"\x00" * 10 + b"\xff\xff" + self.sender_ip
     result += self.sender_port.to_bytes(2, "big")
     result += self.nonce
     result += encode_varint(len(self.user_agent))
     result += self.user_agent
     result += int_to_little_endian(self.latest_block, 4)
     if self.relay:
         result += b"\x01"
     else:
         result += b"\x00"
     return result
示例#7
0
 def serialize(self):
     result = int_to_little_endian(self.version, 4)
     result += encode_varint(self.num_hashes)
     result += self.start_block[::-1]
     result += self.end_block[::-1]
     return result
示例#8
0
 def serialize(self):
     result = encode_varint(len(self.data))
     for data_type, identifier in self.data:
         result += int_to_little_endian(data_type, 4)
         result += identifier[::-1]
     return result
示例#9
0
文件: Script.py 项目: pmuens/pybtc
 def evaluate(self, z, witness):
     cmds = self.cmds[:]
     stack = []
     altstack = []
     while len(cmds) > 0:
         cmd = cmds.pop(0)
         if type(cmd) == int:
             operation = OP_CODE_FUNCTIONS[cmd]
             if cmd in (99, 100):
                 if not operation(stack, cmds):
                     LOGGER.info("bad op: {}".format(OP_CODE_NAMES[cmd]))
                     return False
             elif cmd in (107, 108):
                 if not operation(stack, altstack):
                     LOGGER.info("bad op: {}".format(OP_CODE_NAMES[cmd]))
                     return False
             elif cmd in (172, 173, 174, 175):
                 if not operation(stack, z):
                     LOGGER.info("bad op: {}".format(OP_CODE_NAMES[cmd]))
                     return False
             else:
                 if not operation(stack):
                     LOGGER.info("bad op: {}".format(OP_CODE_NAMES[cmd]))
                     return False
         else:
             stack.append(cmd)
             if (len(cmds) == 3 and cmds[0] == 0xA9
                     and type(cmds[1]) == bytes and len(cmds[1]) == 20
                     and cmds[2] == 0x87):
                 redeem_script = encode_varint(len(cmd)) + cmd
                 cmds.pop()
                 h160 = cmds.pop()
                 cmds.pop()
                 if not op_hash160(stack):
                     return False
                 stack.append(h160)
                 if not op_equal(stack):
                     return False
                 if not op_verify(stack):
                     LOGGER.info("bad p2sh h160")
                     return False
                 redeem_script = encode_varint(len(cmd)) + cmd
                 stream = BytesIO(redeem_script)
                 cmds.extend(Script.parse(stream).cmds)
             if len(stack) == 2 and stack[0] == b"" and len(stack[1]) == 20:
                 h160 = stack.pop()
                 stack.pop()
                 cmds.extend(witness)
                 cmds.extend(p2pkh_script(h160).cmds)
             if len(stack) == 2 and stack[0] == b"" and len(stack[1]) == 32:
                 s256 = stack.pop()
                 stack.pop()
                 cmds.extend(witness[:-1])
                 witness_script = witness[-1]
                 if s256 != sha256(witness_script):
                     print("bad sha256 {} vs {}".format(
                         s256.hex(),
                         sha256(witness_script).hex()))
                     return False
                 stream = BytesIO(
                     encode_varint(len(witness_script)) + witness_script)
                 witness_script_cmds = Script.parse(stream).cmds
                 cmds.extend(witness_script_cmds)
     if len(stack) == 0:
         return False
     if stack.pop() == b"":
         return False
     return True
示例#10
0
文件: Script.py 项目: pmuens/pybtc
 def serialize(self):
     result = self.raw_serialize()
     total = len(result)
     return encode_varint(total) + result