[Tech] — AccountKey Weigthed MultiSig
이번 시간에는 저와 함께 AccountKey Weighted MultiSig에 대해서 알아봅시다.
목차
- AccountKey Weighted MultiSig 란?🤔
- 사용법
1. AccountKey Weighted MultiSig 란?🤔
AccountKey Weighted Multisig 어감이 상당히 어렵게 느껴질 수 있습니다.
하지만 조금씩 뜯어가면서 이해해 봅시다.
AccountKey란 무엇일까요?
지갑 주소에는 키가 있습니다 공개키, 개인키 이런 게 있죠?
“이런 형식이 어떤 식으로 이루어져 있어? “를 의미합니다.
가장 크게 Legacy 방식 Public 방식이 있습니다.
Legacy 방식과 Public 방식은
여기에 자세히 포스팅하였으니 보시면 이해하기 쉬울 겁니다.
그럼 AccountKeyWeightedMultiSig 란 AccountKey 형식이
WeightedMultiSig 방식을 의미합니다.
그럼 WeightedMultiSig 란 무엇일까요?
Weighted : 가중치 ( 중요도)
Multi : 다중
Sig : 서명
즉 다중 서명을 하는데 중요도가 포함되어 있는 다중 서명을 의미합니다.
아직까지 애매모호하죠? 코드와 함께 이해해 봅시다.
전체코드
// AccountKeyWeightedMultiSig
// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig
const { ethers } = require("ethers");
const { Wallet, TxType, AccountKeyType, parseKlay } = require("@klaytn/ethers-ext");
const senderAddr = "Your Sender Address";
const senderNewPriv1 = "Sender New Private Key1";
const senderNewPriv2 = "Sender New Private Key2";
const senderNewPriv3 = "Sender New Private Key3";
const recieverAddr = "Receiver Address";
const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net");
const wallet1 = new Wallet(senderAddr, senderNewPriv1, provider);
const wallet2 = new Wallet(senderAddr, senderNewPriv2, provider);
const wallet3 = new Wallet(senderAddr, senderNewPriv3, provider);
async function updateAccount() {
const pub1 = ethers.utils.computePublicKey(senderNewPriv1, true);
const pub2 = ethers.utils.computePublicKey(senderNewPriv2, true);
const pub3 = ethers.utils.computePublicKey(senderNewPriv3, true);
console.log({ pub1, pub2, pub3 });
const tx = {
type: TxType.AccountUpdate,
from: senderAddr,
gasLimit: 1000000,
key: {
type: AccountKeyType.WeightedMultiSig,
threshold: 2,
keys: [
[1, pub1],
[1, pub2],
[1, pub3],
]
}
};
const populatedTx = await wallet1.populateTransaction(tx);
const rawTx1 = await wallet1.signTransaction(populatedTx);
console.log("rawTx1", rawTx1);
const rawTx2 = await wallet2.signTransaction(rawTx1);
console.log("rawTx2", rawTx2);
const sentTx3 = await wallet3.sendTransaction(rawTx2);
console.log("sentTx3", sentTx3);
const receipt = await sentTx3.wait();
console.log("receipt", receipt);
}
async function main() {
await updateAccount();
}
main().catch(console.error);
저희는 Web3Klaytn을 이용해야 하기 때문에 필요한 라이브러리를 가져옵니다.
const { ethers } = require("ethers");
const { Wallet, TxType, AccountKeyType, parseKlay } = require("@klaytn/ethers-ext");
다중 서명을 위해 필요한 지갑 주소랑 여러 명의 개인키를 가져옵니다.
const senderAddr = "Your Sender Address";
const senderNewPriv1 = "Sender New Private Key1";
const senderNewPriv2 = "Sender New Private Key2";
const senderNewPriv3 = "Sender New Private Key3";
const recieverAddr = "Receiver Address";
네트워크를 사용하기 위해 provider를 들고 와줍니다.
const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net");
sender 지갑 주소에 개인키와 provider를 넣어서 새로운 지갑 객체를 생성해 줍니다.
const wallet1 = new Wallet(senderAddr, senderNewPriv1, provider);
const wallet2 = new Wallet(senderAddr, senderNewPriv2, provider);
const wallet3 = new Wallet(senderAddr, senderNewPriv3, provider);
AccountKey를 업그레이드해주는 함수를 만들어봅시다.
async function updateAccount() {
}
개인키를 사용해 공개키를 만들어봅시다.
async function updateAccount() {
const pub1 = ethers.utils.computePublicKey(senderNewPriv1, true);
const pub2 = ethers.utils.computePublicKey(senderNewPriv2, true);
const pub3 = ethers.utils.computePublicKey(senderNewPriv3, true);
console.log({ pub1, pub2, pub3 });
}
트랜잭션 객체를 생성합니다.
const tx = {
// 이 트랜잭션의 타입은 AccountUpdate 타입입니다.
type: TxType.AccountUpdate,
// senderAddress 로부터 생성이 됩니다.
from: senderAddr,
// gasLimit은 십만입니다.
gasLimit: 1000000,
// AccountKey의 타입을 WeightedMultiSig로 정해줍니다
key: {
type: AccountKeyType.WeightedMultiSig,
// 최소 서명자 수를 의미합니다.
threshold: 2,
// pub은 공개키를 의미하고 1은 Weighted(가중치)를 의미합니다
// 즉 더욱더 중요한(영향력이 있는) 서명자를 지정할 수 있습니다.
keys: [
[1, pub1],
[1, pub2],
[1, pub3],
]
}
};
위에서 설정한 트랜잭션을 지갑에 할당해 줍니다.
const populatedTx = await wallet1.populateTransaction(tx);
실질적으로 트랜잭션 객체를 서명하는 코드입니다.
const rawTx1 = await wallet1.signTransaction(populatedTx);
서명이 되어있는 지갑 1의 정보를 받아서 다시 지갑 2에서도 서명을 합니다.
const rawTx2 = await wallet2.signTransaction(rawTx1);
마지막 지갑은 지갑 1 , 지갑 2에 정보를 모두 받아 최종적으로 지갑에 트랜잭션을 보냅니다.
const sentTx3 = await wallet3.sendTransaction(rawTx2);
트랜잭션까지 모두 보냈으면
KlayScope에서 senderAddress의 Account Key가
MultiSig로 바뀌었는지 확인해 보세요.
예제코드
오늘도 유익한 글이 되셨으면 좋겠습니다 감사합니다.