通过查看以太坊源码发现预编译合约ecrecover也就是地址为0x01的预编译合约中通过入参的txHash和tx中的R,V,S解出签名tx的帐户Addr中有一行v:=输入[63] ]-27看不明白这个减法是什么操作。二进制如此下:``` func(c * ecrecover)Run(input [] byte)([] byte,error){ const ecRecoverInputLength = 128 input = common.RightPadBytes (input,ecRecoverInputLength) //“输入”为(hash,v,r,s),每个32字节 // //对于ecrecover,我们想要(r,s,v) r:= new(big.Int).SetBytes( input [64:96]) s:= new(big.Int).SetBytes(input [96:128]) v:= input [63]-27 // todo这里看不明白 // sig s值输入更严格只有 !allZero(input [32:63])|| 仅适用于tx信号 !crypto.ValidateSignatureValues(v,r,s,false){ return nil,nil }
//我们必须确保不要修改'input',因此将'v'与 签名一起放置//必须在新的分配 sig上完成:= make([] byte,65) copy(sig,input [64:128]) sig [64] = v // v必须在libsecp256k1 pubKey的末尾,err:= crypto.Ecrecover(input [:32],sig) //确保公钥有效一个 if err!= nil { return nil,nil } // pubkey的第一个字节是比特币遗产 return common.LeftPadBytes(crypto.Keccak256(pubKey [1:])[12:],32),nil } ``` 其中第11行看不明白!通过编写坚固合约跨合约的方式调用该ecrecover合约,发现解不出来签名的钱包地址合约代码如下:```
函数ecrecov(bytes32 msgh,uint8 v,bytes32 r,bytes32 s)公共视图返回(地址){ uint256 [4]内存输入; 输入[0] = uint256(msgh); 输入[1] = v; 输入[2] = uint256(r); 输入[3] = uint256(s); uint256 [1]内存检索; uint256成功; 程序集{ 成功:= staticcall(not(0),0x1,input,0x80,retval,32) } if(成功!= 1){ 返回地址(0); } 返回地址(retval [0]); } 而我入参的masHash和R,S,V分别取自交易Tx:
{
blockHash:“ 0x18ccff43c8be8a7181ed714442d07601533dbdc34314c8fb970e7fb73347b022”, blockNumber:75605, 来自:“ 0x493301712671ada506ba6ca7891f436d29185821”, gas:30000000, gasPrice:1000000000, hash:“ 0xdf09d680b7e7e0b
输入:0x608060405234801561001057600080fd5b50610461806100206000396000f3fe6080604052600436106100345760003560e01c806349ba3065146100395780638081a1e7146100d5578063bb8c256a14610160575b600080fd5b34801561004557600080fd5b506100936004803603608081101561005c57600080fd5b8101908080359060200190929190803560ff16906020019092919080359060200190929190803590602001909291905050506101e8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100e157600080fd5b50610122600480360360608110156100f857600080fd5b810190808035906020019092919080359060200190929190803590602001909291905050506102a6565b6040518082600260200280838360005b8381101561014d578082015181840152602081019050610132565b5050505090500191505060405180910390f35b6101aa6004803603608081101561017657600080fd5b8101908080359060200190929190803590602001909291908035906020019092919080359060200190929190505050610318565b6040518082600260200280838360005b838110156101d55780820151818401526020810190506101ba565b5050505090500191505060405180910390f35b60006101f26103a4565b8560001c8160006004811061020357fe5b6020020181815250508460ff168160016004811061021d57fe5b6020020181815250508360001c8160026004811061023757fe5b6020020181815250508260001c8160036004811061025157fe5b6020020181815250506102626103c6565b60006020826080856001600019fa905060018114610286576000935050505061029e565b8160006001811061029357fe5b602002015193505050505b949350505050565b6102ae6103e8565b6102b661040a565b84816000600381106102c457fe5b60200201818152505083816001600381106102db57fe5b60200201818152505082816002600381106102f257fe5b6020020181815250506040826060836007600019fa61031057600080fd5b509392505050565b6103206103e8565b6103286103a4565b858160006004811061033657fe5b60200201”,
随机数:193, R: “0xad73c891a867d814e130e1f456ce024f21079a245a4bb5657122acf31a4454d5”, S: “0x603b0b8506aa7d8df97fd97c7d5c43fffc7904d9d07f4c3b3087354c28460840”, 于:空, transactionIndex:0, ν: “0xec”, 值:0 } `` 其中msgHash用:
0xdf09d680671b085bb24454b7737d0b661a16bbe0e35cb331ef8eec90d7c2e77d,R取值:
0xad73c891a867d814e130e1f456ce024f21079a245a4bb5657122acf31a4454d5,S取值:
0x603b0b8506aa7d8df97fd97c7d5c43fffc7904d9d07f4c3b3087354c28460840,v取值:
0xec解析失败。有大神知道是什么原因么,或者知道预编译合约中第11行的
ν:=输入[63] - 27 `中的减27是什么操作?我的钱包Addr是“ 0x493301712671ada506ba6ca7891f436d29185821”