Skip to content

Commit

Permalink
feat(connector): remove keychain dependency
Browse files Browse the repository at this point in the history
    Primary Changes
    ---------------
    1. Updated besu, ethereum, quorum and xdai connectors
    to remove hard dependencies on keychain

    Changes required to incorporate 1)
    2. Updated openapi.json file of the above mentioned connectors
       to include the new no-keychain endpoints
    3. Generated code and updated related web-services for the same

Fixes hyperledger-cacti#963

Signed-off-by: jagpreetsinghsasan <[email protected]>
  • Loading branch information
jagpreetsinghsasan committed Apr 3, 2024
1 parent db3fe87 commit 49d62e3
Show file tree
Hide file tree
Showing 32 changed files with 1,258 additions and 267 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,73 @@
}
}
},
"DeployContractSolidityBytecodeNoKeychainV1Request": {
"type": "object",
"required": [
"contractName",
"contractAbi",
"contractJson",
"bytecode",
"web3SigningCredential",
"keychainId",
"constructorArgs"
],
"additionalProperties": false,
"properties": {
"contractName": {
"type": "string",
"description": "The contract name for retrieve the contracts json on the keychain.",
"minLength": 1,
"maxLength": 100,
"nullable": false
},
"contractAbi": {
"description": "The application binary interface of the solidity contract",
"type": "array",
"items": {},
"nullable": false
},
"contractJSONString": {
"description": "For use when not using keychain, pass the contract in as this string variable",
"nullable": false,
"type": "string"
},
"constructorArgs": {
"type": "array",
"items": {},
"default": []
},
"web3SigningCredential": {
"$ref": "#/components/schemas/Web3SigningCredential",
"nullable": false
},
"bytecode": {
"type": "string",
"nullable": false,
"minLength": 1,
"maxLength": 24576,
"description": "See https://ethereum.stackexchange.com/a/47556 regarding the maximum length of the bytecode"
},
"gas": {
"type": "number",
"nullable": false
},
"gasPrice": {
"type": "string",
"nullable": false
},
"timeoutMs": {
"type": "number",
"description": "The amount of milliseconds to wait for a transaction receipt with theaddress of the contract(which indicates successful deployment) beforegiving up and crashing.",
"minimum": 0,
"default": 60000,
"nullable": false
},
"privateTransactionConfig": {
"$ref": "#/components/schemas/BesuPrivateTransactionConfig"
}
}
},
"DeployContractSolidityBytecodeV1Response": {
"type": "object",
"required": ["transactionReceipt"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,73 @@ export interface ConsistencyStrategy {
}


/**
*
* @export
* @interface DeployContractSolidityBytecodeNoKeychainV1Request
*/
export interface DeployContractSolidityBytecodeNoKeychainV1Request {
/**
* The contract name for retrieve the contracts json on the keychain.
* @type {string}
* @memberof DeployContractSolidityBytecodeNoKeychainV1Request
*/
'contractName': string;
/**
* The application binary interface of the solidity contract
* @type {Array<any>}
* @memberof DeployContractSolidityBytecodeNoKeychainV1Request
*/
'contractAbi': Array<any>;
/**
* For use when not using keychain, pass the contract in as this string variable
* @type {string}
* @memberof DeployContractSolidityBytecodeNoKeychainV1Request
*/
'contractJSONString'?: string;
/**
*
* @type {Array<any>}
* @memberof DeployContractSolidityBytecodeNoKeychainV1Request
*/
'constructorArgs': Array<any>;
/**
*
* @type {Web3SigningCredential}
* @memberof DeployContractSolidityBytecodeNoKeychainV1Request
*/
'web3SigningCredential': Web3SigningCredential;
/**
* See https://ethereum.stackexchange.com/a/47556 regarding the maximum length of the bytecode
* @type {string}
* @memberof DeployContractSolidityBytecodeNoKeychainV1Request
*/
'bytecode': string;
/**
*
* @type {number}
* @memberof DeployContractSolidityBytecodeNoKeychainV1Request
*/
'gas'?: number;
/**
*
* @type {string}
* @memberof DeployContractSolidityBytecodeNoKeychainV1Request
*/
'gasPrice'?: string;
/**
* The amount of milliseconds to wait for a transaction receipt with theaddress of the contract(which indicates successful deployment) beforegiving up and crashing.
* @type {number}
* @memberof DeployContractSolidityBytecodeNoKeychainV1Request
*/
'timeoutMs'?: number;
/**
*
* @type {BesuPrivateTransactionConfig}
* @memberof DeployContractSolidityBytecodeNoKeychainV1Request
*/
'privateTransactionConfig'?: BesuPrivateTransactionConfig;
}
/**
*
* @export
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Web3JsQuorum, { IWeb3Quorum } from "web3js-quorum";
import { Contract, ContractSendMethod } from "web3-eth-contract";
import { TransactionReceipt } from "web3-eth";
import {
DeployContractSolidityBytecodeNoKeychainV1Request,
GetBalanceV1Request,
GetBalanceV1Response,
Web3TransactionReceipt,
Expand Down Expand Up @@ -912,6 +913,83 @@ export class PluginLedgerConnectorBesu
return deployResponse;
}

public async deployContractNoKeychain(
req: DeployContractSolidityBytecodeNoKeychainV1Request,
): Promise<DeployContractSolidityBytecodeV1Response> {
const fnTag = `${this.className}#deployContract()`;
Checks.truthy(req, `${fnTag} req`);
if (isWeb3SigningCredentialNone(req.web3SigningCredential)) {
throw new Error(`${fnTag} Cannot deploy contract with pre-signed TX`);
}
const { contractName, contractJSONString } = req;
const networkId = await this.web3.eth.net.getId();

const tmpContract = new this.web3.eth.Contract(req.contractAbi);
const deployment = tmpContract.deploy({
data: req.bytecode,
arguments: req.constructorArgs,
});

const abi = deployment.encodeABI();
const data = abi.startsWith("0x") ? abi : `0x${abi}`;
this.log.debug(`Deploying "${req.contractName}" with data %o`, data);

const web3SigningCredential = req.web3SigningCredential as
| Web3SigningCredentialPrivateKeyHex
| Web3SigningCredentialCactusKeychainRef;

const runTxResponse = await this.transact({
transactionConfig: {
data,
from: web3SigningCredential.ethAccount,
gas: req.gas,
gasPrice: req.gasPrice,
},
consistencyStrategy: {
blockConfirmations: 0,
receiptType: ReceiptType.NodeTxPoolAck,
timeoutMs: req.timeoutMs || 60000,
},
web3SigningCredential,
privateTransactionConfig: req.privateTransactionConfig,
});

const { transactionReceipt: receipt } = runTxResponse;
const { status, contractAddress } = receipt;

Checks.truthy(status, `${this.className}#deployContract():status`);

Checks.truthy(
contractAddress,
`${this.className}#deployContract():contractAddress`,
);

if (contractJSONString) {
const networkInfo = { address: contractAddress };
const contractJSON = JSON.parse(contractJSONString);
this.log.debug("Contract JSON: \n%o", JSON.stringify(contractJSON));
const contract = new this.web3.eth.Contract(
contractJSON.abi,
contractAddress || " ",
);
this.contracts[contractName] = contract;
const network = { [networkId]: networkInfo };
contractJSON.networks = network;
} else {
const errorMessage =
`${fnTag} Cannot create an instance of the contract instance because` +
`the contractName in the request does not exist on the keychain`;
throw new createHttpError[400](errorMessage);
}

// creating solidity byte code response
const deployResponse: DeployContractSolidityBytecodeV1Response = {
transactionReceipt: runTxResponse.transactionReceipt,
};

return deployResponse;
}

public async signTransaction(
req: SignTransactionRequest,
): Promise<Optional<SignTransactionResponse>> {
Expand Down
Loading

0 comments on commit 49d62e3

Please sign in to comment.