solidity python 签名和验证

注意,以太坊智能合约里面采用的是公钥非紧凑类型


def gen_secrets_pair():
    """
    得到公钥和私钥
    :return:
    """

    from coincurve import PrivateKey
    p = PrivateKey()
    return p.to_hex(), p.public_key.format(compressed=False).hex()


def hasher(msg_str):
    k = sha3.keccak_256()
    k.update(msg_str.encode("utf-8"))
    return k.hexdigest()


def hash2hex(msg):
    return bytes(bytearray.fromhex(msg))


def sign_recoverable(hash_msg_str, pk_str):
    from coincurve import PrivateKey
    pk = PrivateKey(bytearray.fromhex(pk_str))
    return pk.sign_recoverable(hash2hex(hash_msg_str), hasher=None).hex()


def from_signature_and_message(sig_msg_str, msg_str):
    from coincurve import PublicKey
    pk = PublicKey.from_signature_and_message(bytes(bytearray.fromhex(sig_msg_str)), bytes(bytearray.fromhex(msg_str)),
                                              hasher=None)
    return pk.format(compressed=False).hex()


def pk2address(pk_str):
    k = sha3.keccak_256()
    k.update(bytes(list(hash2hex(pk_str))[1:]))
    return bytes(k.digest()[12:]).hex()


if __name__ == '__main__':
    p, pk = gen_secrets_pair()
    print(p, pk)

    # sig = "f4128988cbe7df8315440adde412a8955f7f5ff9a5468a791433727f82717a6753bd71882079522207060b681fbd3f5623ee7ed66e33fc8e581f442acbcf6ab800"
    # msgHash = "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45"

    msg = "hello"
    h_msg = hasher(msg)

    print(h_msg)
    print(list(hash2hex(h_msg)))

    sig_msg = sign_recoverable(h_msg, p)

    print(sig_msg)
    print(list(hash2hex(sig_msg)))

    # print(from_signature_and_message(sig, msgHash))
    print(from_signature_and_message(sig_msg, h_msg))
    # print(from_signature_and_message(sig_msg, h_msg))
    print(from_signature_and_message(
        "f4128988cbe7df8315440adde412a8955f7f5ff9a5468a791433727f82717a6753bd71882079522207060b681fbd3f5623ee7ed66e33fc8e581f442acbcf6ab800",
        "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45"),
        "60320b8a71bc314404ef7d194ad8cac0bee1e331"
    )
    

合约代码操作

    library ECRecovery {

  /**
   * @dev Recover signer address from a message by using his signature
   * @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address.
   * @param sig bytes signature, the signature is generated using web3.eth.sign()
   */
  function recover(bytes32 hash, bytes sig) public pure returns (address) {
    bytes32 r;
    bytes32 s;
    uint8 v;

    //Check the signature length
    if (sig.length != 65) {
      return (address(0));
    }

    // Divide the signature in r, s and v variables
    assembly {
      r := mload(add(sig, 32))
      s := mload(add(sig, 64))
      v := byte(0, mload(add(sig, 96)))
    }

    // Version of signature should be 27 or 28, but 0 and 1 are also possible versions
    if (v < 27) {
      v += 27;
    }

    // If the version is correct return the signer address
    if (v != 27 && v != 28) {
      return (address(0));
    } else {
      return ecrecover(hash, v, r, s);
    }
  }

}
原文地址:https://www.cnblogs.com/bergus/p/solidity-python-qian-ming-he-yan-zheng.html