[Caver] Klaytn-Kontoschlüssel Updaten mit Caver #2 — AccountKeyWeightedMultiSig

Tech at Klaytn
8 min readOct 8, 2021

--

Hier ist die komplette Liste aller Artikel.

🇰🇷:[Caver] Caver로 Klaytn 계정의 키를 바꾸는 방법 #2 AccountKeyWeightedMultiSig
🇬🇧:[Caver]How to Update Klaytn Account Keys with Caver #2 AccountKeyWeightedMultiSig
🇫🇷: [Caver] Mettre à jour la clé de compte de Klaytn avec Caver #2 AccountKeyWeightedMultiSig

Eines der erwähnenswerten Features der Klaytn Blockchain ist die Entkopplung der Schlüssel von den Adressen. Das heißt, dass Ihre Kontoschlüssel upgedatet werden können. In diesem Post, erklären wir Ihnen wie man mit caver-js and caver-java Kontoschlüssel auf AccountKeyWeightedMultiSig updaten kann. Weitere Details zu den verschiedenen Typen von AccountKey finden Sie in Klaytn Docs.

Bevor es mit diesem Tutorial los geht, müssen Sie die geeignete Umgebungseinrichtung konfiguriert haben. Wenn Sie das noch nicht haben, besuchen Sie zuerst diesen Link: caver-js — Prerequisites or caver-java — Prerequisites.

In jedem Abschnitt behandeln wir kleine Schnipsel des ganzen Codes. Die komplette Version finden sich hier:

1. keyring generieren

Zuallererst müssen wir ein Klaytn-Konto erstellen. Dieses Konto muss dann auch über genügend KLAY verfügen, weil es zum Senden der Transaktionen für das Update der Schlüssel notwendig ist.

Caver hat eine Struktur namens Keyring, der die Privatschlüssel speichert, die für Klaytn-Konto und -Adressen eingesetzt werden.

Unten sehen Sie wie man in caver-js eine Keyring-Instanz erzeugen kann.

// caver-js 
const senderKeyring = caver.wallet.keyring.create(senderAddress, senderPrivateKey)

Falls Sie eine keystore-Datei anstatt eines Privatschlüssel-Strings haben, benutzen Siecaver.wallet.keyring.decrypt zur Erzeugung eines Keyring.

Und das Erstellen einer Keyring-Instanz in caver-java erfolgt wie unten gezeigt:

// caver-java
SingleKeyring senderKeyring = caver.wallet.keyring.create(senderAddress, senderPrivateKey);

Sie können auch für caver-javacaver.wallet.keyring.decrypt benutzen falls Sie eine keystore Datei haben.

2. keyring zum caver-In-Memory-Wallet hinzufügen

In diesem Tutorial, benutzen wir eine In-Memory-Wallet. Nachdem Sie einen Keyring zu caver-In-Memory-Wallet hinzugefügt haben, der darin gespeicherte Schlüssel wird automatisch von nun an eingesetzt um die Transaktionen zu signieren, selbst wenn Sie das nicht explizit festsetzen.

So fügen Sie einen Keyring zur In-Memory-Wallet mit caver-js:

// caver-js
caver.wallet.add(senderKeyring)

Der Prozess ist derselbe mit caver-java:

// caver-java
caver.wallet.add(senderKeyring);

3. Neue Privatschlüssel erstellen

Wenn Sie den AccountKey Ihres Klaytn-Kontos in AccountKeyWeightedMultiSig verändern wollen, benötigen Sie mehrere Privatschlüssel für Ihr Klaytn-Konto. Hier verwenden wir die Schlüssel, der mit der Funktion generateMultiplieKeyszufällig generiert sind. Aber wenn Sie sich für bestimmte Schlüssel entscheiden wollen, ist das auch völlig in Ordnung.

Unten sehen Sie wie man für Ihr Klaytn-Konto neue Privatschlüssel-Strings erstellen kann mit caver-js:

// caver-js
const newKeys = caver.wallet.keyring.generateMultipleKeys(3)

Mit caver-java können Sie auch mit generateMultipleKeys mehrere Privatschlüssel-Strings erzeugen:

// caver-java
String[] newKeys = caver.wallet.keyring.generateMultipleKeys(3);

4. Neuen keyring erstellen

Da wir jetzt neue Privatschlüssel erstellt haben, werden wir nun eine Keyring Instanz erzeugen, um sie zu speichern. Wir können die Instanz mit den neuen Schlüsseln erst verwenden, nachdem AccountKey im Klaytn-Konto erfolgreich verändert ist.

Sie erstellen die Keyring Instanz mit caver-js wie im Folgenden gezeigt:

