Skip to content

Commit

Permalink
feat(cactus-plugin-ledger-connector-ethereum): add signing utils
Browse files Browse the repository at this point in the history
- Add methods for signing transactions to ethereum connector.
- Modify offline signing test to use this new method.
- Modify electricity trade sample to use new signing method.
- Add offline signature section to ethereum connector readme.

Co-authored-by: Peter Somogyvari <peter.somogyvari@accenture.com>

Signed-off-by: Michal Bajer <michal.bajer@fujitsu.com>
Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
  • Loading branch information
outSH authored and petermetz committed Oct 16, 2023
1 parent 814991c commit 84c5b34
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class BusinessLogicElectricityTrade extends BusinessLogicBase {
{
to: accountInfo["toAddress"],
value: Number(transactionSubset["Value"]),
gas: config.electricityTradeInfo.ethereum.gas,
gasLimit: config.electricityTradeInfo.ethereum.gas,
},
accountInfo["fromAddress"],
accountInfo["fromAddressPkey"],
Expand Down
18 changes: 12 additions & 6 deletions examples/cactus-example-electricity-trade/TransactionEthereum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
* transaction-ethereum.ts
*/

import { ConfigUtil } from "@hyperledger/cactus-cmd-socketio-server";
import {
ConfigUtil,
TransactionSigner,
} from "@hyperledger/cactus-cmd-socketio-server";
import { Web3SigningCredentialType } from "@hyperledger/cactus-plugin-ledger-connector-ethereum";
Web3SigningCredentialType,
signTransaction,
} from "@hyperledger/cactus-plugin-ledger-connector-ethereum";

const config: any = ConfigUtil.getConfig();
import { getLogger } from "log4js";
Expand Down Expand Up @@ -37,9 +37,15 @@ export async function sendEthereumTransaction(
}
logger.debug("sendEthereumTransaction", transaction);

