Skip to content
This repository has been archived by the owner on Dec 15, 2023. It is now read-only.

Commit

Permalink
Merge pull request #171 from zeriontech/170_remote_signing_classes
Browse files Browse the repository at this point in the history
#170 — Implement unsigned and manually signed transaction bytes classes
  • Loading branch information
abdulowork authored Jul 25, 2018
2 parents f8eff9d + e1ffade commit c4f92d5
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// This source file is part of the Web3Swift.io open source project
// Copyright 2018 The Web3Swift Authors
// Licensed under Apache License v2.0
//
// EthManuallySignedTransactionBytesTests.swift
//
// Created by Vadim Koleoshkin on 24/07/2018
//

import Nimble
import Quick
@testable import Web3Swift

class EthManuallySignedTransactionBytesTests: XCTestCase {

func testSignedTransactionIsEncodedCorrectly() {
expect{
return try EthManuallyTransactionBytes(
networkID: SimpleInteger(
integer: 1
),
transactionsCount: EthNumber(
value: 130
),
gasPrice: EthNumber(
hex: "0x04A817C800"
),
gasEstimate: EthNumber(
value: 21000
),
recipientAddress: Alice().address(),
weiAmount: EthNumber(
value: 1
),
contractCall: EmptyBytes(),
r: BytesFromHexString(hex: "4566e88fcc334ce45530cd443177fc943573ef2234188df7e5fb58c93f9f1359"),
s: BytesFromHexString(hex: "13d42bc12afce56c22b16d5208209e20dd3825bb9f4b706d080ac565597063bf"),
v: BytesFromHexString(hex: "26")
).value().toHexString()

}.to(
equal(
"f86581828504a817c80082520894cd8ac90d9cc7e4c03430d58d2f3e87dae70b807e018026a04566e88fcc334ce45530cd443177fc943573ef2234188df7e5fb58c93f9f1359a013d42bc12afce56c22b16d5208209e20dd3825bb9f4b706d080ac565597063bf"
),
description: "The above transaction with a nonce of 130 signed with Bob's key on external device is expected to be correctly signed"
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// This source file is part of the Web3Swift.io open source project
// Copyright 2018 The Web3Swift Authors
// Licensed under Apache License v2.0
//
// EthUnsignedTransactionBytesTests.swift
//
// Created by Vadim Koleoshkin on 24/07/2018
//

import Nimble
import Quick
@testable import Web3Swift

class EthUnsignedTransactionBytesTests: XCTestCase {

func testStaticParametersEncodedCorrectly() {
expect{
return try EthUnsignedTransactionBytes(
networkID: SimpleInteger(
integer: 1
),
transactionsCount: EthNumber(
value: 128
),
gasPrice: EthNumber(
hex: "0x04A817C800"
),
gasEstimate: EthNumber(
value: 21000
),
recipientAddress: Alice().address(),
weiAmount: EthNumber(
hex: "0x01"
),
contractCall: EmptyBytes()
).value().toHexString()
}.to(
equal(
"e581808504a817c80082520894cd8ac90d9cc7e4c03430d58d2f3e87dae70b807e0180018080"
),
description: "Transaction parameters expected to encoded correctly"
)
}
}
40 changes: 8 additions & 32 deletions Example/Web3Swift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@
8C77B9F3203DC77A0097DE61 /* BytesParameterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C77B9F2203DC77A0097DE61 /* BytesParameterTests.swift */; };
8C77B9F5203DC9340097DE61 /* BooleanParameterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C77B9F4203DC9340097DE61 /* BooleanParameterTests.swift */; };
8C77B9F9203DCA220097DE61 /* QuantityParameterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C77B9F8203DCA220097DE61 /* QuantityParameterTests.swift */; };
8C8B79012107B99000F6EC2C /* EthUnsignedTransactionBytesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C8B79002107B99000F6EC2C /* EthUnsignedTransactionBytesTests.swift */; };
8C8B79052107C01400F6EC2C /* EthManuallySignedTransactionBytesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C8B79042107C01400F6EC2C /* EthManuallySignedTransactionBytesTests.swift */; };
8CA4CB6220D6CA6F009AAFA8 /* CompactHexStringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CA4CB6120D6CA6F009AAFA8 /* CompactHexStringTests.swift */; };
94831128426593F56EE4BCAF /* Pods_Web3Swift_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F31007316603078343330134 /* Pods_Web3Swift_Example.framework */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -321,6 +323,8 @@
8C77B9F2203DC77A0097DE61 /* BytesParameterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BytesParameterTests.swift; sourceTree = "<group>"; };
8C77B9F4203DC9340097DE61 /* BooleanParameterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BooleanParameterTests.swift; sourceTree = "<group>"; };
8C77B9F8203DCA220097DE61 /* QuantityParameterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuantityParameterTests.swift; sourceTree = "<group>"; };
8C8B79002107B99000F6EC2C /* EthUnsignedTransactionBytesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthUnsignedTransactionBytesTests.swift; sourceTree = "<group>"; };
8C8B79042107C01400F6EC2C /* EthManuallySignedTransactionBytesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthManuallySignedTransactionBytesTests.swift; sourceTree = "<group>"; };
8CA4CB6120D6CA6F009AAFA8 /* CompactHexStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompactHexStringTests.swift; sourceTree = "<group>"; };
8D3D6BEF8030D59C6F4A15FB /* Pods_Web3Swift_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Web3Swift_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D6D1308587140D3019CBC0F5 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
Expand Down Expand Up @@ -398,6 +402,8 @@
584FADA6E364EE1FB2ACF6D5 /* EthContractCreationBytesTests.swift */,
584FA9D0D639D3F5E5025055 /* ContractDeploymentAndCallIT.swift */,
584FA6D971EE16C708F599D9 /* EthContractCallBytesTests.swift */,
8C8B79002107B99000F6EC2C /* EthUnsignedTransactionBytesTests.swift */,
8C8B79042107C01400F6EC2C /* EthManuallySignedTransactionBytesTests.swift */,
);
path = TransactionBytes;
sourceTree = "<group>";
Expand Down Expand Up @@ -872,7 +878,6 @@
607FACCE1AFB9204008FA782 /* Resources */,
EBB6B6BA4C731E232BDF097E /* [CP] Embed Pods Frameworks */,
96C55DCE203C61A300F7B8B3 /* ShellScript */,
91D0BE6005155AEE45F3403C /* [CP] Copy Pods Resources */,
);
buildRules = (
);
Expand All @@ -893,7 +898,6 @@
607FACE31AFB9204008FA782 /* Resources */,
6614058F101887C8832107D8 /* [CP] Embed Pods Frameworks */,
96C55DCF203C64CF00F7B8B3 /* ShellScript */,
00A6FE7CAB021D6BF234D2EE /* [CP] Copy Pods Resources */,
);
buildRules = (
);
Expand Down Expand Up @@ -966,21 +970,6 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
00A6FE7CAB021D6BF234D2EE /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Web3Swift_Tests/Pods-Web3Swift_Tests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
6614058F101887C8832107D8 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down Expand Up @@ -1029,21 +1018,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
91D0BE6005155AEE45F3403C /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Web3Swift_Example/Pods-Web3Swift_Example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
96C55DCE203C61A300F7B8B3 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down Expand Up @@ -1148,6 +1122,7 @@
584FA538B1B4B38D0AD9D0C9 /* SECP256k1SignatureTests.swift in Sources */,
584FACEC7F5AD9060590ED93 /* URL.swift in Sources */,
584FAC63F128D0FD1C832A17 /* EthPrivateKeyTests.swift in Sources */,
8C8B79052107C01400F6EC2C /* EthManuallySignedTransactionBytesTests.swift in Sources */,
584FA1A012191D2A54C91613 /* BytesFromCompactHexStringTests.swift in Sources */,
584FA7EFE57C0E816D2A22FE /* BytesFromHexStringTests.swift in Sources */,
584FAED8755DD6F0E88C6D04 /* ConcatenatedBytesTests.swift in Sources */,
Expand Down Expand Up @@ -1201,6 +1176,7 @@
584FA5983BEADC204550D6B2 /* EncodedContractTests.swift in Sources */,
584FAA11B99158E23C19D72D /* EthContractCreationBytesTests.swift in Sources */,
584FA7C41200ACF7635B34F4 /* Tim.swift in Sources */,
8C8B79012107B99000F6EC2C /* EthUnsignedTransactionBytesTests.swift in Sources */,
584FAFDCB05D1C67298CA74A /* SimpleActor.swift in Sources */,
584FA659D7E3D235F107B30A /* ContractDeploymentAndCallIT.swift in Sources */,
584FA224DD79A59F68AFCD3E /* ComputedContractAddressTests.swift in Sources */,
Expand Down
90 changes: 90 additions & 0 deletions Web3Swift/TransactionBytes/EthManuallySignedTransactionBytes.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//
// This source file is part of the Web3Swift.io open source project
// Copyright 2018 The Web3Swift Authors
// Licensed under Apache License v2.0
//
// EthManuallySignedTransactionBytes.swift
//
// Created by Vadim Koleoshkin on 24/07/2018
//

