Dentro de un contrato de Solidity, tengo esta variable: zBytes32 = "HelloBytes32";
después de que Python web3.py recupere esa variable,
zbytes32 = contractInstance.functions.getzBytes32().call()
# b'HelloBytes32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
zbytes32 = zBytes32.decode('utf8')# shows HelloBytes32
print(zbytes32)
zBytes32str= str(zbytes32)
print('zbytes32 = '+ zBytes32str)
if zBytes32str == 'HelloBytes32':
print('zbytes32str == "HelloBytes32"')
else:
print('zbytes32str != "HelloBytes32"')
print('\ngetBytes32 raw: {}'.format(zbytes32))# shows HelloBytes32
print('zbytes32.decode("utf8") as string = '+ zbytes32)# shows HelloBytes32
AUNQUE se ven iguales a HelloBytes32, ¡en realidad NO lo son!
Tal vez eso explique la siguiente situación:
arr = contractInstance.functions.getVariables().call()
print('arr[4] in str()= '+ str(arr[4]))#must be converted to string
b2= arr[4].decode('utf8')
print('b2.decode("utf8")= '+ b2)
arr[4] = ''
print('after arr[4] = "", arr[4]= '+ arr[4])
arr[4] = b2
print('after arr[4] = b2, arr[4]= '+ arr[4])
arr[0] = 'What man?'
print('after arr[0] = "What man?", arr[0]= '+ arr[0])
print('\nget many variables: {}'.format(arr))
se muestra en la terminal:
arr[4] in str()= b'HelloBytes32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b2.decode("utf8")= HelloBytes32
after arr[4] = "", arr[4]=
after arr[4] = b2, arr[4]= HelloBytes32
after arr[0] = "What man?", arr[0]= What man?
get many variables: ['What man?', '0x583031D11...', 111111, False, 'HelloBytes32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ['0xCA35b7d...', '0x14723A...'], [9999999, 555555]]
Vea la matriz anterior. Cuando configuro un nuevo valor para arr[0], funciona.
Pero cuando configuro un nuevo valor para arr[4], funciona...
¿POR QUÉ cuando muestro toda la matriz, arr[4] todavía muestra esos \x00 ???
Necesito pasar esos valores a otro script, así que debo asegurarme de que estén limpios de esos \x00. Por favor ayuda. Gracias
El problema aquí es que su variable tiene una longitud fija de 32 bytes, lo que explica los ceros a la derecha. Puedes quitar los ceros en python:
zbytes32 = contractInstance.functions.getzBytes32().call()
zbytes32 = zbytes32.hex().rstrip("0")
if len(zbytes32) % 2 != 0:
zbytes32 = zbytes32 + '0'
zbytes32 = bytes.fromhex(zbytes32).decode('utf8')
Imprimir la variable zbytes32 da: 'HelloBytes32' y: zbytes32=='HelloBytes32'
esTrue
La parte condicional if len(zbytes32) % 2 != 0
está ahí porque puede ser que el último carácter sea cero y lo estemos eliminando, la forma de saber esto es que cada byte está representado por dos caracteres hexadecimales, por lo que si la longitud de la variable zbytes32 después de eliminar los ceros es impar, se debe agregar un cero a la derecha.
Espero que esto ayude
Dado que parece estar asumiendo que los bytes son decodificables con UTF-8, es posible que desee un string
tipo en Solidity en lugar de bytes32
.
Si cambia el tipo de variable a Cadena y vuelve a implementar, el contrato web3.py con la nueva ABI le devolverá una cadena ya decodificada como "HelloBytes32"
.
from web3 import Web3
string_content = Web3.toText(bytes_content)
ruso