Solidity utilities
To facilitate cross-chain development, we have provided some Solidity utilites. These can be found here (opens in a new tab). Each of these is described below, along with their proposed use.
Constant Address Deployer
Creating a cross-chain dApp will often require the same contract to be deployed on multiple chains.
Furthermore, it is useful to know each address of this contract on each chain, either to know where to send remote contract calls, or where to trust remote contract calls from -- often both.
If we can guarantee that the contracts in question will be deployed at the same address on each network, then the above is trivial.
This can be achieved by deploying each contract from the same address with the same nonce at each network, or by using create2
(opens in a new tab).
For this purpose, we deployed ConstAddressDeployer
(opens in a new tab) at
0x98b2920d53612483f91f12ed7754e51b4a77919e
on every EVM testnet and mainnet that is supported by Axelar.
We plan on deploying it on future supported testnets and mainnets, too.
ConstAddressDeployer
exposes the following functions:
deployedAddress(bytes bytecode, address sender, bytes32 salt)
: calculates the address of contracts that has been/will be deployed with a certain bytecode and salt, by a certain sender.deploy(bytes bytecode, bytes32 salt)
: deploys a contract with a certain bytecode and salt.deployAndInit(bytes bytecode, bytes32 salt, bytes init)
: deploys a contract with a certain bytecode and salt, and runsdeployedContract.call(init)
afterwards. Use in case you need constructor arguments that are not constant across chains, as different constructor arguments result in different bytecodes.
The above can be used directly, but we also provide some scripts. Simply use require('@axelar-network/axelar-utils-solidity')
to access:
async estimateGasForDeploy(contractJson, args = [])
: estimates the gas needed to deploy a contract with a certaincontractJson
andargs
async estimateGasForDeployAndInit(contractJson, args = [], initArgs = [])
: estimates the gas needed to deploy a contract with a certaincontractJson
andargs
, and to have theinit(...initArgs)
called as part of the deployment.async deployContractConstant(deployer, wallet, contractJson, key, args = [])
: usesdeployer
, an Ethers.js contract pointing to:ConstAddressDeployer
, awallet
with native currency.- The
contractJson
to deploy. - A string
key
, which will be hashed to get thesalt
. - The constructor
args
to make a deployment.
async deployAndInitContractConstant(deployer, wallet, contractJson, key, args = [], initArgs = [])
: same as above, but usesdeployAndInit
(withinitArgs
), instead ofdeploy
.
String and address utilities
Axelar uses the string representation of addresses (42 characters) for EVM addresses (20 bytes). It is often useful to convert between the two. StringAddressUtils.sol
(opens in a new tab) is a library that can be used to do so. Below, see an example showing how to use it.
import { StringToAddress, AddressToString } from '../StringAddressUtils.sol';
contract Test {
using AddressToString for address;
using StringToAddress for string;
function addressToString(address address_) external pure returns (string memory) {
return address_.toString();
}
function stringToAddress(string calldata string_) external pure returns (address) {
return string_.toAddress();
}
}