2

I have a solidity function declared as:

function setUnitData(bytes32[10] my_input_array) public payable {...}

When I run this code:

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})

I get this ValidationError:

web3.exceptions.ValidationError: Could not identify the intended function with name setUnitData, positional argument(s) of type (<class 'bytes'>,) and keyword argument(s) of type {}. Found 1 function(s) with the name setUnitData: ['setUnitData(bytes32[10])'] Function invocation failed due to no matching argument types.

Any possible or best way to send the python byte array or any workable type to this function?

2

The function setUnitData(bytes32[10]) requires an array of 10 elements, each of which is 32 bytes of data. Since we don't know the purpose of the function, let's generate a some random data of that type:

>>> 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 !"#$%&\'(']

If looking at native bytes values in python makes you grumpy, you can convert to hex strings. Web3.py will accept either.

>>> 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']

Now you can send a transaction with:

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 also works, in place of input_array)

  • It returns following error: Could not decode contract function call getJobStorageTime return data b'' @carver – alper Apr 9 at 14:18
0

You need to pass an array of bytes. The cntract is expecting an array of 10 elements but you are passing a bytes variable. You can create an array with all the other elements set to zeros.

Hope this helps

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.