Contract Design – Can You Create and Destroy a Contract in a Single Transaction?

contract-designgas-refundselfdestruct

Is it possible to create and destroy a contract in a single transaction? Specifically could I:

  • deploy to a known address using CREATE2
  • call a function on that contract
  • destroy the contract and recover some of the deployment cost

all in one transaction?

Second part of the question. If that is possible would the account submitting the transaction need to have the full gas amount to deploy the contract or would I only need to provide the deployment cost minus the refund from self-destruct?

Best Answer

Yes, it's possible. The following code does just that if you were to call the create function on a deployed Creator:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Created {

    event AnEvent(uint256);

    function aFunction(uint256 value) public {
        emit AnEvent(value);
    }

    function kill() public {
        selfdestruct(payable(msg.sender));
    }
}

contract Creator {

    function create() public {

        Created tmp = new Created{salt: 0}();
        tmp.aFunction(1);
        tmp.kill();
    }
}

Second part of the question. If that is possible would the account submitting the transaction need to have the full gas amount to deploy the contract or would I only need to provide the deployment cost minus the refund from self-destruct?

The refunds are only processed after the transaction is executed, in go-ethereum : transaction execution followed by refund. So you must provide the whole cost upfront, but it will only cost you that amount minus the refund.

Refunds are no longer as interesting as they used to economically speaking (see EIP-3529), plus for anyone to profit on it there needs to be some variation (i.e., time delay) between the creation and selfdestruct, that is not the case if everything happens inside a single transaction.

I hope that answers your question.

Related Topic