Skip to content

Commit

Permalink
feat(odap): first implemenation for odap plugin and endpoints
Browse files Browse the repository at this point in the history
Signed-off-by: jsjs026 <jasonhack518@gmail.com>
  • Loading branch information
jscode017 authored and petermetz committed Nov 9, 2021
1 parent 4b075f7 commit 51bf753
Show file tree
Hide file tree
Showing 57 changed files with 14,505 additions and 1,346 deletions.
2 changes: 2 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"ccid",
"cids",
"configtx",
"commenceack",
"Corda",
"Cordapp",
"couchdb",
Expand Down Expand Up @@ -87,6 +88,7 @@
"NETWORKSCOPEANYFORTX",
"NODETXPOOLACK",
"notok",
"Odap",
"Oidc",
"oneofs",
"onsi",
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// *****************************************************************************
// IMPORTANT: If you update this code then make sure to recompile
// it and update the .json file as well so that they
// remain in sync for consistent test executions.
// With that said, there shouldn't be any reason to recompile this, like ever...
// *****************************************************************************

pragma solidity >=0.7.0;
struct Asset{
address creator;
bool isLock;
uint size;
}
//TODO: DETEMINE CALLDATA VS MEMORY
contract LockAsset {
//
mapping (string => Asset) assets;
function createAsset( string calldata id, uint size) public{
require(size>0);
assets[id].size= size;
assets[id].creator = msg.sender;
assets[id].isLock = false;
}
function getAsset(string calldata id) public view returns (Asset memory)
{
return assets[id];
}

//Don't care if it is already locked
function lockAsset(string calldata id) public{
bool assetExsist = assets[id].size>0;
require(assetExsist);
assets[id].isLock = true;
}
//Don't care if it is already unlocked
function unLockAsset(string calldata id) public{
bool assetExsist = assets[id].size>0;
require(assetExsist);
assets[id].isLock = false;
}
function deleteAsset(string calldata id) public {
bool assetExsist = assets[id].size>0;
require(assetExsist);
//an asset could only be deleted if it is already locked
bool assetIsLocked = assets[id].isLock;
require(assetIsLocked);
delete assets[id];
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
import test, { Test } from "tape";
import { v4 as uuidv4 } from "uuid";
import { PluginRegistry } from "@hyperledger/cactus-core";
import {
EthContractInvocationType,
Web3SigningCredentialType,
PluginLedgerConnectorBesu,
PluginFactoryLedgerConnector,
//Web3SigningCredentialCactusKeychainRef,
ReceiptType,
} from "../../../../main/typescript/public-api";
import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory";
import { BesuTestLedger } from "@hyperledger/cactus-test-tooling";
import { LoggerProvider, LogLevelDesc } from "@hyperledger/cactus-common";
import LockAssetContractJson from "../../../solidity/hello-world-contract/LockAsset.json";
import Web3 from "web3";
import { PluginImportType } from "@hyperledger/cactus-core-api";
const level = "INFO";
const label = "lock-contact test";
const log = LoggerProvider.getOrCreate({ level, label });
test("deploys contract via .json file", async (t: Test) => {
const logLevel: LogLevelDesc = "TRACE";
const besuTestLedger = new BesuTestLedger();
await besuTestLedger.start();

test.onFinish(async () => {
await besuTestLedger.stop();
await besuTestLedger.destroy();
});

const rpcApiHttpHost = await besuTestLedger.getRpcApiHttpHost();
const rpcApiWsHost = await besuTestLedger.getRpcApiWsHost();

/**
* Constant defining the standard 'dev' Besu genesis.json contents.
*
* @see https://github.com/hyperledger/besu/blob/1.5.1/config/src/main/resources/dev.json
*/
const firstHighNetWorthAccount = besuTestLedger.getGenesisAccountPubKey();
const besuKeyPair = {
privateKey: besuTestLedger.getGenesisAccountPrivKey(),
};
const contractName = "LockAsset";

const web3 = new Web3(rpcApiHttpHost);
const testEthAccount = web3.eth.accounts.create(uuidv4());

const keychainEntryKey = uuidv4();
const keychainEntryValue = testEthAccount.privateKey;
const keychainPlugin = new PluginKeychainMemory({
instanceId: uuidv4(),
keychainId: uuidv4(),
// pre-provision keychain with mock backend holding the private key of the
// test account that we'll reference while sending requests with the
// signing credential pointing to this keychain entry.
backend: new Map([[keychainEntryKey, keychainEntryValue]]),
logLevel,
});
keychainPlugin.set(
LockAssetContractJson.contractName,
JSON.stringify(LockAssetContractJson),
);
const factory = new PluginFactoryLedgerConnector({
pluginImportType: PluginImportType.Local,
});
const connector: PluginLedgerConnectorBesu = await factory.create({
rpcApiHttpHost,
rpcApiWsHost,
instanceId: uuidv4(),
pluginRegistry: new PluginRegistry({ plugins: [keychainPlugin] }),
});

await connector.transact({
web3SigningCredential: {
ethAccount: firstHighNetWorthAccount,
secret: besuKeyPair.privateKey,
type: Web3SigningCredentialType.PrivateKeyHex,
},
consistencyStrategy: {
blockConfirmations: 0,
receiptType: ReceiptType.NodeTxPoolAck,
},
transactionConfig: {
from: firstHighNetWorthAccount,
to: testEthAccount.address,
value: 10e9,
gas: 1000000,
},
});

const balance = await web3.eth.getBalance(testEthAccount.address);
t.ok(balance, "Retrieved balance of test account OK");
t.equals(parseInt(balance, 10), 10e9, "Balance of test account is OK");

let contractAddress: string;

test("deploys contract via .json file", async (t2: Test) => {
const deployOut = await connector.deployContract({
keychainId: keychainPlugin.getKeychainId(),
contractName: LockAssetContractJson.contractName,
contractAbi: LockAssetContractJson.abi,
constructorArgs: [],
web3SigningCredential: {
ethAccount: firstHighNetWorthAccount,
secret: besuKeyPair.privateKey,
type: Web3SigningCredentialType.PrivateKeyHex,
},
bytecode: LockAssetContractJson.bytecode,
gas: 1000000,
});
t2.ok(deployOut, "deployContract() output is truthy OK");
t2.ok(
deployOut.transactionReceipt,
"deployContract() output.transactionReceipt is truthy OK",
);
t2.ok(
deployOut.transactionReceipt.contractAddress,
"deployContract() output.transactionReceipt.contractAddress is truthy OK",
);

contractAddress = deployOut.transactionReceipt.contractAddress as string;
t2.ok(
typeof contractAddress === "string",
"contractAddress typeof string OK",
);

const { success: createRes } = await connector.invokeContract({
contractName,
keychainId: keychainPlugin.getKeychainId(),
invocationType: EthContractInvocationType.Send,
methodName: "createAsset",
params: ["asset1", 5],
signingCredential: {
ethAccount: testEthAccount.address,
secret: besuKeyPair.privateKey,
type: Web3SigningCredentialType.PrivateKeyHex,
},
gas: 1000000,
});
t2.ok(createRes, "create Asset() output is truthy");
t2.equals(createRes, true, "create Asset Ok");
log.warn("create ok");
const { success: lockRes } = await connector.invokeContract({
contractName,
keychainId: keychainPlugin.getKeychainId(),
invocationType: EthContractInvocationType.Send,
methodName: "lockAsset",
params: ["asset1"],
signingCredential: {
ethAccount: testEthAccount.address,
secret: besuKeyPair.privateKey,
type: Web3SigningCredentialType.PrivateKeyHex,
},
gas: 1000000,
});
log.warn("checking lock res");
t2.ok(lockRes, "lock Asset() output is truthy");
t2.equals(lockRes, true, "lock Asset Ok");
const { success: unLockRes } = await connector.invokeContract({
contractName,
keychainId: keychainPlugin.getKeychainId(),
invocationType: EthContractInvocationType.Send,
methodName: "unLockAsset",
params: ["asset1"],
signingCredential: {
ethAccount: testEthAccount.address,
secret: besuKeyPair.privateKey,
type: Web3SigningCredentialType.PrivateKeyHex,
},
gas: 1000000,
});
t2.ok(unLockRes, "unlock Asset() output is truthy");
t2.equals(unLockRes, true, "unlock Asset Ok");
const { success: lockRes2 } = await connector.invokeContract({
contractName,
keychainId: keychainPlugin.getKeychainId(),
invocationType: EthContractInvocationType.Send,
methodName: "lockAsset",
params: ["asset1"],
signingCredential: {
ethAccount: testEthAccount.address,
secret: besuKeyPair.privateKey,
type: Web3SigningCredentialType.PrivateKeyHex,
},
gas: 1000000,
});
t2.ok(lockRes2, "lock Asset() again output is truthy");
t2.equals(lockRes2, true, "lock Asset again Ok");
log.warn("asset is locked again");
const { success: deleteRes } = await connector.invokeContract({
contractName,
keychainId: keychainPlugin.getKeychainId(),
invocationType: EthContractInvocationType.Send,
methodName: "deleteAsset",
params: ["asset1"],
signingCredential: {
ethAccount: testEthAccount.address,
secret: besuKeyPair.privateKey,
type: Web3SigningCredentialType.PrivateKeyHex,
},
gas: 1000000,
});
console.log(deleteRes);
t2.ok(deleteRes, "delete Asset() output is truthy");
t2.equals(deleteRes, true, "delete Asset Ok");
});
t.end();
});
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
"node-vault": "0.9.22",
"openapi-types": "9.1.0",
"prom-client": "13.2.0",
"secp256k1": "^4.0.2",
"temp": "0.9.4",
"typescript-optional": "2.0.1",
"uuid": "8.3.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "asset-transfer-basic",
"version": "1.0.0",
"description": "Asset Transfer Basic contract implemented in TypeScript",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"engines": {
"node": ">=12",
"npm": ">=5"
},
"scripts": {
"lint": "tslint -c tslint.json 'src/**/*.ts'",
"pretest": "npm run lint",
"test": "nyc mocha -r ts-node/register src/**/*.spec.ts",
"start": "fabric-chaincode-node start",
"build": "tsc",
"build:watch": "tsc -w",
"prepublishOnly": "npm run build"
},
"engineStrict": true,
"author": "Hyperledger",
"license": "Apache-2.0",
"dependencies": {
"fabric-contract-api": "^2.0.0",
"fabric-shim": "^2.0.0"
},
"devDependencies": {
"@types/chai": "^4.1.7",
"@types/mocha": "^5.2.5",
"@types/node": "^10.12.10",
"@types/sinon": "^5.0.7",
"@types/sinon-chai": "^3.2.1",
"chai": "^4.2.0",
"mocha": "^5.2.0",
"nyc": "^14.1.1",
"sinon": "^7.1.1",
"sinon-chai": "^3.3.0",
"ts-node": "^7.0.1",
"tslint": "^5.11.0",
"typescript": "^3.1.6"
},
"nyc": {
"extension": [
".ts",
".tsx"
],
"exclude": [
"coverage/**",
"dist/**"
],
"reporter": [
"text-summary",
"html"
],
"all": true,
"check-coverage": true,
"statements": 100,
"branches": 100,
"functions": 100,
"lines": 100
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
SPDX-License-Identifier: Apache-2.0
*/

import { Object, Property } from "fabric-contract-api";

@Object()
export class Asset {
@Property()
public docType?: string;

@Property()
public ID: string;

@Property()
public IsLock: boolean;

@Property()
public Size: number;
}
Loading

0 comments on commit 51bf753

Please sign in to comment.