// caver-js
const newKeyring = caver.wallet.keyring.create(senderKeyring.address, newKeys)

Der newKeyring, der den neuen Privatschlüssel speichert, wird von nun an zum Signieren von Transaktionen newKeys verwenden.

In caver-java, das Erstellen von einer Keyring-Instanz, die die neuen Privatschlüssel speichert, sieht aus wie im Folgenden Beispiel.

// caver-java
MultipleKeyring newKeyring = caver.wallet.keyring.create(senderKeyring.getAddress(), newKeys);

5. Account-Instanz erstellen

Die Klasse Account zur Verfügung gestellt von caver beinhaltet die notwendigen Informationen für das Konto-Update. Was Sie brauchen beim Updaten auf AccountKeyWeightedMultiSig sind: die Klaytn-Kontoadresse und die neuen weighted multisig (gewichteten multisig)-Schlüssel, die Sie ab jetzt verwenden werden. In AccountKeyWeightedMultiSig werden die Schlüssel als öffentliche Schlüssel gespeichert, und die threshold (Schwelle) und die weights (Gewichte) der jeweiligen öffentlichen Schlüssel werden auch definiert.

Sie können eine Account Intanz erzeugen, indem Sie die toAccount Funktion des keyrings aufrufen, der die neuen Privatschlüssel speichert. So sieht das aus mit caver-js:

Die Schwelle und die jeweiligen Gewichte der Schlüssel von AccountKeyWeightedMultiSig werden zum Beispiel so definiert:

// caver-js
const account = newKeyring.toAccount({ threshold: 3, weights: [2, 1, 1] })

In caver-java können Sie ebenfalls eine die Account-Intanz erzeugen mit der Funktion toAccount. Die Schwelle und die Gewichte der Schlüssel in AccountKeyWeightedMultiSig werden mit der WeightedMultiSigOptions Klasse definiert.

BigInteger[] weights = {BigInteger.valueOf(2), BigInteger.ONE, BigInteger.ONE};
WeightedMultiSigOptions options = new WeightedMultiSigOptions(BigInteger.valueOf(3), Arrays.asList(weights));
Account account = newKeyring.toAccount(options);

Die Account Intanz beinhaltet nun die Klaytn-Kontoadresse, die zu updaten ist, und die Schlüssel in der Form von öffentlichen Schlüsseln, bei denen die Schwelle sowie die Gewichte der jeweiligen Schlüssel definiert sind.

6. Transaktion erstellen

Wir haben gerade eine Account-Intanz erzeugt. Nun wird sie verwendet, um eine Update-Transaktion zu erstellen.

So erstellt man eine Update-Transaktion mit caver-js:

// caver-js
const accountUpdate = caver.transaction.accountUpdate.create({
from: senderKeyring.address,
account: account,
gas: 100000,})

Und mit caver-java sieht das so aus:

// caver-java
AccountUpdate accountUpdate = caver.transaction.accountUpdate.create(
TxPropertyBuilder.accountUpdate()
.setFrom(senderKeyring.getAddress())
.setAccount(account)
.setGas(BigInteger.valueOf(100000))
);

7. Transaktion signieren

Sie haben die Update-Transaktion erstellt, die Sie nun signieren müssen, und zwar mit dem keyring, der zur In-Memory Wallet hinzugefügt wurde. Cavers In-Memory Wallet, caver.wallet, hat für diesen Zweck eine sign Funktion.

Und so signieren Sie eine Transaktion mit caver-js:

// caver-js
await caver.wallet.sign(senderKeyring.address, accountUpdate)

Und mit caver-java:

// caver-java
caver.wallet.sign(senderKeyring.getAddress(), accountUpdate);

Wenn caver.wallet.sign erfolgreich durchgeführt ist, werden Sie sehen, dass nun die Signatur dem signatures Feld von accountUpdate zugewiesen ist.

Alles, was uns noch bleibt, ist die Transaktion ans Netzwerk zu übermitteln!

8. Transaktion schicken

Wir haben die Transaktion erstellt und signiert. Lass uns sie nun ans Netzwerk übermitteln. Ab dem Punkt, an dem diese Transaktion erst im Netzwerk verarbeitet ist, können Sie Ihren alten Klaytn-Kontoschlüssel nicht mehr verwenden. Weil Ihr alten keyring auch unbrauchbar wird, werden Sie einen Neuen erstellen müssen, der die neuen Privatschlüssel speichert.

Sie schicken die signierte Transaktion ans Netzwerk mit caver.rpc.klay.sendRawTransaction.

