exchange.IO("api", ...)
Calls a smart contract method on a Web3 exchange object. Read-only methods return the decoded value. Write methods sign and broadcast a transaction.
exchange.IO(k, address, method)
exchange.IO(k, address, method, ...args)
exchange.IO(k, address, method, value, ...args)
exchange.IO(k, address, method, ...args, options)Examples
-
The
decimalsmethod is aconstantmethod of ERC20. Calling it costs no gas. It returns the precision (number of decimals) of the specified token.The
decimalsmethod takes no parameters. Return value: the precision of the token.javascriptfunction main(){ var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302" // Contract address of the token; the token in this example is 1INCH Log(exchange.IO("api", tokenAddress, "decimals")) // Output: 18 (the precision of the 1INCH token) } -
The
allowancemethod is aconstantmethod of ERC20. Calling it costs no gas. It returns the amount of the specified token that a given contract address is approved to spend.The
allowancemethod takes 2 parameters: the first is the wallet address and the second is the approved (spender) address. Return value: the token allowance.owner: the wallet address. The example uses the string "owner" as a placeholder; replace it with the actual address.spender: the approved contract address. The example uses the string "spender" as a placeholder; replace it with the actual address, such as the address ofUniswap V3 router v1.javascriptfunction main(){ // Contract address of the token; the token in this example is 1INCH var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302" // If the query returns 1000000000000000000, dividing it by the token's precision unit 1e18 shows that the wallet bound to the current exchange object has approved the spender address for 1 1INCH Log(exchange.IO("api", tokenAddress, "allowance", "owner", "spender")) } -
The
approvemethod is a non-constantmethod of ERC20. Calling it costs gas. It approves a specified contract address to spend a given amount of the token.The
approvemethod takes 2 parameters: the first is the approved (spender) address and the second is the allowance amount. Return value: txid.spender: the approved contract address. The example uses the string "spender" as a placeholder; replace it with the actual address, such as the address ofUniswap V3 router v1.0xde0b6b3a7640000: the approved amount, written here as a hexadecimal string. Its decimal value is 1e18. Dividing it by the token's precision unit in the example (1e18) gives 1, so 1 token is approved.The third parameter of the
exchange.IO()function is the method nameapprove. You can also pass the methodId, e.g. "0x095ea7b3", or the full standard method signature, e.g. "approve(address,uint256)".javascriptfunction main(){ // Contract address of the token; the token in this example is 1INCH var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302" // Hexadecimal string of the allowance: 0xde0b6b3a7640000 , decimal value: 1e18 , 1e18 divided by the token's precision unit equals 1 token , so this approves 1 token Log(exchange.IO("api", tokenAddress, "approve", "spender", "0xde0b6b3a7640000")) } -
The
multicallmethod is a non-constantmethod ofUniswap V3. Calling it consumes gas. Use it to swap tokens across multiple paths.
multicallcan accept parameters in several ways; check the ABI that contains the method for details. Register the ABI before calling it. Return value: txid.
For swaps on Uniswap or PancakeSwap, you can use theUniswaporPancakeSwapexchange object directly instead of encoding the call yourself.The pseudocode below shows some of the details:
javascriptexchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data)ContractV3SwapRouterV2: the address of the Uniswap V3 router v2 contract.
value: the amount of native coin sent with the transaction, in wei (an on-chain integer; useexchange.IO("toUnits", "0.01", 18)to convert). Set it to 0 when the tokenIn token being swapped is not ETH.
deadline:deadlineis a parameter of themulticallmethod. You can set it to(new Date().getTime() / 1000) + 3600, which makes the transaction valid for one hour.
data:datais a parameter of themulticallmethod, of typebytes[]. It is an array of the call data (hexadecimal strings starting with0x) for each operation to run. As withexchange.IO("api", "eth", "send", "toAddress", toAmount), you can setgasLimit/gasPrice/noncefor amulticallcall. Pseudocode again:javascriptexchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data, {gasPrice: 123456, gasLimit: 300000})Set the
{gasPrice: 11, gasLimit: 111, nonce: 111}parameter to suit your needs, and pass it as the last argument of theexchange.IO()function.
You can omitnonceto use the system default, or leave outgasLimit/gasPrice/nonceentirely to use the system defaults for all of them.With
dryRun: truein this parameter, the transaction is signed but not broadcast, and the call returns an object with fields such ashashandraw(the signed transaction). To check in advance whether the call will succeed, replaceapiwithcalland simulate it withexchange.IO("call", ...), which does not sign and consumes no gas. For details, seeexchange.IO("call", ...).javascriptfunction main() { var ContractV3SwapRouterV2 = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45" // multicall(uint256,bytes[]) is not an ERC20 method: register the ABI first (built-in template) exchange.IO("abi", ContractV3SwapRouterV2, "uniswapV3SwapRouter02") var tokenInName = "ETH" // Convert 0.01 ETH to wei: value for a payable method is an on-chain integer var amountIn = exchange.IO("toUnits", "0.01", 18) var options = {gasPrice: 5000000000, gasLimit: 300000, nonce: 100} // Example values only; set them for your actual use case // bytes[]: encoded call data for each operation (hex strings starting with 0x); an empty array here, set it for your actual use case var data = [] var tx = exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", (tokenInName == 'ETH' ? amountIn : 0), (new Date().getTime() / 1000) + 3600, data, options || {}) }
Returns
| Type | Description |
string / number / bool / object / array | Read-only methods return the decoded value. Write methods return the transaction hash (or the signed transaction object when |
Arguments
| Name | Type | Required | Description |
k | string | Yes | Fixed as |
address | string | Yes | The smart contract address. |
method | string | Yes | The smart contract method to call. |
value | number / string | No | The amount of native coin sent with the call, in on-chain integer units (wei on Ethereum, sun on TRON). Pass it only when the method's |
arg | string / number / bool / any | No | The arguments of the smart contract method to call. |
options | object | No | Options for sending the transaction. They apply only to write methods and are passed as the last argument (when there is one more argument than the method takes, the last argument is treated as the options). |
See Also
Web3 exchange.IO exchange.IO("abi") exchange.IO("call") exchange.IO("multicall") exchange.IO("waitReceipt")
Remarks
Read-only methods run via eth_call on the latest block. They are not signed and use no gas.
Write methods are signed with the configured private key and then broadcast. When gasPrice is not set, chains that support EIP-1559 send an EIP-1559 (type 2) transaction. The priority fee is the larger of the node's suggested value (eth_maxPriorityFeePerGas) and the median of the actual priority fees over the last 20 blocks (eth_feeHistory). The max fee is 2 × baseFee + priority fee. Chains that do not support EIP-1559 bid at the eth_gasPrice returned by the node.
When nonce is not set, it is assigned automatically and kept in sync with the on-chain pending transaction count, so consecutive sends never reuse a nonce; see exchange.IO("nonce", ...). After a transaction is sent, use exchange.IO("waitReceipt", ...) to wait for it to be confirmed on-chain. If it stays unconfirmed for a long time, use exchange.IO("speedUp", ...) to resend it with a higher fee, or exchange.IO("cancelTx", ...) to cancel it.
Quote methods declared as nonpayable (such as Uniswap QuoterV2) are treated as write methods, so a transaction is signed and sent. To get only the return value or to dry-run a write operation, use exchange.IO("call", ...) to simulate the call.
Calls to read-only methods (view, pure) return the decoded value. If there is a single return value, it is returned directly. If there are several, an object keyed by output parameter names is returned, and unnamed outputs are named ret0, ret1, and so on. Integers of uint64 width or smaller are returned as numbers, and larger integers as decimal strings (in JavaScript and Python, integers with an absolute value of 2^53 or more are also returned as decimal strings to avoid losing precision). address is returned as a lowercase address starting with 0x (on TRON, an address starting with T). bytes is returned as a hex string without the 0x prefix. Fixed-length bytesN types such as bytes32 are returned as arrays of byte values (e.g. [17, 17, ...]).
Calls to write methods return the transaction hash (on Ethereum, a string starting with 0x; on TRON, a transaction ID without the 0x prefix). When dryRun is set, an object is returned with hash, raw (the signed transaction), from, to, value, data, nonce, gasLimit, chainId, type, gasPrice, maxFeePerGas and maxPriorityFeePerGas. If the call fails, a null value is returned; use GetLastError() to get the error message.