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

Commit cdf0b3c

Browse files
committed
Implement EIP1191
1 parent a7bfe26 commit cdf0b3c

File tree

2 files changed

+105
-16
lines changed

2 files changed

+105
-16
lines changed

src/account.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,16 @@ export const isZeroAddress = function(address: string): boolean {
3131

3232
/**
3333
* Returns a checksummed address.
34+
*
35+
* If a chainId is provided, the result will be an EIP-1191 checksum. Otherwise, it will be an
36+
* EIP-55 checksum.
3437
*/
35-
export const toChecksumAddress = function(address: string): string {
38+
export const toChecksumAddress = function(address: string, chainId?: number): string {
3639
address = ethjsUtil.stripHexPrefix(address).toLowerCase()
37-
const hash = keccak(address).toString('hex')
40+
41+
const prefix = chainId !== undefined ? chainId.toString() + '0x' : ''
42+
43+
const hash = keccak(prefix + address).toString('hex')
3844
let ret = '0x'
3945

4046
for (let i = 0; i < address.length; i++) {
@@ -50,9 +56,12 @@ export const toChecksumAddress = function(address: string): string {
5056

5157
/**
5258
* Checks if the address is a valid checksummed address.
59+
*
60+
* If a chainId is provided, the address is compared to an EIP-1191 checksum. Otherwise, it will be
61+
* compared to an EIP-55 checksum.
5362
*/
54-
export const isValidChecksumAddress = function(address: string): boolean {
55-
return isValidAddress(address) && toChecksumAddress(address) === address
63+
export const isValidChecksumAddress = function(address: string, chainId?: number): boolean {
64+
return isValidAddress(address) && toChecksumAddress(address, chainId) === address
5665
}
5766

5867
/**

test/index.js

Lines changed: 92 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ describe('isValidSignature', function () {
642642
// FIXME: add homestead test
643643
})
644644

645-
const checksumAddresses = [
645+
const eip55ChecksumAddresses = [
646646
// All caps
647647
'0x52908400098527886E0F7030069857D2E4169EE7',
648648
'0x8617E340B3D01FA5F11F306F4090FD50E238070D',
@@ -656,23 +656,103 @@ const checksumAddresses = [
656656
'0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb'
657657
]
658658

659+
const eip1191ChecksummAddresses = {
660+
1: [
661+
'0x88021160c5C792225E4E5452585947470010289d',
662+
'0x27b1FdB04752bBc536007a920D24ACB045561c26',
663+
'0x52908400098527886e0f7030069857D2e4169EE7',
664+
'0x5aaeB6053f3E94C9b9A09f33669435e7Ef1bEAed',
665+
'0x8617E340b3d01FA5F11F306f4090FD50E238070d',
666+
'0xd1220a0CF47C7B9Be7A2E6ba89F429762E7B9Adb',
667+
'0xdBf03b407c01e7cD3CBea99509d93f8dDDC8C6fB',
668+
'0xDe709F2102306220921060314715629080E2fb77',
669+
'0xfb6916095Ca1dF60bB79cE92ce3ea74C37c5D359',
670+
],
671+
30: [
672+
'0x6549F4939460DE12611948B3F82B88C3C8975323',
673+
'0x27b1FdB04752BBc536007A920D24ACB045561c26',
674+
'0x3599689E6292B81B2D85451025146515070129Bb',
675+
'0x52908400098527886E0F7030069857D2E4169ee7',
676+
'0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD',
677+
'0x8617E340b3D01Fa5f11f306f4090fd50E238070D',
678+
'0xD1220A0Cf47c7B9BE7a2e6ba89F429762E7B9adB',
679+
'0xDBF03B407c01E7CD3cBea99509D93F8Dddc8C6FB',
680+
'0xDe709F2102306220921060314715629080e2FB77',
681+
'0xFb6916095cA1Df60bb79ce92cE3EA74c37c5d359'
682+
],
683+
31: [
684+
'0x42712D45473476B98452F434E72461577D686318',
685+
'0x27B1FdB04752BbC536007a920D24acB045561C26',
686+
'0x3599689e6292b81b2D85451025146515070129Bb',
687+
'0x52908400098527886E0F7030069857D2e4169EE7',
688+
'0x5aAeb6053F3e94c9b9A09F33669435E7EF1BEaEd',
689+
'0x66f9664F97F2b50f62d13eA064982F936DE76657',
690+
'0x8617e340b3D01fa5F11f306F4090Fd50e238070d',
691+
'0xDE709F2102306220921060314715629080e2Fb77',
692+
'0xFb6916095CA1dF60bb79CE92ce3Ea74C37c5D359',
693+
'0xd1220a0CF47c7B9Be7A2E6Ba89f429762E7b9adB',
694+
'0xdbF03B407C01E7cd3cbEa99509D93f8dDDc8C6fB'
695+
]
696+
}
697+
659698
describe('.toChecksumAddress()', function () {
660-
it('should work', function () {
661-
for (let i = 0; i < checksumAddresses.length; i++) {
662-
let tmp = checksumAddresses[i]
663-
assert.equal(ethUtils.toChecksumAddress(tmp.toLowerCase()), tmp)
664-
}
699+
describe("EIP55", function () {
700+
it('should work', function () {
701+
for (let i = 0; i < eip55ChecksumAddresses.length; i++) {
702+
let tmp = eip55ChecksumAddresses[i]
703+
assert.equal(ethUtils.toChecksumAddress(tmp.toLowerCase()), tmp)
704+
}
705+
})
706+
})
707+
708+
describe("EIP1191", function () {
709+
it('Should encode the example addresses correctly', function () {
710+
for (const [chainId, addresses] of Object.entries(eip1191ChecksummAddresses)) {
711+
for (const addr of addresses) {
712+
assert.equal(ethUtils.toChecksumAddress(addr.toLowerCase(), chainId), addr)
713+
}
714+
}
715+
})
665716
})
666717
})
667718

668719
describe('.isValidChecksumAddress()', function () {
669-
it('should return true', function () {
670-
for (let i = 0; i < checksumAddresses.length; i++) {
671-
assert.equal(ethUtils.isValidChecksumAddress(checksumAddresses[i]), true)
672-
}
720+
describe("EIP55", function () {
721+
it('should return true', function () {
722+
for (let i = 0; i < eip55ChecksumAddresses.length; i++) {
723+
assert.equal(ethUtils.isValidChecksumAddress(eip55ChecksumAddresses[i]), true)
724+
}
725+
})
726+
it('should validate', function () {
727+
assert.equal(ethUtils.isValidChecksumAddress('0x2f015c60e0be116b1f0cd534704db9c92118fb6a'), false)
728+
})
673729
})
674-
it('should validate', function () {
675-
assert.equal(ethUtils.isValidChecksumAddress('0x2f015c60e0be116b1f0cd534704db9c92118fb6a'), false)
730+
731+
describe("EIP1191", function () {
732+
it('Should return true for the example addresses', function () {
733+
for (const [chainId, addresses] of Object.entries(eip1191ChecksummAddresses)) {
734+
for (const addr of addresses) {
735+
assert.equal(ethUtils.isValidChecksumAddress(addr, chainId), true)
736+
}
737+
}
738+
})
739+
740+
it("Should return false for invalid cases", function () {
741+
// If we set the chain id, an EIP55 encoded address should be invalid
742+
for (let i = 0; i < eip55ChecksumAddresses.length; i++) {
743+
assert.equal(ethUtils.isValidChecksumAddress(eip55ChecksumAddresses[i], 1), false)
744+
}
745+
746+
assert.equal(ethUtils.isValidChecksumAddress('0x2f015c60e0be116b1f0cd534704db9c92118fb6a', 1), false)
747+
})
748+
749+
it("Should return false if the wrong chain id is used", function () {
750+
for (const [chainId, addresses] of Object.entries(eip1191ChecksummAddresses)) {
751+
for (const addr of addresses) {
752+
assert.equal(ethUtils.isValidChecksumAddress(addr, chainId + 1), false)
753+
}
754+
}
755+
})
676756
})
677757
})
678758

0 commit comments

Comments
 (0)