def verify_input(self, input_index):
        """
        현재 트랜잭션 입력에 대한 검증
        step 1 : 현재 입력에 대응하는 결합 스크립트 생성
            - 입력에 대응하는 이전 트랜잭션 출력의 잠금 스크립트
            - 입력의 해제 스크립트
        step 2 : 현재 입력에 대응하는 서명 생성
        step 3 : 결합스크립트를 이용하여 서명 계산
        :param input_index: 현재 입력에 대한 인덱스
        :return: 검증 boolean
        """
        # 해당 트랜잭션 해시값에 대응되는 트랜잭션의 잠금 스크립트
        current_intput_tx = self.tx_inputs[input_index]
        current_pubkey = current_intput_tx.script_pubkey(testnet=self.testnet)

        # 스크립트 형식에 따라 리딤 스크립트 생성
        if current_pubkey.is_p2sh_script_pubkey():
            command = current_intput_tx.script_sig.commands[-1]
            redeem_script_raw = encode_varint(len(command)) + command
            redeem_script = Script.parse(BytesIO(redeem_script_raw))
        else:
            redeem_script = None

        # 현재 트랜잭션 입력에 대한 결합 스크립트
        combined = current_intput_tx.script_sig + current_pubkey

        # 현재 트랜잭션 입력에 대한 서명 생성
        message_hash = self.sig_hash(input_index, redeem_script)

        # 결합 스크립트를 통한 서명 검증
        return combined.evaluate(message_hash)
Beispiel #2
0
    def parse(cls, stream):
        # 금액 : 8바이트 리틀엔디언
        amount = little_endian_to_int(stream.read(8))
        # 해제 스크립트
        script_pubkey = Script.parse(stream)

        return cls(amount, script_pubkey)
def example2():
    print("Example : Height of Transaction in the block")
    stream = BytesIO(
        bytes.fromhex(
            '5e03d71b07254d696e656420627920416e74506f6f6c20626a31312f4542312f4144362f43205914293101fabe6d6d678e2c8c34afc36896e7d9402824ed38e856676ee94bfdb0c6c4bcd8b2e5666a0400000000000000c7270000a5e00e00'
        ))
    script_sig = Script.parse(stream)
    print("Height : {}".format(little_endian_to_int(script_sig.commands[0])))
def example1():
    print("Example : Miner-defined ScriptSig")
    stream = BytesIO(
        bytes.fromhex(
            '4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73'
        ))
    script = Script.parse(stream)
    for cmd in script.commands:
        print(cmd)
Beispiel #5
0
 def parse(cls, stream):
     # 이전 트랜잭션 해시값 : 32바이트 리틀엔디언
     prev_tx = stream.read(32)[::-1]
     # 이전 트랜잭션 번호 : 4바이트 리틀엔디언
     prev_index = little_endian_to_int(stream.read(4))
     # 해제 스크립트
     script_sig = Script.parse(stream)
     # 시퀀스 필드 : 4바이트 리틀엔디언
     seqeunce = little_endian_to_int(stream.read(4))
     return cls(prev_tx, prev_index, script_sig, seqeunce)
Beispiel #6
0
    def verify_input(self, input_index):
        """
        현재 트랜잭션 입력에 대한 검증
        step 1 : 현재 입력에 대응하는 결합 스크립트 생성
            - 입력에 대응하는 이전 트랜잭션 출력의 잠금 스크립트
            - 입력의 해제 스크립트
                - p2sh의 경우 리딤 스크립트
                    - 호환성을 위해 p2wpkh/p2wsh 또한 리딤 스크립트에 포함
                - p2wpkh 스크립트의 경우, 증인필드(서명, 공개키)
        step 2 : 현재 입력에 대응하는 서명 생성
        step 3 : 결합 스크립트를 이용하여 서명 계산
        :param input_index: 현재 입력에 대한 인덱스
        :return: 검증 boolean
        """
        # 해당 트랜잭션 해시값에 대응되는 트랜잭션의 잠금 스크립트
        current_intput_tx = self.tx_inputs[input_index]
        current_pubkey = current_intput_tx.script_pubkey(testnet=self.testnet)

        # 스크립트 형식에 따라 리딤 스크립트 생성
        if current_pubkey.is_p2sh_script_pubkey():
            command = current_intput_tx.script_sig.commands[-1]
            redeem_script_raw = encode_varint(len(command)) + command
            redeem_script = Script.parse(BytesIO(redeem_script_raw))

            # 리딤 스크립트 : p2sh-p2wpkh 이거나 p2sh-p2wsh 이다
            # p2wpkh인 경우 :
            if redeem_script.is_p2wpkh_script_pubkey():
                message_hash = self.sig_hash_bip143(input_index, redeem_script)
                witness = current_intput_tx.witness
            # p2wsh인 경우
            elif redeem_script.is_p2wsh_script_pubkey():
                # 증인 스크립트 추출
                cmd = current_intput_tx.witness[-1]

                # 가변 길이의 증인 스크립트 파싱
                raw_witness = encode_varint(len(cmd)) + cmd
                witness_script = Script.parse(BytesIO(raw_witness))
                message_hash = self.sig_hash_bip143(
                    input_index, witness_script=witness_script)
                witness = current_intput_tx.witness
            # p2sh인 경우
            else:
                message_hash = self.sig_hash(input_index, redeem_script)
                witness = None
        else:
            # 리딤 스크립트 : p2sh-p2wpkh 이거나 p2sh-p2wsh 이다
            # p2wpkh인 경우 :
            if current_pubkey.is_p2wpkh_script_pubkey():
                message_hash = self.sig_hash_bip143(input_index)
                witness = current_intput_tx.witness
            # p2wsh인 경우 :
            elif current_pubkey.is_p2wsh_script_pubkey():
                # 증인 스크립트 추출
                cmd = current_intput_tx.witness[-1]

                # 가변 길이의 증인 스크립트 파싱
                raw_witness = encode_varint(len(cmd)) + cmd
                witness_script = Script.parse(BytesIO(raw_witness))
                message_hash = self.sig_hash_bip143(
                    input_index, witness_script=witness_script)
                witness = current_intput_tx.witness
            # p2sh인 경우
            else:
                message_hash = self.sig_hash(input_index)
                witness = None

        # 현재 트랜잭션 입력에 대한 결합 스크립트
        combined = current_intput_tx.script_sig + current_pubkey

        # 결합 스크립트를 통한 서명 검증
        return combined.evaluate(message_hash, witness)