Arbitrary Split approach
Edit: Added this section to address arbitrary split destinations
By the time you are splitting, you should know the length of the target data. Below is an example implementation of copying the bytes to their destination inside solidity, which should be trivially extendable to N buckets.
pragma solidity ^0.4.15;
contract HelpLogs {
event LogFirstHalf(bytes _data);
event LogSecondHalf(bytes _data);
function logit(bytes data) external {
uint midpoint = data.length / 2;
bytes memory data1 = new bytes(midpoint);
for (uint i = 0; i < midpoint; i++) {
data1[i] = data[i];
}
bytes memory data2 = new bytes(data.length - midpoint);
for (i = 0; i < data.length - midpoint; i++) {
data2[i] = data[i + midpoint];
}
LogFirstHalf(data1);
LogSecondHalf(data2);
}
}
Note that the gas usage is higher than it needs to be, because it works byte-by-byte. It would be faster to use 32-byte words, with bitmasking. A good reference is memcpy
from Arachnid's solidity-string utils library.
[Edit: old] Fixed Bucket Approach
You can split the data externally without the 21 kgas overhead. Send the pre-split data as two parameters to a single function call:
pragma solidity ^0.4.15;
contract HelpLogs {
event LogFirstHalf(bytes _data);
event LogSecondHalf(bytes _data);
function logit(bytes dataPart1, bytes dataPart2) external {
LogFirstHalf(dataPart1);
LogSecondHalf(dataPart2);
}
}
This will cost less gas than splitting inside the EVM.
For starters let's not equate smart contracts with people, that's a very OOP idea and it just confuses the entire issue, in my opinion.
I definitely agree that technical documentation and teaching material like this are very lacking. You often get very surface level information.
can listen to certain events
A smart contract can not listen to events.
A smart contract is a passive static thing. You call it to do something and it will do the thing. It never does things on its own. It may respond differently depending how much time has passed or blockheight or similar. Or depending on the state of other smart contracts, which it may enquire, as part of your request.
a human person can interact with the smart contract through a frontend interface and so full-fledged applications can be built on top of that "backend" interface.
Correct. Basically a blockchain is just a immutable database that lives "on the internet" decentralized with no single location. And in case of smart contract chains it can also have code.
smart contracts are compiled into bytecode i.e. EVM assembly instructions that are ran on the EVM and each instruction [cost] Gas.
Right.
Is it attached, to a block, on a newly mined block
It is! Everything is blocks, so everything on the chain is on the blocks. I think a contract might be split between blocks, technically, since there is a block size limited, not sure though.
How does one access that contract, then? You just scan the whole chain for smart contracts with a certain contract address?
Upon deployment, which is an EVM action performed with an existing ethereum address, which costs gas, you receive an address. That address is where you find the smart contract. Similar to a hashmap, access is very fast.
a transaction and then recorded on the block
There are two types of function calls in solidity on ethereum "view" types and normal ones. a view type call, does not write anything to the chain and does not cost any gas. Normal ones do. The gas cost is equivalent to the amount and cost of EVM instructions needed to completely the entire call.
So its only recorded for when you actually write to the chain, not when you just red out a variable, for instance.
Do note that for some view calls, some processing is still needed, like going through a loop lets say, and it does in fact not cost any gas to do this.
This is relevant to the next point.
Who does the code execution per-se
I think this is a very important question.
So first of all, the way these blockchains are designed is: you run a node yourself and you use it to communicate with the chain.
In reality most people use a third party, lets say metamask or infura or others. But these third parties just run nodes themselves and give you the answer you are looking for, they must still run a node like you can do yourself. These services usually cache all blockchain data in a faster and more convenient database.
(a lot of this seems like magic since we use convenient services like that, but really you just run a node, which collects all blocks and can communicate to the blockchain, which again is just a giant database)
When you make a VIEW call I assume you execute the EVM instructions yourself on your node, which is why it doesnt cost any gas.
When doing a call that writes, a miner has to actually mine it. Mine the block, attach your stuff to the block, execute code if there is any and write the result to block.
This is where it does get foggy for me: The consensus mechanism ensures data is correct and by more nodes picking up the blocks you produced, it becomes accepted. But it is only written once.
This goes into the territory of knowledge proofs for example if you want to look further into it.
But you do only write once, a miner does it. After that via consensus we determine, via consensus algorithm, that this write was correct and you didn't trick the system.
Best Answer
Amplifying @Ismael's answer,you could achieve the effect by deploying contracts with the code to run, and running in a proxy that accepts a contract address and uses delegate call to execute the arbitrary function. There would be a deployment cost for each arbitrary code instance and, of course, the main contract would plainly do literally anything, casting more than a little doubt on any assurances about what it actually does.
Check out "diamond pattern" for inspiration.
Hope it helps.