const { serializedTx, txId } = TransactionSigner.signTxEthereum(
const { serializedTransactionHex, txId } = signTransaction(
transaction,
privateKey,
{
name: config.signTxInfo.ethereum.chainName,
chainId: config.signTxInfo.ethereum.chainID,
networkId: config.signTxInfo.ethereum.networkID,
defaultHardfork: config.signTxInfo.ethereum.defaultHardfork,
},
);
logger.info("Sending ethereum transaction with ID", txId);

Expand All @@ -48,7 +54,7 @@ export async function sendEthereumTransaction(
type: Web3SigningCredentialType.None,
},
transactionConfig: {
rawTransaction: serializedTx,
rawTransaction: serializedTransactionHex,
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ blpRegistry:

logLevel: debug

signTxInfo:
ethereum:
chainName: geth1
networkID: 10
chainID: 10
defaultHardfork: petersburg

appRouters:
-
path: /api/v1/bl/electricity-trade/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,3 @@ ledgerPluginInfo:
ledgerInfo:
ledgerAbstract: Sawtooth Ledger
apiInfo: []

signTxInfo:
ethereum:
chainName: geth1
networkID: 10
chainID: 10
network: mainnet
hardfork: petersburg
68 changes: 68 additions & 0 deletions packages/cactus-plugin-ledger-connector-ethereum/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,74 @@ args: {
},
```
### Offline signing utils
- Use `signTransaction` from this package to sign transactions payload locally (outside of connector process).
- Offline signed transaction can be send with `Web3SigningCredentialType.None` signing credetnial type in runTransactionV1 endpoint.
``` typescript
// Offline sign transaction
const { serializedTransactionHex } = signTransaction(
{
to: anotherAccount,
value: 10e6,
maxPriorityFeePerGas: 0,
maxFeePerGas: 0x40000000,
gasLimit: 21000,
type: 2
},
myPrivateKey,
{
networkId: 10,
chainId: 10,
defaultHardfork: "london",
},
);

// Send transaction payload to connector
await apiClient.runTransactionV1({
web3SigningCredential: {
type: Web3SigningCredentialType.None,
},
transactionConfig: {
rawTransaction: serializedTransactionHex,
},
});
```
### Offline signing utils
- Use `signTransaction` from this package to sign transactions payload locally (outside of connector process).
- Offline signed transaction can be send with `Web3SigningCredentialType.None` signing credetnial type in runTransactionV1 endpoint.
``` typescript
// Offline sign transaction
const { serializedTransactionHex } = signTransaction(
{
to: anotherAccount,
value: 10e6,
maxPriorityFeePerGas: 0,
maxFeePerGas: 0x40000000,
gasLimit: 21000,
type: 2
},
myPrivateKey,
{
networkId: 10,
chainId: 10,
defaultHardfork: "london",
},
);

// Send transaction payload to connector
await apiClient.runTransactionV1({
web3SigningCredential: {
type: Web3SigningCredentialType.None,
},
transactionConfig: {
rawTransaction: serializedTransactionHex,
},
});
```
## JSON-RPC Proxy
- Connector can be used with web3js to send any JSON-RPC request to the ethereum node.
Expand Down
2 changes: 2 additions & 0 deletions packages/cactus-plugin-ledger-connector-ethereum/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"webpack:dev:web": "webpack --env=dev --target=web --config ../../webpack.config.js"
},
"dependencies": {
"@ethereumjs/common": "4.0.0",
"@ethereumjs/tx": "5.0.0",
"@hyperledger/cactus-common": "2.0.0-alpha.2",
"@hyperledger/cactus-core": "2.0.0-alpha.2",
"@hyperledger/cactus-core-api": "2.0.0-alpha.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export {
IPluginLedgerConnectorEthereumOptions,
} from "./plugin-ledger-connector-ethereum";

export * from "./sign-utils";

export * from "./types/model-type-guards";

export { PluginFactoryLedgerConnector } from "./plugin-factory-ledger-connector";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Chain, Common } from "@ethereumjs/common";
import {
AccessListEIP2930Transaction,
BlobEIP4844Transaction,
FeeMarketEIP1559Transaction,
LegacyTransaction,
TransactionFactory,
TypedTxData,
} from "@ethereumjs/tx";

type CustomChainArg = Parameters<typeof Common.custom>[0];

/**
* Sign ethereum transaction data offline. Can be used with both mainnet and custom chains.
*
* @param txData transaction data (format must be compatible with @ethereumjs/tx)
* @param privateKey HEX private signing key
* @param customChainInfo optional custom chain information (default: mainnet)
*
* @returns serialized transaction, txId (hash) and signedTransaction object
*/
export function signTransaction(
txData: TypedTxData,
privateKey: string,
customChainInfo?: CustomChainArg,
): {
serializedTransactionHex: string;
txId: string;
signedTransactionObject:
| LegacyTransaction
| AccessListEIP2930Transaction
| FeeMarketEIP1559Transaction
| BlobEIP4844Transaction;
} {
let chainConfiguration = new Common({ chain: Chain.Mainnet });
if (customChainInfo) {
chainConfiguration = Common.custom(customChainInfo);
}

const transaction = TransactionFactory.fromTxData(txData, {
common: chainConfiguration,
});
if (privateKey.toLowerCase().startsWith("0x")) {
privateKey = privateKey.slice(2);
}
const signedTransaction = transaction.sign(Buffer.from(privateKey, "hex"));

const hash = signedTransaction.hash();
const txId = "0x" + Buffer.from(hash).toString("hex");
const serializedTransaction = signedTransaction.serialize();
const serializedTransactionHex =
"0x" + Buffer.from(serializedTransaction).toString("hex");

return {
serializedTransactionHex,
txId,
signedTransactionObject: signedTransaction,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
InvokeContractV1Request,
DeployContractV1Request,
ContractKeychainDefinition,
signTransaction,
} from "../../../main/typescript/public-api";
import { K_CACTI_ETHEREUM_TOTAL_TX_COUNT } from "../../../main/typescript/prometheus-exporter/metrics";

Expand Down Expand Up @@ -348,13 +349,12 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => {
expect(invokeGetNameOut.data.callOutput).toBe(newName);
});

test("invoke Web3SigningCredentialType.NONE", async () => {
test("invoke Web3SigningCredentialType.None", async () => {
const testEthAccount2 = web3.eth.accounts.create();

const value = 10e6;
const { rawTransaction } = await web3.eth.accounts.signTransaction(
const { serializedTransactionHex } = signTransaction(
{
from: testEthAccount.address,
to: testEthAccount2.address,
value,
maxPriorityFeePerGas: 0,
Expand All @@ -363,14 +363,19 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => {
type: 2,
},
testEthAccount.privateKey,
{
networkId: 10,
chainId: 10,
defaultHardfork: "london",
},
);

await apiClient.runTransactionV1({
web3SigningCredential: {
type: Web3SigningCredentialType.None,
},
transactionConfig: {
rawTransaction,
rawTransaction: serializedTransactionHex,
},
});

Expand Down
65 changes: 65 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4335,6 +4335,16 @@ __metadata:
languageName: node
linkType: hard

"@ethereumjs/common@npm:4.0.0, @ethereumjs/common@npm:^4.0.0":
version: 4.0.0
resolution: "@ethereumjs/common@npm:4.0.0"
dependencies:
"@ethereumjs/util": ^9.0.0
crc: ^4.3.2
checksum: 3fa2f6a55ff5a2406241fc1ffbdc6f60cfa139edaf9afac2164d25ca35e31a0d2901de40a517f42e5a466aab316f9187c5b787f33f3260e746b13209c910c67f
languageName: node
linkType: hard

"@ethereumjs/common@npm:^2.3.0, @ethereumjs/common@npm:^2.4.0, @ethereumjs/common@npm:^2.6.1":
version: 2.6.2
resolution: "@ethereumjs/common@npm:2.6.2"
Expand Down Expand Up @@ -4374,6 +4384,15 @@ __metadata:
languageName: node
linkType: hard

"@ethereumjs/rlp@npm:^5.0.0":
version: 5.0.0
resolution: "@ethereumjs/rlp@npm:5.0.0"
bin:
rlp: bin/rlp
checksum: 86d42f88945f25fc2874f80efc4d4c37cc85fc375920134392b658c0140346fb22b815e73680b87d1fea3ae55ad6ca42ea9fec7150583be496577b01bffb9e58
languageName: node
linkType: hard

"@ethereumjs/tx@npm:3.3.2":
version: 3.3.2
resolution: "@ethereumjs/tx@npm:3.3.2"
Expand All @@ -4384,6 +4403,23 @@ __metadata:
languageName: node
linkType: hard

"@ethereumjs/tx@npm:5.0.0":
version: 5.0.0
resolution: "@ethereumjs/tx@npm:5.0.0"
dependencies:
"@ethereumjs/common": ^4.0.0
"@ethereumjs/rlp": ^5.0.0
"@ethereumjs/util": ^9.0.0
ethereum-cryptography: ^2.1.2
peerDependencies:
c-kzg: ^2.1.0
peerDependenciesMeta:
c-kzg:
optional: true
checksum: 1f642781cca8251fb036ef9b77e95c8e3e8e7b1996d295e01f9875a581ccf25fa38eea270d032a8ab4cb1b6d716b50496b7400ccc37875b896912e6fd0300de8
languageName: node
linkType: hard

"@ethereumjs/tx@npm:^3.2.1":
version: 3.5.0
resolution: "@ethereumjs/tx@npm:3.5.0"
Expand Down Expand Up @@ -4415,6 +4451,21 @@ __metadata:
languageName: node
linkType: hard

"@ethereumjs/util@npm:^9.0.0":
version: 9.0.0
resolution: "@ethereumjs/util@npm:9.0.0"
dependencies:
"@ethereumjs/rlp": ^5.0.0
ethereum-cryptography: ^2.1.2
peerDependencies:
c-kzg: ^2.1.0
peerDependenciesMeta:
c-kzg:
optional: true
checksum: c0e2a50aac614a8167df060f0fe6d7b9805adebd83df81a26b596c92eb76454e2e6f25d8f5b9e49cb629355020a8a07feb4d6c1b8238990dcf82e256153bf328
languageName: node
linkType: hard

"@ethersproject/abi@npm:5.0.7":
version: 5.0.7
resolution: "@ethersproject/abi@npm:5.0.7"
Expand Down Expand Up @@ -6475,6 +6526,8 @@ __metadata:
version: 0.0.0-use.local
resolution: "@hyperledger/cactus-plugin-ledger-connector-ethereum@workspace:packages/cactus-plugin-ledger-connector-ethereum"
dependencies:
"@ethereumjs/common": 4.0.0
"@ethereumjs/tx": 5.0.0
"@hyperledger/cactus-common": 2.0.0-alpha.2
"@hyperledger/cactus-core": 2.0.0-alpha.2
"@hyperledger/cactus-core-api": 2.0.0-alpha.2
Expand Down Expand Up @@ -17341,6 +17394,18 @@ __metadata:
languageName: node
linkType: hard

"crc@npm:^4.3.2":
version: 4.3.2
resolution: "crc@npm:4.3.2"
peerDependencies:
buffer: ">=6.0.3"
peerDependenciesMeta:
buffer:
optional: true
checksum: 8231cc25331727083ffd22da3575110fc49b4dc8725de973bd43261d4426aba134ed3a75cc247f7c5e97a6e171f87dffc3325b82890e86d032de2e6bcef09c32
languageName: node
linkType: hard

"create-ecdh@npm:^4.0.0":
version: 4.0.4
resolution: "create-ecdh@npm:4.0.4"
Expand Down

0 comments on commit 84c5b34

Please sign in to comment.