Skip to content

Commit

Permalink
Adding tests for the Transactions in Solidity
Browse files Browse the repository at this point in the history
Signed-off-by: Stefan Stefanov <[email protected]>
  • Loading branch information
stefan-stefanooov committed Oct 11, 2023
1 parent c44c315 commit ea0f10a
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cache
# ignore non repo contract related aritifacts
artifacts/@openzeppelin
artifacts/build-info
artifacts/contracts/**/**.dbg.json
artifacts/contracts
.openzeppelin/unknown-298.json
.env
test-results.*
Expand Down
12 changes: 12 additions & 0 deletions contracts/solidity/transaction/Secondary.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

contract Secondary {
function getTxOrigin() public view returns (address) {
return tx.origin;
}

function getMsgSender() public view returns (address) {
return msg.sender;
}
}
54 changes: 54 additions & 0 deletions contracts/solidity/transaction/Transaction.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import { Secondary } from "./Secondary.sol";

contract Transaction {
string public message;
uint myInteger;
address secondaryAddr;
Secondary secondaryContract;
event MsgValue(uint256);

constructor(address secondaryAddress) {
secondaryAddr = secondaryAddress;
secondaryContract = Secondary(payable(secondaryAddress));
}

function checkGasleft() public view returns (uint256) {
return gasleft();
}

function getMessageData(uint integer, string memory inputMessage) public returns (bytes memory) {
message = inputMessage;
myInteger = integer;

return msg.data;
}

function getMessageSender() public view returns (address) {
return msg.sender;
}

function getMessageSignature() public pure returns (bytes4) {
return msg.sig;
}

function getMessageValue() public payable {
emit MsgValue(msg.value);
}

function getGasPrice() public view returns (uint256) {
return tx.gasprice;
}

function getTxOriginFromSecondary() public view returns (address) {
address secondaryOrigin = secondaryContract.getTxOrigin();
return secondaryOrigin;
}

function getMsgSenderFromSecondary() public view returns (address) {
address secondaryMsgSender = secondaryContract.getMsgSender();
return secondaryMsgSender;
}
}
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@openzeppelin/contracts": "^4.9.3",
"@openzeppelin/contracts-upgradeable": "^4.9.3",
"@openzeppelin/hardhat-upgrades": "^1.22.1",
"hardhat": "^2.14.0",
"hardhat": "^2.18.0",
"mocha-junit-reporter": "^2.2.0",
"mocha-multi-reporters": "^1.5.1",
"prettier": "3.0.0"
Expand Down
2 changes: 2 additions & 0 deletions test/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ const Contract = {
HRCContract: 'HRCContract',
ExchangeRateMock: 'ExchangeRateMock',
PrngSystemContract: 'PrngSystemContract',
Transaction: 'Transaction',
Secondary: 'Secondary',
}

const CALL_EXCEPTION = 'CALL_EXCEPTION'
Expand Down
118 changes: 118 additions & 0 deletions test/solidity/transaction/transaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*-
*
* Hedera Smart Contracts
*
* Copyright (C) 2023 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

const { expect } = require('chai')
const { ethers } = require('hardhat')
const Constants = require('../../constants')
const {
Hbar,
} = require("@hashgraph/sdk");

describe('PrngSystemContract tests', function () {
let contractTr, contractSec, wallet, senderWalletAddr

before(async function () {
const factoryTrasnactionSol = await ethers.getContractFactory(
Constants.Contract.Transaction
)
const factorySecondarySol = await ethers.getContractFactory(
Constants.Contract.Secondary
)

contractSec = await factorySecondarySol.deploy()
await contractSec.deployed();
contractTr = await factoryTrasnactionSol.deploy(contractSec.address)
await contractTr.deployed();

const signers = await ethers.getSigners()
wallet = signers[0];
senderWalletAddr = await wallet.getAddress()
})

it('gasleft() returns (uint256): remaining gas', async function () {
const gasLeft = await contractTr.checkGasleft()

expect(gasLeft).to.exist
expect(ethers.BigNumber.isBigNumber(gasLeft)).to.be.true
})

it('msg.data (bytes calldata): complete calldata', async function () {
const myString = 'Hello, world!';
const txRes = await contractTr.getMessageData(12, myString)
const returnedData = txRes.data

const ABI = [
"function getMessageData(uint integer, string memory inputMessage)"
];
const interface = new ethers.utils.Interface(ABI);
const encodedFunction = interface.encodeFunctionData("getMessageData", [ 12, myString ])

expect(returnedData).to.exist
expect(returnedData).to.be.equal(encodedFunction);
})

it('msg.sender (address): sender of the message (current call)', async function () {
const sender = await contractTr.getMessageSender()

expect(sender).to.exist
expect(sender).to.be.equal(senderWalletAddr);
})

it('msg.sig (bytes4): first four bytes of the calldata (i.e. function identifier)', async function () {
const msgSig = await contractTr.getMessageSignature()

const ABI = [
"function getMessageSignature()"
];
const interface = new ethers.utils.Interface(ABI);
const encodedFunctionSig = interface.encodeFunctionData("getMessageSignature")

expect(msgSig).to.exist
expect(msgSig).to.be.equal(encodedFunctionSig);
})

it('msg.value (uint): number of wei sent with the message', async function () {
const valueToSend = ethers.utils.parseEther(String(1));
const txRes = await contractTr.getMessageValue({value: valueToSend});
const receipt = await txRes.wait()
const amount = receipt.events[0].args[0]
ethers.utils.formatEther(amount)

// to compare with the value sent, we need to convert to tinybar
expect(amount.mul('10000000000')).to.equal(valueToSend)
})

it('tx.gasprice (uint): gas price of the transaction', async function () {
const gasPrice = await contractTr.getGasPrice()

expect(gasPrice).to.exist
expect(ethers.BigNumber.isBigNumber(gasPrice)).to.be.true
})

it('tx.origin (address): sender of the transaction (full call chain)', async function () {
const originAddr = await contractTr.getTxOriginFromSecondary()
const msgSender = await contractTr.getMsgSenderFromSecondary()

expect(originAddr).to.exist
expect(msgSender).to.exist
expect(originAddr).to.be.equal(senderWalletAddr);
expect(msgSender).to.be.equal(contractTr.address);
})
})

0 comments on commit ea0f10a

Please sign in to comment.