Senin, 04 September 2023

Cara mengambil public key dari transaksi Ethereum

Pada saat pembuatan address pada walet Metamask atau wallet web3 lainnya, public key selalu tidak ditampilkan walaupun sebenarnya sudah dibuat. 

Ini menjadi masalah tersendiri jika kita ingin memanfaatkan key ini untuk percakapan dengan enkripsi asimetri.

Address yang dihasilkan wallet web3 tidak bisa dikonversi langsung menjadi public key dengan mudah walaupun address tersebut merupakan turunan dari public key. Ini karena address itu dihasilkan melalui tahapan dari public key yang melibatkan fungsi satu arah (hashing) seperti berikut;

1. Mendapatkan Public Key

Setelah private key di generate. artinya kita juga memiliki asosiasi dengan public key. Public key disini dinamakan dengan Public ECDSA Key

Public key ini dimasukkan kedalam fungsi keccak-256(public key)

2. Dimasukkan kedalam fungsi Keccak-256 hash

3. Mengambil 20 bytes terakhir

Untuk mengenerate secara online, Anda dapat mencoba pada link berikut: https://www.rfctools.com/ethereum-address-test-tool/

Harap berhati-hati, jangan pernah memasukkan private key Anda.


Sedangkan untuk mendapatkan public key jika addressnya diketahui, kita tidak dapat membalik alur tersebut. Satu-satunya langkah yang dapat dilakukan adalah dengan membuat transaksi ethereum sehingga kita bisa mendapatkan nilai v, r dan s dari transaksi tersebut

Berikut adalah codenya;

import Web3 from 'web3';
import Cookie from "js-cookie";
import { fromRpcSig, hashPersonalMessage, ecrecover, pubToAddress } from 'ethereumjs-util';

var web3;
if (window.ethereum) {
web3 = new Web3(window.ethereum);
} else {
web3 = new Web3(window.ethProvider);
}
// The message you want to sign
const message = 'I want to get my public key';

// Get the user's connected Ethereum address
const userAddress = Cookie.get("connectedAddress");

try {
// Sign the message using Metamask
const signature = await web3.eth.personal.sign(message, userAddress);

// Ensure the input is a Buffer
const signatureBuffer = Buffer.from(signature.slice(2), 'hex'); // Remove the '0x' prefix

// Extract the components from the signature
const { v, r, s } = fromRpcSig(signatureBuffer);

// Calculate the message hash
const messageHash = hashPersonalMessage(Buffer.from(message));

// Recover the public key
const publicKey = ecrecover(messageHash, v, r, s);

// Convert the publicKey to a hexadecimal string
// (this line just to make sure the public key in hex format)
const publicKeyHex = '0x' + publicKey.toString('hex');
console.log(`Public Key (Hex): ${publicKeyHex}`);

// Convert the public key to an Ethereum address
const recoveredAddress = '0x' + pubToAddress(publicKey).toString('hex');

console.log(`Recovered Address: ${recoveredAddress}`);

} catch (error) {
console.error('Error:', error);
}

Pada code diatas, kita menggunakan web3 wallet Metamask. Disini kita menghindari meg-ekspose private key. 

Strategi yang digunakan adalah;

1. Menandatangani sebuah pesan. 

2. Meng-ekstrak v, r dan s

3. Membuat message hash

4. Merecover public key dengan function ecrecover dan memasukkan nilai message hash, v, r dan s

5. Mengambil address dengan function pubToAddress

Untuk memastikan public key yang Anda convert kepada Address adalah benar, Anda dapat melakukan test sekali lagi dengan mengambil public key dari baris `console.log(`Public Key (Hex): ${publicKeyHex}`);` dan memasukkannya pada public key ECDSA pada link  https://www.rfctools.com/ethereum-address-test-tool/



Tidak ada komentar:

Posting Komentar

Cara Mengetahui Besar Database PostgreSQL Tanpa Mendownloadnya

Berikut adalah langkah-langkah untuk mengetahui ukuran semua database di instance PostgreSQL yang berjalan di dalam kontainer Docker: 1. Men...