Cómo generar firma y validar firma sin conexión sin usar web3

Solo necesito una forma sencilla de firmar un mensaje sin conexión, preferiblemente usando Python o JavaScript. No quiero tener que iniciar sesión con Web3 . Solo quiero que mi clave privada se use desde una variable en el código.

Esto es solo para una herramienta de prueba de concepto que estoy creando, por lo que no quiero usar Web3 ni ningún nodo para hacer esto. ¿Existe una biblioteca que me permita firmar y verificar un mensaje de la misma manera que lo harían los nodos de Ethereum?

web3.py w3.eth.account.sign()hace lo que estás buscando. Desafortunadamente, solo se puede acceder a él mediante la instalación desde la fuente, por el momento. Está programado para ser lanzado como beta en la próxima semana más o menos.

Respuestas (1)

Esta pregunta es un posible duplicado . Sin embargo, creo que este código puede ser útil para su POC, es decir, firmar y verificar mensajes sin el uso de Web3js.

Usando Java, la clase ECKey.java en EthereumJ le brinda toda la funcionalidad requerida. He aquí un ejemplo de ello en la práctica...

Firma:

public void testEthereumSign() throws IOException {
    ECKey key = ECKey.fromPrivate(privateKey);
    System.out.println("Secret\t: " + Hex.toHexString(key.getPrivKeyBytes()));
    System.out.println("Pubkey\t: " + Hex.toHexString(key.getPubKey()));
    System.out.println("Data\t: " + exampleMessage);
    byte[] messageHash = HashUtil.sha3(exampleMessage.getBytes());
    ECDSASignature signature = key.sign(messageHash);
    String output = signature.toBase64();
    System.out.println("Signtr\t: " + output + " (Base64, length: " + output.length() + ")");
    assertEquals(sigBase64, output);
}

Verificando:

public void testVerifySignature1() {
    ECKey key = ECKey.fromPublicOnly(pubKey);
    BigInteger r = new BigInteger("28157690258821599598544026901946453245423343069728565040002908283498585537001");
    BigInteger s = new BigInteger("30212485197630673222315826773656074299979444367665131281281249560925428307087");
    ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray(), (byte) 28);
    key.verify(HashUtil.sha3(exampleMessage.getBytes()), sig);
}

Python con pyethereum :

sign(key, network_id=None)- firma la transacción con la clave dada

sha3(data)- calcula el hash SHA3 (o más precisamente, keccak256)

ecrecover_to_pub(hash, v, r, s)- recupera la clave pública que hizo la firma como un blob binario de 64 bytes de encode_int32(x) + encode_int32(y). Hashing esto y tomando los últimos 20 bytes da la dirección que firmó un mensaje.

ecsign(hash, key)- devuelve los valores v, r, s de una firma

normalize_key(key)- convierte una clave de muchos formatos en binario de 32 bytes

privtoaddr(key)- convierte una clave en una dirección

Gracias. ¿Hay una implementación js o python de esto fácilmente disponible?
@Cuervo sí! Consulte la pregunta actualizada para python.