Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
add generateMultiEd25519AccountFromPrivateKey
  • Loading branch information
wk3368 committed Dec 3, 2021
1 parent 2bec926 commit c0f6f68
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 13 deletions.
63 changes: 57 additions & 6 deletions src/utils/account.ts
@@ -1,9 +1,9 @@

import { utils } from '@starcoin/stc-ed25519';
import { addHexPrefix, stripHexPrefix } from 'ethereumjs-util';
import { hexlify } from '@ethersproject/bytes';
import { hexlify, arrayify } from '@ethersproject/bytes';
import { privateKeyToPublicKey, publicKeyToAuthKey, publicKeyToAddress, encodeReceiptIdentifier, bcsEncode } from "../encoding";
import { MultiEd25519KeyShard } from "../lib/runtime/starcoin_types";
import { MultiEd25519KeyShard, Ed25519PublicKey, Ed25519PrivateKey } from "../lib/runtime/starcoin_types";
import { accountType } from "../types";

export function generatePrivateKey(): string {
Expand Down Expand Up @@ -40,19 +40,36 @@ export async function showAccount(privateKey: string): Promise<Record<string, st
};
}

export function showMultiEd25519Account(shard: MultiEd25519KeyShard): Record<string, string> {
export function getMultiEd25519AccountPrivateKey(shard: MultiEd25519KeyShard): string {
const privateKey = hexlify(shard.privateKey())
return privateKey;
}

export function getMultiEd25519AccountPublicKey(shard: MultiEd25519KeyShard): string {
const multiEd25519PublicKey = shard.publicKey()

const publicKey = hexlify(multiEd25519PublicKey.value())
return publicKey;
}

const authKey = publicKeyToAuthKey(publicKey, accountType.MULTI)

export function getMultiEd25519AccountAddress(shard: MultiEd25519KeyShard): string {
const publicKey = getMultiEd25519AccountPublicKey(shard)
const address = publicKeyToAddress(publicKey, accountType.MULTI)
return address;
}

export function getMultiEd25519AccountReceiptIdentifier(shard: MultiEd25519KeyShard): string {
const address = getMultiEd25519AccountAddress(shard)
// same with Rust, receiptIdentifier do not include authKey
const receiptIdentifier = encodeReceiptIdentifier(stripHexPrefix(address))
return receiptIdentifier;
}

export function showMultiEd25519Account(shard: MultiEd25519KeyShard): Record<string, string> {
const privateKey = getMultiEd25519AccountPrivateKey(shard)
const publicKey = getMultiEd25519AccountPublicKey(shard)
const address = getMultiEd25519AccountAddress(shard)
const receiptIdentifier = getMultiEd25519AccountReceiptIdentifier(shard)
const authKey = publicKeyToAuthKey(publicKey, accountType.MULTI)

return {
privateKey,
Expand All @@ -61,4 +78,38 @@ export function showMultiEd25519Account(shard: MultiEd25519KeyShard): Record<str
authKey,
receiptIdentifier
};
}

export function generateMultiEd25519AccountFromPrivateKey(privateKey: string): MultiEd25519KeyShard {
const bytes = arrayify(privateKey)

const publicKeysLengthBytes = bytes.slice(0, 1);
const publicKeysLength = publicKeysLengthBytes[0];

const thresholdBytes = bytes.slice(1, 2);
const threshold = thresholdBytes[0];

const privateKeysLengthBytes = bytes.slice(2, 3);
const privateKeysLength = privateKeysLengthBytes[0];

const publicKeys = []
const privateKeys = []
let start = 3
const length = 32
let end

for (let i = 0; i < publicKeysLength; i += 1) {
end = start + length
const publicKeyBytes = bytes.slice(start, end);
publicKeys.push(new Ed25519PublicKey(publicKeyBytes))
start = end
}
for (let i = 0; i < privateKeysLength; i += 1) {
end = start + length
const privateKeyBytes = bytes.slice(start, end);
privateKeys.push(new Ed25519PrivateKey(privateKeyBytes))
start = end
}
const shard = new MultiEd25519KeyShard(publicKeys, threshold, privateKeys)
return shard;
}
3 changes: 2 additions & 1 deletion src/utils/index.ts
@@ -1,9 +1,10 @@
export * as abi from "./abi";
export * as account from "./account";
export * as errors from "./errors";
export * as helper from "./helper";
export * as hex from "./hex";
export * as parser from './parser';
export * as properties from './properties';
export * as signedMessage from "./signed-message";
export * as multiSign from "./multi-sign";
export * as tx from "./tx";
export * as helper from "./helper";
31 changes: 25 additions & 6 deletions src/utils/multi-sign.spec.ts
Expand Up @@ -18,11 +18,11 @@ import {
} from "./tx";
import { createMultiEd25519KeyShard, signMultiEd25519KeyShard } from "./multi-sign";
import { dec2bin, bin2dec, setBit, isSetBit, dec2uint8array, uint8array2dec } from "./helper";
import { showMultiEd25519Account } from "./account";
import { showMultiEd25519Account, generateMultiEd25519AccountFromPrivateKey } from "./account";
import * as starcoin_types from "../lib/runtime/starcoin_types";

// Implemention of multi sign in https://starcoin.org/zh/developer/cli/multisig_account/
const thresHold = 2;
const threshold = 2;

const alice = {
'address': '0xd597bcfa4d3464b98bea990ce21aca06',
Expand All @@ -42,6 +42,25 @@ const tom = {
'private_key': '0x359059828e89fe42dddd5f9571a0c623b071379fc6287c712649dcc8c77f5eb4'
}

test('import from multiSign account privateKey', async () => {
const publicKeys1 = [bob.public_key, tom.public_key];
const privateKeys1 = [alice.private_key];

const shardAlice = await createMultiEd25519KeyShard(publicKeys1, privateKeys1, threshold)
const multiAccountAlice = showMultiEd25519Account(shardAlice)
console.log({ multiAccountAlice });

const shard = generateMultiEd25519AccountFromPrivateKey(multiAccountAlice.privateKey)
const multiAccount = showMultiEd25519Account(shard)
console.log({ multiAccount });

expect(multiAccount.privateKey).toEqual(multiAccountAlice.privateKey);
expect(multiAccount.publicKey).toEqual(multiAccountAlice.publicKey);
expect(multiAccount.address).toEqual(multiAccountAlice.address);
expect(multiAccount.authKey).toEqual(multiAccountAlice.authKey);
expect(multiAccount.receiptIdentifier).toEqual(multiAccountAlice.receiptIdentifier);
})

test('first multi sign', async () => {


Expand All @@ -51,7 +70,7 @@ test('first multi sign', async () => {
const publicKeys1 = [bob.public_key, tom.public_key];
const privateKeys1 = [alice.private_key];

const shardAlice = await createMultiEd25519KeyShard(publicKeys1, privateKeys1, thresHold)
const shardAlice = await createMultiEd25519KeyShard(publicKeys1, privateKeys1, threshold)
console.log({ shardAlice })
const multiAccountAlice = showMultiEd25519Account(shardAlice)
console.log({ multiAccountAlice });
Expand All @@ -68,7 +87,7 @@ test('first multi sign', async () => {
const publicKeys2 = [alice.public_key, tom.public_key];
const privateKeys2 = [bob.private_key];

const shardBob = await createMultiEd25519KeyShard(publicKeys2, privateKeys2, thresHold)
const shardBob = await createMultiEd25519KeyShard(publicKeys2, privateKeys2, threshold)
console.log({ shardBob })
const multiAccountBob = showMultiEd25519Account(shardBob)
console.log({ multiAccountBob });
Expand All @@ -85,7 +104,7 @@ test('first multi sign', async () => {
const publicKeys3 = [alice.public_key, bob.public_key];
const privateKeys3 = [tom.private_key];

const shardTom = await createMultiEd25519KeyShard(publicKeys3, privateKeys3, thresHold)
const shardTom = await createMultiEd25519KeyShard(publicKeys3, privateKeys3, threshold)
console.log({ shardTom })
const multiAccountTom = showMultiEd25519Account(shardTom)
console.log({ multiAccountTom });
Expand Down Expand Up @@ -264,7 +283,7 @@ test('second multi sign', async () => {
const publicKeys1 = [bob.public_key, tom.public_key];
const privateKeys1 = [alice.private_key];

const shardAlice = await createMultiEd25519KeyShard(publicKeys1, privateKeys1, thresHold)
const shardAlice = await createMultiEd25519KeyShard(publicKeys1, privateKeys1, threshold)
console.log({ shardAlice })
const multiAccountAlice = showMultiEd25519Account(shardAlice)
console.log({ multiAccountAlice });
Expand Down

0 comments on commit c0f6f68

Please sign in to comment.