OffchainLabs / stylus-sdk-rs

Rust Smart Contracts on Arbitrum
226 stars 78 forks source link

Equivalent of Solidity constructor #99

Open afosan opened 8 months ago

afosan commented 8 months ago

Is there an equivalent of Solidity constructor in Stylus? If not, is there any Stylus specific pattern you would suggest to achieve the same behavior?

I want to set a state variable to a value from msg context or passed as an argument to the constructor. Sharing a simple example Solidity contract to illustrate.

contract Example {
    address public owner;
    uint256 public num;

    constructor(uint256 _num) {
        owner = msg.sender;
        num = _num;
    }
}

edit: I have found an example using init function and initialized variable. It still seems possible that someone frontruns you to call init function (e.g. to become "owner" of the contract). Another example hardcodes the "owner" to prevent that.

edit2: I have just found the part about constructors here. I feel it might be helpful to have a link to it under "Developer reference" section.

rauljordan commented 8 months ago

Hi @afosan , one pattern that could work for you today would be to use a multicall program to both deploy and activate in a single tx. Here's how:

You can deploy a simple multicall program our team wrote in Rust for Stylus here.

Then, you can prepare a deployment + activation in a single tx and interact with this multicall program:

For the calldata needed to do a deployment, see here. For the calldata to do an activation, see here.

To send a deployment tx, send the calldata for deployment to a nil address. To do an activation, send the activation calldata to the ARB_WASM_ADDRESS. You can put these together according to how the multicall program requires them and send them. This will guarantee atomic deploy + activation in one tx

afosan commented 8 months ago

Thanks for the explanation @rauljordan!

I also thought about employing multicall to achieve atomicity (not just for deployment and activation, also for "initialization" of the contract, e.g. where the owner is set). In fact, created an issue on multicall repo and it is now deployed on Stylus testnet here.

I think both Multicall3 and Stylus implementation actually need modification though. Multicall3 always uses call and Stylus implementation can employ other call types as well (e.g. staticcall, delegatecall) but neither actually uses create or create2 opcode. I am working on a Stylus contract right now which can perform deploy, activate and (optionally) initialize in a single tx.