From e5ecc5479e6a145273ccde12777aa48c4764df81 Mon Sep 17 00:00:00 2001 From: h0ngcha0 Date: Wed, 11 Sep 2024 13:53:48 +0200 Subject: [PATCH] Address comments --- packages/web3/src/address/address.ts | 21 ++++++++---- packages/web3/src/signer/tx-builder.ts | 7 ++-- packages/web3/src/transaction/utils.test.ts | 17 +++++---- packages/web3/src/transaction/utils.ts | 8 ++++- packages/web3/src/utils/group.ts | 38 --------------------- packages/web3/src/utils/index.ts | 1 - packages/web3/src/utils/utils.ts | 8 +++++ 7 files changed, 45 insertions(+), 55 deletions(-) delete mode 100644 packages/web3/src/utils/group.ts diff --git a/packages/web3/src/address/address.ts b/packages/web3/src/address/address.ts index 959c43f2e..d35380dd1 100644 --- a/packages/web3/src/address/address.ts +++ b/packages/web3/src/address/address.ts @@ -21,11 +21,12 @@ import BN from 'bn.js' import { TOTAL_NUMBER_OF_GROUPS } from '../constants' import blake from 'blakejs' import bs58 from '../utils/bs58' -import { binToHex, concatBytes, groupFromBytes, hexToBinUnsafe, isHexString } from '../utils' +import { binToHex, concatBytes, hexToBinUnsafe, isHexString, xorByte } from '../utils' import { KeyType } from '../signer' import { P2MPKH, lockupScriptCodec } from '../codec/lockup-script-codec' import { i32Codec } from '../codec' import { LockupScript } from '../codec/lockup-script-codec' +import djb2 from '../utils/djb2' const ec = new EC('secp256k1') const PublicKeyHashSize = 32 @@ -114,17 +115,17 @@ export function groupOfAddress(address: string): number { // Pay to public key hash address function groupOfP2pkhAddress(address: Uint8Array): number { - return groupFromBytes(address) + return groupFromBytesForAssetAddress(address) } // Pay to multiple public key hash address function groupOfP2mpkhAddress(address: Uint8Array): number { - return groupFromBytes(address.slice(1, 33)) + return groupFromBytesForAssetAddress(address.slice(1, 33)) } // Pay to script hash address function groupOfP2shAddress(address: Uint8Array): number { - return groupFromBytes(address) + return groupFromBytesForAssetAddress(address) } export function contractIdFromAddress(address: string): Uint8Array { @@ -220,14 +221,20 @@ export function subContractId(parentContractId: string, pathInHex: string, group export function groupOfLockupScript(lockupScript: LockupScript): number { if (lockupScript.kind === 'P2PKH') { - return groupFromBytes(lockupScript.value) + return groupFromBytesForAssetAddress(lockupScript.value) } else if (lockupScript.kind === 'P2MPKH') { - return groupFromBytes(lockupScript.value.publicKeyHashes[0]) + return groupFromBytesForAssetAddress(lockupScript.value.publicKeyHashes[0]) } else if (lockupScript.kind === 'P2SH') { - return groupFromBytes(lockupScript.value) + return groupFromBytesForAssetAddress(lockupScript.value) } else { // P2C const contractId = lockupScript.value return contractId[`${contractId.length - 1}`] } } + +function groupFromBytesForAssetAddress(bytes: Uint8Array): number { + const hint = djb2(bytes) | 1 + const hash = xorByte(hint) + return hash % TOTAL_NUMBER_OF_GROUPS +} diff --git a/packages/web3/src/signer/tx-builder.ts b/packages/web3/src/signer/tx-builder.ts index 9e59698a7..7bc938457 100644 --- a/packages/web3/src/signer/tx-builder.ts +++ b/packages/web3/src/signer/tx-builder.ts @@ -34,6 +34,7 @@ import { } from './types' import { unsignedTxCodec, UnsignedTxCodec } from '../codec' import { groupIndexOfTransaction } from '../transaction' +import { blakeHash } from '../codec/hash' export abstract class TransactionBuilder { abstract get nodeProvider(): NodeProvider @@ -116,13 +117,15 @@ export abstract class TransactionBuilder { } buildUnsignedTx(params: SignUnsignedTxParams): Omit { - const decoded = unsignedTxCodec.decode(hexToBinUnsafe(params.unsignedTx)) + const unsignedTxBin = hexToBinUnsafe(params.unsignedTx) + const decoded = unsignedTxCodec.decode(unsignedTxBin) + const txId = binToHex(blakeHash(unsignedTxBin)) const [fromGroup, toGroup] = groupIndexOfTransaction(decoded) return { fromGroup: fromGroup, toGroup: toGroup, unsignedTx: params.unsignedTx, - txId: UnsignedTxCodec.txId(decoded), + txId: txId, gasAmount: decoded.gasAmount, gasPrice: decoded.gasPrice } diff --git a/packages/web3/src/transaction/utils.test.ts b/packages/web3/src/transaction/utils.test.ts index 53412541d..78625b9e3 100644 --- a/packages/web3/src/transaction/utils.test.ts +++ b/packages/web3/src/transaction/utils.test.ts @@ -16,9 +16,9 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ -import { getSigners } from '@alephium/web3-test' +import { getSigner, getSigners } from '@alephium/web3-test' import { groupIndexOfTransaction } from './utils' -import { ONE_ALPH } from '../constants' +import { ONE_ALPH, TOTAL_NUMBER_OF_GROUPS } from '../constants' import { bs58, hexToBinUnsafe } from '../utils' import { unsignedTxCodec } from '../codec' import { groupOfAddress } from '../address' @@ -32,7 +32,8 @@ describe('transaction utils', () => { }) it('should calculate the group of transfer transaction', async () => { - const [signer1, signer2] = await getSigners(2) + const signer1 = await getSigner(undefined, randomGroup()) + const signer2 = await getSigner(undefined, randomGroup()) const fromAccount = await signer1.getSelectedAccount() const toAccount = await signer2.getSelectedAccount() @@ -50,7 +51,7 @@ describe('transaction utils', () => { it('should calculate the group of multisig transaction', async () => { const nodeProvider = web3.getCurrentNodeProvider() - const [signer1, signer2, signer3] = await getSigners(3) + const [signer1, signer2, signer3] = await getSigners(3, undefined, randomGroup()) const pkh1 = toPublicKeyHash(signer1.publicKey) const pkh2 = toPublicKeyHash(signer2.publicKey) const pkh3 = toPublicKeyHash(signer3.publicKey) @@ -86,8 +87,8 @@ describe('transaction utils', () => { it('should calculate the group of p2sh transaction', async () => { const nodeProvider = web3.getCurrentNodeProvider() - const [signer1] = await getSigners(2) - const schnorrSigner = PrivateKeyWallet.Random(undefined, nodeProvider, 'bip340-schnorr') + const signer1 = await getSigner(undefined, randomGroup()) + const schnorrSigner = PrivateKeyWallet.Random(randomGroup(), nodeProvider, 'bip340-schnorr') const fromAccount = await signer1.getSelectedAccount() { @@ -123,4 +124,8 @@ describe('transaction utils', () => { function toPublicKeyHash(publicKey: string): Uint8Array { return blake2b(hexToBinUnsafe(publicKey), undefined, 32) } + + function randomGroup(): number { + return Math.floor(Math.random() * TOTAL_NUMBER_OF_GROUPS) + } }) diff --git a/packages/web3/src/transaction/utils.ts b/packages/web3/src/transaction/utils.ts index eea712b99..b48f0f5cb 100644 --- a/packages/web3/src/transaction/utils.ts +++ b/packages/web3/src/transaction/utils.ts @@ -19,8 +19,9 @@ along with the library. If not, see . import { groupOfLockupScript } from '../address' import { node } from '../api' import { UnsignedTx } from '../codec' +import { TOTAL_NUMBER_OF_GROUPS } from '../constants' import { getCurrentNodeProvider } from '../global' -import { groupFromHint } from '../utils' +import { xorByte } from '../utils' function isConfirmed(txStatus: node.TxStatus): txStatus is node.Confirmed { return txStatus.type === 'Confirmed' @@ -56,3 +57,8 @@ export function groupIndexOfTransaction(unsignedTx: UnsignedTx): [number, number return [fromGroup, toGroup] } + +function groupFromHint(hint: number): number { + const hash = xorByte(hint) + return hash % TOTAL_NUMBER_OF_GROUPS +} diff --git a/packages/web3/src/utils/group.ts b/packages/web3/src/utils/group.ts deleted file mode 100644 index 93e829258..000000000 --- a/packages/web3/src/utils/group.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2018 - 2022 The Alephium Authors -This file is part of the alephium project. - -The library is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -The library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with the library. If not, see . -*/ - -import { TOTAL_NUMBER_OF_GROUPS } from '../constants' -import djb2 from './djb2' - -export function groupFromBytes(bytes: Uint8Array): number { - const hint = djb2(bytes) | 1 - return groupFromHint(hint) -} - -export function groupFromHint(hint: number): number { - const hash = xorByte(hint) - return hash % TOTAL_NUMBER_OF_GROUPS -} - -export function xorByte(intValue: number): number { - const byte0 = (intValue >> 24) & 0xff - const byte1 = (intValue >> 16) & 0xff - const byte2 = (intValue >> 8) & 0xff - const byte3 = intValue & 0xff - return (byte0 ^ byte1 ^ byte2 ^ byte3) & 0xff -} diff --git a/packages/web3/src/utils/index.ts b/packages/web3/src/utils/index.ts index 3bd439417..326cf0b1a 100644 --- a/packages/web3/src/utils/index.ts +++ b/packages/web3/src/utils/index.ts @@ -23,4 +23,3 @@ export * from './utils' export * from './subscription' export * from './sign' export * from './number' -export * from './group' diff --git a/packages/web3/src/utils/utils.ts b/packages/web3/src/utils/utils.ts index dacab051d..cea0652f3 100644 --- a/packages/web3/src/utils/utils.ts +++ b/packages/web3/src/utils/utils.ts @@ -156,6 +156,14 @@ export function concatBytes(arrays: Uint8Array[]): Uint8Array { return result } +export function xorByte(intValue: number): number { + const byte0 = (intValue >> 24) & 0xff + const byte1 = (intValue >> 16) & 0xff + const byte2 = (intValue >> 8) & 0xff + const byte3 = intValue & 0xff + return (byte0 ^ byte1 ^ byte2 ^ byte3) & 0xff +} + type _Eq = (() => T extends X ? 1 : 2) extends () => T extends Y ? 1 : 2 ? true : false export type Eq = _Eq<{ [P in keyof X]: X[P] }, { [P in keyof Y]: Y[P] }> // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars