¿Cómo puedo obtener el mismo hash resultante de Keccak-256 () en solidity y web3.sha3() en web3?
IN solidity usando keccak256 (dirección) y usando web3.sha3 (dirección) da resultados diferentes.
En web3, el campo de dirección es una cadena, mientras que en Solidity es una dirección.
¿Cómo puedo convertir una cadena web3 en un campo de tipo de dirección?
Intenté convertir el campo de tipo de dirección en una cadena en solidez y aún recibí diferentes resultados en hashes.
Para la dirección de picar en la solidez que usé
function toString(address x) returns (string) {
bytes memory b = new bytes(20);
for (uint i = 0; i < 20; i++)
b[i] = byte(uint8(uint(x) / (2**(8*(19 - i)))));
return string(b);
}
web3.sha3()
toma un parámetro de codificación para especificar que está pasando una dirección hexadecimal:
address_string = '0x5b2063246f2191f18f2675cedb8b28102e957458';
web3.sha3(address_string, {encoding: 'hex'});
Como nota al margen general: debe pagar los costos de la gasolina para realizar cualquier trabajo personalizado en Solidity, por lo que, cuando sea posible, es mejor que trabaje en el lado de JavaScript.
Además, puede realizar keccak256( address )
una constant
función de solidez localmente y luego pasar el resultado a una transacción. Por supuesto, esto no es seguro para la producción, si permite que los usuarios lo hagan en su navegador.
La última versión de web3 tiene una web3.utils.soliditySha3
función que puede usar que imita el hashing de Solidity:
address = '0x407D73d8a49eeb85D32Cf465507dd71d507100c1';
hash = web3.utils.soliditySha3(address);
A menudo es fácil de usar el kit de herramientas de codificación ABI que hace lo que se denomina "empaquetado ajustado" o argumentos dados. Puede realizar esto con una función integrada.
en solidez
/**
* A test method exposed to be called from clients to compare that ABI packing and hashing
* is same across different programming languages.
*
* Does ABI encoding for an address and then calculates KECCAK-256 hash over the bytes.
*
* https://web3js.readthedocs.io/en/v1.2.0/web3-utils.html#soliditysha3
*
*/
function calculateAddressHash(address a) public pure returns (bytes32 hash, bytes memory data) {
// First we ABI encode the address to bytes.
// This is so called "tight packing"
// https://web3js.readthedocs.io/en/v1.2.0/web3-utils.html#soliditysha3
bytes memory packed = abi.encodePacked(a);
// Then we calculate keccak256 over the resulting bytes
bytes32 hashResult = keccak256(packed);
return(hashResult, packed);
}
En JavaScript/TypeScript
import { soliditySha3 } from 'web3-utils';
// Sign address
const { signature, v, r, s } = signAddress(user2);
// This is an address is a hexadecimal format
const ourData = user2.toLowerCase();
// https://web3js.readthedocs.io/en/v1.2.0/web3-utils.html#id23
// Convert address to bytes using "tight packing"
// and them calculates keccak-256 over the resulting bytes
const ourHash = soliditySha3({t: 'address', v: user2 });
// We hash data in similar in TypeScript and Solidity
const { hash, data } = await tokenSwap.calculateAddressHash(user2);
assert(ourData.toLowerCase() == data.toLowerCase());
assert(ourHash.toLowerCase() == hash.toLowerCase());
tallista
Richard Horrocks