import CryptoSwift
import Foundation

/** Remotly signed transaction bytes */
public final class EthManuallyTransactionBytes: BytesScalar {

private let networkID: IntegerScalar
private let transactionsCount: BytesScalar
private let gasPrice: BytesScalar
private let gasEstimate: BytesScalar
private let recipientAddress: BytesScalar
private let weiAmount: BytesScalar
private let contractCall: BytesScalar
private let r: BytesScalar
private let s: BytesScalar
private let v: BytesScalar

/**
Ctor

- parameters:
- networkID: id of a network where the transaction is to be deployed
- transactionsCount: count of all transactions previously sent by the sender
- gasPrice: gas price in Wei
- gasEstimate: estimate for gas needed for transaction to be mined
- recipientAddress: address of a recipient
- weiAmount: amount to be sent in wei
- contractCall: a bytes representation of the ABI call to the contract
- r: bytes describe R point as defined in ecdsa
- s: bytes describe S point as defined in ecdsa
- v: bytes describe recovery point as defined in ecdsa and EIP-155
*/
public init(
networkID: IntegerScalar,
transactionsCount: BytesScalar,
gasPrice: BytesScalar,
gasEstimate: BytesScalar,
recipientAddress: BytesScalar,
weiAmount: BytesScalar,
contractCall: BytesScalar,
r: BytesScalar,
s: BytesScalar,
v: BytesScalar
) {
self.networkID = networkID
self.transactionsCount = transactionsCount
self.gasPrice = gasPrice
self.gasEstimate = gasEstimate
self.recipientAddress = recipientAddress
self.weiAmount = weiAmount
self.contractCall = contractCall
self.r = r
self.s = s
self.v = v
}

/**
- returns:
signed transaction as `Data` that can be deployed for mining

- throws:
`DescribedError` if something went wrong
*/
public func value() throws -> Data {
return try SimpleRLP(
rlps: [
EthRLP(number: transactionsCount),
EthRLP(number: gasPrice),
EthRLP(number: gasEstimate),
SimpleRLP(bytes: recipientAddress),
EthRLP(number: weiAmount),
SimpleRLP(bytes: contractCall),
SimpleRLP(bytes: v),
SimpleRLP(bytes: r),
SimpleRLP(bytes: s),
]
).value()
}

}
11 changes: 0 additions & 11 deletions Web3Swift/TransactionBytes/EthTransactionBytes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,6 @@ public final class EthTransactionBytes: BytesScalar {
self.contractCall = contractCall
}

