本章的主題會把接續昨天的數位簽章把整個 Sign 的原理及應用梳理完畢,首先要知道的一個情況是我們常常會使用「私鑰來對一個信息進行簽章」。而這邊有幾件事情非常重要:
在這邊 Provider 可以當作一個幫助客戶端與區塊鏈節點互動的角色,通常會是節點商 Infura、Alchemy 等等。然而我們沒辦法提供私鑰給節點商(Hosting Parity, openning RESTful API)讓他們代替我們簽章(因為他們是中心化的服務),這時候就需要「錢包」,也就是「私鑰管理器」!
於是乎互動過程就變成:Metamask <-> Infura <-> Blockchain Node <-> Blockchain
,在 Metamask(當然也可以用其他錢包)背後其實仍然是跟 Infura 互動,只是 Metamask 會在本地端保管好(理想中)我們的私鑰與進行簽章的動作。
如果我們今天使用 web3.eth.sendTransaction
的交易物件長這樣:
{
from:...
to:...
value:...
gas, gasprice, nonce
}
我們需要先把「帳戶解鎖(unlocked account)」後去「簽核交易(web3.eth.signTransaction
)」:
> {
...
tx:{
v:...
r:..
s:...
}
}
在這個步驟中,有兩個元素:
如果把兩個元素融合就可以變成 Signed Transaction,在 Signed Transaction 中如果擁有 r 和 s,就可以使用 ECRECOVER 來產出 public key 和 ethereum account,這樣就可以確保此交易是合法經過授權的。
現在 Ethereum 的私鑰管理器基本上是使用 EIP-712 來去簽核 msg,而在這之前使用者很難去驗證自己到底簽了什麼,因為在跳出 Metamask 時的是 hexadecimal string,而不是現在看見的可讀字串。在 EIP-712 之後用戶們看見的簽核界面或出現 pre-hash 資訊,也就是 raw data,用戶就可以知道自己到底簽了什麼。
一個簽章機制包含了兩個演算法:一是 hashing algor. 一個是 signing algor.。 Signing algorithm 在 Ethereum 中是 secp256k1
,Hashing algorithm 則是 keccak256
。
在以太坊中有兩種訊息:一個是 transaction 一個是 bytestrings。簽章方式的 RPC Call 分別為 eth_sendTransaction
和 eth_sign
:
encode(transaction : ?) = RLP_encode(transaction)
encode(message : ?⁸ⁿ) = "\x19Ethereum Signed Message:\n" ‖ len(message) ‖ message
在合約接收到一個簽章後的訊息時,可以對其進行 recover 來看我們合約中儲存的 Signer 地址與簽章者是否相同,就可以達到檢驗鏈下資訊的用途(需要具備一定安全性),也就是說我們可以在鏈下以私鑰對某個訊息進行簽核,交付到鏈上時可以使用 ecrecover 來辨別簽核這個訊息的私鑰是否與我們認可的 signer 相符。
EIP-1271 幫助我們可以在合約裡面回復簽章來驗證交易者,其實我們也可以使用 OpenZeppelin 中的 ECDSA,辨別簽章中的資訊是否與我們定義的 signer 相符。
pragma solidity ^0.8.13;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
contract Claim is Ownable{
using ECDSA for bytes32;
address private signer;
function setSigner(address signer_) external onlyOwner{
signer = signer_;
}
function recover(bytes32 hash,, bytes memory sig) public {
address recovered = keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32",
hash
)).recover(sig);
require(signer == recovered, "Signer is invalid!");
}
}
最後歡迎大家拍打餵食大學生
0x2b83c71A59b926137D3E1f37EF20394d0495d72d