【solitidy】数学&hash&签名加密
solitidy官方文档
数学函数
- addmod(uint x, uint y, uint k) returns (uint)
计算(x + y) % k。加法支持任意的精度。但不超过(wrap around?)2**256。 - mulmod(uint x, uint y, uint k) returns (uint):
计算(x y) % k。乘法支持任意精度,但不超过(wrap around?)2*256。
hash
keccak256()
SHA3
采用Keccak
算法,在很多场合下Keccak
和SHA3
是同义词,但在2015年8月SHA3最终完成标准化时,NIST调整了填充算法,标准的SHA3和原先的Keccak算法就有所区别了。在早期的Ethereum相关代码中,普遍使用SHA3代指Keccak256
,为了避免和NIST标准的SHA3混淆,现在的代码直接使用Keccak256
作为函数名。keccak256(...) returns (bytes32)
// 紧密打包:参数不会补位,就直接连接在一起的。下面来看一个例子效果一样: keccak256("ab", "c") keccak256("abc") keccak256(0x616263) keccak256(6382179) keccak256(97, 98, 99)
- sha256(...) returns (bytes32):
使用SHA-256计算HASH值。紧密打包。 - sha3()
等于 keccak256() - ripemd160(...) returns (bytes20)
计算RIPEMD-160 hash。紧密打包。
ecrecover()
椭圆曲线加密
引用pragma solidity ^0.4.4; contract Decode{ //公匙:0x60320b8a71bc314404ef7d194ad8cac0bee1e331 //sha3(msg): 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 (web3.sha3("abc");) //签名后的数据:0xf4128988cbe7df8315440adde412a8955f7f5ff9a5468a791433727f82717a6753bd71882079522207060b681fbd3f5623ee7ed66e33fc8e581f442acbcf6ab800 //验签数据入口函数 function decode() returns (address){ bytes memory signedString =hex"f4128988cbe7df8315440adde412a8955f7f5ff9a5468a791433727f82717a6753bd71882079522207060b681fbd3f5623ee7ed66e33fc8e581f442acbcf6ab800"; bytes32 r = bytesToBytes32(slice(signedString, 0, 32)); bytes32 s = bytesToBytes32(slice(signedString, 32, 32)); byte v = slice(signedString, 64, 1)[0]; return ecrecoverDecode(r, s, v); } //将原始数据按段切割出来指定长度 function slice(bytes memory data, uint start, uint len) returns (bytes){ bytes memory b = new bytes(len); for(uint i = 0; i < len; i++){ b[i] = data[i + start]; } return b; } //使用ecrecover恢复公匙 function ecrecoverDecode(bytes32 r, bytes32 s, byte v1) returns (address addr){ uint8 v = uint8(v1) + 27; addr = ecrecover(hex"4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45", v, r, s); } //bytes转换为bytes32 function bytesToBytes32(bytes memory source) returns (bytes32 result) { assembly { result := mload(add(source, 32)) } } }
上述代码使用临时写的slice()函数把数据签名中的r,s,v切割出来;由于返回的仍是一个bytes类型,所以我们使用bytesToBytes32()进行一下类型转换8;另外需要注意的是ecrecoverDecode()根据前面的说明,我们需要对v值,加上27后再进行调用。最后调用decode()函数,我们将会得到公匙0x60320b8a71bc314404ef7d194ad8cac0bee1e331。
bancor.network里面的验证算法 function verifyTrustedSender(IERC20Token[] _path, uint256 _amount, uint256 _block, address _addr, uint8 _v, bytes32 _r, bytes32 _s) private returns(bool) { bytes32 hash = keccak256(_block, tx.gasprice, _addr, msg.sender, _amount, _path); // checking that it is the first conversion with the given signature // and that the current block number doesn't exceeded the maximum block // number that's allowed with the current signature require(!conversionHashes[hash] && block.number <= _block); // recovering the signing address and comparing it to the trusted signer // address that was set in the contract bytes32 prefixedHash = keccak256("\x19Ethereum Signed Message:\n32", hash); bool verified = ecrecover(prefixedHash, _v, _r, _s) == signerAddress; // if the signer is the trusted signer - mark the hash so that it can't // be used multiple times if (verified) conversionHashes[hash] = true; return verified; }
相关推荐
xceman 2020-10-13
算法与数学之美 2020-10-07
Anscor 2020-10-05
liwg0 2020-09-08
数学爱好者 2020-08-31
thermodynamicB 2020-08-11
夕加加 2020-07-20
willowwgx 2020-07-18
kuoying 2020-07-16
Anscor 2020-07-14
starletkiss 2020-07-08
kingzone 2020-06-27
xceman 2020-06-27
算法与数学之美 2020-06-21
kuoying 2020-06-21
秒懂数学 2020-06-17