Solidity
通過範例文件將簽名功能拆分為solidity
大家好,我正在研究簽名驗證過程。我在這里通過範例文件閱讀了solidity ,我發現了這段程式碼:
/// signature methods. function splitSignature(bytes memory sig) internal pure returns (uint8 v, bytes32 r, bytes32 s) { require(sig.length == 65); assembly { // first 32 bytes, after the length prefix. r := mload(add(sig, 32)) // second 32 bytes. s := mload(add(sig, 64)) // final byte (first byte of the next 32 bytes). v := byte(0, mload(add(sig, 96))) } return (v, r, s); }
為什麼它有效?有人可以解釋裝配部分嗎?非常感謝。謝謝。
我複制了 Solidity 中的邏輯,以便您在比較時更好地理解它。
看一下函式
splitSignatureWithSlicing
,它和函式做的事情splitSignature
一樣,但沒有彙編。更容易理解它。// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; contract Contract { function splitSignature(bytes memory sig) public pure returns (uint8 v, bytes32 r, bytes32 s) { require(sig.length == 65); assembly { // first 32 bytes, after the length prefix. r := mload(add(sig, 32)) // second 32 bytes. s := mload(add(sig, 64)) // final byte (first byte of the next 32 bytes). v := byte(0, mload(add(sig, 96))) } return (v, r, s); } function splitSignatureWithSlicing(bytes calldata sig) public pure returns (uint8 v, bytes32 r, bytes32 s){ r = bytes32(sig[0:32]); // Copy first 32 bytes s = bytes32(sig[32:64]); // Copy 32 more bytes v = uint8(bytes1(sig[64:65])); // Copy last byte } }
嘗試使用以下字節:
0x997997d543f68c7b77e62a13efc6e546bd2a81c2aa8769c3354422ebbbb4fba4001c4a94f7f79e3a29652092d905b5ce47e84d6c0dd13d0ef0dd063abc149dffa7
,他們都返回相同的:
請記住,我們只能對數組使用數組切片
calldata
,而不是使用memory
orstorage
數組。這就是我宣布sig
as的原因bytes calldata sig
。它所做的是複制前 32 個字節,然後在前 32 個字節之後再复制 32 個字節,然後再复制最後一個字節。
組裝部分只是意味著將
r := mload(add(sig, 32))
32 添加到記憶體中sig
字節的起始位置,然後mload
將從該點讀取 32 個字節。
mload
一次讀取 32 個字節。然後,
s := mload(add(sig, 64))
從上一步中的剩餘字節中再讀取 32 個字節。然後再
v := byte(0, mload(add(sig, 96)))
讀取 32 個字節,但我們知道現在這 32 個字節中只有一個字節有值。所以我們只需要一個字節,這就是為什麼將它轉換為一個字節,相當於uint8
.在Remix中自己嘗試一下。