Client: add commands for managing a multisig smart contract
This MR adds a few commands to the client to ease the interaction with the multisig smart contract written by @murbard.
Usage example in sandbox mode:
$ # Generate some keys
$ tezos-client gen keys alice
$ tezos-client gen keys bob --sig secp256k1
$ tezos-client gen keys charlie --sig ed25519
$ # Originate the multisig contract
$ tezos-client deploy multisig msig for bootstrap1 transferring 100 from bootstrap1 with threshold 2 on public keys alice bob charlie --burn-cap 100
Node is bootstrapped, ready for injecting operations.
Estimated gas: 34825 units (will add 100 for safety)
Estimated storage: 1283 bytes added (will add 20 for safety)
Operation successfully injected in the node.
Operation hash is 'opUJAVrUtzCyHKbvsFwJPcEjaLE94sEAhc1xe8tcw9JPkHtUNTq'
Waiting for the operation to be included...
Operation found in block: BLCTTB5rirYiUPKKvYRMuhZja7frTagRhUBRZQpPkY5rNxqd3v3 (pass: 3, offset: 0)
This sequence of operations was run:
Manager signed operations:
From: tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx
Fee to the baker: ꜩ0.004838
Expected counter: 1
Gas limit: 34925
Storage limit: 1303 bytes
Balance updates:
tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx ........... -ꜩ0.004838
fees(tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx,0) ... +ꜩ0.004838
Origination:
From: tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx
For: tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx
Credit: ꜩ100
Script:
{ parameter
(pair (pair :payload
(nat %counter)
(or :action
(pair :transfer (mutez %amount) (contract %dest unit))
(or (option %delegate key_hash)
(pair %change_keys (nat %threshold) (list %keys key)))))
(list %sigs (option signature))) ;
storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ;
code { UNPAIR ;
SWAP ;
DUP ;
DIP { SWAP } ;
DIP { UNPAIR ;
DUP ;
SELF ;
ADDRESS ;
PAIR ;
PACK ;
DIP { { { DUP ; CAR @counter ; DIP { CDR } } } ; DIP { SWAP } } ;
SWAP } ;
{ { DUP ; CAR @stored_counter ; DIP { CDR } } } ;
DIP { SWAP } ;
ASSERT_CMPEQ ;
DIP { SWAP } ;
{ { DUP ; CAR @threshold ; DIP { CDR @keys } } } ;
DIP { PUSH @valid nat 0 ;
SWAP ;
ITER { DIP { SWAP } ;
SWAP ;
IF_CONS
{ IF_SOME
{ SWAP ;
DIP { SWAP ;
DIIP { DUUP } ;
{ DUUUP ;
DIP { CHECK_SIGNATURE } ;
SWAP ;
IF { DROP } { FAILWITH } } ;
PUSH nat 1 ;
ADD @valid } }
{ SWAP ; DROP } }
{ FAIL } ;
SWAP } } ;
ASSERT_CMPLE ;
DROP ;
DROP ;
DIP { UNPAIR ; PUSH nat 1 ; ADD @new_counter ; PAIR } ;
NIL operation ;
SWAP ;
IF_LEFT
{ UNPAIR ; UNIT ; TRANSFER_TOKENS ; CONS }
{ IF_LEFT
{ SET_DELEGATE ; CONS }
{ DIP { SWAP ; CAR } ; SWAP ; PAIR ; SWAP } } ;
PAIR } }
Initial storage:
(Pair 0
(Pair 2
{ "edpkuakZ5gDnDb4eWf4NVDqBKHPgtgNouffLZqtUncZzzAvrknHJqv" ;
"sppk7ZcEgHvnkV6Za5qkLyJRUZr9ydEB8FbMUz2fmGpnsQaVLBNFJoY" ;
"edpktgXhBmgbBEJqdWf95pZMt1pGjZ5VUB3g4dARAfapXM7jdvC8y3" }))
No delegate for this contract
This origination was successfully applied
Originated contracts:
KT1NvL2n8qtBUHPWQNzviTprvUagjgQmHv4d
Storage size: 1026 bytes
Paid storage size diff: 1026 bytes
Consumed gas: 34825
Balance updates:
tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx ... -ꜩ1.026
tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx ... -ꜩ0.257
tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx ... -ꜩ100
KT1NvL2n8qtBUHPWQNzviTprvUagjgQmHv4d ... +ꜩ100
New contract KT1NvL2n8qtBUHPWQNzviTprvUagjgQmHv4d originated.
The operation has only been included 0 blocks ago.
We recommend to wait more.
Use command
tezos-client wait for opUJAVrUtzCyHKbvsFwJPcEjaLE94sEAhc1xe8tcw9JPkHtUNTq to be included --confirmations 30 --branch BM8UwMguNd5pXqnEKqSEafg6zJVQ7J4omqWmRHaVqxDTn1eBFWv
and/or an external block explorer.
Contract memorized as msig.
$ # Alice and Charlie agree to send 10tz to bootstrap2
$ # Alice has an up-to-date client, she signs using the new command
$ SIGA=$(tezos-client sign multisig transaction on msig transferring 10 to bootstrap2 using secret key alice)
$ echo "$SIGA"
edsigtuiywJo1aCyAocrjoL38KEmgeP3YuchQFdAtDjrB3dJa4np9iPEfYj9QD98LENQioSyF7jP3cN1um2bjEGUR3WW4kZtKqa
$ # Charlie's client does not feature the new multisig commands, we send him the bytes to sign,
$ tezos-client prepare multisig transaction on msig transferring 10 to bootstrap2
Bytes to sign: '0x0507070a00000016019d44c3ea27ec7d974a7ba05318bee422d1d39cbb0007070000050507070080dac4090a000000160000e7670f32038107a59a2b9cfefae36ea21f5aa63c'
Threshold (number of signatures required): 2
Public keys of the signers:
edpkuakZ5gDnDb4eWf4NVDqBKHPgtgNouffLZqtUncZzzAvrknHJqv
sppk7ZcEgHvnkV6Za5qkLyJRUZr9ydEB8FbMUz2fmGpnsQaVLBNFJoY
edpktgXhBmgbBEJqdWf95pZMt1pGjZ5VUB3g4dARAfapXM7jdvC8y3
$ BYTES=$(tezos-client prepare multisig transaction on msig transferring 10 to bootstrap2 --bytes-only)
$ echo "$BYTES"
0x0507070a00000016019d44c3ea27ec7d974a7ba05318bee422d1d39cbb0007070000050507070080dac4090a000000160000e7670f32038107a59a2b9cfefae36ea21f5aa63c
$ # Charlie can partly check what he signs, he can see that it is a transfer of 10tz
$ tezos-client unpack michelson data "$BYTES"
Pair 0x019d44c3ea27ec7d974a7ba05318bee422d1d39cbb00
(Pair 0 (Left (Pair 10000000 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c)))
$ # And he can sign
$ SIGC=$(tezos-client sign bytes "$BYTES" for charlie | cut -d ' ' -f 2)
$ echo "$SIGC"
edsigtuLZWdyecNDatT2t2E1wPrWo9jxLEahV8wJiriDhJMUVPKFZ4uNF3TZwJz7x4bqB5KHEHbbDtED2hDfnqeNfWBzwXvRNRA
$ tezos-client multisign transfer 10 from bootstrap1 to bootstrap2 on msig with signatures "$SIGA" "$SIGC"
Node is bootstrapped, ready for injecting operations.
Estimated gas: 44492 units (will add 100 for safety)
Estimated storage: no bytes added
Operation successfully injected in the node.
Operation hash is 'ooi3Ucat2dkNV7mYqWFMu2wDZg8k7cpwJxWNEC3qJ9U4sjoCLJj'
Waiting for the operation to be included...
Operation found in block: BLzLmL4unhhZY8z19Y5bqgWzHdXmXeaqU35vob2uGTqh3BzAkqY (pass: 3, offset: 0)
This sequence of operations was run:
Manager signed operations:
From: tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx
Fee to the baker: ꜩ0.004975
Expected counter: 2
Gas limit: 44592
Storage limit: 0 bytes
Balance updates:
tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx ........... -ꜩ0.004975
fees(tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx,0) ... +ꜩ0.004975
Transaction:
Amount: ꜩ0
From: tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx
To: KT1NvL2n8qtBUHPWQNzviTprvUagjgQmHv4d
Parameter: (Pair (Pair 0 (Left (Pair 10000000 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c)))
{ Some "edsigtuiywJo1aCyAocrjoL38KEmgeP3YuchQFdAtDjrB3dJa4np9iPEfYj9QD98LENQioSyF7jP3cN1um2bjEGUR3WW4kZtKqa" ;
None ;
Some "edsigtuLZWdyecNDatT2t2E1wPrWo9jxLEahV8wJiriDhJMUVPKFZ4uNF3TZwJz7x4bqB5KHEHbbDtED2hDfnqeNfWBzwXvRNRA" })
This transaction was successfully applied
Updated storage:
(Pair 1
(Pair 2
{ 0x007bcfedcb5bab7fd810cab9d0b92acdfe26a9b84e1df8090d1be3edac367d5c34 ;
0x010227f6be91c739897f1b26130a20ceb841d34074431c65a7c825d5e0b7fa934b2c ;
0x00053c84a5996c98d2471a5ce27a5d2eadc85a32e7fd569221dc67f6da34e660e0 }))
Storage size: 1026 bytes
Consumed gas: 34385
Internal operations:
Transaction:
Amount: ꜩ10
From: KT1NvL2n8qtBUHPWQNzviTprvUagjgQmHv4d
To: tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN
Parameter: Unit
This transaction was successfully applied
Consumed gas: 10107
Balance updates:
KT1NvL2n8qtBUHPWQNzviTprvUagjgQmHv4d ... -ꜩ10
tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN ... +ꜩ10
The operation has only been included 0 blocks ago.
We recommend to wait more.
Use command
tezos-client wait for ooi3Ucat2dkNV7mYqWFMu2wDZg8k7cpwJxWNEC3qJ9U4sjoCLJj to be included --confirmations 30 --branch BLCTTB5rirYiUPKKvYRMuhZja7frTagRhUBRZQpPkY5rNxqd3v3
and/or an external block explorer.
Edited by Raphaël Cauderlier