У меня есть функция прочности, объявленная как:
function setUnitData(bytes32[10] my_input_array) public payable {...}
Когда я запускаю этот код:
contract = self.contract_instance['../contracts/test.sol:test']
test_byte = b'0x01234567890123456789012345678901' * 24
tx_hash = contract.functions.setUnitData(test_byte).transact({'from': self.w3.toChecksumAddress(unit['update_account']), 'gas': 3400000})
Я получаю это ValidationError
:
web3.exceptions.ValidationError: Не удалось идентифицировать предполагаемую функцию с именем
setUnitData
, позиционным аргументом (аргументами) типа(<class 'bytes'>,)
и аргументом (аргументами) ключевого слова типа{}
. Найдено 1 функция (функции) с именемsetUnitData
: ['setUnitData(bytes32[10])'] Не удалось вызвать функцию из-за отсутствия соответствующих типов аргументов.
Любой возможный или лучший способ отправить массив байтов python или любой работоспособный тип этой функции?
Для функции setUnitData(bytes32[10])
требуется массив из 10 элементов, каждый из которых представляет собой 32 байта данных. Поскольку мы не знаем назначение функции, давайте сгенерируем случайные данные такого типа:
>>> input_array = [bytes(range(idx, 32 + idx)) for idx in range(10)]
[b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f',
b'\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ',
b'\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !',
b'\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"',
b'\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#',
b'\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$',
b'\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%',
b'\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&',
b'\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'',
b'\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'(']
Если просмотр собственных значений байтов в python вызывает у вас раздражение, вы можете преобразовать их в шестнадцатеричные строки. Web3.py тоже примет.
>>> from web3 import Web3
>>> hex_array = [Web3.toHex(bytes_data) for bytes_data in input_array]
['0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
'0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20',
'0x02030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021',
'0x030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122',
'0x0405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223',
'0x05060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324',
'0x060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425',
'0x0708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526',
'0x08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627',
'0x090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728']
Теперь вы можете отправить транзакцию с помощью:
contract = self.contract_instance['../contracts/test.sol:test']
tx_hash = contract.functions.setUnitData(input_array).transact({'from': self.w3.toChecksumAddress(unit['update_account']), 'gas': 3400000})
( hex_array
также работает вместо input_array
)
Вам нужно передать массив байтов. cntract ожидает массив из 10 элементов, но вы передаете переменную bytes. Вы можете создать массив со всеми остальными элементами, установленными в нули.
Надеюсь это поможет
альпер
Could not decode contract function call getJobStorageTime return data b''
@carver