Description
Instead of placing all contructor params at the beginning of the contract, the compiler could auto-insert the params at first usage. This would be a nice default, resulting in optimized contracts with limited extra complexity for the compiler. Stack juggling the constructor parameters will likely become a bigger overhead with the increased VM Limits CHIP.
Changing the placement of constructor variables would be a breaking change but if it can be bundled together with other compiler changes, then it is not too bad that compatibility is broken as CashScript is still evolving and improving.
This could be a nice optimisation. There's also some advantages to keeping them at the start with e.g. simulated state. I think it's also easier to use compiled CashScript contracts outside of the official SDK if the constructor args are at the start.
Simulated state is a pretty niche use-case now after CashTokens and developers using it already need to be aware of many intricacies
// Cut out old initialBlock (OP_PUSHBYTES_8 <initialBlock>)
// Insert new initialBlock (OP_PUSHBYTES_8 <tx.locktime>)
// Note that constructor parameters are added in reverse order,
// so initialBlock is the first statement in the contract bytecode.
bytes newContract = 0x08 + bytes8(tx.locktime) + this.activeBytecode.split(9)[1];
// Create the locking bytecode for the new contract and check that
// the change output sends to that contract
bytes23 newContractLock = new LockingBytecodeP2SH(hash160(newContract));
require(tx.outputs[1].lockingBytecode == newContractLock);
For simulated state there could be a way to explicitly opt-out of this compiler optimizations. ChatGPT suggested a keyword anchor
contract Mecenas(
bytes20 recipient,
bytes20 funder,
int pledgePerBlock,
anchor bytes8 initialBlock // Ensures `initialBlock` is placed at the start of the bytecode for simulated state purposes.
) {