/**
Ctor

- parameters:
- network: Network where transaction is to be deployed
- senderKey: private key of a sender
- recipientAddress: address of a recipient
- weiAmount: amount to be sent in wei
- contractCall: a bytes representation of the ABI call to the contract
*/

/**
It should be noted that 35 is the magic number suggested by EIP155 https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md

Expand Down
65 changes: 65 additions & 0 deletions Web3Swift/TransactionBytes/EthUnsignedTransactionBytes.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// This source file is part of the Web3Swift.io open source project
// Copyright 2018 The Web3Swift Authors
// Licensed under Apache License v2.0
//
// EthUnsignedTransactionBytes.swift
//
// Created by Vadim Koleoshkin on 24/07/2018
//

import Foundation

/** Unsigned transaction bytes */
public final class EthUnsignedTransactionBytes: BytesScalar {

private let origin: BytesScalar

/**
Ctor

- parameters:
- networkID: id of a network where the transaction is to be deployed
- transactionsCount: count of all transactions previously sent by the sender
- gasPrice: gas price in Wei
- gasEstimate: estimate for gas needed for transaction to be mined
- recipientAddress: address of a recipient
- weiAmount: amount to be sent in wei
- contractCall: a bytes representation of the ABI call to the contract
*/
public init(
networkID: IntegerScalar,
transactionsCount: BytesScalar,
gasPrice: BytesScalar,
gasEstimate: BytesScalar,
recipientAddress: BytesScalar,
weiAmount: BytesScalar,
contractCall: BytesScalar
) {
self.origin = EthManuallyTransactionBytes(
networkID: networkID,
transactionsCount: transactionsCount,
gasPrice: gasPrice,
gasEstimate: gasEstimate,
recipientAddress: recipientAddress,
weiAmount: weiAmount,
contractCall: contractCall,
r: EmptyBytes(),
s: EmptyBytes(),
v: EthNumber(value: networkID)
)
}


/**
- returns:
unsigned transaction as `Data`

- throws:
`DescribedError` if something went wrong
*/
public func value() throws -> Data {
return try origin.value()
}

}

0 comments on commit c4f92d5

Please sign in to comment.