Skip to content
This repository was archived by the owner on Jun 17, 2021. It is now read-only.

Commit c0798ed

Browse files
authored
Merge pull request #277 from ethereumjs/tobuffer-improvements
Add `toBuffer()` method to Address, make `toBuffer()` function convert TransformableToBuffer
2 parents c5dca47 + 45512f8 commit c0798ed

File tree

6 files changed

+98
-29
lines changed

6 files changed

+98
-29
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ A new file with helpful TypeScript types has been added to the exports of this p
3939

4040
In this release it contains `BNLike`, `BufferLike`, and `TransformableToBuffer`.
4141

42+
### Address.toBuffer()
43+
44+
The Address class has as a new method `address.toBuffer()` that will give you a copy of the underlying `address.buf`.
45+
46+
### `toBuffer()` now converts TransformableToBuffer
47+
48+
The `toBuffer()` exported function now additionally converts any object with a `toBuffer()` method.
49+
4250
## [7.0.5] - 2020-09-09
4351

4452
This release adds a new module `address` - see [README](https://github.com/ethereumjs/ethereumjs-util#modules) -

src/address.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,11 @@ export class Address {
8888
toString(): string {
8989
return '0x' + this.buf.toString('hex')
9090
}
91+
92+
/**
93+
* Returns Buffer representation of address.
94+
*/
95+
toBuffer(): Buffer {
96+
return Buffer.from(this.buf)
97+
}
9198
}

src/bytes.ts

Lines changed: 56 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import * as ethjsUtil from 'ethjs-util'
21
import * as BN from 'bn.js'
2+
import { intToBuffer, stripHexPrefix, padToEven, isHexString, isHexPrefixed } from 'ethjs-util'
3+
import { TransformableToArray, TransformableToBuffer } from './types'
34
import { assertIsBuffer, assertIsArray, assertIsHexString } from './helpers'
45

56
/**
@@ -86,7 +87,7 @@ export const unpadArray = function(a: number[]): number[] {
8687
*/
8788
export const unpadHexString = function(a: string): string {
8889
assertIsHexString(a)
89-
a = ethjsUtil.stripHexPrefix(a)
90+
a = stripHexPrefix(a)
9091
return stripZeros(a) as string
9192
}
9293

@@ -105,35 +106,62 @@ const stripZeros = function(a: any): Buffer | number[] | string {
105106
}
106107

107108
/**
108-
* Attempts to turn a value into a `Buffer`. As input it supports `Buffer`, `String`, `Number`, null/undefined, `BN` and other objects with a `toArray()` method.
109+
* Attempts to turn a value into a `Buffer`.
110+
* Inputs supported: `Buffer`, `String`, `Number`, null/undefined, `BN` and other objects with a `toArray()` or `toBuffer()` method.
109111
* @param v the value
110112
*/
111-
export const toBuffer = function(v: any): Buffer {
112-
if (!Buffer.isBuffer(v)) {
113-
if (Array.isArray(v) || v instanceof Uint8Array) {
114-
v = Buffer.from(v as Uint8Array)
115-
} else if (typeof v === 'string') {
116-
if (ethjsUtil.isHexString(v)) {
117-
v = Buffer.from(ethjsUtil.padToEven(ethjsUtil.stripHexPrefix(v)), 'hex')
118-
} else {
119-
throw new Error(
120-
`Cannot convert string to buffer. toBuffer only supports 0x-prefixed hex strings and this string was given: ${v}`,
121-
)
122-
}
123-
} else if (typeof v === 'number') {
124-
v = ethjsUtil.intToBuffer(v)
125-
} else if (v === null || v === undefined) {
126-
v = Buffer.allocUnsafe(0)
127-
} else if (BN.isBN(v)) {
128-
v = v.toArrayLike(Buffer)
129-
} else if (v.toArray) {
130-
// converts a BN to a Buffer
131-
v = Buffer.from(v.toArray())
132-
} else {
133-
throw new Error('invalid type')
113+
export const toBuffer = function(
114+
v:
115+
| string
116+
| number
117+
| BN
118+
| Buffer
119+
| Uint8Array
120+
| number[]
121+
| TransformableToArray
122+
| TransformableToBuffer
123+
| null
124+
| undefined,
125+
): Buffer {
126+
if (v === null || v === undefined) {
127+
return Buffer.allocUnsafe(0)
128+
}
129+
130+
if (Buffer.isBuffer(v)) {
131+
return Buffer.from(v)
132+
}
133+
134+
if (Array.isArray(v) || v instanceof Uint8Array) {
135+
return Buffer.from(v as Uint8Array)
136+
}
137+
138+
if (typeof v === 'string') {
139+
if (!isHexString(v)) {
140+
throw new Error(
141+
`Cannot convert string to buffer. toBuffer only supports 0x-prefixed hex strings and this string was given: ${v}`,
142+
)
134143
}
144+
return Buffer.from(padToEven(stripHexPrefix(v)), 'hex')
145+
}
146+
147+
if (typeof v === 'number') {
148+
return intToBuffer(v)
135149
}
136-
return v
150+
151+
if (BN.isBN(v)) {
152+
return v.toArrayLike(Buffer)
153+
}
154+
155+
if (v.toArray) {
156+
// converts a BN to a Buffer
157+
return Buffer.from(v.toArray())
158+
}
159+
160+
if (v.toBuffer) {
161+
return Buffer.from(v.toBuffer())
162+
}
163+
164+
throw new Error('invalid type')
137165
}
138166

139167
/**
@@ -178,7 +206,7 @@ export const addHexPrefix = function(str: string): string {
178206
return str
179207
}
180208

181-
return ethjsUtil.isHexPrefixed(str) ? str : '0x' + str
209+
return isHexPrefixed(str) ? str : '0x' + str
182210
}
183211

184212
/**

src/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,20 @@ export type BufferLike =
2323
*/
2424
export type PrefixedHexString = string
2525

26+
/*
27+
* A type that represents an object that has a `toArray()` method.
28+
*/
29+
export interface TransformableToArray {
30+
toArray(): Uint8Array
31+
toBuffer?(): Buffer
32+
}
33+
2634
/*
2735
* A type that represents an object that has a `toBuffer()` method.
2836
*/
2937
export interface TransformableToBuffer {
3038
toBuffer(): Buffer
39+
toArray?(): Uint8Array
3140
}
3241

3342
/**

test/address.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,12 @@ describe('Address', () => {
7676
assert.equal(addr.toString(), result)
7777
}
7878
})
79+
80+
it('should provide a buffer that does not mutate the original address', () => {
81+
const str = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a'
82+
const address = Address.fromString(str)
83+
const addressBuf = address.toBuffer()
84+
addressBuf.fill(0)
85+
assert.equal(address.toString(), str)
86+
})
7987
})

test/bytes.spec.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as assert from 'assert'
22
import * as BN from 'bn.js'
33
import {
4+
Address,
45
zeros,
56
zeroAddress,
67
isZeroAddress,
@@ -215,7 +216,7 @@ describe('toBuffer', function() {
215216
// 'toArray'
216217
assert.deepEqual(
217218
toBuffer({
218-
toArray: function() {
219+
toArray: function(): any {
219220
return [1]
220221
},
221222
}),
@@ -224,6 +225,7 @@ describe('toBuffer', function() {
224225
})
225226
it('should fail', function() {
226227
assert.throws(function() {
228+
// @ts-ignore
227229
toBuffer({ test: 1 })
228230
})
229231
})
@@ -233,6 +235,13 @@ describe('toBuffer', function() {
233235
assert.throws(() => toBuffer(''))
234236
assert.throws(() => toBuffer('0xR'), '0xR')
235237
})
238+
239+
it('should convert a TransformableToBuffer like the Address class (i.e. provides a toBuffer method)', function() {
240+
const str = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a'
241+
const address = Address.fromString(str)
242+
const addressBuf = toBuffer(address)
243+
assert.ok(addressBuf.equals(address.toBuffer()))
244+
})
236245
})
237246

238247
describe('baToJSON', function() {

0 commit comments

Comments
 (0)