Skip to content

Commit

Permalink
Merge pull request #384 from multiversx/replace-bignumber-with-bigint
Browse files Browse the repository at this point in the history
Replaced BigNumber with BigInt
  • Loading branch information
popenta committed Feb 20, 2024
2 parents eca0221 + b3ce9ae commit 2647a16
Show file tree
Hide file tree
Showing 18 changed files with 361 additions and 390 deletions.
8 changes: 4 additions & 4 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ export type ITokenPayment = ITokenTransfer;
export interface ITransactionNext {
sender: string;
receiver: string;
gasLimit: BigNumber.Value;
gasLimit: bigint;
chainID: string;
nonce: BigNumber.Value;
value: BigNumber.Value;
nonce: bigint;
value: bigint;
senderUsername: string;
receiverUsername: string;
gasPrice: BigNumber.Value;
gasPrice: bigint;
data: Uint8Array;
version: number;
options: number;
Expand Down
6 changes: 3 additions & 3 deletions src/smartcontracts/smartContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export class SmartContract implements ISmartContract {
const nextTx = scNextTransactionFactory.createTransactionForDeploy({
sender: deployer,
bytecode: bytecode,
gasLimit: gasLimit.valueOf(),
gasLimit: BigInt(gasLimit.valueOf()),
args: initArguments,
isUpgradeable: metadataAsJson.upgradeable,
isReadable: metadataAsJson.readable,
Expand Down Expand Up @@ -191,7 +191,7 @@ export class SmartContract implements ISmartContract {
sender: caller,
contract: this.getAddress(),
bytecode: bytecode,
gasLimit: gasLimit.valueOf(),
gasLimit: BigInt(gasLimit.valueOf()),
args: initArguments,
isUpgradeable: metadataAsJson.upgradeable,
isReadable: metadataAsJson.readable,
Expand Down Expand Up @@ -229,7 +229,7 @@ export class SmartContract implements ISmartContract {
sender: caller,
contract: receiver ? receiver : this.getAddress(),
functionName: func.toString(),
gasLimit: gasLimit.valueOf(),
gasLimit: BigInt(gasLimit.valueOf()),
args: args
})

Expand Down
8 changes: 4 additions & 4 deletions src/transaction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ describe("test transaction construction", async () => {
const plainTransactionNextObject = {
sender: "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th",
receiver: "erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx",
gasLimit: 56000,
value: "1000000000000000000",
gasLimit: 56000n,
value: 1000000000000000000n,
data: Buffer.from("test"),
chainID: "T"
};
Expand All @@ -32,8 +32,8 @@ describe("test transaction construction", async () => {
const transaction = Transaction.fromTransactionNext(nextTransaction);
assert.deepEqual(transaction.getSender(), Address.fromBech32(plainTransactionNextObject.sender));
assert.deepEqual(transaction.getReceiver(), Address.fromBech32(plainTransactionNextObject.receiver));
assert.equal(transaction.getGasLimit().valueOf(), plainTransactionNextObject.gasLimit);
assert.equal(transaction.getValue().toString(), plainTransactionNextObject.value);
assert.equal(transaction.getGasLimit().valueOf().toFixed(0), plainTransactionNextObject.gasLimit.toString());
assert.equal(transaction.getValue().toString(), plainTransactionNextObject.value.toString());
assert.equal(transaction.getData().toString(), plainTransactionNextObject.data.toString());
assert.equal(transaction.getChainID().valueOf(), plainTransactionNextObject.chainID);
assert.equal(transaction.getNonce().valueOf(), 0);
Expand Down
46 changes: 22 additions & 24 deletions src/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,9 @@ export class Transaction {
const tx = new Transaction({
sender: Address.fromBech32(transaction.sender),
receiver: Address.fromBech32(transaction.receiver),
gasLimit: new BigNumber(transaction.gasLimit).toNumber(),
gasLimit: Number(transaction.gasLimit),
chainID: transaction.chainID,
value: new BigNumber(transaction.value).toFixed(0),
value: new BigNumber(transaction.value.toString()).toFixed(0),
data: new TransactionPayload(Buffer.from(transaction.data)),
nonce: Number(transaction.nonce),
gasPrice: Number(transaction.gasPrice),
Expand Down Expand Up @@ -485,12 +485,12 @@ export class TransactionNext {
/**
* The nonce of the transaction (the account sequence number of the sender).
*/
public nonce: BigNumber.Value;
public nonce: bigint;

/**
* The value to transfer.
*/
public value: BigNumber.Value;
public value: bigint;

/**
* The address of the sender.
Expand All @@ -515,12 +515,12 @@ export class TransactionNext {
/**
* The gas price to be used.
*/
public gasPrice: BigNumber.Value;
public gasPrice: bigint;

/**
* The maximum amount of gas to be consumed when processing the transaction.
*/
public gasLimit: BigNumber.Value;
public gasLimit: bigint;

/**
* The payload of the transaction.
Expand Down Expand Up @@ -575,27 +575,27 @@ export class TransactionNext {
options,
guardian,
}: {
nonce?: BigNumber.Value;
value?: BigNumber.Value;
nonce?: bigint;
value?: bigint;
sender: string;
receiver: string;
senderUsername?: string;
receiverUsername?: string;
gasPrice?: BigNumber.Value;
gasLimit: BigNumber.Value;
gasPrice?: bigint;
gasLimit: bigint;
data?: Uint8Array;
chainID: string;
version?: number;
options?: number;
guardian?: string;
}) {
this.nonce = nonce || 0;
this.value = value || new BigNumber(0);
this.nonce = nonce || 0n;
this.value = value || 0n;
this.sender = sender;
this.receiver = receiver;
this.senderUsername = senderUsername || "";
this.receiverUsername = receiverUsername || "";
this.gasPrice = gasPrice || new BigNumber(TRANSACTION_MIN_GAS_PRICE);
this.gasPrice = gasPrice || BigInt(TRANSACTION_MIN_GAS_PRICE);
this.gasLimit = gasLimit;
this.data = data || new Uint8Array();
this.chainID = chainID;
Expand All @@ -614,26 +614,24 @@ export class TransactionNext {
export class TransactionComputer {
constructor() { }

computeTransactionFee(transaction: ITransactionNext, networkConfig: INetworkConfig): BigNumber {
const moveBalanceGas = new BigNumber(
computeTransactionFee(transaction: ITransactionNext, networkConfig: INetworkConfig): bigint {
const moveBalanceGas = BigInt(
networkConfig.MinGasLimit + transaction.data.length * networkConfig.GasPerDataByte);
if (moveBalanceGas > transaction.gasLimit) {
throw new errors.ErrNotEnoughGas(parseInt(transaction.gasLimit.toString(), 10));
}

const gasPrice = new BigNumber(transaction.gasPrice);
const feeForMove = moveBalanceGas.multipliedBy(gasPrice);
const gasPrice = transaction.gasPrice;
const feeForMove = moveBalanceGas * gasPrice;
if (moveBalanceGas === transaction.gasLimit) {
return feeForMove;
}

const diff = new BigNumber(transaction.gasLimit).minus(moveBalanceGas);
const modifiedGasPrice = gasPrice.multipliedBy(
new BigNumber(networkConfig.GasPriceModifier)
);
const processingFee = diff.multipliedBy(modifiedGasPrice);
const diff = transaction.gasLimit - moveBalanceGas;
const modifiedGasPrice = BigInt(new BigNumber(gasPrice.toString()).multipliedBy(new BigNumber(networkConfig.GasPriceModifier)).toFixed(0));
const processingFee = diff * modifiedGasPrice;

return feeForMove.plus(processingFee);
return feeForMove + processingFee;
}

computeBytesForSigning(transaction: ITransactionNext): Uint8Array {
Expand Down Expand Up @@ -671,7 +669,7 @@ export class TransactionComputer {
private toPlainObject(transaction: ITransactionNext) {
return {
nonce: Number(transaction.nonce),
value: new BigNumber(transaction.value).toFixed(0),
value: transaction.value.toString(),
receiver: transaction.receiver,
sender: transaction.sender,
senderUsername: transaction.senderUsername ? Buffer.from(transaction.senderUsername).toString("base64") : undefined,
Expand Down
71 changes: 35 additions & 36 deletions src/transactionNext.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { assert } from "chai";
import { TestWallet, loadTestWallets } from "./testutils";
import { TransactionNext, TransactionComputer, Transaction } from "./transaction";
import BigNumber from "bignumber.js";
import { ProtoSerializer } from "./proto";

class NetworkConfig {
Expand Down Expand Up @@ -35,28 +34,28 @@ describe("test transaction next", async () => {
chainID: networkConfig.ChainID,
sender: sender,
receiver: receiver,
gasLimit: 50000,
value: 0,
gasLimit: 50000n,
value: 0n,
version: 2,
nonce: 89,
nonce: 89n,
});

let serializedTransactionBytes = transactionComputer.computeBytesForSigning(transaction);
let serializedTransaction = Buffer.from(serializedTransactionBytes).toString();

assert.equal(
serializedTransaction,
`{"nonce":89,"value":"0","receiver":"erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx","sender":"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th","gasPrice":1000000000,"gasLimit":50000,"chainID":"D","version":2}`
`{"nonce":89,"value":"0","receiver":"erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx","sender":"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th","gasPrice":1000000000,"gasLimit":50000,"chainID":"D","version":2}`,
);

transaction = new TransactionNext({
chainID: networkConfig.ChainID,
sender: sender,
receiver: receiver,
gasLimit: 70000,
value: new BigNumber("1000000000000000000"),
gasLimit: 70000n,
value: 1000000000000000000n,
version: 2,
nonce: 90,
nonce: 90n,
data: new Uint8Array(Buffer.from("hello")),
});

Expand All @@ -65,7 +64,7 @@ describe("test transaction next", async () => {

assert.equal(
serializedTransaction,
`{"nonce":90,"value":"1000000000000000000","receiver":"erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx","sender":"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th","gasPrice":1000000000,"gasLimit":70000,"data":"aGVsbG8=","chainID":"D","version":2}`
`{"nonce":90,"value":"1000000000000000000","receiver":"erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx","sender":"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th","gasPrice":1000000000,"gasLimit":70000,"data":"aGVsbG8=","chainID":"D","version":2}`,
);
});

Expand All @@ -74,22 +73,22 @@ describe("test transaction next", async () => {
chainID: "T",
sender: wallets.carol.address.bech32(),
receiver: wallets.alice.address.bech32(),
gasLimit: 50000,
value: new BigNumber("1000000000000000000"),
gasLimit: 50000n,
value: 1000000000000000000n,
version: 2,
nonce: 204,
nonce: 204n,
senderUsername: "carol",
receiverUsername: "alice",
});

transaction.signature = await wallets.carol.signer.sign(
Buffer.from(transactionComputer.computeBytesForSigning(transaction))
Buffer.from(transactionComputer.computeBytesForSigning(transaction)),
);
console.log(Buffer.from(transaction.signature).toString("hex"));

assert.equal(
Buffer.from(transaction.signature).toString("hex"),
"51e6cd78fb3ab4b53ff7ad6864df27cb4a56d70603332869d47a5cf6ea977c30e696103e41e8dddf2582996ad335229fdf4acb726564dbc1a0bc9e705b511f06"
"51e6cd78fb3ab4b53ff7ad6864df27cb4a56d70603332869d47a5cf6ea977c30e696103e41e8dddf2582996ad335229fdf4acb726564dbc1a0bc9e705b511f06",
);
});

Expand All @@ -98,21 +97,21 @@ describe("test transaction next", async () => {
chainID: networkConfig.ChainID,
sender: wallets.alice.address.bech32(),
receiver: wallets.alice.address.bech32(),
gasLimit: 100000,
value: new BigNumber("1000000000000"),
gasLimit: 100000n,
value: 1000000000000n,
version: 2,
nonce: 17243,
nonce: 17243n,
data: Buffer.from("testtx"),
});
transaction.signature = Buffer.from(
"eaa9e4dfbd21695d9511e9754bde13e90c5cfb21748a339a79be11f744c71872e9fe8e73c6035c413f5f08eef09e5458e9ea6fc315ff4da0ab6d000b450b2a07",
"hex"
"hex",
);

const hash = transactionComputer.computeTransactionHash(transaction);
assert.equal(
Buffer.from(hash).toString("hex"),
"169b76b752b220a76a93aeebc462a1192db1dc2ec9d17e6b4d7b0dcc91792f03"
"169b76b752b220a76a93aeebc462a1192db1dc2ec9d17e6b4d7b0dcc91792f03",
);
});

Expand All @@ -121,23 +120,23 @@ describe("test transaction next", async () => {
chainID: networkConfig.ChainID,
sender: wallets.alice.address.bech32(),
receiver: wallets.alice.address.bech32(),
gasLimit: 100000,
value: new BigNumber("1000000000000"),
gasLimit: 100000n,
value: 1000000000000n,
version: 2,
nonce: 17244,
nonce: 17244n,
data: Buffer.from("testtx"),
senderUsername: "alice",
receiverUsername: "alice",
});
transaction.signature = Buffer.from(
"807bcd7de5553ea6dfc57c0510e84d46813c5963d90fec50991c500091408fcf6216dca48dae16a579a1611ed8b2834bae8bd0027dc17eb557963f7151b82c07",
"hex"
"hex",
);

const hash = transactionComputer.computeTransactionHash(transaction);
assert.equal(
Buffer.from(hash).toString("hex"),
"41b5acf7ebaf4a9165a64206b6ebc02021b3adda55ffb2a2698aac2e7004dc29"
"41b5acf7ebaf4a9165a64206b6ebc02021b3adda55ffb2a2698aac2e7004dc29",
);
});

Expand All @@ -146,7 +145,7 @@ describe("test transaction next", async () => {
chainID: networkConfig.ChainID,
sender: wallets.alice.address.bech32(),
receiver: wallets.alice.address.bech32(),
gasLimit: 50000,
gasLimit: 50000n,
data: Buffer.from("toolittlegaslimit"),
});

Expand All @@ -160,8 +159,8 @@ describe("test transaction next", async () => {
chainID: networkConfig.ChainID,
sender: wallets.alice.address.bech32(),
receiver: wallets.alice.address.bech32(),
gasLimit: 20,
gasPrice: 500,
gasLimit: 20n,
gasPrice: 500n,
});

const config = new NetworkConfig(10);
Expand All @@ -174,8 +173,8 @@ describe("test transaction next", async () => {
chainID: networkConfig.ChainID,
sender: wallets.alice.address.bech32(),
receiver: wallets.alice.address.bech32(),
gasLimit: 12010,
gasPrice: 500,
gasLimit: 12010n,
gasPrice: 500n,
data: Buffer.from("testdata"),
});

Expand All @@ -191,18 +190,18 @@ describe("test transaction next", async () => {
chainID: "local-testnet",
sender: alice.address.bech32(),
receiver: wallets.bob.address.bech32(),
gasLimit: 150000,
gasPrice: 1000000000,
gasLimit: 150000n,
gasPrice: 1000000000n,
data: new Uint8Array(Buffer.from("test data field")),
version: 2,
options: 2,
nonce: 92,
value: new BigNumber("123456789000000000000000000000"),
nonce: 92n,
value: 123456789000000000000000000000n,
guardian: "erd1x23lzn8483xs2su4fak0r0dqx6w38enpmmqf2yrkylwq7mfnvyhsxqw57y",
});
transaction.guardianSignature = new Uint8Array(64);
transaction.signature = new Uint8Array(
await alice.signer.sign(Buffer.from(transactionComputer.computeBytesForSigning(transaction)))
await alice.signer.sign(Buffer.from(transactionComputer.computeBytesForSigning(transaction))),
);

const oldTransaction = Transaction.fromTransactionNext(transaction);
Expand All @@ -211,13 +210,13 @@ describe("test transaction next", async () => {
let buffer = serializer.serializeTransaction(oldTransaction);
assert.equal(
buffer.toString("hex"),
"085c120e00018ee90ff6181f3761632000001a208049d639e5a6980d1cd2392abcce41029cda74a1563523a202f09641cc2618f82a200139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1388094ebdc0340f093094a0f746573742064617461206669656c64520d6c6f63616c2d746573746e657458026240e574d78b19e1481a6b9575c162e66f2f906a3178aec537509356385c4f1a5330a9b73a87a456fc6d7041e93b5f8a1231a92fb390174872a104a0929215600c0c6802722032a3f14cf53c4d0543954f6cf1bda0369d13e661dec095107627dc0f6d33612f7a4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
"085c120e00018ee90ff6181f3761632000001a208049d639e5a6980d1cd2392abcce41029cda74a1563523a202f09641cc2618f82a200139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1388094ebdc0340f093094a0f746573742064617461206669656c64520d6c6f63616c2d746573746e657458026240e574d78b19e1481a6b9575c162e66f2f906a3178aec537509356385c4f1a5330a9b73a87a456fc6d7041e93b5f8a1231a92fb390174872a104a0929215600c0c6802722032a3f14cf53c4d0543954f6cf1bda0369d13e661dec095107627dc0f6d33612f7a4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
);

const txHash = transactionComputer.computeTransactionHash(transaction);
assert.equal(
Buffer.from(txHash).toString("hex"),
"242022e9dcfa0ee1d8199b0043314dbda8601619f70069ebc441b9f03349a35c"
"242022e9dcfa0ee1d8199b0043314dbda8601619f70069ebc441b9f03349a35c",
);
});
});
Loading

0 comments on commit 2647a16

Please sign in to comment.