完整的代码为:
pragma solidity 0.4.14;
contract SimpleMultiSig {
uint publicnonce; // (only) mutablestate
uint publicthreshold; // immutable state
mapping(address => bool) isOwner; // immutable state
address[]public ownersArr; // immutablestate
function SimpleMultiSig(uint threshold_,address[] owners_) {
if(owners_.length > 10 || threshold_ > owners_.length || threshold_ == 0){throw;}
for (uinti=0; i isOwner[owners_[i]] = true;
}
ownersArr= owners_;
threshold= threshold_;
}
// Notethat address recovered from signatures must be strictly increasing
functionexecute(uint8[] sigV, bytes32[] sigR, bytes32[] sigS, address destination, uintvalue, bytes data) {
if(sigR.length != threshold) {throw;}
if(sigR.length != sigS.length || sigR.length != sigV.length) {throw;}
//Follows ERC191 signature scheme: https://github.com/ethereum/EIPs/issues/191
bytes32txHash = sha3(byte(0x19), byte(0), this, destination, value, data, nonce);
addresslastAdd = address(0); // cannot have address(0) as an owner
for (uinti = 0; i < threshold; i++) {
address recovered = ecrecover(txHash, sigV[i], sigR[i], sigS[i]);
if(recovered <= lastAdd || !isOwner[recovered]) throw;
lastAdd = recovered;
}
// If wemake it here all signatures are accounted for
nonce =nonce + 1;
if(!destination.call.value(value)(data)) {throw;}
}
function ()payable {}
}
此代码也可以在github中找到。
效益
此合约的有益属性包括:
l 最小代码库:只有40行代码
l 最少可变状态:唯一可变的数据是,每一次执行都会增加一个单元(unit)。
l 最小界面:由单一功能构成的界面.
l 能够发送任意交易,故而支持代币(token)
由于缺乏复杂的状态转换,在没有资金的情况下,该合约便无法转入“冻结”状态。而因为唯一可能的状态转换是简单的增量计数器,所以该合约永远处于正确状态。且由于使用了32字节的整数,计数器便不可能溢出。同时,测试也变得更简单了,因为事实上(除构造函数外)只有一个函数需要测试。
但由于我们尽可能地简化了链上逻辑,因而增加了链下工作流程的复杂性,这便导致了一些缺陷与不足,比如:
l 需要用户给非交易签名,而这可能妨碍某些硬件钱包的使用
l 为了发送交易,需要终端用户进行链下协调。