所谓多重签名(multisig)钱包是指需要多个私钥来授权交易的钱包。多重签名对于数字资产管理的重要性不言而喻,通过多重签名可以实现多个用户共同管理同一笔资产,利用区块链技术,可以确保必须是在多方达成共识的情况下才能转移资产。
几乎所有主流的公链都是支持多钱钱包的,Filecoin 作为其中明星公链,自然也是支持的。本文讲述如何使用 lotus 提供的工具来创建和使用多重签名钱包,以及如何使用将 Miner 的 Owner 地址设置成多签钱包地址。
01. 测试环境 在测试之前我们先准备好测试环境,我本次测试的环境如下:
操作系统: Ubuntu 20.04
Lotus version: 1.15.0+2k+intel+opencl+blst=0+git.ca194fd3c.dirty
测试网络:本地 2K 网络
先创建一个 Miner 用于测试(你也可以直接用 Genesis Miner 做测试,我这里选择新建 Miner 测试的原因是担心把创世 Miner 搞死了,整个链就崩溃了):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 $ lotus wallet new bls t3vjv265fawzcbepom356bipqtiiexf6bzpxulw5avg4pmfbnahd4n6nhcl5xuv3xrgug6itcjj3hrcusiljqq $ lotus send t3vjv265fawzcbepom356bipqtiiexf6bzpxulw5avg4pmfbnahd4n6nhcl5xuv3xrgug6itcjj3hrcusiljqq 10000 $ lotus-miner init --sector-size=8M --owner=t3vjv265fawzcbepom356bipqtiiexf6bzpxulw5avg4pmfbnahd4n6nhcl5xuv3xrgug6itcjj3hrcusiljqq $ nohup lotus-miner run --nosync > miner.log 2>&1 & $ lotus state miner-info t01004 Available Balance: 0 FIL Owner: t01003 Worker: t01003 PeerID: 12D3KooWDTV9JBteM2GNxNBPUExuBoZNFEE1d5EkTjWnPxkc3hHv Multiaddrs: Consensus Fault End: -1 SectorSize: 8 MiB (8388608) Byte Power: 0 B / 16 MiB (0.0000%) Actual Power: 0 / 160 Mi (0.0000%) $ lotus-miner actor control list name ID key use balance owner t01003 t3vjv265f... other 9999.999977542737098922 FIL worker t01003 t3vjv265f... other 9999.999977542737098922 FIL
02. 创建一个多重签名钱包 首先创建三个多签成员钱包:
1 2 3 4 5 6 7 8 9 $ lotus wallet new t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply $ lotus wallet new t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja $ lotus wallet new t1vrmavqwrw7rqm6e5zzqelfrvcyebywgotv6rvba
创建一个多签钱包:
1 2 3 4 lotus msgig create <多签成员1> <多签成员2> <多签成员N...> $ lotus msig create --required=2 t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja t1vrmavqwrw7rqm6e5zzqelfrvcyebywgotv6rvba sent create in message: bafy2bzaceddscrkjgex3pv2wnjmenlml6tlwdnml75z7izkcy5oq4xb3y4uda Created new multisig: t01005 t2v62e2di2ayw5htqky6tmmqatg5p3qe3q3z6t27a
--required
参数来指定需要签名者的数量,--required=2
表示只需要 2 个人签名就可以批准交易。
多重签名钱包以 f2
(测试网是 t2
) 开头,这里顺便提一下,Filecoin 的所有钱包都对应着两个地址,以上面的多签钱包为例:
t2v62e2di2ayw5htqky6tmmqatg5p3qe3q3z6t27a
是多签钱包的 Actor Address。
t01005
是多签钱包的 ID Address。
以上两个地址都可以代表这个多签钱包,绝大部分情况下,两个地址都可以换着使用,在后面的示例代码中,我们除了多签地址使用 ID Address(t01005),其他地址都使用 Actor Address。
我们可以通过 Actor Address 获取对应的 ID Address:
1 2 $ lotus state lookup t2v62e2di2ayw5htqky6tmmqatg5p3qe3q3z6t27a t01005
::: tip 提示: 多签钱包只是一个合约钱包,或者说只是一个虚拟钱包,它没有具体的私钥(Key),所以你在钱包列表里面是看不到我们刚刚创建的多签钱包的:
1 2 3 4 5 6 7 $ lotus wallet list Address Balance Nonce Default t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply 0 FIL 0 t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja 0 FIL 0 t1vrmavqwrw7rqm6e5zzqelfrvcyebywgotv6rvba 0 FIL 0 t3tbrlbuf2xfte2h6yo2tm7j6r434skzahor42skxugoh57blpovqxm4hg3a7luytmtswwhnlnw5yhac6tvt5q 49999999.986410752200339072 FIL 3 X t3vjv265fawzcbepom356bipqtiiexf6bzpxulw5avg4pmfbnahd4n6nhcl5xuv3xrgug6itcjj3hrcusiljqq 9999.999977438895991462 FIL 2
所以,你需要保存好你的多签钱包地址,忘记地址会比较麻烦。 :::
查看一个多签钱包的详细信息:
1 2 3 4 5 6 7 8 9 10 11 $ lotus msig inspect t01005 Balance: 0 FIL Spendable: 0 FIL Threshold: 2 / 3 Signers: ID Address t01006 t1vrmavqwrw7rqm6e5zzqelfrvcyebywgotv6rvba t01001 t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply t01002 t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja Transactions: 0
03. 往多签钱包充值 你只需将多签钱包地址当做普通的钱包地址就好了,直接往里面转账就行:
1 2 3 4 5 6 $ lotus send t01005 1000 bafy2bzacedwbsbymeceu7kegnytkb43qwyijqydgujwmynu3xn4qqmt7xy42g $ lotus wallet balance t01005 1000 FIL
04. 发起一个多重签名提案 多重签名钱包的任何签名者都可以发起交易提案。发起交易提案的人自动批准交易,只有当收到的批准数量等于所需批准的数量时,才会执行交易。 如果多重签名钱包只需要一个签名者,那么交易将在其发起提案后立即执行。
1 2 3 4 5 6 7 8 $ lotus msig propose --from=<多签成员1> <多签地址> <收款地址> <交易金额> $ lotus send t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply 5 $ lotus msig propose --from=t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply t01005 t1zpcgsepbvlgqqjilhxwdmuzqdqg3sbvnwituxmy 10 sent proposal in message: bafy2bzacecbprohhf2ubks46ng3eg6phpmj2avpgit5cgvgj23xmk6vsrdmiu Transaction ID: 0
此时再查看多签钱包信息,会发现交易列表中多了一笔带批准(Pending)的交易:
{12} 1 2 3 4 5 6 7 8 9 10 11 12 $ lotus msig inspect t01005 Balance: 1000 FIL Spendable: 1000 FIL Threshold: 2 / 3 Signers: ID Address t01002 t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply t01003 t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja t01004 t1vrmavqwrw7rqm6e5zzqelfrvcyebywgotv6rvba Transactions: 1 ID State Approvals To Value Method Params 0 pending 1 t1zpcgsepbvlgqqjilhxwdmuzqdqg3sbvnwituxmy 10 FIL Send(0)
05. 批准一个多重签名提案 其他签名者可以 lotus msig approve
用来批准消息:
1 2 3 4 5 6 $ lotus msig approve <walletAddress> <transactionID> <proposerAddress> <destinationAddress> <value> $ lotus send t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja 3 $ lotus msig approve --from=t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja t01005 0 t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply t1zpcgsepbvlgqqjilhxwdmuzqdqg3sbvnwituxmy 10 sent approval in message: bafy2bzaceans5xucvbov3ue2nhviyfwxy5ikeylfr6x6kvwypt6f5eeabbqtu
::: warning 注意: 批准交易的时候,walletAddress
(多签地址),transactionID
, proposerAddress
和 value
必须和提案中使用的值匹配。 :::
由于我们前面设置只需要两个人签名就可以批准交易执行,此时应该交易已经成功了,我们在此查看多签钱包的信息:
{2-3} 1 2 3 4 5 6 7 8 9 10 $ lotus msig inspect t01005 Balance: 990 FIL Spendable: 990 FIL Threshold: 2 / 3 Signers: ID Address t01002 t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply t01003 t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja t01004 t1vrmavqwrw7rqm6e5zzqelfrvcyebywgotv6rvba Transactions: 0
发现余额已经少了 10 个FIL,并且等待批准的交易列表(Transactions)也清零了。
我们可以使用 lotus-shed
工具查看某个多重签名提案消息详情:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 $ ./lotus-shed msg <MessageCID> $ ./lotus-shed msg bafy2bzacecbprohhf2ubks46ng3eg6phpmj2avpgit5cgvgj23xmk6vsrdmiu --- Message Details: Value: 0 FIL Max Fees: 0.000000142330205256 FIL Max Total Cost: 0.000000142330205256 FIL Method: Propose Params: { "To" : "t1zpcgsepbvlgqqjilhxwdmuzqdqg3sbvnwituxmy" , "Value" : "10000000000000000000" , "Method" : 0, "Params" : null } --- Params message: Msig Propose: HEX: 845501cbc46911e1aacd08250b3dec3653301c0db906ad49008ac7230489e800000040 B64: hFUBy8RpEeGqzQglCz3sNlMwHA25Bq1JAIrHIwSJ6AAAAEA= JSON: { "To" : "t1zpcgsepbvlgqqjilhxwdmuzqdqg3sbvnwituxmy" , "Value" : "10000000000000000000" , "Method" : 0, "Params" : null } ---
06. 取消一个未决的多重签名提案 在交易没有批准之前,你都可以取消挂起的多重签名交易:
1 2 3 4 $ lotus msig cancel <walletAddress> <transactionID> <destinationAddress> <value> $ lotus msig cancel --from=t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply t01005 1 t1zpcgsepbvlgqqjilhxwdmuzqdqg3sbvnwituxmy 20 sent cancel in message: bafy2bzacedwgmeyqlt5n76p7ilmauc62op55nqxe2llwky4dypnfmofj5eo2w
::: tip 提示:你只能取消自己发起的提案消息,不能取消其他签名者发起的提案消息。 :::
07. 设置 Miner Owner 地址为多签地址 我们知道,Lotus 更改 Owner 的操作主要分 2 步:
使用旧 Owner 地址签名,发起更换操作;
使用新 Owner 地址签名,确认更换操作。
因此,Owner 使用多签操作也比较简单,我们只需要在第二步确认操作的时候,使用多签地址签名就好了。
7.1 使用原地址发起 Change Owner 操作 1 2 3 4 5 6 7 $ lotus-miner actor set-owner --really-do-it t01005 t3vjv265fawzcbepom356bipqtiiexf6bzpxulw5avg4pmfbnahd4n6nhcl5xuv3xrgug6itcjj3hrcusiljqq Message CID: bafy2bzaceccpaoftqe4aaaznczq6zbzymkwao2ixdaxmjk4wkuqfv5lta23us message succeeded! $ ./lotus-shed actor set-owner --really-do-it --actor=t01004 t01005 t3vjv265fawzcbepom356bipqtiiexf6bzpxulw5avg4pmfbnahd4n6nhcl5xuv3xrgug6itcjj3hrcusiljqq
7.2 使用多签地址确认 Change Owner 操作 7.2.1 - 生成签名参数 1 2 3 4 5 6 $ lotus chain encode params --encoding=hex <MinerID> <method> \"<多签地址 ID>\" $ lotus chain encode params --encoding=hex t01004 23 \"t01005\" 4300ed07
7.2.2 - 提交更改 Owner 提案 1 2 3 4 5 $ lotus msig propose --from=<多签成员1> <多签地址ID> <MinerID> 0 23 <params> $ lotus msig propose --from=t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply t01005 t01004 0 23 4300ed07 sent proposal in message: bafy2bzaceask3yw5dof2l7hgtzp2mkfqdpmisyphvckfpw6asktunwdd4p7ai Transaction ID: 2
7.2.3 - 其他签名者批准提案 1 2 3 4 $ lotus msig approve --from=<多签成员2> <多签地址ID> <transactionId> <多签成员1> <MinerID> 0 23 <params> $ lotus msig approve --from=t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja t01005 2 t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply t01004 0 23 4300ed07 sent approval in message: bafy2bzacedrhoq2decf4o32ahjd2v24dpea7luosd7a24lytkobwlllpwa2c2
7.3 确认是否更改成功 消息被批准执行之后,Owner 更换操作就成功了,我们可以查看更换 Owner 之后的 Miner 的信息:
{3} 1 2 3 4 5 6 7 8 9 10 $ lotus state miner-info t01004 Available Balance: 0 FIL Owner: t01005 Worker: t01003 PeerID: 12D3KooWDTV9JBteM2GNxNBPUExuBoZNFEE1d5EkTjWnPxkc3hHv Multiaddrs: Consensus Fault End: -1 SectorSize: 8 MiB (8388608) Byte Power: 0 B / 16 MiB (0.0000%) Actual Power: 0 / 160 Mi (0.0000%)
可以看到 Owner 已经变成 t01005
(多签地址 ID Address) 了。再看下 Miner 的 control list
:
{2} 1 2 3 4 $ lotus-miner actor control list owner t01005: error getting account key: failed to get account actor state for t01005: unknown actor code bafkqadtgnfwc6nzpnv2wy5djonuwo name ID key use balance worker t01003 t3ufmq52y... other 9999.999977438895991462 FIL
这里我们看到这里提示报错,因为获取不到 t01005
的 Key,这个是正常的,上面我们已经讨论过了,多签地址是一个虚拟地址,没有 Key。
08. 多签 Owner 提现操作 偶然发现 lotus-shed 工具包里面居然有个多签的命令,提现,更改 Owner 什么的功能齐全:
{12-15} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $ ./lotus-shed miner-multisig NAME: lotus-shed miner-multisig - A new cli application USAGE: lotus-shed miner-multisig command [command options] [arguments...] DESCRIPTION: a collection of utilities for using multisigs as owner addresses of miners COMMANDS: propose-withdraw Propose to withdraw FIL from the miner approve-withdraw Approve to withdraw FIL from the miner propose-change-owner Propose an owner address change approve-change-owner Approve an owner address change help , h Shows a list of commands or help for one command OPTIONS: --from value specify address to send message from --multisig value specify multisig that will receive the message --miner value specify miner being acted upon --help , -h show help (default: false ) --version, -v print the version (default: false )
看了一下代码,它其实就是把一些步骤合并了,比如参数的编码解码什么,可以少一些步骤,推荐使用这个工具,不要手动发送消息了,减少出错的概率,我们先用这个工具提现试一下:
因为我们这个 Miner 是新创建的,没有算力,自然也就挖不到币,无币可提了。不过我们可以直接给他转一笔钱:
1 2 $ lotus send t01004 10000 bafy2bzaceae7ll3el7psrgvegzl2e43leikxh2y7frtmt557wolwqfl4cim5u
确认一下资金是否到账:
{9,13} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ lotus-miner info Miner: t01004 (8 MiB sectors) Power: 0 / 160 Mi (0.0000%) Raw: 0 B / 16 MiB (0.0000%) Committed: 0 B Proving: 0 B Below minimum power threshold, no blocks will be won Miner Balance: 10000 FIL PreCommit: 0 Pledge: 0 Vesting: 0 Available: 10000 FIL Market Balance: 0 Locked: 0 Available: 0 Worker Balance: 10000 FIL Total Spendable: 20000 FIL
可以看到目前 Miner 的可用余额为 10000 FIL,接下来我们提 2000 个 FIL 到 Owner 钱包:
8.1 多签成员发起提现请求 后面的操作我们都直接使用 lotus-shed 工具了:
1 2 3 4 5 6 7 8 lotus-shed miner-multisig --from=<多签成员1> --multisig=<多签地址> --miner <MinerID> propose-withdraw <提现金额> $ ./lotus-shed miner-multisig --from=t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply --multisig=t01005 --miner=t01004 propose-withdraw 2000 Propose Message CID: bafy2bzaceauwfqguxptehn43rzohxbxe6evrynk5pl7jzd43xlzyvitsjpxcw Transaction ID: 3
8.2 其他成员批准提现请求 1 2 3 4 5 6 7 8 9 10 lotus-shed miner-multisig --from=<多签成员2> --multisig=<多签地址> --miner=<MinerID> approve-withdraw <提现金额> <Transaction> <多签成员1> $ ./lotus-shed miner-multisig --from=t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja --multisig=t01005 --miner=t01004 approve-withdraw 2000 3 t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply Approve Message CID: bafy2bzaceafm7amduxwjlyhqwz7oxbzwofchh4nvw3xpcsdneczcllmkasjku Transaction was executed with the approve Exit Code: 0 Return Value: 4a006c6b935b8bbd400000
8.3 确认提现是否成功 我们只需要查一下多签地址的余额就能确认提现是否成功:
1 2 $ lotus wallet balance t01005 2990 FIL
可以看到,之前的余额是 990 FIL, 现在是 2990 FIL,提现已到账。
::: info 结论: 首先,你需要知道:只有在 Miner 的所有权不明确的情况下才考虑使用多签地址作为 Miner 的 Owner, 比如多个人联合挖矿。如果 Miner 确权明确,比如你只是请人帮你代运维,那么就不要使用什么多签地址了,直接自己离线保管就好,不需要提供给技术服务商。 至于具体怎么操作请参考我之前的文章:Lotus 私钥安全防护 。
其次,通过上面的内容我们可以得到: Owner 多签虽然提升了 Miner 安全性的,但是操作起来比较麻烦,不管是提现也好,终止扇区也好,要多操作好几步。最重要的是,并不是所有的 Miner 方法都支持多签的,所以如非必要,不建议 Owner 使用多签地址。 :::
09. 多签 Owner 改回成单签 Owner 前面我们说了,多签虽然安全,但是操作起来流程比较多,如非必要不推荐使用多签。如果你不想用多签了,想改回原来的单签的话,只需要反过来操作就好了:
使用多签钱包发起 Change Owner 请求;
使用单签钱包确认 Change Owner 请求。
具体操作步骤如下:
9.1 多签钱包发起 Change Owner 请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 lotus-shed miner-multisig --from=<多签成员1> --multisig=<多签地址ID> --miner=<MinerID> propose-change-owner <单签Owner地址> $ ./lotus-shed miner-multisig --from=t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply --multisig=t01005 --miner=t01004 propose-change-owner t3vjv265fawzcbepom356bipqtiiexf6bzpxulw5avg4pmfbnahd4n6nhcl5xuv3xrgug6itcjj3hrcusiljqq Propose Message CID: bafy2bzacealffv77nlsbfnis66pjz7rf2qnzgbj7pwwc7ctkhnb4ryt2xsb6a Transaction ID: 4 lotus-shed miner-multisig --from=<多签成员2> --multisig=<多签地址ID> --miner=<MinerID> approve-change-owner <单签Owner地址> <Transaction> <多签成员1> $ ./lotus-shed miner-multisig --from=t1toqsuwmyqpbcyfdr7km3orj46y52omckub3w6ja --multisig=t01005 --miner=t01004 approve-change-owner t3vjv265fawzcbepom356bipqtiiexf6bzpxulw5avg4pmfbnahd4n6nhcl5xuv3xrgug6itcjj3hrcusiljqq 4 t1hj2ftubovrftte7vwrqiarzijay3w6wq4g6gply Approve Message CID: bafy2bzacebp572ck76rz5ive6ecwawo5zej5h4awv4fgctoquqbnif3a5pzkc Transaction was executed with the approve Exit Code: 0 Return Value:
9.2 单签钱包确认 Change Owner 请求 1 2 3 4 lotus-miner actor set-owner --really-do-it <单签Owner地址> <单签Owner地址> $ lotus-miner actor set-owner --really-do-it t3vjv265fawzcbepom356bipqtiiexf6bzpxulw5avg4pmfbnahd4n6nhcl5xuv3xrgug6itcjj3hrcusiljqq t3vjv265fawzcbepom356bipqtiiexf6bzpxulw5avg4pmfbnahd4n6nhcl5xuv3xrgug6itcjj3hrcusiljqq
9.3 确认更改是否成功
查看一下 Miner 的 control list:
{3} 1 2 3 4 $ lotus-miner actor control list name ID key use balance owner t01003 t3vjv265f... other 9999.999977542737098922 FIL worker t01003 t3vjv265f... other 9999.999977542737098922 FIL
查看一下 Miner Info:
{2,3} 1 2 3 4 5 6 7 8 9 10 $ lotus state miner-info t01004 Available Balance: 7999.999998782919737128 FIL Owner: t01003 Worker: t01003 PeerID: 12D3KooWDTV9JBteM2GNxNBPUExuBoZNFEE1d5EkTjWnPxkc3hHv Multiaddrs: Consensus Fault End: -1 SectorSize: 8 MiB (8388608) Byte Power: 0 B / 16 MiB (0.0000%) Actual Power: 0 / 160 Mi (0.0000%)
可以看到 Owner 地址都改成原来的 t01003
了,多签 Owner 已经改成单签 Owner。
10. 参考链接