From 84c41024be7da5d8b5a74b2ca03897bf8ff3cfc5 Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Wed, 9 Oct 2024 17:21:46 +0300 Subject: [PATCH] chore: reusable tinybarsToWeibars method and tests Signed-off-by: Nadezhda Popova --- packages/relay/src/formatters.ts | 11 +- packages/relay/src/lib/constants.ts | 1 + packages/relay/tests/lib/formatters.spec.ts | 26 ++++ packages/server/tests/helpers/assertions.ts | 7 +- scripts/signTransaction.js | 125 ++++++++++++++++++++ 5 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 scripts/signTransaction.js diff --git a/packages/relay/src/formatters.ts b/packages/relay/src/formatters.ts index eff447c706..55084ddf34 100644 --- a/packages/relay/src/formatters.ts +++ b/packages/relay/src/formatters.ts @@ -176,7 +176,7 @@ const formatContractResult = (cr: any) => { transactionIndex: nullableNumberTo0x(cr.transaction_index), type: cr.type === null ? '0x0' : nanOrNumberTo0x(cr.type), v: cr.v === null ? '0x0' : nanOrNumberTo0x(cr.v), - value: nanOrNumberTo0x(cr.amount * constants.TINYBAR_TO_WEIBAR_COEF), + value: nanOrNumberTo0x(tinybarsToWeibars(cr.amount)), // for legacy EIP155 with tx.chainId=0x0, mirror-node will return a '0x' (EMPTY_HEX) value for contract result's chain_id // which is incompatibile with certain tools (i.e. foundry). By setting this field, chainId, to undefined, the end jsonrpc // object will leave out this field, which is the proper behavior for other tools to be compatible with. @@ -301,6 +301,14 @@ const getFunctionSelector = (data?: string): string => { return data.replace(/^0x/, '').substring(0, 8); }; +const tinybarsToWeibars = (value: number | null) => { + if (value && value < 0) throw new Error('Invalid value - cannot pass negative number'); + if (value && value > constants.TOTAL_SUPPLY_TINYBARS) + throw new Error('Value cannot be more than the total supply of tinybars in the blockchain'); + + return value == null ? null : value * constants.TINYBAR_TO_WEIBAR_COEF; +}; + export { hashNumber, formatRequestIdMessage, @@ -328,4 +336,5 @@ export { ASCIIToHex, getFunctionSelector, mapKeysAndValues, + tinybarsToWeibars, }; diff --git a/packages/relay/src/lib/constants.ts b/packages/relay/src/lib/constants.ts index e86cf75739..abcbf5e6af 100644 --- a/packages/relay/src/lib/constants.ts +++ b/packages/relay/src/lib/constants.ts @@ -71,6 +71,7 @@ export enum CallType { export default { HBAR_TO_TINYBAR_COEF: 100_000_000, TINYBAR_TO_WEIBAR_COEF: 10_000_000_000, + TOTAL_SUPPLY_TINYBARS: 5_000_000_000_000_000_000, // 131072 bytes are 128kbytes SEND_RAW_TRANSACTION_SIZE_LIMIT: process.env.SEND_RAW_TRANSACTION_SIZE_LIMIT ? parseInt(process.env.SEND_RAW_TRANSACTION_SIZE_LIMIT) diff --git a/packages/relay/tests/lib/formatters.spec.ts b/packages/relay/tests/lib/formatters.spec.ts index bb21d85387..cd0c81d413 100644 --- a/packages/relay/tests/lib/formatters.spec.ts +++ b/packages/relay/tests/lib/formatters.spec.ts @@ -43,6 +43,7 @@ import { toNullIfEmptyHex, trimPrecedingZeros, weibarHexToTinyBarInt, + tinybarsToWeibars, } from '../../src/formatters'; import constants from '../../src/lib/constants'; import { BigNumber as BN } from 'bignumber.js'; @@ -737,4 +738,29 @@ describe('Formatters', () => { expect(result).to.deep.equal({ A: '1', B: '2', C: '3' }); }); }); + + describe('tinybarsToWeibars', () => { + it('should convert tinybars to weibars', () => { + expect(tinybarsToWeibars(10)).to.eql(100000000000); + }); + + it('should return null if null is passed', () => { + expect(tinybarsToWeibars(null)).to.eql(null); + }); + + it('should return 0 for 0 input', () => { + expect(tinybarsToWeibars(0)).to.eql(0); + }); + + it('should throw an error when value is smaller than 0', () => { + expect(() => tinybarsToWeibars(-10)).to.throw(Error, 'Invalid value - cannot pass negative number'); + }); + + it('should throw an error when value is larger than the total supply of tinybars', () => { + expect(() => tinybarsToWeibars(constants.TOTAL_SUPPLY_TINYBARS * 10)).to.throw( + Error, + 'Value cannot be more than the total supply of tinybars in the blockchain', + ); + }); + }); }); diff --git a/packages/server/tests/helpers/assertions.ts b/packages/server/tests/helpers/assertions.ts index 1a92dc1817..afa0a90326 100644 --- a/packages/server/tests/helpers/assertions.ts +++ b/packages/server/tests/helpers/assertions.ts @@ -190,9 +190,10 @@ export default class Assertions { relayResponse.transactionIndex, "Assert transaction: 'transactionIndex' should equal mirrorNode response", ).to.eq(ethers.toQuantity(mirrorNodeResponse.transaction_index)); - expect(relayResponse.value, "Assert transaction: 'value' should equal mirrorNode response").to.eq( - ethers.toQuantity(mirrorNodeResponse.amount), - ); + expect( + relayResponse.value, + "Assert transaction: 'value' should equal mirrorNode response converted in weibar", + ).to.eq(ethers.toQuantity(BigInt(mirrorNodeResponse.amount * constants.TINYBAR_TO_WEIBAR_COEF))); } static transactionReceipt = (transactionReceipt, mirrorResult, effectiveGas) => { diff --git a/scripts/signTransaction.js b/scripts/signTransaction.js new file mode 100644 index 0000000000..4b80659c6b --- /dev/null +++ b/scripts/signTransaction.js @@ -0,0 +1,125 @@ +require('ts-node/register'); +const helper = require('../packages/relay/tests/helpers.ts'); + +const gasPrice = '0x2C68AF0BB14000'; +const gasLimit = "0x493E0"; +const value = '0xDE0B6B3A7640000'; +const gasPrice1 = '0xa53f4c3c00'; +const defaultGasPrice = '0xA54F4C3C00'; +const bytecode ="0x6080604052348015600f57600080fd5b50609e8061001e6000396000f3fe608060405260043610602a5760003560e01c80635c36b18614603557806383197ef014605557600080fd5b36603057005b600080fd5b348015604057600080fd5b50600160405190815260200160405180910390f35b348015606057600080fd5b50606633ff5b00fea2646970667358221220886a6d6d6c88bcfc0063129ca2391a3d98aee75ad7fe3e870ec6679215456a3964736f6c63430008090033" +const estimateGassContractBytecode = "0x6080604052600160005534801561001557600080fd5b5060405161002290610064565b604051809103906000f08015801561003e573d6000803e3d6000fd5b50600180546001600160a01b0319166001600160a01b0392909216919091179055610070565b60938061105583390190565b610fd68061007f6000396000f3fe6080604052600436106101bb5760003560e01c806380f009b6116100ec578063ddf363d71161008a578063ec3e88cf11610064578063ec3e88cf14610461578063f96757d1146104a0578063fa5e414e146104b3578063ffaf0890146104d357600080fd5b8063ddf363d71461041b578063e080b4aa14610421578063e7df080e1461044157600080fd5b8063bbbfb986116100c6578063bbbfb986146103be578063c648049d146103d3578063d737d0c7146103f3578063dbb6f04a1461040657600080fd5b806380f009b61461036b57806383197ef01461038b578063bb376a961461039e57600080fd5b80635256b99d116101595780636e6662b9116101335780636e6662b914610301578063700799631461031657806374259795146103365780637df6ee271461034b57600080fd5b80635256b99d146102b65780635c929889146102d657806361bc221a146102eb57600080fd5b80633ec4de35116101955780633ec4de351461023957806341f32f0c146102615780634929af371461028157806351be4eaa146102a157600080fd5b80630c772ca5146101c75780630ec1551d146101f957806319a6e3d51461021757600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101dc6104f3565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561020557600080fd5b5060045b6040519081526020016101f0565b34801561022357600080fd5b50610237610232366004610d7a565b610565565b005b34801561024557600080fd5b50610209610254366004610daa565b6001600160a01b03163190565b34801561026d57600080fd5b5061023761027c366004610daa565b610609565b34801561028d57600080fd5b5061023761029c366004610d7a565b61068d565b3480156102ad57600080fd5b50610209610742565b3480156102c257600080fd5b506102376102d1366004610dc7565b61074a565b3480156102e257600080fd5b506101dc610770565b3480156102f757600080fd5b5061020960005481565b34801561030d57600080fd5b506101dc6107d8565b34801561032257600080fd5b50610237610331366004610daa565b61080a565b34801561034257600080fd5b50610237610885565b34801561035757600080fd5b50610237610366366004610daa565b610939565b34801561037757600080fd5b50610237610386366004610d7a565b6109b2565b34801561039757600080fd5b5061023733ff5b3480156103aa57600080fd5b506102096103b9366004610de0565b610a65565b3480156103ca57600080fd5b506101dc610b42565b3480156103df57600080fd5b506102376103ee366004610dc7565b600055565b3480156103ff57600080fd5b50336101dc565b34801561041257600080fd5b506101dc610baa565b34610209565b34801561042d57600080fd5b5061023761043c366004610daa565b610bdf565b34801561044d57600080fd5b5061023761045c366004610e19565b610c2a565b34801561046d57600080fd5b506040517fffffffff000000000000000000000000000000000000000000000000000000006000351681526020016101f0565b3480156104ac57600080fd5b50326101dc565b3480156104bf57600080fd5b506102376104ce366004610d7a565b610c7f565b3480156104df57600080fd5b506102376104ee366004610e19565b610d20565b6001546040517f38cc48316aea9070a6b9a07b3cefc3f4db049e914955401a9d60fc9eb4c698d180825260009260609284926001600160a01b039092169190602081600481878761c350f2602082810160405282875290945061055c9186018101908601610e45565b94505050505090565b60005b828110156106045760408051600481526024810182526020810180516001600160e01b03166338cc483160e01b17905290516001600160a01b038416916105ae91610e62565b600060405180830381855af49150503d80600081146105e9576040519150601f19603f3d011682016040523d82523d6000602084013e6105ee565b606091505b50505080806105fc90610eb3565b915050610568565b505050565b60408051600481526024810182526020810180516001600160e01b0316632d3c86dd60e11b17905290516001600160a01b0383169161064791610e62565b600060405180830381855afa9150503d8060008114610682576040519150601f19603f3d011682016040523d82523d6000602084013e610687565b606091505b50505050565b60005b8281101561060457816001600160a01b0316816040516024016106b591815260200190565b60408051601f198184030181529181526020820180516001600160e01b031663c648049d60e01b179052516106ea9190610e62565b6000604051808303816000865af19150503d8060008114610727576040519150601f19603f3d011682016040523d82523d6000602084013e61072c565b606091505b505050808061073a90610eb3565b915050610690565b60005a905090565b60005b8181101561076c5760008190558061076481610eb3565b91505061074d565b5050565b6001546040517f38cc48316aea9070a6b9a07b3cefc3f4db049e914955401a9d60fc9eb4c698d180825260009260609284926001600160a01b0390921691906020816004818661c350f4602082810160405282875290945061055c9186018101908601610e45565b6000806040516107e790610d56565b604051809103906000f080158015610803573d6000803e3d6000fd5b5092915050565b60408051600481526024810182526020810180516001600160e01b0316632d3c86dd60e11b17905290516001600160a01b0383169161084891610e62565b6000604051808303816000865af19150503d8060008114610682576040519150601f19603f3d011682016040523d82523d6000602084013e610687565b608061160c8152602081a07fac3e966f295f2d5312f973dc6d42f30a6dc1c1f76ab8ee91cc8ca5dad1fa60fd80602083a17fae85c7887d510d629d8eb59ca412c0bf604c72c550fb0eec2734b12c76f2760b8082602085a261055160a0527ff4cd3854cb47c6b2f68a3a796635d026b9b412a93dfb80dd411c544cbc3c1817808284604087a37fe32ef46652011110f84325a4871007ee80018c1b6728ee04ffae74eb557e3fbf818385604088a450505050565b60408051600481526024810182526020810180516001600160e01b0316632d3c86dd60e11b17905290516001600160a01b0383169161097791610e62565b600060405180830381855af49150503d8060008114610682576040519150601f19603f3d011682016040523d82523d6000602084013e610687565b60005b8281101561060457816001600160a01b0316816040516024016109da91815260200190565b60408051601f198184030181529181526020820180516001600160e01b031663c648049d60e01b17905251610a0f9190610e62565b600060405180830381855af49150503d8060008114610a4a576040519150601f19603f3d011682016040523d82523d6000602084013e610a4f565b606091505b5050508080610a5d90610eb3565b9150506109b5565b600082841015610b385760006001600160a01b038316610a86866001610ece565b6040516024810191909152604481018690526001600160a01b038516606482015260840160408051601f198184030181529181526020820180516001600160e01b0316635d9bb54b60e11b17905251610adf9190610e62565b6000604051808303816000865af19150503d8060008114610b1c576040519150601f19603f3d011682016040523d82523d6000602084013e610b21565b606091505b5091505080610b2f90610ee6565b9150610b3b9050565b50825b9392505050565b6001546040517f38cc48316aea9070a6b9a07b3cefc3f4db049e914955401a9d60fc9eb4c698d180825260009260609284926001600160a01b0390921691906020816004818661c350fa602082810160405282875290945061055c9186018101908601610e45565b60008060005460001b604051610bbf90610d56565b8190604051809103906000f5905080158015610803573d6000803e3d6000fd5b60606000807f5a790dba3c23b59f4183a2d8e5d0ceae10b15e337a4dcaeae2d5897a5f68a3d4905060405181815260208160048360008961c350f25060208101604052909252505050565b6040516001600160a01b038316908290600081818185875af1925050503d8060008114610c73576040519150601f19603f3d011682016040523d82523d6000602084013e610c78565b606091505b5050505050565b60005b828110156106045760408051600481526024810182526020810180516001600160e01b03166338cc483160e01b17905290516001600160a01b03841691610cc891610e62565b6000604051808303816000865af19150503d8060008114610d05576040519150601f19603f3d011682016040523d82523d6000602084013e610d0a565b606091505b5050508080610d1890610eb3565b915050610c82565b6040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015610604573d6000803e3d6000fd5b609380610f0e83390190565b6001600160a01b0381168114610d7757600080fd5b50565b60008060408385031215610d8d57600080fd5b823591506020830135610d9f81610d62565b809150509250929050565b600060208284031215610dbc57600080fd5b8135610b3b81610d62565b600060208284031215610dd957600080fd5b5035919050565b600080600060608486031215610df557600080fd5b83359250602084013591506040840135610e0e81610d62565b809150509250925092565b60008060408385031215610e2c57600080fd5b8235610e3781610d62565b946020939093013593505050565b600060208284031215610e5757600080fd5b8151610b3b81610d62565b6000825160005b81811015610e835760208186018101518583015201610e69565b81811115610e92576000828501525b509190910192915050565b634e487b7160e01b600052601160045260246000fd5b6000600019821415610ec757610ec7610e9d565b5060010190565b60008219821115610ee157610ee1610e9d565b500190565b80516020808301519190811015610f07576000198160200360031b1b821691505b5091905056fe6080604052348015600f57600080fd5b50607680601d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806338cc483114602d575b600080fd5b6040805130815290519081900360200190f3fea26469706673582212206581057925cb8c91b475dfd65cb1bc362e8198d1260dee32cec18103302c548464736f6c63430008090033a264697066735822122095333591d755aa725f8a8b489c8c528213ca55abc2d8981f073d5242f3b989f164736f6c634300080900336080604052348015600f57600080fd5b50607680601d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806338cc483114602d575b600080fd5b6040805130815290519081900360200190f3fea26469706673582212206581057925cb8c91b475dfd65cb1bc362e8198d1260dee32cec18103302c548464736f6c63430008090033" +let transaction1559 = { + nonce: 2, + chainId: 0x12a, + to: "0x67d8d32e9bf1a9968a5ff53b87d777aa8ebbee69", + from: "0x05fba803be258049a27b820088bab1cad2058871", + value, + gasLimit: gasLimit, + accessList: [], + maxPriorityFeePerGas: defaultGasPrice, + maxFeePerGas:defaultGasPrice +}; + +// let transaction2930 = { +// nonce: 0, +// chainId: 0x12a, +// to: "0x67D8d32E9Bf1a9968a5ff53B87d777Aa8EBBEe69", +// from: "0xc37f417fA09933335240FCA72DD257BFBdE9C275", +// value, +// gasLimit: gasLimit, +// type: 1, +// gasPrice: gasPrice, +// accessList: [], +// // maxPriorityFeePerGas: defaultGasPrice, +// // maxFeePerGas:defaultGasPrice + +// }; + +// let legacyTransaction = { +// nonce: 0, +// chainId: 0x12a, +// to: null, +// from: "0x29cbb51A44fd332c14180b4D471FBBc6654b1657", +// gasLimit: gasLimit, +// gasPrice: gasPrice, +// type: 0, +// value +// }; + +// let createContractLegacyTransaction = { +// nonce: 2, +// chainId: 0x12a, +// to: null, +// from: "0xc37f417fA09933335240FCA72DD257BFBdE9C275", +// gasLimit: gasLimit, +// gasPrice: gasPrice, +// type: 0, +// data: bytecode, +// }; +// // data: "0x608060405234801561001057600080fd5b506040516105fc3803806105fc83398101604081905261002f9161015f565b8051610042906000906020840190610080565b507fad181ee258ff92d26bf7ed2e6b571ef1cba3afc45f028b863b0f02adaffc2f0681604051610072919061020b565b60405180910390a150610279565b82805461008c9061023e565b90600052602060002090601f0160209004810192826100ae57600085556100f4565b82601f106100c757805160ff19168380011785556100f4565b828001600101855582156100f4579182015b828111156100f45782518255916020019190600101906100d9565b50610100929150610104565b5090565b5b808211156101005760008155600101610105565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561014a578181015183820152602001610132565b83811115610159576000848401525b50505050565b60006020828403121561017157600080fd5b81516001600160401b038082111561018857600080fd5b818401915084601f83011261019c57600080fd5b8151818111156101ae576101ae610119565b604051601f8201601f19908116603f011681019083821181831017156101d6576101d6610119565b816040528281528760208487010111156101ef57600080fd5b61020083602083016020880161012f565b979650505050505050565b602081526000825180602084015261022a81604085016020870161012f565b601f01601f19169190910160400192915050565b600181811c9082168061025257607f821691505b6020821081141561027357634e487b7160e01b600052602260045260246000fd5b50919050565b610374806102886000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae321714610050575b600080fd5b61004e6100493660046101fd565b61006e565b005b6100586100bc565b60405161006591906102ae565b60405180910390f35b805161008190600090602084019061014e565b507fad181ee258ff92d26bf7ed2e6b571ef1cba3afc45f028b863b0f02adaffc2f06816040516100b191906102ae565b60405180910390a150565b6060600080546100cb90610303565b80601f01602080910402602001604051908101604052809291908181526020018280546100f790610303565b80156101445780601f1061011957610100808354040283529160200191610144565b820191906000526020600020905b81548152906001019060200180831161012757829003601f168201915b5050505050905090565b82805461015a90610303565b90600052602060002090601f01602090048101928261017c57600085556101c2565b82601f1061019557805160ff19168380011785556101c2565b828001600101855582156101c2579182015b828111156101c25782518255916020019190600101906101a7565b506101ce9291506101d2565b5090565b5b808211156101ce57600081556001016101d3565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561020f57600080fd5b813567ffffffffffffffff8082111561022757600080fd5b818401915084601f83011261023b57600080fd5b81358181111561024d5761024d6101e7565b604051601f8201601f19908116603f01168101908382118183101715610275576102756101e7565b8160405282815287602084870101111561028e57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156102db578581018301518582016040015282016102bf565b818111156102ed576000604083870101525b50601f01601f1916929092016040019392505050565b600181811c9082168061031757607f821691505b6020821081141561033857634e487b7160e01b600052602260045260246000fd5b5091905056fea2646970667358221220d450959bd13a5c79ab8546a400f6af65e1c3d24b6877b871e663861bbf17234664736f6c63430008090033000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000076e696b6f6c617900000000000000000000000000000000000000000000000000" + +// let invokeFunction = { +// nonce: 4, +// chainId: 0x12a, +// to: "0x4a9c86ffbf6f46221a6b18ed5b26ecece19c9b27", +// from: "0xc37f417fA09933335240FCA72DD257BFBdE9C275", +// gasLimit: gasLimit, +// gasPrice: gasPrice, +// type: 0, +// data: '0x5c36b186', +// }; + +// let estimateGasContract = { +// nonce: 0, +// chainId: 0x12a, +// to: "0x637a6a8e5a69c087c24983b05261f63f64ed7e9c", +// from: "0xc37f417fA09933335240FCA72DD257BFBdE9C275", +// gasPrice: gasPrice, +// type: 2, +// data: estimateGassContractBytecode, +// gasLimit: gasLimit, +// maxPriorityFeePerGas: defaultGasPrice, +// maxFeePerGas:defaultGasPrice +// }; + +// let estimateGasContractDeploy = { +// nonce: 1, +// chainId: 0x12a, +// from: "0xc37f417fA09933335240FCA72DD257BFBdE9C275", +// gasPrice: gasPrice, +// type: 2, +// data: estimateGassContractBytecode, +// gasLimit: gasLimit, +// maxPriorityFeePerGas: defaultGasPrice, +// maxFeePerGas:defaultGasPrice +// }; + +// let estimateGasContractDelegate = { +// nonce: 1, +// chainId: 0x12a, +// to: "0xffc7d3ff264c838ad75167e64d043794bf1bd57c", +// from: "0xc37f417fA09933335240FCA72DD257BFBdE9C275", +// gasLimit: gasLimit, +// gasPrice: '0x333f4c3c00', +// type: 0, +// data: '0x5c929889', + +// }; + +// let estimateGasContractUpdateCounter = { +// nonce: 3, +// chainId: 0x12a, +// to: "0xffc7d3ff264c838ad75167e64d043794bf1bd57c", +// from: "0xc37f417fA09933335240FCA72DD257BFBdE9C275", +// gasLimit: gasLimit, +// gasPrice: gasPrice, +// type: 0, +// data: '0x1687fe8e', + +// }; + +async function main() { + const transactionHash = await helper.signTransaction(transaction1559, "0x2e1d968b041d84dd120a5860cee60cd83f9374ef527ca86996317ada3d0d03e7"); + console.log(transactionHash); +} +main(); \ No newline at end of file