In einem Solidity-Vertrag habe ich diese Variable: zBytes32 = "HelloBytes32";
nachdem Python web3.py diese Variable abgerufen hat,
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
OBWOHL sie genauso aussehen wie HelloBytes32, sind sie es eigentlich NICHT!
Vielleicht erklärt das folgende Situation:
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))
es zeigt im 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]]
Siehe das obige Array. Wenn ich einen neuen Wert auf arr[0] setze, funktioniert es.
Aber wenn ich einen neuen Wert für arr[4] setze, funktioniert es irgendwie ...
WARUM zeigt arr[4] immer noch diese \x00 an, wenn ich das gesamte Array zeige ???
Ich muss diese Werte an ein anderes Skript weitergeben, damit ich sicherstellen muss, dass sie sauber von diesen \x00 sind. Bitte helfen Sie. Danke
Das Problem hier ist, dass Ihre Variable eine feste Länge von 32 Bytes hat, was die Nullen rechts erklärt. Sie können die Nullen in Python entfernen:
zbytes32 = contractInstance.functions.getzBytes32().call()
zbytes32 = zbytes32.hex().rstrip("0")
if len(zbytes32) % 2 != 0:
zbytes32 = zbytes32 + '0'
zbytes32 = bytes.fromhex(zbytes32).decode('utf8')
Das Drucken der Variablen zbytes32 ergibt: 'HelloBytes32' und: zbytes32=='HelloBytes32'
isTrue
Der bedingte Teil if len(zbytes32) % 2 != 0
ist da, weil es sein kann, dass das letzte Zeichen tatsächlich Null ist und wir es entfernen. Der Weg, dies zu wissen, ist, dass jedes Byte durch zwei hexadezimale Zeichen dargestellt wird, also wenn die Länge der Variablen zbytes32 nach dem Entfernen der Nullen ist ungerade muss rechts eine Null hinzugefügt werden.
Hoffe das hilft
Da Sie anscheinend davon ausgehen, dass die Bytes mit UTF-8 dekodierbar sind, möchten Sie vielleicht tatsächlich einen string
Typ in Solidity anstelle von bytes32
.
Wenn Sie den Variablentyp in String ändern und erneut bereitstellen, würde der web3.py-Vertrag mit der neuen ABI eine bereits decodierte Zeichenfolge als zurückgeben "HelloBytes32"
.
from web3 import Web3
string_content = Web3.toText(bytes_content)
Russo