SetcodeMultisigWallet

SetcodeMultisigWallet is the second smart contract created by TON Labs for FreeTON that implements a custom wallet. It differs from SafeMultisigWallet in that it supports updating its own code (the setcode function) “on the fly”, i.e. without changing the wallet address in the blockchain. It also supports changing the main parameters of the wallet (the list of wallet custodians, the required number of confirmations). The other functions are completely similar to SafeMultisigWallet.

The information described in this article applies to this version of this smart contract: https://github.com/tonlabs/ton-labs-contracts/tree/b79bf98b89ae95b714fbcf55eb43ea22516c4788/solidity/setcodemultisig

## Typical update scripts

### Change, add or cut the list of wallet custodians

To do this, it is necessary:

1. For any custodian to call the submitUpdate function to make a suggestion to change custodians for the current set of wallet custodians;
2. For the number of custodians required for a confirmation to call the confirmUpdate function; the confirmation process can be observed calling the getUpdateRequests method;
3. For any custodian to start the key change process by calling the executeUpdate function.

In the same way, it is possible to change the number of necessary custodians’ signatures for performing actions with the wallet (sending transactions, updating).

## Functions

### submitUpdate

It proposes to start the procedure of updating the code and the list of wallet keepers, and *submits an update proposal* to be considered by the custodians. Called by any of the custodians, its confirmation is immediately entered into the update offer.

**Function parameters**:

