p2pkの問題点とp2pkh

secp256k1の公開鍵は圧縮で33バイト、非圧縮で65バイト(130文字)で長い
UTXOセットが大きくなる
ScriptPubKeyフィールドに公開鍵が存在する

### p2pkhで解決
– アドレスが短くなる
– sha256とripemd160
=> hash160と呼ぶ 160ビット
p2pkhは短くて安全性が高い

### ScriptPubKey(output)
76 OP_DUB
a9 OP_HASH160
14 Length of
bc3b…da
88 OP_EQUALVERIFY
ac OC_CHECKSIG

### ScriptSig(input)
48 Length of signature
30..01 signature
21 Length of pubkey
0349…8a pubkey

### 構成
– ScriptPubKey(output)
OP_DUB, OP_HASH160, HASH, OP_EQUALVERIFY, OP_CHECKSIG
– ScriptSig(input)
,

OP_DUPはエレメントの先頭を複製するため、pubkeyが複製される

def op_dup(stack):
    if len(stack) < 1:
        return False
    stack.append(stack[-1])
    return True

OP_HASH160でpubkeyをhash160(sha256, ripemd160)実行、20バイトのハッシュを生成する

def op_hash160(stack):
    if len(stack) < 1:
        return False
    element = stack.pop()
    stack.append(hash160(element))
    return True

OP_EQUALVERIFYで、生成されたhashとhash値が正しいか確認

def op_equalverify(stack):
    return op_equal(stack) and op_verify(stack)

def op_equal(stack):
    if len(stack) < 2:
        return False
    element1 = stack.pop()
    element2 = stack.pop()
    if element1 == element2:
        stack.append(encode_num(1))
    else:
        stack.append(encode_num(0))
    return True

def op_verify(stack):
    if len(stack) < 1:
        return False
    element = stack.pop()
    if decode_num(element) == 0:
        return False
    return True

OP_CHECKSIGはP2PKと同じ

def op_checksig(stack, z):
    if len(stack) < 1:
        return False
    sec_pubkey = stack.pop()
    der_signature = stack.pop()[:-1]
    try:
        point = S256Point.parse(sec_pubkey)
        sig = Signature.parse(der_signature)
    except (ValueError, SyntaxError) as e:
        return False
    if point.verify(z, sig):
        stack.append(encode_num(1))
    else:
        stack.append(encode_num(0))
    return True

### P2PKH
– ScriptPubKeyが短くなる
– ripemd160,sha256も計算する