Skip to content

Commit aa1b811

Browse files
gupadhyayadenniswon
authored andcommitted
Merge pull request #45 from peekpi/master
contract method imporvement
2 parents 2a1bcbb + 6a0163e commit aa1b811

3 files changed

Lines changed: 53 additions & 31 deletions

File tree

packages/harmony-contract/src/contract.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ export class Contract {
2727
transaction?: Transaction;
2828
status: ContractStatus;
2929
shardID: number;
30+
errorFunc: string = 'Error(string)';
31+
errorFuncSig: string;
3032

3133
constructor(
3234
abi: any = [],
@@ -47,6 +49,7 @@ export class Contract {
4749
this.runMethodFactory();
4850
this.runEventFactory();
4951
this.status = status;
52+
this.errorFuncSig = this.abiCoder.encodeFunctionSignature(this.errorFunc);
5053
// tslint:disable-next-line: no-unused-expression
5154
}
5255
isInitialised() {

packages/harmony-contract/src/methods/method.ts

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,26 @@ export class ContractMethod {
4545

4646
const waitConfirm: boolean = params && params.waitConfirm === false ? false : true;
4747
const updateNonce: boolean = params && params.nonce !== undefined ? false : true;
48-
this.signTransaction(updateNonce).then((signed) => {
49-
this.sendTransaction(signed).then((sent) => {
50-
const [txn, id] = sent;
51-
this.transaction = txn;
52-
this.contract.transaction = this.transaction;
53-
if (waitConfirm && id.startsWith("0x")) {
54-
this.confirm(id).then(() => {
48+
this.signTransaction(updateNonce)
49+
.then((signed) => {
50+
this.sendTransaction(signed).then((sent) => {
51+
const [txn, id] = sent;
52+
this.transaction = txn;
53+
this.contract.transaction = this.transaction;
54+
if (this.transaction.isRejected()) {
55+
this.transaction.emitter.reject(id); // in this case, id is error message
56+
} else if (waitConfirm) {
57+
this.confirm(id).then(() => {
58+
this.transaction.emitter.resolve(this.contract);
59+
});
60+
} else {
5561
this.transaction.emitter.resolve(this.contract);
56-
});
57-
} else {
58-
this.transaction.emitter.resolve(this.contract);
59-
}
62+
}
63+
});
64+
})
65+
.catch((error) => {
66+
this.transaction.emitter.reject(error);
6067
});
61-
}).catch((error) => {
62-
this.transaction.emitter.reject(error);
63-
});
6468
};
6569

6670
// tslint:disable-next-line: prefer-conditional-expression
@@ -82,29 +86,23 @@ export class ContractMethod {
8286
}
8387
async call(options: any, blockNumber: any = 'latest') {
8488
try {
85-
options = { ...this.contract.options, ...options };
89+
options = { ...this.contract.options, data: this.transaction.txParams.data, ...options };
8690
const shardID =
8791
options !== undefined && options.shardID !== undefined
8892
? options.shardID
8993
: this.contract.shardID;
9094
const nonce = '0x0';
9195

92-
let gasLimit: any;
93-
// tslint:disable-next-line: prefer-conditional-expression
94-
if (options !== undefined) {
96+
let gasLimit: any = '21000000';
97+
if (options !== undefined && (options.gas || options.gasLimit)) {
9598
gasLimit = options.gas || options.gasLimit;
96-
} else {
97-
gasLimit = '21000000';
9899
}
99-
let from: string;
100-
// tslint:disable-next-line: prefer-conditional-expression
101-
if (this.wallet.signer) {
102-
from = options && options.from ? options.from : this.wallet.signer.address;
103-
} else {
104-
from =
105-
options && options.from ? options.from : '0x0000000000000000000000000000000000000000';
100+
let from: string = this.wallet.signer
101+
? this.wallet.signer.address
102+
: '0x0000000000000000000000000000000000000000';
103+
if (options && options.from) {
104+
from = options.from;
106105
}
107-
108106
this.transaction = this.transaction.map((tx: any) => {
109107
return {
110108
...tx,
@@ -321,11 +319,28 @@ export class ContractMethod {
321319
}
322320

323321
protected afterCall(response: any) {
324-
if (!response || response === '0x') {
325-
return null;
322+
// length of `0x${methodSig}` is 2+4*2=10
323+
if (response.length % 32 === 10 && response.startsWith(this.contract.errorFuncSig)) {
324+
const errmsg = this.contract.abiCoder.decodeParameters(
325+
[{ type: 'string' }],
326+
'0x' + response.slice(10),
327+
);
328+
throw { revert: errmsg[0] };
329+
}
330+
331+
if (this.methodKey === 'contractConstructor') {
332+
return response;
326333
}
327334

328335
const outputs = this.abiItem.getOutputs();
336+
if (outputs.length === 0) {
337+
// if outputs is empty, we can't know the call is revert or not
338+
return response;
339+
}
340+
if (!response || response === '0x') {
341+
// if outputs isn't empty, treat it as revert
342+
throw { revert: response };
343+
}
329344
if (outputs.length > 1) {
330345
return this.contract.abiCoder.decodeParameters(outputs, response);
331346
}

packages/harmony-crypto/src/keyTool.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import * as errors from './errors';
99

1010
import { keccak256 } from './keccak256';
1111
import { randomBytes } from './random';
12-
import { isPrivateKey, strip0x, isAddress } from '@harmony-js/utils';
12+
import { isPrivateKey, strip0x, isAddress, isBech32Address } from '@harmony-js/utils';
13+
import { fromBech32 } from './bech32';
1314
import { encode } from './rlp';
1415

1516
const secp256k1 = elliptic.ec('secp256k1');
@@ -81,6 +82,9 @@ export const getAddressFromPublicKey = (publicKey: string): string => {
8182
* @return {string} checksumed address
8283
*/
8384
export const toChecksumAddress = (address: string): string => {
85+
if (typeof address === 'string' && isBech32Address(address)) {
86+
address = fromBech32(address);
87+
}
8488
if (typeof address !== 'string' || !address.match(/^0x[0-9A-Fa-f]{40}$/)) {
8589
errors.throwError('invalid address', errors.INVALID_ARGUMENT, {
8690
arg: 'address',

0 commit comments

Comments
 (0)