How to make a simple multisig contract
This tutorial help you learn how to deploy your multisig contract.
Recall, that (n, k)-multisig contract is a multisignature wallet with n private keys holders, which accepts requests to send messages if the request (aka order, query) collects at least k signatures of the holders.
Based on original multisig contract code and updates by akifoq:
For anyone new with multisig: What is Multisig Technology? (video)
📖 What you'll learn
- How to create and customize a simple multisig wallet.
- How to deploy multisig wallet using lite-client.
- How to sign request and send it in message to blockchain.
⚙ Set your environment
Before we begin our journey, check and prepare your environment.
fiftlibfrom the Installation section.
- Clone repository and open its directory in CLI.
🚀 Let's get started!
- Compile the code to fift.
- Prepare multisig owners keys.
- Deploy your contract.
- Interact with deployed multisig wallet in blockchain.
Compile the contract
Compile the contract to Fift with:
func -o multisig-code.fif -SPA stdlib.fc multisig-code.fc
Prepare multisig owners keys
Create participants keys
To create a key you need to run:
fift -s new-key.fif $KEY_NAME$
KEY_NAMEis the name of the file where the private key will be written.
fift -s new-key.fif multisig_key
We'll receive a file
multisig_key.pk with private key inside.
Collect public keys
Also, the script will issue a public key in the format:
Public key = Pub5XqPLwPgP8rtryoUDg2sadfuGjkT4DLRaVeIr08lb8CB5HW
"Public key = " needs to be saved somewhere!
Let's store in file
keys.txt. One Public Key per line, it's important.
Deploy your contract
Deploy via lite-client
After creating all the keys, you need to collect the public keys into a text file
After that, you need to run:
fift -s new-multisig.fif 0 $WALLET_ID$ wallet $KEYS_COUNT$ ./keys.txt
$WALLET_ID$- the wallet number assigned for current key. It is recommended to use a unique
$WALLET_ID$for each new wallet with the same key.
$KEYS_COUNT$- the number of keys needed for confirmation, usually equal to the number of public keys
It's possible to create many wallets with the same keys (Alice key, Bob key). What to do if Alice and Bob already have treasure? That's why
$WALLET_ID$ is crucial here.
The script will output something like:
new wallet address = 0:4bbb2660097db5c72dd5e9086115010f0f8c8501e0b8fef1fe318d9de5d0e501
(Saving address to file wallet.addr)
Non-bounceable address (for init): 0QBLuyZgCX21xy3V6QhhFQEPD4yFAeC4_vH-MY2d5dDlAbel
Bounceable address (for later access): kQBLuyZgCX21xy3V6QhhFQEPD4yFAeC4_vH-MY2d5dDlAepg
(Saved wallet creating query to file wallet-create.boc)
If you have "public key must be 48 characters long" error, please make sure your
keys.txt has unix type word wrap - LF. For example, word wrap can be changed via Sublime text editor.
Bounceable address is better to keep - this is the address of the wallet.
Activate your contract
You need to send some TON to our newly generated treasure. For example 0.5 TON.
After that, you need to run lite-client:
lite-client -C global.config.json
After starting lite-client, it's best to run the
time command in lite-client console to make sure the connection was successful:
Okay, lite-client is works!
After you need to deploy the wallet. run the command:
After that, the wallet will be ready to work within a minute.
Interact with multisig wallet
Create a request
First you need to create a message request:
fift -s create-msg.fif $ADDRESS$ $AMOUNT$ $MESSAGE$
$ADDRESS$- address where to send coins
$AMOUNT$- number of coins
$MESSAGE$- name of file for compiled message.
fift -s create-msg.fif EQApAj3rEnJJSxEjEHVKrH3QZgto_MQMOmk8l72azaXlY1zB 0.1 message
To add comment for your transaction, use
-C comment attribute. To get more information, run create-msg.fif file without parameters.
Choose a wallet
Next you need to choose a wallet to send a coins from:
fift -s create-order.fif $WALLET_ID$ $MESSAGE$ -t $AWAIT_TIME$
$WALLET_ID$— is an ID of wallet backed by this multisig contract.
$AWAIT_TIME$— Time in seconds that smart contract will await signs from multisig wallet's owners for request.
$MESSAGE$— here is a name of message boc-file created on the previous step.
If time equals
$AWAIT_TIME$ passed before the request signs, the request becomes expired. As usual, $AWAIT_TIME$ equals a couple of hours (7200 seconds)
fift -s create-order.fif 0 message -t 7200
Ready file will be saved in
order.boc needs to be shared with key holders, they have to sign it.
Sign your part
To sign, you need to do:
fift -s add-signature.fif $KEY$ $KEY_INDEX$
$KEY$- name of the file containing the private key to sign, without extension.
$KEY_INDEX$- index of the given key in
For example, for our
fift -s add-signature.fif multisig_key 0
Create a message
After everyone has signed the order, it needs to be turned into a message for the wallet and signed again with the following command:
fift -s create-external-message.fif wallet $KEY$ $KEY_INDEX$
In this case, will be enough only one sign of wallet's owner. The idea is that you can't attack a contract with invalid signatures.
fift -s create-external-message.fif wallet multisig_key 0
Send sign to TON Blockchain
After that, you need to start the light client again:
lite-client -C global.config.json
And after finally, we want to send our sign! Just run:
If everyone else signed the request, it will be completed!
You did it, ha-ha! 🚀🚀🚀
- Read more about multisig wallets in TON from akifoq