Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 18 additions & 26 deletions Sources/web3swift/Convenience/Base58.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ struct Base58 {
}

for b in base58 {
// str = "\(str)\(base58Alphabet[String.Index(encodedOffset: Int(b))])"
str = "\(str)\(base58Alphabet[String.Index(utf16Offset: Int(b), in: base58Alphabet)])"
}

Expand All @@ -67,23 +66,27 @@ struct Base58 {
static func bytesFromBase58(_ base58: String) -> [UInt8] {
// remove leading and trailing whitespaces
let string = base58.trimmingCharacters(in: CharacterSet.whitespaces)

guard !string.isEmpty else { return [] }

var zerosCount = 0
var length = 0
// count leading ASCII "1"'s [decodes directly to binary zero bytes]
var leadingZeros = 0
for c in string {
if c != "1" { break }
zerosCount += 1
leadingZeros += 1
}

let size = string.lengthOfBytes(using: String.Encoding.utf8) * 733 / 1000 + 1 - zerosCount
var base58: [UInt8] = Array(repeating: 0, count: size)
// calculate the size of the decoded output, rounded up
let size = (string.lengthOfBytes(using: String.Encoding.utf8) - leadingZeros) * 733 / 1000 + 1

// allocate a buffer large enough for the decoded output
var base58: [UInt8] = Array(repeating: 0, count: size + leadingZeros)

// decode what remains of the data
var length = 0
for c in string where c != " " {
// search for base58 character
guard let base58Index = base58Alphabet.index(of: c) else { return [] }
guard let base58Index = base58Alphabet.firstIndex(of: c) else { return [] }

// var carry = base58Index.encodedOffset
var carry = base58Index.utf16Offset(in: base58Alphabet)
var i = 0
for j in 0...base58.count where carry != 0 || i < length {
Expand All @@ -97,20 +100,16 @@ struct Base58 {
length = i
}

// skip leading zeros
var zerosToRemove = 0

// calculate how many leading zero bytes we have
var totalZeros = 0
for b in base58 {
if b != 0 { break }
zerosToRemove += 1
totalZeros += 1
}
base58.removeFirst(zerosToRemove)
// remove the excess zero bytes
base58.removeFirst(totalZeros - leadingZeros)

var result: [UInt8] = Array(repeating: 0, count: zerosCount)
for b in base58 {
result.append(b)
}
return result
return base58
}
}

Expand Down Expand Up @@ -158,11 +157,4 @@ extension String {
return bytes
}

// public var littleEndianHexToUInt: UInt {
// let data = Data.fromHex(self)!
// let revensed =
// return UInt(sel)
// return UInt(self.dataWithHexString().bytes.reversed().fullHexString, radix: 16)!
// }

}
102 changes: 102 additions & 0 deletions Tests/web3swiftTests/localTests/DataConversionTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Package: web3swift
// Created by Alex Vlasov.
// Copyright © 2018 Alex Vlasov. All rights reserved.
//
// Base58 tests by Mark Loit 2022
//

import XCTest

@testable import web3swift

//
// This Test suite is intended to hold various tests for our data conversion code
// that don't seem to fit elsewhere
//

// Some base58 test vectors pulled from: https://tools.ietf.org/id/draft-msporny-base58-01.html
// note that one of the return values is incorrect in the reference above, it is corrected here
class DataConversionTests: XCTestCase {
// test an empty input for the base58 decoder & decoder
func testBase58() throws {
let vector = ""

print("Testing Base58 Decode \"\(vector)\"")
guard let resultDecoded = vector.base58DecodedData else { return XCTFail("base58 decode unexpectedly returned nil") }
XCTAssert(resultDecoded.count == 0)

print("Testing Base58 Encode \"\(vector)\"")
let resultEncoded1 = vector.base58EncodedString
XCTAssert(resultEncoded1 == vector)

print("Testing Base58 Encode [empty]")
let arr = resultDecoded.withUnsafeBytes { Array($0) }
let resultEncoded2 = arr.base58EncodedString
XCTAssert(resultEncoded2 == vector)
}

// test a reference string "Hello World!"
func testBase58HelloWorld() throws {
let vector = "2NEpo7TZRRrLZSi2U"
let expected = "Hello World!"

print("Testing Base58 Decode \"\(vector)\"")
guard let resultDecoded = vector.base58DecodedData else { return XCTFail("base58 decode unexpectedly returned nil") }
let arr = resultDecoded.withUnsafeBytes { Array($0) }
let str = String(bytes: arr, encoding: .utf8)
XCTAssert(str == expected)

print("Testing Base58 Encode \"\(expected)\"")
let resultEncoded = expected.base58EncodedString
XCTAssert(resultEncoded == vector)
}

// test a reference string "The quick brown fox jumps over the lazy dog."
func testBase58LazyFox() throws {
let vector = "USm3fpXnKG5EUBx2ndxBDMPVciP5hGey2Jh4NDv6gmeo1LkMeiKrLJUUBk6Z"
let expected = "The quick brown fox jumps over the lazy dog."

print("Testing Base58 Decode \"\( vector )\"")
guard let resultDecoded = vector.base58DecodedData else { return XCTFail("base58 decode unexpectedly returned nil") }
let arr = resultDecoded.withUnsafeBytes { Array($0) }
let str = String(bytes: arr, encoding: .utf8)
XCTAssert(str == expected)

print("Testing Base58 Encode \"\(expected)\"")
let resultEncoded = expected.base58EncodedString
XCTAssert(resultEncoded == vector)
}

// test a reference binary value "0x000000287fb4cd" (tested as a hex string to validate length) **corrected from ref document
func testBase58HexData() throws {
let vector = "111233QC4"
let expected = "0x000000287fb4cd"

print("Testing Base58 Decode \"\(vector)\"")
guard let resultDecoded = vector.base58DecodedData else { return XCTFail("base58 decode unexpectedly returned nil") }
let str = resultDecoded.toHexString().addHexPrefix()
XCTAssert(str == expected)

print("Testing Base58 Encode \(expected)")
let arr = resultDecoded.withUnsafeBytes { Array($0) }
let resultEncoded = arr.base58EncodedString
XCTAssert(resultEncoded == vector)
}

// test all zero encoded data from issue 424
func testBase58Zero() throws {
let vector = "11111111111111111111111111111111"
let expected = "0x0000000000000000000000000000000000000000000000000000000000000000"

print("Testing Base58 Decode \"\(vector)\"")
guard let resultDecoded = vector.base58DecodedData else { return XCTFail("base58 decode unexpectedly returned nil") }
let str = resultDecoded.toHexString().addHexPrefix()
XCTAssert(str == expected)

print("Testing Base58 Encode \(expected)")
let arr = resultDecoded.withUnsafeBytes { Array($0) }
let resultEncoded = arr.base58EncodedString
XCTAssert(resultEncoded == vector)
}

}
1 change: 1 addition & 0 deletions Tests/web3swiftTests/remoteTests/RemoteTests.xctestplan
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"testTargets" : [
{
"skippedTests" : [
"DataConversionTests",
"EIP712Tests",
"web3swiftAdvancedABIv2Tests",
"web3swiftBasicLocalNodeTests",
Expand Down
4 changes: 4 additions & 0 deletions web3swift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
5CF7E8BA276B79380009900F /* web3swiftGanacheTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF7E8B5276B79380009900F /* web3swiftGanacheTests.swift */; };
5CF7E8BB276B79380009900F /* web3swiftENSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF7E8B6276B79380009900F /* web3swiftENSTests.swift */; };
5CF7E8BC276B79380009900F /* web3swiftWebsocketTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF7E8B7276B79380009900F /* web3swiftWebsocketTests.swift */; };
604FA4FF27ECBDC80021108F /* DataConversionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604FA4FE27ECBDC80021108F /* DataConversionTests.swift */; };
CB50A52827060BD600D7E39B /* EIP712Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB50A52727060BD600D7E39B /* EIP712Tests.swift */; };
E22A911F241ED71A00EC1021 /* browser.min.js in Resources */ = {isa = PBXBuildFile; fileRef = E22A911E241ED71A00EC1021 /* browser.min.js */; };
E2B76710241ED479007EBFE3 /* browser.js in Resources */ = {isa = PBXBuildFile; fileRef = E2B7670F241ED479007EBFE3 /* browser.js */; };
Expand Down Expand Up @@ -405,6 +406,7 @@
5CF7E8B5276B79380009900F /* web3swiftGanacheTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = web3swiftGanacheTests.swift; sourceTree = "<group>"; };
5CF7E8B6276B79380009900F /* web3swiftENSTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = web3swiftENSTests.swift; sourceTree = "<group>"; };
5CF7E8B7276B79380009900F /* web3swiftWebsocketTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = web3swiftWebsocketTests.swift; sourceTree = "<group>"; };
604FA4FE27ECBDC80021108F /* DataConversionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataConversionTests.swift; sourceTree = "<group>"; };
CB50A52727060BD600D7E39B /* EIP712Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP712Tests.swift; sourceTree = "<group>"; };
CB50A52927060C5300D7E39B /* EIP712.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP712.swift; sourceTree = "<group>"; };
E22A911E241ED71A00EC1021 /* browser.min.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = browser.min.js; sourceTree = "<group>"; };
Expand Down Expand Up @@ -980,6 +982,7 @@
E252E68126B542D000717C16 /* localTests */ = {
isa = PBXGroup;
children = (
604FA4FE27ECBDC80021108F /* DataConversionTests.swift */,
5CF7E8A0276B79290009900F /* web3swiftAdvancedABIv2Tests.swift */,
5CF7E89C276B79280009900F /* web3swiftBasicLocalNodeTests.swift */,
5CF7E8A1276B79290009900F /* web3swiftEIP67Tests.swift */,
Expand Down Expand Up @@ -1384,6 +1387,7 @@
5CF7E8B2276B792A0009900F /* web3swiftEIP67Tests.swift in Sources */,
5CF7E8AE276B792A0009900F /* web3swiftPromisesTests.swift in Sources */,
5CF7E8A2276B79290009900F /* web3swiftEIP681Tests.swift in Sources */,
604FA4FF27ECBDC80021108F /* DataConversionTests.swift in Sources */,
5CF7E8B1276B792A0009900F /* web3swiftAdvancedABIv2Tests.swift in Sources */,
5CF7E8A6276B792A0009900F /* web3swiftHelpers.swift in Sources */,
5CF7E8BA276B79380009900F /* web3swiftGanacheTests.swift in Sources */,
Expand Down