Say we have a contract function which need some address[]
parameter as input:
function do_sth(
address[] memory ads,
uint256 in
) external returns (uint256 out) {
...
}
This will produce the transaction Input Data
as follows (detail data here just for example):
0x65432121
0x0000000000000000000000000000000000000000000000000000000000000040
0x00000000000000000000000000000000000000000000000783c5395de63b678d
0x0000000000000000000000000000000000000000000000000000000000000002
0x000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d56
0x000000000000000000000000b387c824cafe52b25fbbe793d7b6800b1ddbfe7d
For example the ads=[0xe9e7cea3dedca5984780bafc599bd69add087d56, 0xb387c824cafe52b25fbbe793d7b6800b1ddbfe7d]
and in=0x783c5395de63b678d
are the function inputs.
We can see that this is a little bit low efficient (higher gas), since there're so many zeros there.
Is there any way to get the exact Input Data
as e9e7cea3dedca5984780bafc599bd69add087d56b387c824cafe52b25fbbe793d7b6800b1ddbfe7d00000000000000000000000000000000000000000000000783c5395de63b678d
? How to implement it in Solidity?
Best Answer
Of course you can.
A better question is : should you ?
Probably not, because to do so you will have to write low level assembly code that's error-prone, difficult to debug / read and possibly make assumptions about the solidity compiler that might not hold over time.
Your input data will be :
The assumption about the compiler will be the following :
The following function :
Should only receive 4 bytes of calldata : the function identifier. It cannot receive less, but it can receive more. There is no saying if this assumption will hold on every subsequent versions of solidity...
Your parameters will therefore be embedded in the calldata, and not accessible from solidity, only from assembly reading directly from calldata.
This can be achieved with the following implementation that just reads from calldata, decodes the embedded input and returns them following the standard ABI specifications :
If you were to call this function with the following calldata (you can add as many addresses as you want before the uint256 value / function identifier was omitted):
With this web3 code for example :
You get your addresses and your uint value extracted from the calldata :
Which cost 23593 gas on default settings, a slight improvement over the 24331 gas cost of this solidity version on the same settings :
Now you shouldn't do that, and probably don't even need to. You should stick to solidity.
So, it's possible but clearly not recommended.
I hope that answers your question.