JavaScript testing helpers for Ethereum smart contract development with assertions, event verification, balance tracking, and time manipulation.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Common Ethereum constants and utility functions for conversions, interface IDs, and transaction sending. Essential building blocks for smart contract testing.
Common constants used in Ethereum smart contract development.
const constants = {
/**
* Zero address - commonly used as null address
* @type {string}
*/
ZERO_ADDRESS: '0x0000000000000000000000000000000000000000',
/**
* Zero bytes32 value - commonly used as null bytes32
* @type {string}
*/
ZERO_BYTES32: '0x0000000000000000000000000000000000000000000000000000000000000000',
/**
* Maximum uint256 value (2^256 - 1)
* @type {BN}
*/
MAX_UINT256: BN,
/**
* Maximum int256 value (2^255 - 1)
* @type {BN}
*/
MAX_INT256: BN,
/**
* Minimum int256 value (-2^255)
* @type {BN}
*/
MIN_INT256: BN,
};Usage Examples:
const { constants, expectRevert } = require('@openzeppelin/test-helpers');
// Test zero address validation
await expectRevert(
token.transfer(constants.ZERO_ADDRESS, 100),
'ERC20: transfer to the zero address'
);
// Test maximum values
await token.approve(spender, constants.MAX_UINT256);
// Test with zero bytes32
await myContract.setData(constants.ZERO_BYTES32);Convert ether amounts to wei for precise calculations.
/**
* Convert ether amount to wei as BigNumber
* @param {string|number} n - Amount in ether
* @returns {BN} - Amount in wei as BigNumber
*/
function ether(n);Usage Examples:
const { ether, BN } = require('@openzeppelin/test-helpers');
// Convert ether to wei
const oneEther = ether('1');
console.log(oneEther.toString()); // "1000000000000000000"
// Use in transactions
await contract.deposit({ value: ether('0.5') });
// Compare with BN
const halfEther = new BN('500000000000000000');
expect(ether('0.5')).to.be.bignumber.equal(halfEther);
// Use in calculations
const totalValue = ether('1.5').add(ether('2.3'));
expect(totalValue).to.be.bignumber.equal(ether('3.8'));Generate interface IDs for ERC165 and ERC1820 standards.
/**
* Generate ERC165 interface ID from function signatures
* @param {string[]} functionSignatures - Array of function signature strings
* @returns {string} - 4-byte interface ID as hex string
*/
function makeInterfaceId.ERC165(functionSignatures = []);
/**
* Generate ERC1820 interface hash from interface name
* @param {string} interfaceName - Name of the interface
* @returns {string} - 32-byte interface hash as hex string
*/
function makeInterfaceId.ERC1820(interfaceName);Usage Examples:
const { makeInterfaceId } = require('@openzeppelin/test-helpers');
// Generate ERC165 interface ID for ERC721
const ERC721InterfaceId = makeInterfaceId.ERC165([
'balanceOf(address)',
'ownerOf(uint256)',
'approve(address,uint256)',
'getApproved(uint256)',
'setApprovalForAll(address,bool)',
'isApprovedForAll(address,address)',
'transferFrom(address,address,uint256)',
'safeTransferFrom(address,address,uint256)',
'safeTransferFrom(address,address,uint256,bytes)',
]);
console.log('ERC721 Interface ID:', ERC721InterfaceId); // "0x80ac58cd"
// Test interface support
const supportsInterface = await nft.supportsInterface(ERC721InterfaceId);
expect(supportsInterface).to.equal(true);
// Generate ERC1820 interface hash
const ERC777TokensRecipientHash = makeInterfaceId.ERC1820('ERC777TokensRecipient');
console.log('ERC777TokensRecipient Hash:', ERC777TokensRecipientHash);Low-level transaction sending utilities for custom scenarios.
/**
* Send ether from one address to another
* @param {string} from - Sender address
* @param {string} to - Recipient address
* @param {BN|string|number} value - Amount to send in wei
* @returns {Promise<TransactionReceipt>} - Transaction receipt
*/
async function send.ether(from, to, value);
/**
* Send a transaction to call a contract function
* @param {ContractInstance} target - Contract instance to call
* @param {string} name - Function name to call
* @param {string} argsTypes - Comma-separated argument types
* @param {any[]} argsValues - Array of argument values
* @param {object} opts - Transaction options (from, gas, etc.)
* @returns {Promise<TransactionReceipt>} - Transaction receipt
*/
async function send.transaction(target, name, argsTypes, argsValues, opts = {});Usage Examples:
const { send, ether } = require('@openzeppelin/test-helpers');
// Send ether between accounts
await send.ether(sender, recipient, ether('1'));
// Call contract function with encoded parameters
await send.transaction(
myContract,
'transfer',
'address,uint256',
[recipient, ether('100')],
{ from: sender }
);
// Advanced transaction with custom gas
await send.transaction(
complexContract,
'complexFunction',
'uint256[],string,bool',
[[1, 2, 3], 'hello', true],
{ from: sender, gas: 200000 }
);const { makeInterfaceId } = require('@openzeppelin/test-helpers');
contract('MyNFT', function () {
it('should support required interfaces', async function () {
// ERC165
const ERC165InterfaceId = makeInterfaceId.ERC165(['supportsInterface(bytes4)']);
expect(await this.nft.supportsInterface(ERC165InterfaceId)).to.equal(true);
// ERC721
const ERC721InterfaceId = makeInterfaceId.ERC165([
'balanceOf(address)',
'ownerOf(uint256)',
'approve(address,uint256)',
'getApproved(uint256)',
'setApprovalForAll(address,bool)',
'isApprovedForAll(address,address)',
'transferFrom(address,address,uint256)',
'safeTransferFrom(address,address,uint256)',
'safeTransferFrom(address,address,uint256,bytes)',
]);
expect(await this.nft.supportsInterface(ERC721InterfaceId)).to.equal(true);
});
});const { constants, expectRevert, ether } = require('@openzeppelin/test-helpers');
contract('Token', function ([owner, user]) {
it('should handle maximum approvals', async function () {
// Approve maximum amount
await this.token.approve(user, constants.MAX_UINT256, { from: owner });
const allowance = await this.token.allowance(owner, user);
expect(allowance).to.be.bignumber.equal(constants.MAX_UINT256);
});
it('should reject zero address operations', async function () {
await expectRevert(
this.token.transfer(constants.ZERO_ADDRESS, ether('1')),
'ERC20: transfer to the zero address'
);
await expectRevert(
this.token.approve(constants.ZERO_ADDRESS, ether('1')),
'ERC20: approve to the zero address'
);
});
});const { send, ether, expectEvent } = require('@openzeppelin/test-helpers');
contract('PaymentSplitter', function ([owner, beneficiary1, beneficiary2]) {
it('should handle direct ether transfers', async function () {
// Send ether directly to contract
const receipt = await send.ether(
owner,
this.splitter.address,
ether('1')
);
// Check for payment received event
await expectEvent.inTransaction(
receipt.transactionHash,
this.splitter,
'PaymentReceived',
{ from: owner, amount: ether('1') }
);
});
});// All constants are BigNumber instances
constants.MAX_UINT256.toString(); // "115792089237316195423570985008687907853269984665640564039457584007913129639935"
constants.MAX_INT256.toString(); // "57896044618658097711785492504343953926634992332820282019728792003956564819967"
constants.MIN_INT256.toString(); // "-57896044618658097711785492504343953926634992332820282019728792003956564819968"constants.ZERO_ADDRESS; // "0x0000000000000000000000000000000000000000"
constants.ZERO_BYTES32; // "0x0000000000000000000000000000000000000000000000000000000000000000"Install with Tessl CLI
npx tessl i tessl/npm-openzeppelin--test-helpers