Solidity
如何通過 web3.py 將 Solidity bytes32 轉換/解碼為 Python 字元串
在 Solidity 合約中,我有這個變數: zBytes32 = “HelloBytes32”;
在 Python web3.py 檢索該變數之後,
zbytes32 = contractInstance.functions.getzBytes32().call()
print(zbytes32) 顯示 zbytes32 的值是什麼:
# 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)
decode(‘utf8’) 刪除前面的 b,print() 將隱藏所有 \x00,但它們仍然存在!為了證明它:
zBytes32str= str(zbytes32) print('zbytes32 = '+ zBytes32str) if zBytes32str == 'HelloBytes32': print('zbytes32str == "HelloBytes32"') else: print('zbytes32str != "HelloBytes32"')
zbytes32str != “HelloBytes32” 顯示!!!那麼如何在 Python 中正確解碼 byte32 ???
print('\ngetBytes32 raw: {}'.format(zbytes32))# shows HelloBytes32 print('zbytes32.decode("utf8") as string = '+ zbytes32)# shows HelloBytes32
儘管它們看起來與 HelloBytes32 相同,但實際上它們不是!
也許這解釋了以下情況:
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))
它顯示在終端中:
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]]
請參閱上面的數組。當我將新值設置為 arr
$$ 0 $$, 有用。 但是當我為 arr 設置一個新值時
$$ 4 $$,它有點工作…… 為什麼當我顯示整個數組時,arr
$$ 4 $$仍然顯示那些 \x00 ??? 我需要將這些值傳遞給另一個腳本,因此我必須確保它們與那些 \x00. 請幫忙。謝謝
這裡的問題是您的變數具有 32 個字節的固定長度,這解釋了右側的零。您可以在 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')
列印變數 zbytes32 給出: ‘HelloBytes32’ 和:
zbytes32=='HelloBytes32'
是True
條件部分
if len(zbytes32) % 2 != 0
在那裡,因為它可能是最後一個字元確實為零並且我們正在刪除它,知道這一點的方法是每個字節都由兩個十六進製字元表示,所以如果刪除零後變數 zbytes32 的長度是奇數,右邊必須加一個零。希望這可以幫助