Skip to content

Commit

Permalink
Merge pull request #309 from nervosnetwork/develop
Browse files Browse the repository at this point in the history
[ᚬrc/v0.17.0] update address format
  • Loading branch information
Keith-CY authored Jul 25, 2019
2 parents a15c25c + 6dd46f9 commit 8a79273
Show file tree
Hide file tree
Showing 6 changed files with 904 additions and 685 deletions.
14 changes: 7 additions & 7 deletions packages/ckb-sdk-address/__tests__/ckb-sdk-address.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ describe('ckb-sdk-address', () => {
it('generate address with default configuration', () => {
const fixture = {
privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3',
address: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
}
const address = new Address(fixture.privateKey)
expect(address.value).toBe(fixture.address)
Expand All @@ -14,7 +14,7 @@ describe('ckb-sdk-address', () => {
const fixture = {
privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3',
prefix: 'ckt',
address: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
}
const address = new Address(fixture.privateKey, {
prefix: fixture.prefix,
Expand All @@ -26,24 +26,24 @@ describe('ckb-sdk-address', () => {
const fixture = {
privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3',
type: '0x01',
address: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
}
const address = new Address(fixture.privateKey, {
type: fixture.type,
})
expect(address.value).toBe(fixture.address)
})

it('generate address specified type 0x01 and binIdx of P2PH', () => {
it('generate address specified type 0x01 and code hash index of 0x00', () => {
const fixture = {
privateKey: 'e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3',
type: '0x01',
binIdx: 'P2PH',
address: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
codeHashIndex: '0x00',
address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
}
const address = new Address(fixture.privateKey, {
type: fixture.type,
binIdx: fixture.binIdx,
codeHashIndex: fixture.codeHashIndex,
})
expect(address.value).toBe(fixture.address)
})
Expand Down
12 changes: 6 additions & 6 deletions packages/ckb-sdk-address/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import ECPair from '@nervosnetwork/ckb-sdk-utils/lib/ecpair'
import * as utils from '@nervosnetwork/ckb-sdk-utils'
import { AddressOptions } from '@nervosnetwork/ckb-sdk-utils/lib/address'

const { hexToBytes, pubkeyToAddress, blake160, AddressPrefix, AddressType, AddressBinIdx } = utils
const { hexToBytes, pubkeyToAddress, blake160, AddressPrefix, AddressType } = utils

class Address extends ECPair {
public value = ''
Expand All @@ -14,24 +14,24 @@ class Address extends ECPair {
{
addressAlgorithm = pubkeyToAddress,
prefix = AddressPrefix.Testnet,
type = AddressType.BinIdx,
binIdx = AddressBinIdx.P2PH,
type = AddressType.HashIdx,
codeHashIndex = '0x00',
}: Partial<
{
addressAlgorithm: Function
} & AddressOptions
> = {
addressAlgorithm: pubkeyToAddress,
prefix: AddressPrefix.Testnet,
type: AddressType.BinIdx,
binIdx: AddressBinIdx.P2PH,
type: AddressType.HashIdx,
codeHashIndex: '0x00',
}
) {
super(typeof sk === 'string' ? hexToBytes(sk) : sk)
this.value = addressAlgorithm(this.publicKey, {
prefix,
type,
binIdx,
codeHashIndex,
})
this.identifier = blake160(this.publicKey as string, 'hex')
}
Expand Down
8 changes: 4 additions & 4 deletions packages/ckb-sdk-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,16 @@ class Core {

public generateAddress = (
privateKey: string,
{ prefix = utils.AddressPrefix.Testnet, type = utils.AddressType.BinIdx, binIdx = utils.AddressBinIdx.P2PH } = {
{ prefix = utils.AddressPrefix.Testnet, type = utils.AddressType.HashIdx, codeHashIndex = '0x00' } = {
prefix: utils.AddressPrefix.Testnet,
type: utils.AddressType.BinIdx,
binIdx: utils.AddressBinIdx.P2PH,
type: utils.AddressType.HashIdx,
codeHashIndex: '0x00',
}
) =>
new Address(privateKey, {
prefix,
type,
binIdx,
codeHashIndex,
})

public loadSystemCell = async () => {
Expand Down
28 changes: 14 additions & 14 deletions packages/ckb-sdk-utils/__tests__/ckb-utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ describe('address', () => {
it('identifier to address payload', () => {
const fixture = {
identifier: '36c329ed630d6ce750712a477543672adab57f4c',
payload: '015032504836c329ed630d6ce750712a477543672adab57f4c',
payload: '010036c329ed630d6ce750712a477543672adab57f4c',
}
const payload = bytesToHex(toAddressPayload(fixture.identifier))
expect(payload).toBe(fixture.payload)
Expand All @@ -180,7 +180,7 @@ describe('address', () => {
const fixture = {
identifier: '36c329ed630d6ce750712a477543672adab57f4c',
prefix: 'ckt',
address: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
}
const address = bech32Address(fixture.identifier, {
prefix: fixture.prefix,
Expand All @@ -192,7 +192,7 @@ describe('address', () => {
const fixture = {
identifier: '36c329ed630d6ce750712a477543672adab57f4c',
prefix: 'ckb',
address: 'ckb1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6vqdd7em',
address: 'ckb1qyqrdsefa43s6m882pcj53m4gdnj4k440axqdt9rtd',
}
const address = bech32Address(fixture.identifier, {
prefix: fixture.prefix,
Expand All @@ -203,16 +203,16 @@ describe('address', () => {
it('bech32Address with empty options', () => {
const fixture = {
identifier: '36c329ed630d6ce750712a477543672adab57f4c',
address: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
}
const address = bech32Address(fixture.identifier, {})
expect(address).toBe(fixture.address)
})

it('bech32Address with default options which should be prefix: ckb, type: binIndx, binIdx: P2PH', () => {
it('bech32Address with default options which should be prefix: ckb, type: binIndx, code hash index: 0x00', () => {
const fixture = {
identifier: '36c329ed630d6ce750712a477543672adab57f4c',
address: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
}
const address = bech32Address(fixture.identifier)
expect(address).toBe(fixture.address)
Expand All @@ -224,17 +224,17 @@ describe('address', () => {
config: {
prefix: 'ckt',
},
address: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
},
'with empty configuration': {
pubkey: '024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01',
config: {},
address: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
},
'with undefined configuration': {
pubkey: '024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01',
config: undefined,
address: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
},
}
test.each(Object.keys(pubkeyToAddressFixtures))('%s', caseName => {
Expand All @@ -245,9 +245,9 @@ describe('address', () => {

it('parse address', () => {
const fixture = {
addr: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
addr: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
prefix: 'ckt',
hrp: `01${Buffer.from('P2PH').toString('hex')}`,
hrp: '0100',
blake160Pubkey: '36c329ed630d6ce750712a477543672adab57f4c',
}
const parsedHex = parseAddress(fixture.addr, fixture.prefix, 'hex')
Expand All @@ -258,9 +258,9 @@ describe('address', () => {

it('parse address with default options prefix: ckt, encode: binary', () => {
const fixture = {
addr: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
addr: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
prefix: 'ckt',
hrp: `01${Buffer.from('P2PH').toString('hex')}`,
hrp: '0100',
blake160Pubkey: '36c329ed630d6ce750712a477543672adab57f4c',
}
const parsedHex = bytesToHex(parseAddress(fixture.addr))
Expand All @@ -271,7 +271,7 @@ describe('address', () => {

it('parser incorrect address', () => {
const fixture = {
addr: 'ckt1q9gry5zgxmpjnmtrp4kww5r39frh2sm89tdt2l6v234ygf',
addr: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83',
incorrectPrefix: 'ckb',
}
expect(() => parseAddress(fixture.addr, fixture.incorrectPrefix)).toThrow('Prefix not matched')
Expand Down
36 changes: 17 additions & 19 deletions packages/ckb-sdk-utils/src/address/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { bech32, blake160, hexToBytes, bytesToHex, utf8ToBytes } from '..'
import { bech32, blake160, hexToBytes, bytesToHex } from '..'

export enum AddressPrefix {
Mainnet = 'ckb',
Expand All @@ -7,62 +7,60 @@ export enum AddressPrefix {

export enum AddressType {
BinHash = '0x00',
BinIdx = '0x01',
HashIdx = '0x01',
}

export enum AddressBinIdx {
P2PH = 'P2PH',
}
export type CodeHashIndex = '0x00' | string

export interface AddressOptions {
prefix: AddressPrefix
type: AddressType
binIdx: AddressBinIdx
codeHashIndex: CodeHashIndex
}

export const defaultAddressOptions = {
prefix: AddressPrefix.Testnet,
type: AddressType.BinIdx,
binIdx: AddressBinIdx.P2PH,
type: AddressType.HashIdx,
codeHashIndex: '0x00',
}

/**
* @description payload = type(01) | bin-idx("P2PH" => "50|32|50|40") | blake160-formatted pubkey
* @description payload = type(01) | code hash index(00) | blake160-formatted pubkey
* @see https://github.com/nervosnetwork/ckb/wiki/Common-Address-Format
*/
export const toAddressPayload = (
identifier: string | Uint8Array,
type: AddressType = AddressType.BinIdx,
params: AddressBinIdx = AddressBinIdx.P2PH
type: AddressType = AddressType.HashIdx,
params: CodeHashIndex = '0x00'
): Uint8Array => {
if (typeof identifier === 'string') {
return new Uint8Array([...hexToBytes(type), ...utf8ToBytes(params), ...hexToBytes(identifier)])
return new Uint8Array([...hexToBytes(type), ...hexToBytes(params), ...hexToBytes(identifier)])
}
return new Uint8Array([...hexToBytes(type), ...utf8ToBytes(params), ...identifier])
return new Uint8Array([...hexToBytes(type), ...hexToBytes(params), ...identifier])
}

export const bech32Address = (
identifier: Uint8Array | string,
{
prefix = AddressPrefix.Testnet,
type = AddressType.BinIdx,
binIdx = AddressBinIdx.P2PH,
type = AddressType.HashIdx,
codeHashIndex = '0x00',
}: AddressOptions = defaultAddressOptions
) => bech32.encode(prefix, bech32.toWords(toAddressPayload(identifier, type, binIdx)))
) => bech32.encode(prefix, bech32.toWords(toAddressPayload(identifier, type, codeHashIndex)))

export const pubkeyToAddress = (
pubkey: Uint8Array | string,
{
prefix = AddressPrefix.Testnet,
type = AddressType.BinIdx,
binIdx = AddressBinIdx.P2PH,
type = AddressType.HashIdx,
codeHashIndex = '0x00' as CodeHashIndex,
}: AddressOptions = defaultAddressOptions
) => {
const identifier = blake160(pubkey)
return bech32Address(identifier, {
prefix,
type,
binIdx,
codeHashIndex,
})
}

Expand Down
Loading

0 comments on commit 8a79273

Please sign in to comment.