En Solidity, ¿cómo puedo convertir la dirección del remitente en una cadena?
Los comentarios en ¿Cómo convertir una dirección a bytes en Solidity? no proporcionó una solución de trabajo
abi.encodePacked(x)
donde x
esta la direccion (Gracias @k06a )
toAsciiString
el ejemplo en la otra respuesta.Invalid type for argument in the string.concat function call. string type is required, but t_bytes_memory_ptr provided
, toAsciiString
funciona para mí.No pude leer la cadena codificada con ABI con web3.js. Por lo tanto, agregué algo de conversión a los caracteres ASCII:
function toAsciiString(address x) internal pure returns (string memory) {
bytes memory s = new bytes(40);
for (uint i = 0; i < 20; i++) {
bytes1 b = bytes1(uint8(uint(uint160(x)) / (2**(8*(19 - i)))));
bytes1 hi = bytes1(uint8(b) / 16);
bytes1 lo = bytes1(uint8(b) - 16 * uint8(hi));
s[2*i] = char(hi);
s[2*i+1] = char(lo);
}
return string(s);
}
function char(bytes1 b) internal pure returns (bytes1 c) {
if (uint8(b) < 10) return bytes1(uint8(b) + 0x30);
else return bytes1(uint8(b) + 0x57);
}
if (b < 10)
tiene que cambiarse a if (uint8(b) < 10)
, entonces el Operator < not compatible with types bytes1 ...
error se corrige. Hice una edición a la respuesta. Espero que se apruebe.Web3.utils.toChecksumAddress()
.Este es el método para convertir address
a hexadecimal string
:
function toString(address account) public pure returns(string memory) {
return toString(abi.encodePacked(account));
}
function toString(uint256 value) public pure returns(string memory) {
return toString(abi.encodePacked(value));
}
function toString(bytes32 value) public pure returns(string memory) {
return toString(abi.encodePacked(value));
}
function toString(bytes memory data) public pure returns(string memory) {
bytes memory alphabet = "0123456789abcdef";
bytes memory str = new bytes(2 + data.length * 2);
str[0] = "0";
str[1] = "x";
for (uint i = 0; i < data.length; i++) {
str[2+i*2] = alphabet[uint(uint8(data[i] >> 4))];
str[3+i*2] = alphabet[uint(uint8(data[i] & 0x0f))];
}
return string(str);
}
Puede convertir la dirección a uint160, luego usar la biblioteca OpenZeppelin Strings.
Strings.toHexString(uint160(address), 20)
Referencia:
Esto funciona con solidez 0.6.0
function addressToString(address _pool) public pure returns (string memory _uintAsString) {
uint _i = uint256(_pool);
if (_i == 0) {
return "0";
}
uint j = _i;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len - 1;
while (_i != 0) {
bstr[k--] = byte(uint8(48 + _i % 10));
_i /= 10;
}
return string(bstr);
}
returns (string memory _uintAsString)
!!! por lo que es un int, no la cadena de dirección como cabría esperar a primera vista. Esto también significa que si su dirección comienza con uno o más ceros (0x 0 A1bC4...), convertirlo a un int y luego volver a hexadecimal (dirección) nuevamente resultará en la falta de este 0 inicial. Necesitará algo como esto: '0x' + BigInt(ethAddressAsInt).toString(16).padStart(40, '0')
(siendo 40 la longitud de una dirección ethereum, excluyendo el "0x")
Kushan Gunasekera
internal pure
palabra clave, de lo contrario recibirá una advertencia. Para obtener más información sobre la función pura .