Der Code unten zeigt wie Sie mit caver-js eine Transaktion senden können, indem Sie EventEmitter verwenden:

// caver-js
caver.rpc.klay.sendRawTransaction(accountUpdate)
.on('transactionHash', hash => {
console.log(hash)
})
.on('receipt', receipt => {
console.log(receipt)
})

Mit caver-js, können Sie ein Receipt der Transaktion erhalten mit Promise, wie unten gezeigt:

// caver-js
const receipt = await caver.rpc.klay.sendRawTransaction(accountUpdate)

Sie können auch caver-java verwenden:

// caver-java
Bytes32 sendResult = caver.rpc.klay.sendRawTransaction(accountUpdate).send();
String txHash = sendResult.getResult();

Wenn dieser Code durchgeführt ist, erhalten Sie einen Hashwert der Transaktion. Das Ergebnis der Transaktion können Sie mit dem Code unten erhalten:

// caver-java
public String objectToString(Object value) throws JsonProcessingException {
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
return ow.writeValueAsString(value);
}
TransactionReceiptProcessor receiptProcessor = new PollingTransactionReceiptProcessor(caver, 1000, 15);TransactionReceipt.TransactionReceiptData receiptData = receiptProcessor.waitForTransactionReceipt(txHash);System.out.println(objectToString(receiptData));

Wenn im Receipt der Status true ausgegeben hat, bedeutet das, dass die Transaktion erfolgreich verarbeitet ist. Der Transaktion-Typ ist TxTypeAccountUpdate und der upgedatet AccountKeyWeightedMultiSigcountKeyPublic ist im Feld key ausgegeben in enkodierter Form.

{
blockHash: ‘0xdf8b53b76fc1bc2dde099199026c48b7cae56724b752b1476ae2ab867598a1d5’,
blockNumber: ‘0x33c98c3’,
contractAddress: null,
from: ‘0xf3ecd45eeb2bb22d33d2d83dc2350d18691b5f80’,
gas: ‘0x186a0’,
gasPrice: ‘0x5d21dba00’,
gasUsed: ‘0x13c68’,
key: ‘0x04f86f03f86ce302a103d2df49e8d3b4da20b39a81f422c82c50e29a32b0a001b90d6de72a9cc76535f5e301a103b00854f13c6cb6cabab766c2c4b74bc568568a5600599be6ace18a789fc3b5dce301a1021968807b49413b84eea56d24bfe212166ccafdba2c1ae4d7c1e04a179f28dc5f’,
logs: [],
logsBloom: ‘0x00000…’,
nonce: ‘0x0’,
senderTxHash: ‘0x736f2a35cd4618f00ed4e6a76637b526b2b72e8fdc1a7dab35c3341a2c2027af’,
signatures: [
{ V: ‘0x7f5’, R: ‘0x89e33…’, S: ‘0x1c9a0…’ }
],
status: ‘0x1’,
transactionHash: ‘0x736f2a35cd4618f00ed4e6a76637b526b2b72e8fdc1a7dab35c3341a2c2027af’,
transactionIndex: ‘0x0’,
type: ‘TxTypeAccountUpdate’,
typeInt: 32
}

9. Update-Ergebnis bestätigen

Wenn die Transaktion erfolgreich war, der Kontoschlüssel, der im Netzwerk gespeichert ist, wird upgedatet sein. Sie können das Ergebnis bestätigen mit caver.rpc.klay.getAccountKey.

Bestätigen Sie Ihren neuen accountKey in caver-js:

// caver-js
const accountKey = await caver.rpc.klay.getAccountKey(senderKeyring.address)
console.log(accountKey)

Und mit caver-java:

// caver-java
AccountKey accountKey = caver.rpc.klay.getAccountKey(senderKeyring.getAddress()).send();
System.out.println(objectToString(accountKey));

Der Code oben wird den Kontoschlüssel im Klaytn-Konto ausgeben. Der Schlüssel soll auf AccountKeyWeightedMultiSig upgedatet sein, also der keyType, der für eine Schlüsseltyp-ID steht, ist 4. Weitere Details über Kontoschlüsseltyp-IDs können Sie in Klaytn Docs finden.

{
keyType: 4,
key: {
threshold: 3,
keys: [
{
weight: 2,
key: { x: ‘0xd2df4…’, y: ‘0x813fe…’ }
},
{
weight: 1,
key: { x: ‘0xb0085…’, y: ‘0x478f5…’ }
},
{
weight: 1,
key: { x: ‘0x19688…’, y: ‘0x9d8b3…’ }
}
]
}
}

10. keyring der In-Memory Wallet updaten

