-
Notifications
You must be signed in to change notification settings - Fork 73
Expand file tree
/
Copy pathHIP755.js
More file actions
148 lines (119 loc) · 6.01 KB
/
HIP755.js
File metadata and controls
148 lines (119 loc) · 6.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// SPDX-License-Identifier: Apache-2.0
const {expect} = require('chai');
const {ethers} = require('hardhat');
const Utils = require('../../hedera-token-service/utils');
const Constants = require('../../../constants');
const HashgraphProto = require('@hashgraph/proto');
const {
ScheduleCreateTransaction,
TransferTransaction,
Hbar,
HbarUnit,
PrivateKey
} = require('@hashgraph/sdk');
const convertScheduleIdToUint8Array = (scheduleId) => {
const [shard, realm, num] = scheduleId.split('.');
// size of the buffer is aligned with the services scheduleId to bytes conversion
// https://github.com/hiero-ledger/hiero-consensus-node/blob/main/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/utils/SystemContractUtils.java#L153
const buffer = new ArrayBuffer(24);
const dataView = new DataView(buffer);
dataView.setBigUint64(0, BigInt(shard));
dataView.setBigUint64(8, BigInt(realm));
dataView.setBigUint64(16, BigInt(num));
return new Uint8Array(buffer);
};
const getRandomInt = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
const createScheduleTransactionForTransfer = async (senderInfo, receiverInfo, client) => {
const transferAmountAsTinybars = getRandomInt(1, 100_000_000);
const transferAmountAsWeibar = BigInt(transferAmountAsTinybars) * BigInt(Utils.tinybarToWeibarCoef);
let transferTx = await new TransferTransaction()
.addHbarTransfer(senderInfo.accountId, new Hbar(-transferAmountAsTinybars, HbarUnit.Tinybar))
.addHbarTransfer(receiverInfo.accountId, new Hbar(transferAmountAsTinybars, HbarUnit.Tinybar));
const {scheduleId} = await (await new ScheduleCreateTransaction()
.setScheduledTransaction(transferTx)
.execute(client)).getReceipt(client);
return {scheduleId, transferAmountAsWeibar};
};
describe('HIP755 Test Suite', function () {
let genesisSdkClient, signers, signerSender, signerReceiver, senderInfo, receiverInfo, contractHRC755;
before(async () => {
genesisSdkClient = await Utils.createSDKClient();
signers = await ethers.getSigners();
signerSender = signers[0];
signerReceiver = signers[1];
senderInfo = await Utils.getAccountInfo(signerSender.address, genesisSdkClient);
receiverInfo = await Utils.getAccountInfo(signerReceiver.address, genesisSdkClient);
const contractHRC755Factory = await ethers.getContractFactory('HRC755Contract');
contractHRC755 = await contractHRC755Factory.deploy();
await contractHRC755.waitForDeployment();
});
it('should be able to signSchedule via IHRC755ScheduleFacade', async () => {
const {
scheduleId,
transferAmountAsWeibar
} = await createScheduleTransactionForTransfer(senderInfo, receiverInfo, genesisSdkClient);
const senderBalanceBefore = await signers[0].provider.getBalance(signerSender);
const receiverBalanceBefore = await signers[0].provider.getBalance(signerReceiver);
const contract = await ethers.getContractAt(
'IHRC755ScheduleFacade',
Utils.convertAccountIdToLongZeroAddress(scheduleId.toString(), true),
signerSender
);
const signScheduleTx = await contract.signSchedule(Constants.GAS_LIMIT_2_000_000);
await signScheduleTx.wait();
const senderBalanceAfter = await signers[0].provider.getBalance(signerSender);
const receiverBalanceAfter = await signers[0].provider.getBalance(signerReceiver);
expect(receiverBalanceBefore).to.not.equal(receiverBalanceAfter);
expect(senderBalanceBefore).to.not.equal(senderBalanceAfter);
expect(senderBalanceAfter + transferAmountAsWeibar).to.be.lessThanOrEqual(senderBalanceBefore);
expect(receiverBalanceBefore + transferAmountAsWeibar).to.equal(receiverBalanceAfter);
});
it('should be able to signSchedule via HRC755 contract', async () => {
const {
scheduleId,
transferAmountAsWeibar
} = await createScheduleTransactionForTransfer(senderInfo, receiverInfo, genesisSdkClient);
const privateKey = PrivateKey.fromStringECDSA(Utils.getHardhatSignerPrivateKeyByIndex(0));
const scheduleIdAsBytes = convertScheduleIdToUint8Array(scheduleId.toString());
const sigMapProtoEncoded = await HashgraphProto.proto.SignatureMap.encode({
sigPair: [{
pubKeyPrefix: privateKey.publicKey.toBytesRaw(),
ECDSASecp256k1: privateKey.sign(scheduleIdAsBytes)
}]
}).finish();
const senderBalanceBefore = await signers[0].provider.getBalance(signerSender);
const receiverBalanceBefore = await signers[0].provider.getBalance(signerReceiver);
const signScheduleCallTx = await contractHRC755.signScheduleCall(
Utils.convertAccountIdToLongZeroAddress(scheduleId.toString(), true),
sigMapProtoEncoded,
Constants.GAS_LIMIT_2_000_000
);
await signScheduleCallTx.wait();
const senderBalanceAfter = await signers[0].provider.getBalance(signerSender);
const receiverBalanceAfter = await signers[0].provider.getBalance(signerReceiver);
expect(receiverBalanceBefore).to.not.equal(receiverBalanceAfter);
expect(senderBalanceBefore).to.not.equal(senderBalanceAfter);
expect(senderBalanceAfter + transferAmountAsWeibar).to.be.lessThanOrEqual(senderBalanceBefore);
expect(receiverBalanceBefore + transferAmountAsWeibar).to.equal(receiverBalanceAfter);
});
it('should be able to authorizeSchedule via HRC755 contract', async () => {
const {scheduleId} = await createScheduleTransactionForTransfer(senderInfo, receiverInfo, genesisSdkClient);
const signScheduleCallTx = await contractHRC755.authorizeScheduleCall(
Utils.convertAccountIdToLongZeroAddress(scheduleId.toString(), true),
Constants.GAS_LIMIT_2_000_000
);
await signScheduleCallTx.wait();
const debugTraceRes = await signers[0].provider.send('debug_traceTransaction', [
signScheduleCallTx.hash, {
tracer: 'callTracer',
tracerConfig: {
onlyTopCall: true,
}
}
]
);
expect(parseInt(debugTraceRes.output)).to.equal(Constants.TX_SUCCESS_CODE);
});
});