Skip to content

Commit

Permalink
feat: 🎸 contract upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
SmilingXinyi committed Sep 29, 2020
1 parent 9cf9105 commit b6c4bc9
Show file tree
Hide file tree
Showing 9 changed files with 362 additions and 164 deletions.
15 changes: 10 additions & 5 deletions src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {PrivateKey, PublicKey, AccountModel} from './types';
import {Cryptography, Language, Strength} from './constants';
import {
arrayPadStart, base58Decode, base58Encode, deepEqual,
isBrowser, stringToPublicOrPrivateKey
isBrowser, stringToPublicOrPrivateKey, publicOrPrivateKeyToString
} from './utils';

import * as Requests from './requests';
Expand Down Expand Up @@ -71,7 +71,7 @@ export default class Account {
};
}

public recover(
public retrieve(
mnemonic: string,
language: Language = Language.SimplifiedChinese,
cryptography: Cryptography = Cryptography.EccFIPS
Expand Down Expand Up @@ -166,6 +166,12 @@ export default class Account {
};
}

export(password: string, privateKey: PrivateKey): string {
return btoa(
this.encryptPrivateKey(password, privateKey)
);
}

private decryptPrivateKey(password: string, keyStr: string): string {
const bytes = atob(keyStr).split('').map(s => s.charCodeAt(0));
const blockSize = 16;
Expand All @@ -183,8 +189,8 @@ export default class Account {
return td.decode(decryptedBytes);
}

/*
private encryptPrivateKey(password: string, privateKey: PrivateKeyModel): string {

private encryptPrivateKey(password: string, privateKey: PrivateKey): string {
const keyStr = publicOrPrivateKeyToString(privateKey);
const te = new TextEncoder();
const keyBytes: Uint8Array = te.encode(keyStr);
Expand All @@ -198,7 +204,6 @@ export default class Account {
const ts = Array.from(result).map((s: number) => String.fromCharCode(s));
return ts.join('');
}
*/

private generateEntropy(strength: Strength): Uint8Array {
if ((strength + 8) % 32 !== 0 || strength + 8 < 128 || strength + 8 > 256) {
Expand Down
68 changes: 66 additions & 2 deletions src/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ export default class Contract {

// invoke contract

deployWasmContractRequests(
deployContractRequests(
contractAccount: string,
contractName: string,
code: string,
lang: string,
initArgs: any
) {

/*
const newInitArgs = {
...initArgs
};
Expand Down Expand Up @@ -113,6 +113,70 @@ export default class Contract {
args: contractArgs
}];
return invokeRequests;
*/

return this.generateContractRequests('Deploy', contractAccount, contractName, code, lang, initArgs);
}

upgradContractRequests(
contractAccount: string,
contractName: string,
code: string,
lang: string,
initArgs: any
) {
return this.generateContractRequests('Upgrade', contractAccount, contractName, code, lang, initArgs);
}

generateContractRequests(
methodName: string,
contractAccount: string,
contractName: string,
code: string,
lang: string,
initArgs: any
) {
const newInitArgs = {
...initArgs
};

const te = new TextEncoder();

Object.keys(initArgs).forEach(key => {
const bytes = te.encode(initArgs[key]);
const valueBuf: Array<any> = [];
bytes.forEach(b => valueBuf.push(String.fromCharCode(b)));
newInitArgs[key] = btoa(valueBuf.join(''));
});

const desc = new Uint8Array([10, 1].concat(lang.split('').map(w => w.charCodeAt(0))));
const descBuf = Object.values(desc).map(n => String.fromCharCode(n));

const args = {
account_name: contractAccount,
contract_name: contractName,
contract_desc: descBuf.join(''),
contract_code: code,
init_args: JSON.stringify(newInitArgs)
};

const contractArgs = {
...args
};

Object.keys(contractArgs).forEach(key => {
// @ts-ignore
contractArgs[key] = btoa(contractArgs[key]);
});

const invokeRequests: ContractRequesttModel[] = [{
module_name: 'xkernel',
method_name: methodName,
args: contractArgs
}];

return invokeRequests;
}

Expand Down
95 changes: 77 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
} from './types';
import BN from 'bn.js';

export {Cryptography, Language, Strength};

export default class XuperSDK implements XuperSDKInterface {
static instance: XuperSDK;
private options: Options;
Expand Down Expand Up @@ -61,14 +63,14 @@ export default class XuperSDK implements XuperSDKInterface {
return this.accountInstance.create(language, strength, cryptography);
}

recover(
retrieve(
mnemonic: string,
language: Language = Language.SimplifiedChinese,
cryptography: Cryptography = Cryptography.EccFIPS,
cache = false
): AccountModel {
if (mnemonic) {
const account = this.accountInstance.recover(mnemonic, language, cryptography);
const account = this.accountInstance.retrieve(mnemonic, language, cryptography);
if (cache) {
this.account = account;
return account;
Expand All @@ -93,6 +95,22 @@ export default class XuperSDK implements XuperSDKInterface {
}
}

export(password: string): string {

const acc = this.account;

if (!password) {
throw Errors.PARAMETER_ERROR;
}

if (acc) {
return this.accountInstance.export(password, acc.privateKey);
}
else {
throw Errors.ACCOUNT_NOT_EXIST;
}
}

checkAddress(address?: string): boolean {
const addr = address || this.account?.address;

Expand Down Expand Up @@ -163,11 +181,15 @@ export default class XuperSDK implements XuperSDKInterface {
totalNeed = totalNeed.add(new BN(auth.fee || 0));
});

// @ts-ignore
const preExecWithUtxos = await this.transactionInstance.preExecWithUTXO(node, chain, acc.address, totalNeed, Object.keys(authRequires), null, acc)
const preExecWithUtxosObj = JSON.parse(atob(preExecWithUtxos.ResponseData));

return this.transactionInstance.makeTransaction(acc, ti, authRequires, preExecWithUtxosObj);
try {
// @ts-ignore
const preExecWithUtxos = await this.transactionInstance.preExecWithUTXO(node, chain, acc.address, totalNeed, Object.keys(authRequires), null, acc)
const preExecWithUtxosObj = JSON.parse(atob(preExecWithUtxos.ResponseData));
return this.transactionInstance.makeTransaction(acc, ti, authRequires, preExecWithUtxosObj);
}
catch (e) {
throw e;
}
}

async postTransaction(tx: TransactionModel, account?: AccountModel) {
Expand Down Expand Up @@ -280,16 +302,31 @@ export default class XuperSDK implements XuperSDKInterface {
code: string,
lang: string,
initArgs: any,
upgrade: boolean = false,
account?: AccountModel
): Promise<any> {
const {node, chain} = this.options;
const invokeRequests = this.contractInstance.deployWasmContractRequests(
contractAccount,
contractName,
code,
lang,
initArgs
);

let invokeRequests: ContractRequesttModel[];

if (upgrade) {
invokeRequests = this.contractInstance.upgradContractRequests(
contractAccount,
contractName,
code,
lang,
initArgs
)
}
else {
invokeRequests = this.contractInstance.deployContractRequests(
contractAccount,
contractName,
code,
lang,
initArgs
);
}

if (!account) {
account = this.account;
Expand Down Expand Up @@ -342,15 +379,25 @@ export default class XuperSDK implements XuperSDKInterface {
methodName: string,
moduleName: string,
args: any,
address: string
account?: AccountModel
): Promise<any> {
const {node, chain} = this.options;
const invokeRequests = this.contractInstance.invokeContract(
contractName,
methodName,
moduleName,
args
)
);

if (!account) {
account = this.account;
}

if (!account) {
throw Errors.ACCOUNT_NOT_EXIST;
}

const address = account.address;

const authRequires: { [propName: string]: AuthModel } = {};
let totalNeed = new BN(0);
Expand All @@ -362,10 +409,22 @@ export default class XuperSDK implements XuperSDKInterface {

const preExecWithUtxos = await this.transactionInstance.preExecWithUTXO(node, chain, address, totalNeed, Object.keys(authRequires), invokeRequests)

console.log(preExecWithUtxos)
const preExecWithUtxosObj = JSON.parse(atob(preExecWithUtxos.ResponseData));

return new Promise<any>(resolve => resolve(preExecWithUtxosObj));
// return new Promise<any>(resolve => resolve(preExecWithUtxosObj));

const gasUsed = preExecWithUtxosObj.response.gas_used || 0;

const tx = await this.transactionInstance.makeTransaction(account, {
amount: '0',
fee: gasUsed.toString(),
to: ''
}, authRequires, preExecWithUtxosObj);

return {
preExecutionTransaction: preExecWithUtxosObj,
transaction: tx
};
}

transactionIdToHex(t: Required<string>): string {
Expand Down
6 changes: 4 additions & 2 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ export default interface XuperSDKInterface extends AccountInterface, Transaction
export interface AccountInterface {
create(language: Language, strength: Strength, cryptography: Cryptography): AccountModel;

recover(mnemonic: string, language: Language, cryptography: Cryptography, cache?: boolean): AccountModel;
retrieve(mnemonic: string, language: Language, cryptography: Cryptography, cache?: boolean): AccountModel;

import(password: string, privateKeyStr: string, cache?: boolean): AccountModel;

export(password: string): string;

checkAddress(address?: string): boolean;

checkMnemonic(mnemonic: string, language: Language): boolean;
Expand Down Expand Up @@ -54,7 +56,7 @@ export interface ContractInterface {

getContracts(target: string): Promise<any>;

deployWasmContract(contractAccount: string, contractName: string, code: string, lang: string, initArgs: any, account?: AccountModel): Promise<any>;
deployWasmContract(contractAccount: string, contractName: string, code: string, lang: string, initArgs: any, upgrade: boolean, account?: AccountModel): Promise<any>;

// upgradeContract(): Promise<any>;
// imvokeContract(): Promise<any>;
Expand Down
Loading

0 comments on commit b6c4bc9

Please sign in to comment.