Nachdem Ihr Kontoschlüssel durch eine erfolgreiche Transaktion richtig upgedatet ist, müssen Sie von nun an den upgedateten Schlüssel verwenden, um die Transaktionen zu signieren.

Im Moment ist der Schlüssel, der im keyring verwendet wird, und in der In-Memory-Wallet gespeichert ist, noch in der alten Version. Wenn Sie eine Transaktion sendet, ohne die Schlüssel in der In-Memory-Wallet upzudaten, wird das einen Fehler verursachen, wie unten gezeigt :

Error: Returned error: invalid transaction v, r, s values of the sender

Aus diesem Grund müssen Sie den Schlüssel in keyring, der in der In-Memory-Wallet gespeichert ist, auch updaten, nach dem Kontoschlüssel-Update.

Dieser Privatschlüssel kann mit caver.wallet.updateKeyring upgedatet werden. Der newKeyring, der die upgedatete Klaytn-Kontoadresse und die neue Privatschlüssel beinhaltet, wird als Parameter übergeben.

Unten sehen Sie wie das mit caver-js gemacht wird:

// caver-js
caver.wallet.updateKeyring(newKeyring)

Und nun mit caver-java:

// caver-java
caver.wallet.updateKeyring(newKeyring);

11. Transaktion schicken mit dem neuen Konto

Ihr Klaytn-Kontoschlüssel ist upgedatet; lass uns nun eine Transaktion schicken mit dem upgedateten Konto.

Weil der im Netzwerk gespeicherte Kontoschlüssel upgedatet ist, müssen Sie jetzt die Transaktion signieren mit dem neuen Schlüssel. Im Abschnitt [10. keyring der In-Memory Wallet updaten] haben wir den Schlüssel im keyring in der In-Memory-Wallet ebenfalls upgedatet. Wenn also eine Transaktion gesendet wird, wird sie mit diesem upgedateten Schlüssel signiert.

In diesem Tutorial senden wir eine einfache Value Transfer (Wertübertragung)-Transaktion um das Update zu bestätigen.

Der Code unten zeigt wir man mit caver-js eine valueTransfer-Transaktion erstellt, signiert und übermittelt.

// caver-js
const vt = caver.transaction.valueTransfer.create({
from: senderKeyring.address,
to: recipientAddress,
value: 1,
gas: 100000,
})await caver.wallet.sign(senderKeyring.address, vt)const vtReceipt = await caver.rpc.klay.sendRawTransaction(vt)

Die Transaktion wird durch caver.transaction.valueTransfer erstellt, und durch die Funktion caver.wallet.sign signiert, wie schon erklärt. Da der keyring in der In-Memory caver.wallet auch upgedatet wurde in [10. keyring der In-Memory Wallet updaten], die Transaktion wird mit den neuen Privatschlüsseln signiert. Danach wird die Transaktion ans Netzwerk übermittelt mit caver.rpc.klay.sendRawTransaction. In diesem Beispiel ist das Ergebnis der Transaktion mit Promise ausgegeben.

Nun derselbe Prozess in caver-java:

// caver-javaValueTransfer vt = caver.transaction.valueTransfer.create(
TxPropertyBuilder.valueTransfer()
.setFrom(sednerKeyring.getAddress())
.setTo(recipientAddress)
.setValue(BigInteger.valueOf(1))
.setGas(BigInteger.valueOf(100000))
);caver.wallet.sign(senderKeyring.getAddress(), vt);Bytes32 vtResult = caver.rpc.klay.sendRawTransaction(vt).send();TransactionReceipt.TransactionReceiptData vtReceiptData = receiptProcessor.waitForTransactionReceipt(vtResult.getResult());

Erstellen Sie eine ValueTransfer-Transaktion und signieren Sie sie mit dercaver.wallet.sign Funktion. Die Transaktion wird ans Netzwerk gesendet durch Aufruf von caver.rpc.klay.sendRawTransaction. Den Transaktionsstatus können Sie abrufen mit dem ausgegebenen Hash.

In diesem Post haben wir Ihnen gezeigt, wie man einen Kontoschlüssel auf AccountKeyWeightedMultiSig updaten kann. Wir hoffen, dass alles leicht verständlich war!

Im nächsten Post geht es um das Update auf AccountKeyRoleBased. Der Vorgang ist diesem sehr ähnlich, nur der Schlüsseltyp ist anders. Wenn Sie kein Problem mit diesem Tutorial gehabt haben, wird das Nächste auch ein Kinderspiel!

Danke fürs Lesen und bleiben Sie dran für mehr!

Quellcode aus dem Beitrag:

Bei Fragen wenden Sie sich an unser Developer Forum. 😉

--

--