1. `uint256 codeHash`: the standard hash (SHA256) of the representation hash of the cell containing the new code proposed for updating (for more information, see https://ton.org/tvm.pdf, section "3.1.5. The representation hash of a cell" and "A.11.6. Hashing and cryptography primitives." , operation "HASHCU"); an analog in "simple" programs (outside the blockchain) - the checksum that is checked when a file with a program or its update is received;
2. `uint256[] owners`: an array with the keys of new wallet custodians that will come into force after the update is accepted;
3. `uint8 reqConfirms`: the required number of confirmations of (different) custodians for making transactions using the wallet or code update, which will take effect after the update is accepted.

**Data returned**: ID of the accepted update offer (updateId).

**Call example**:

```
tonos-cli call 0:609a0b947f385ef7642954c30a6c31ef0a7bc9e319b9bba99842f738164a4487 submitUpdate '{"codeHash":"0xe2b60b6b602c10ced7ea8ede4bdf96342c97570a3798066f3fb50a4b2b27a208","owners":["0x729ccaabe9092f8a6ca0dd6b3fcee3eff94643b36869be3dbf43386fcb30035a","0xd77258c93db1d543b80b90a5fbaabb221daa88d7c975b5ab42e9320202a99ab3","0x268ef13439dace88ca0656f148127380d48c9e143052133a31281c484dac94b1"],"reqConfirms":2}' --abi SetcodeMultisigWallet.abi.json --sign deploy-key-1.json

```

**Result**:

```
Result: {
  "updateId": "0x5f34e8d40bbfab41"
}

```

The update offer ID was received - `0x5f34e8d40bbfab41`. It should be used in further calls of the confirmUpdate and executeUpdate functions. You can view all the IDs of update offers currently registered for the wallet by calling the getUpdateRequests method.

#### Calculating the codeHash value

For the standard SetcodeMultisigWallet located in the SetcodeMultisigWallet.tvc code, this value is `0xe2b60b6b602c10ced7ea8ede4bdf96342c97570a3798066f3fb50a4b2b27a208`. If there is no need to update the wallet code itself (it is necessary just to change/expand/cut the list of wallet custodians and the required number of confirmations), it is possible to use the provided ready-made value.

To facilitate the task of calculating the desired hash for arbitrary cells (including those containing code), a simple smart contract was created.

If there is no need to calculate this value yourself, you can use the options listed below.

For both options, getting a cell with the smart contract code from which the hash will be calculated is described below.

##### Option 1. Use a smart contract in the FreeTON test network (tonos-cli)

In the FreeTON test network, a smart contract is deployed with a single `calcCellHash` function that allows you to calculate the hash (representation hash) of a cell (for example, cells with code). As input, the function accepts a single parameter named `c`, in the value of which you need to specify the contents of the cell; as a result, the calculated hash is returned in the value `codeHash`.

This method can be called in this way:

`%%tonos-cli run 0:0049aa0d8d995a544dfe0d681c785b166dbb27360f0e3a1168be9748c17e2b30 calcCellHash '{"c":"te6ccg<...>HbpDeg="}' --abi CellhashCalc.abi.json%%`

Result:

```
Result: {
  "codeHash": "0x<значение_хеша_ячейки>"
}

```

The required for calling CellhashCalc.abi.json ABI file is located on GitHub.

##### Option 2. Execute a smart contract locally, without deploying it in any network (tvm\_linker)

To do this, a TVM linker is necessary, since it can run contract code from local files without getting it from the blockchain. The following steps should be done:

1. Prepare (compile) TVM linker;
2. Download the CellhashCalc.abi.json and CellhashCalc.tvc files;
3. Rename the CellhashCalc.tvc file to <contract\_adress\_without\_workchain>.tvc (the address can be any), for example, 0049aa0d8d995a544dfe0d681c785b166dbb27360f0e3a1168be9748c17e2b30.tvc;
4. Start tvm\_linker: `%%tvm_linker test -a CellhashCalc.abi.json -m calcCellHash -p '{"c":"te6ccg<...>HbpDeg="}' --decode-c6 0049aa0d8d995a544dfe0d681c785b166dbb27360f0e3a1168be9748c17e2b30%%`; specify the cell content as the value of parameter `с`.

As a result, the smart contract code will be executed locally, and the desired result will be obtained in the form

```
<...>
{"codeHash":"0x<hash_cell_value>"}
Contract persistent data updated
TEST COMPLETED

```

### confirmUpdate

The vote “Yes” confirms the update offer on behalf of one of the wallet custodians. Those wallet custodians which want to be confirmed should call this function for the subsequent successful update.

**Function parameters**:

* `uint64 updateId`: the update offer ID that a wallet keeper confirms (votes “Yes”)

**Data returned**: the update offer confirmation status

**Call example**: `%%tonos-cli call 0:609a0b947f385ef7642954c30a6c31ef0a7bc9e319b9bba99842f738164a4487 confirmUpdate '{"updateId":"0x5f34fc557a13b001"}' --abi SetcodeMultisigWallet.abi.json --sign deploy-key-2.json%%`

**Result**:

```
Succeeded.
```

In case of success, (the specified update offer is registered at the moment, as well as the function call, i.e. the message to the wallet smart contract was signed by one of the current wallet custodians), its vote is successfully counted. It is possible to see the status of the current confirmation of update offers by calling the getUpdateRequests method; as the votes are received, the output values `signs` (will increase) and `confirmationsMask` (will change according to the keepers who have signed it) will change accordingly.

### executeUpdate

It starts the procedure of updating the wallet smart contract code in accordance with the update offer. The function is performed successfully only after receiving all the necessary wallet custodians’ confirmations received by using the confirmUpdate function calls, and also requires that the hash of the actually transmitted code matches the previously declared one.

**Function parameters:**

1. `uint64 updateId`: the ID of the launched update offer
2. `TvmCell code`: a cell containing a new code for the wallet smart contract; the hash representation of this cell must match the codeHash of the launched update offer

**Data returned**: the update status

**Call example**: `%%tonos-cli call 0:609a0b947f385ef7642954c30a6c31ef0a7bc9e319b9bba99842f738164a4487 executeUpdate '{"updateId":"0x5f3405d6ff575881","code":"te6ccg<...>HbpDeg="}' --abi SetcodeMultisigWallet.abi.json --sign deploy-key-1.json%%`

Any of the current wallet custodians can act as a signer (%%--sign%%) of this call (message to the wallet smart contract).

In the given example of a call, the full value of `the code` parameter is omitted, because it is quite large and it makes no sense to give it, the method for getting it is described below.

**Result**:

`Succeeded.`

In case of success (the update offer was accepted by the required number of wallet custodians and the calculated hash of the new code corresponds to the hash proposed in the update offer, and the call was signed by one of the current wallet custodians), the confirmation of the successful update is displayed.

The estimated number of tokens spent on updating for the standard SetCodeMultisigWallet is about 0.7 - 0.8.

#### Getting the value of the code parameter

To get the value of the code parameter, first, it is necessary to compose the smart contract code using TVM linker. If the smart contract code has already been compiled into a TVM assembler using, for example, Sol2TVM Compiler - it can be compiled into a tvc file by calling [ https://github.com/tonlabs/TVM-linker#1-generating-a-ready-to-deploy-contract tvm-linker compile], the initial data of the smart contract is not required in this case.

If the smart contract code has already been compiled, as in the case of SetcodeMultisigWallet, getting the required value of `the code` parameter using the same TVM linker can be started immediately. Since this tvc file contains both its code and initial data within the initial state of a smart contract, it is possible to decode this initial state by getting the code from it.

It can be done in this way: `%%tvm_linker decode --tvc SetcodeMultisigWallet.tvc%%`

Part of the command output:

```
<...>
Decoded:
StateInit
 split_depth: None
 special: None
 data: te6ccg<...>AABA==
 code: te6ccg<...>bpDeg=
 lib:  None

```

The required value of `the code` parameter is in the form of a base64-encoded BOC in the output of the command, in the form of `code: <base64_boc_with_code>`. It can be used immediately when calling the executeUpdate function.

## Public methods

### getUpdateRequests

It gets the current list of registered wallet update offers with detailed information for each of them, as well as with the confirmation status of wallet custodians for each of the offers.

**Method parameter**: *<absent>*

**Data returned**: a list of registered wallet upgrade offers with detailed information

**Call example**: `%%tonos-cli run 0:609a0b947f385ef7642954c30a6c31ef0a7bc9e319b9bba99842f738164a4487 getUpdateRequests {} --abi SetcodeMultisigWallet.abi.json%%`

**Result**:

```
Result: {
  "updates": [
    {
      "codeHash": "0xe2b60b6b602c10ced7ea8ede4bdf96342c97570a3798066f3fb50a4b2b27a208",
      "confirmationsMask": "0x1",
      "creator": "0xd77258c93db1d543b80b90a5fbaabb221daa88d7c975b5ab42e9320202a99ab3",
      "custodians": [
        "0x729ccaabe9092f8a6ca0dd6b3fcee3eff94643b36869be3dbf43386fcb30035a",
        "0xd77258c93db1d543b80b90a5fbaabb221daa88d7c975b5ab42e9320202a99ab3",
        "0x268ef13439dace88ca0656f148127380d48c9e143052133a31281c484dac94b1"
      ],
      "id": "0x5f34e8d40bbfab41",
      "index": "0x0",
      "reqConfirms": "0x2",
      "signs": "0x1"
    }
  ]
}

```

A list (array) of registered wallet upgrade offers with detailed information for each of them is received. Let's look at the parameters of each item in this list (in the example, there is only one update offer, and there may be several of them at the same time):

1. the code hash of the proposed update `codeHash` in the example is equal `0xe2b60b6b602c10ced7ea8ede4bdf96342c97570a3798066f3fb50a4b2b27a208`
2. the mask (bit array) of received confirmations of wallet custodians confirmationsMask, in the example is equal to `0x1` = 0b0000000000000000000000000001 (received confirmation from one, the first custodian); in this bit array, the bits of the custodians who signed the update offer are set to “1” according to the indexes returned as a result of calling the `getCustodians` method, their order - starting from lowest bits of the 32-bit mask (little-endian);
3. the public key of the custodian `creator` which offered the update, in the example, is equal to `0xd77258c93db1d543b80b90a5fbaabb221daa88d7c975b5ab42e9320202a99ab3`;
4. the proposed new list of custodians' public wallets `custodians`, in example 3;
5. the update offer `ID` id, in the example is equal to `0x5f34e8d40bbfab41`;
6. the index of the wallet custodian who suggested this update in the list of current wallet custodians `id`, in the example is `0x0` = 0; the index corresponds to the returned as a result of calling the `getCustodians` method;
7. the proposed new value of the required number of custodian confirmations for transactions using the wallet `reqConfirms`, in the example, is equal to `0x2` = 2.
8. the current number of signatures (confirmations) received from wallet custodians under this update offer `signs`, in the example, is equal to `0x1` = 1.