在比特币发展的过程中,曾多次出现因私钥被盗导致交易所倒闭和比特币用户损失大量资金的情况。比特币系统每个用户都拥有一个经过编码的34个字符比特币地址,用于接受比特币。每个比特币地址都有一个对应的32个字符的私钥,可以使用它来发送比特币。私钥必须被安全地管理好,只有你签署一笔转账时才需要用到,比特币地址可以自由地分发到全世界。这就是比特币钱包的原理。当你的私钥是安全的,那么一切都好,如果你失去了你的私钥,那么你的所有资金都没有了。
为了解决当私钥被盗后,尽量减少损失,在2011和2012年出现了多重签名交易。普通的交易只要一个私钥签名即可完成转账,多重签名交易关联两个及以上私钥,只有当其中两个或更多私钥对该交易进行签名,才能完成一笔转账。最常见的是2/3组合,意思是三个私钥中有两个私钥做了签名该转账有效。多重签名交易可以有效保证资金安全,同时在商业上也很有应用价值。可以基于多重交易实现第三方交易担保,以保证交易的顺利进行。
以太坊根据自身平台特点采用智能合约实现多重签名功能,一般在钱包合约中实现该功能。智能合约可以简单的理解为一段可执行的程序片段,具体的代码由发布人使用特定的编程语言来编写(以太坊使用的是Solidity编程语言,类似JavaScript),在本地编译成功后可以发布到区块链上。而以太坊的智能合约也可以理解为一个特殊的交易(包括可执行代码的),被发送出去后会被矿工打包记录在某一个区块中,当需要调用这个智能合约的方法时只需要向这个智能合约的地址发送一笔交易即可。下图为以太坊智能合约模型:
主流的以太坊钱包(如MIST、PARITY等)均提供多重签名功能。新建钱包合约时选择多重签名,输入相应的多重签名组合及对应的账号信息即可。钱包内置的钱包合约代码与这些输入信息通过SOLC编译为二进制码,然后通过一笔交易发送给以太坊网络,一旦以太坊网络节点把该交易打包记录到以太坊区块链中,该智能合约则部署成功。部署成功后会生成该智能合约地址,后续调用该智能合约只需要向该地址发送交易或者事件即可。
在测试private网中进行测试,运行MIST程序进入钱包首页。程序进入账户总览页:
点击“新增钱包”,进入新钱包合约界面。
这里我们选择“多重签名的钱包合约”:
上图是多重签名的参数设置,表示该合约由3个账号控制,每天消费超过5以太币则启动多重签名功能,合约由MAIN ACCOUNT账户拥有,ACCOUNT 2和ACCOUNT 3参与多重签名确认。设置好了相关参数后,点击“创建”则开始创建钱包合约,过程中MIST会提示输入MAIN ACCOUNT的操作口令,创建成功后在钱包界面上会出现该钱包合约信息。
其实这里的W1钱包合约,大家可以理解为就是一个账号,只不过这个账号受多人控制而已,这些我们可以向W1合约转账了,转账过程和普通交易一样,这儿不再啰嗦。
下面讲如何通过W1钱包合约向其他账户转账,多重签名的功能主要也就体现在这儿。
首先我们得确保W1合约里面有充足的余额,我们通过MAIN ACCOUNT已经转了100以太币到W1合约。我们现在新增一个账户ACCOUNT 4。使用W1合约给ACCOUNT
4分别转1以太币和5以太币。我们首先转1以太币,MIST钱包只提示了MAIN
ACCOUNT口令认证。再转5以太币,此时转出的以太币数量已经超过了W1合约设置的每天5以太币。
点击界面上的“发送”后,会弹出如下窗口:
注意这儿是执行W1合约,而不是执行交易。MAIN ACCOUNT向W1合约发送执行合约的交易命令,因此需要输入MAIN ACCOUNT的口令。RAW DATA就是合约执行的二进制参数,包括转到的目的账户和金额等。
当执行合约的交易发送给了以太坊网络后,则等待以太坊确认该交易,一旦以太坊网络确认了该交易,则在账户总览界面上会立即弹出下面信息:
点击“批准”后,MIST会弹出“选择一个账户”的对话框:
对话框上面可以选择确认的账户是之前在创建W1合约时,选择的ACCOUNT 2和ACCOUNT 3。我们选择其中一个进行合约确认,转账成功。
MIST钱包实现的钱包合约代码中有两个关键函数execute()和confirm()。当合约发布者执行交易时,execute()负责启动钱包合约,在执行该合约之前需要该合约发布者和相关账号的签名才能执行。当execute()函数在执行过程中发现需要进行多次签名时,会自动调用confirm()请求其它账号进行签名。Confirm()函数负责通知其它账号进行签名并确认,该函数根据钱包合约设定的参数多次被调用。直到账号签名的次数满足原先预定值后,execute()完成执行,此时钱包合约执行交易操作。
以太坊基于智能合约实现多重签名,具有很强的灵活性,应用非常广泛,尤其在当前火爆的ICO众筹中大量应用。但智能合约代码需要非常严谨,稍有不慎出现BUG导致大量资金损失,如parity钱包因智能合约BUG导致15万以太币被盗事件。