> For the complete documentation index, see [llms.txt](https://calnix.gitbook.io/eth-dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://calnix.gitbook.io/eth-dev/compendium/smart-contract-life-cycle.md).

# Smart Contract Life-cycle

How to start, stop, update and destroy a smart contract.

### Insecure Example

```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.1;

contract StartStopUpdateExample {

    function sendMoney() public payable {

    }

    function withdrawAllMoney(address payable _to) public {
        _to.transfer(address(this).balance);
    }
}
```

![](/files/y9vJcQ66fGpwbXJ6hN7P)

* with sendMoney() we can send the SC some ETH
* with withdrawAllMoney(), **anyone** can input their address and withdraw all balances.

### Secure Example

We will secure this SC by ensuring that the person interacting with `withdrawAllMoney` is the same as the one who deployed the Smart Contract.

```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.1;

contract StartStopUpdateExample {
    
    // set ownership
    address public owner;
    
    constructor(){
        owner = msg.sender;
    }

    function sendMoney() public payable {
    }

    function withdrawAllMoney(address payable _to) public {
        require(owner == msg.sender, "You are not the the owner - cannot withdraw!");
        _to.transfer(address(this).balance);
    }

}
```

* create an address state variable to hold the owner's address.
* use constructor, which will run on deployment, to assign `owner` with the deployer's address.
  * whomever deploys is deemed to be the owner automatically.
* add conditional check, `require` statement, to withdraw function
  * `require` is like `if`, if this condition is true -> proceed. else fails.
  * require checks if the person initiating the withdraw function is indeed owner.
  * if true, balances transferred.
  * If require evaluates to false it will stop the transaction, roll-back any changes made so far and emit the error message as String.

![](/files/l7P3o8RUVm1XhPnNUP8H)

{% hint style="info" %}
Note, the msg.sender would be different for the constructor and the withdraw as these are two different interactions with 2 different messages.&#x20;

msg of constructor -> emitted on whomever deployed

msg of withdraw -> emitted on whomever calling withdraw()
{% endhint %}

#### An alternative&#x20;

An alternative way is require(\_to == owner, "...'), this will only allow withdrawals made to the owner/deployer's address.

The above allows the owner to withdraw to an address of choice, different from his deployment wallet.&#x20;

{% hint style="info" %}
Other ownable models:

<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol>
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://calnix.gitbook.io/eth-dev/compendium/smart-contract-life-cycle.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
