Sumber daya yang dimuat... Pemuatan...

Web3

pertukaran.IO ((abi,...)

Di inventor kuantitatif platform perdagangan terutama melaluiexchange.IO()Fungsi ini memungkinkan berbagai fungsi, panggilan, dan fungsi yang terkait dengan blockchain.exchange.IO()Fungsi dijelaskan berdasarkan fungsinya.exchange.IO("abi", ...)Cara panggilan fungsi digunakan untuk mendaftarkan ABI.

exchange.IO(k, alamat, abiContent)

k
true
string
```address```参数用于指定智能合约的地址。
address
true
string
```abiContent```参数用于指定智能合约的```ABI```。
abiContent
true
string

```javascript
function main() {
    // register Uniswap SwapRouter02 abi
    var routerAddress = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
    var abi = `[{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct IV3SwapRouter.ExactOutputParams","name":"params","type":"tuple"}],"name":"exactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"}]`
    
    // abi只使用了局部的exactOutput方法的内容,完整的abi可以在网上搜索
    exchange.IO("abi", routerAddress, abi)
}

Metode kontrak pintar yang digunakan tidak perlu didaftarkan jika metode ERC20 standar. Menerima kontrakABIKonten dapat diakses melalui URL di bawah ini.resultAnda dapat menggunakan halaman ini untuk membuat halaman Anda lebih menarik.

https://api.etherscan.io/api?module=contract&action=getabi&address=0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45

pertukaran.IO ((api, eth,...)


```exchange.IO("api", "eth", ...)```函数返回调用的RPC方法的返回值。
string、number、bool、object、array、空值等系统支持的所有类型

exchange.IO(k, blockChain, rpcMethod)
exchange.IO(k, blockChain, rpcMethod, ...args)

```k```参数用于设置```exchange.IO()```函数的功能,设置为```"api"```表示该函数用于扩展调用请求。
k
true
string
```blockChain```参数用于设置```exchange.IO()```函数的功能,设置为```"eth"```表示该函数用于以太坊网络的RPC方法调用。
blockChain
true
string
```rpcMethod```参数用于设置```exchange.IO()```函数调用的RPC方法。
rpcMethod
true
string
```arg```参数用于指定所要调用的RPC方法的参数。 ```arg```参数可能有多个,```arg```参数的类型与个数根据```rpcMethod```参数指定的RPC方法而定。
arg
false
string、number、bool、object、array、function、空值等系统支持的所有类型

```javascript
function main() {
    // "owner" 需要替换为具体钱包地址
    // "latest"字符串位置的参数标签:'latest'、'earliest'或'pending',参考https://eth.wiki/json-rpc/API#the-default-block-parameter
    // 返回值 ethBalance 为十六进制字符串:0x9b19ce56113070
    var ethBalance = exchange.IO("api", "eth", "eth_getBalance", "owner", "latest")              

    // ETH的精度单位为1e18
    var ethDecimal = 18              

    // 由于JavaScript语言精度原因,需要使用系统底层封装的函数BigInt、BigDecimal处理
    // 将ethBalance转换为可读数量,0x9b19ce56113070转换为0.043656995388076145
    Log(Number((BigDecimal(BigInt(ethBalance))/BigDecimal(Math.pow(10, ethDecimal))).toString()))
}

Untuk mencari saldo ETH di dompet:

function mian() {
    // ETH的精度单位为1e18
    var ethDecimal = 18  

    // 转账数量,可读的数量例如:0.01个ETH
    var sendAmount = 0.01  

    // 由于JavaScript语言精度原因,需要使用系统底层封装的函数BigInt、BigDecimal处理,并且将可读数量转换为链上处理的数据
    var toAmount = (BigDecimal(sendAmount)*BigDecimal(Math.pow(10, ethDecimal))).toFixed(0)
    
    // "toAddress"为转账时接收方的ETH钱包地址,需要具体填写,toAmount为转账数量
    exchange.IO("api", "eth", "send", "toAddress", toAmount)
}

Transfer ETH, dapat disesuaikan sesuai kebutuhan{gasPrice: 11, gasLimit: 111, nonce: 111}Parameter, yang diatur diexchange.IO()Pada parameter terakhir dari fungsi.nonceMenggunakan nilai default sistem atau tidakgasLimit/gasPrice/nonce, semua menggunakan standar sistem.

function toAmount(s, decimals) {
    return Number((BigDecimal(BigInt(s))/BigDecimal(Math.pow(10, decimals))).toString())
}

function main() {
    var gasPrice = exchange.IO("api", "eth", "eth_gasPrice")
    Log("gasPrice:", toAmount(gasPrice, 0))   // 5000000000 , in wei (5 gwei)
}

PertanyaangasPrice

function toAmount(s, decimals) {
    // toAmount函数可以把hex编码的数值转换为十进制数值
    return Number((BigDecimal(BigInt(s))/BigDecimal(Math.pow(10, decimals))).toString())
}                

function main() {
    // 编码approve(授权)方法的调用
    var data = exchange.IO("encode", "0x111111111117dC0aa78b770fA6A738034120C302", "approve", "0xe592427a0aece92de3edee1f18e0157c05861564", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
    Log("data:", data)
    var gasPrice = exchange.IO("api", "eth", "eth_gasPrice")
    Log("gasPrice:", toAmount(gasPrice, 0))
    var obj = {
        "from" : "0x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",   // walletAddress
        "to"  : "0x111111111117dC0aa78b770fA6A738034120C302",
        "gasPrice" : gasPrice,
        "value" : "0x0",
        "data" : "0x" + data,
    }
    
    var gasLimit = exchange.IO("api", "eth", "eth_estimateGas", obj)
    Log("gasLimit:", toAmount(gasLimit, 0))
    Log("gas fee", toAmount(gasLimit, 0) * toAmount(gasPrice, 0) / 1e18)
}

Pertanyaaneth_estimateGas


{@fun BigDecimal}, {@fun BigInt}

### exchange.IO("encode", ...)

```exchange.IO("encode", ...)```函数的调用方式用于数据编码。

```exchange.IO("encode", ...)```函数返回编码后的数据。
string

exchange.IO(k, dataFormat, ...args)
exchange.IO(k, address, dataFormat)
exchange.IO(k, address, dataFormat, ...args)

```k```参数用于设置```exchange.IO()```函数的功能,设置为```"encode"```表示该函数用于数据编码。
k
true
string
```address```参数用于设置智能合约的地址。 在调用```exchange.IO("encode", ...)```函数时,如果传入```address```参数表示编码(encode)智能合约上的方法调用。 在调用```exchange.IO("encode", ...)```函数时,如果未传入```address```参数,则该函数用于编码指定的类型顺序,功能等同```Solidity```中的```abi.encode```。
address
false
string
```dataFormat```参数用于指定编码数据的方法、类型、顺序。
dataFormat
true
string
```arg```参数用于指定与```dataFormat```参数匹配的具体数据值。 ```arg```参数可能有多个,```arg```参数的类型与个数根据```dataFormat```参数设置而定。
arg
false
string、number、tuple、array等系统支持的所有类型

```javascript
function main() {
    // ContractV3SwapRouterV2 主网地址 : 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
    // 调用unwrapWETH9方法需要先注册ABI,此处省略注册
    // "owner"代表钱包地址,需要具体填写,1代表解包装数量,把一个WETH解包装为ETH
    var data = exchange.IO("encode", "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", "unwrapWETH9(uint256,address)", 1, "owner")
    Log(data)
}

KodeunwrapWETH9Contoh panggilan metode:

function main() {
    var x = 10 
    var address = "0x02a5fBb259d20A3Ad2Fdf9CCADeF86F6C1c1Ccc9"
    var str = "Hello World"
    var array = [1, 2, 3]
    var ret = exchange.IO("encode", "uint256,address,string,uint256[]", x, address, str, array)   // uint 即 uint256 , FMZ上需要指定类型长度
    Log("ret:", ret)
    /*
    000000000000000000000000000000000000000000000000000000000000000a    // x
    00000000000000000000000002a5fbb259d20a3ad2fdf9ccadef86f6c1c1ccc9    // address
    0000000000000000000000000000000000000000000000000000000000000080    // str 的偏移
    00000000000000000000000000000000000000000000000000000000000000c0    // array 的偏移
    000000000000000000000000000000000000000000000000000000000000000b    // str 的长度
    48656c6c6f20576f726c64000000000000000000000000000000000000000000    // str 数据
    0000000000000000000000000000000000000000000000000000000000000003    // array 的长度
    0000000000000000000000000000000000000000000000000000000000000001    // array 第一个数据
    0000000000000000000000000000000000000000000000000000000000000002    // array 第二个数据
    0000000000000000000000000000000000000000000000000000000000000003    // array 第三个数据
    */
}

sama denganSolidityDalamabi.encodeContoh kode:

function main() {
    var types = "tuple(a uint256,b uint8,c address),bytes"
    var ret = exchange.IO("encode", types, {
        a: 30,
        b: 20,
        c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    }, "0011")
    Log("encode: ", ret)
}

Mendukung pengkodean urutan tipe untuk elemen (tuple) atau yang mengandung elemen, Ini adalah urutan tipe.tuplebytesJadi, ini adalah panggilan.exchange.IO()Untuk mengenkode, Anda harus melanjutkan dengan memasukkan dua parameter:

  • 1, variabel yang sesuai dengan tipe tuples:
  {
      a: 30,
      b: 20,
      c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
  }

Parameter yang ditransfer juga harustupleAda beberapa hal yang harus diperhatikan, yaitu:typesBentuk yang didefinisikan dalam parameter:tuple(a uint256,b uint8,c address)Saya tidak tahu. - 2, sesuai.bytesVariabel tipe:

  "0011"
function main() {
    var path = ["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0xdac17f958d2ee523a2206206994597c13d831ec7"]   // ETH address, USDT address
    var ret = exchange.IO("encode", "address[]", path)
    Log("encode: ", ret)
}

Mendukung pengkodean urutan tipe untuk array atau yang berisi array:

编码智能合约上的方法调用时,需要先注册对应的ABI。

### exchange.IO("encodePacked", ...)

```exchange.IO("encodePacked", ...)```函数的调用方式用于```encodePacked```编码。

```exchange.IO("encodePacked", ...)```函数返回```encodePacked```编码后的数据。
string

exchange.IO(k, dataFormat, ...args)

```k```参数用于设置```exchange.IO()```函数的功能,设置为```"encodePacked"```表示该函数用于数据```encodePacked```编码。
k
true
string
```dataFormat```参数用于指定```encodePacked```编码数据的类型、顺序。
dataFormat
true
string
```arg```参数用于指定与```dataFormat```参数匹配的具体数据值。 ```arg```参数可能有多个,```arg```参数的类型与个数根据```dataFormat```参数设置而定。
arg
true
string、number、tuple、array等系统支持的所有类型

```javascript
function main() {
    var fee = exchange.IO("encodePacked", "uint24", 3000)
    var tokenInAddress = "0x111111111117dC0aa78b770fA6A738034120C302"
    var tokenOutAddress = "0x6b175474e89094c44da98b954eedeac495271d0f"
    var path = tokenInAddress.slice(2).toLowerCase()
    path += fee + tokenOutAddress.slice(2).toLowerCase()
    Log("path:", path)
}

PenggunaanUniswap V3Jika Anda ingin memasukkan parameter seperti jalur konversi, Anda harus menggunakanencodePackedKode operasi:

pertukaran.IO ((decode,...)


```exchange.IO("decode", ...)```函数返回解码后的数据。 当```dataFormat```参数指定的数据只有一个时返回一个字符串。 当```dataFormat```参数指定的数据有多个时返回一个数组。
array、string

exchange.IO(k, dataFormat, data)

```k```参数用于设置```exchange.IO()```函数的功能,设置为```"decode"```表示该函数用于数据解码。
k
true
string
```dataFormat```参数用于指定解码数据的类型、顺序。
dataFormat
true
string
```data```参数用于设置所要解码的数据。
data
true
string

```javascript
function main() {
    var types = "tuple(a uint256,b uint8,c address),bytes"
    var ret = exchange.IO("encode", types, {
        a: 30,
        b: 20,
        c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    }, "0011")
    Log("encode: ", ret)            

    var rawData = exchange.IO("decode", types, ret)
    Log("decode:", rawData)
}
```javascript
function main() {
    // register SwapRouter02 abi
    var walletAddress = "0x398a93ca23CBdd2642a07445bCD2b8435e0a373f"
    var routerAddress = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
    var abi = `[{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct IV3SwapRouter.ExactOutputParams","name":"params","type":"tuple"}],"name":"exactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"}]`
    exchange.IO("abi", routerAddress, abi)   // abi只使用了局部的exactOutput方法的内容,完整的abi可以在网上搜索              

    // encode path
    var fee = exchange.IO("encodePacked", "uint24", 3000)
    var tokenInAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    var tokenOutAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7"
    var path = tokenInAddress.slice(2).toLowerCase()
    path += fee + tokenOutAddress.slice(2).toLowerCase()
    Log("path:", path)              

    var dataTuple = {
        "path" : path, 
        "recipient" : walletAddress, 
        "amountOut" : 1000, 
        "amountInMaximum" : 1, 
    }
    // encode SwapRouter02 exactOutput 
    var rawData = exchange.IO("encode", routerAddress, "exactOutput", dataTuple)
    Log("method hash:", rawData.slice(0, 8))   // 09b81346
    Log("params hash:", rawData.slice(8))              

    // decode exactOutput params
    var decodeRaw = exchange.IO("decode", "tuple(path bytes,recipient address,amountOut uint256,amountInMaximum uint256)", rawData.slice(8))
    Log("decodeRaw:", decodeRaw)
}

Contoh pertama adalah:pathPerangkat lunak ini dapat digunakan untuk mengolah data.encodePackedAnda bisa mengoperasikannya, karena kemudian Anda harus mengkodenya.exactOutputMetode panggilan diperlukanpathJadi, jika Anda ingin menggunakan parameter tersebut sebagai parameter Anda, Anda dapat menggunakan parameter tersebut sebagai parameter Anda.encodeKontrak ruteexactOutputMetode ini hanya memiliki satu parameter, dan tipe parameternya adalahtupleJenisnya.exactOutputDi bawah ini adalah kode dari metode ini:0x09b81346Menggunakanexchange.IO("decode", ...)Bagaimana cara memecahkannya?decodeRaw, dengan variabeldataTupleSaya tidak tahu apa yang terjadi.

"Saya tidak tahu apa yang akan terjadi.exchange.IO()Fungsi tidak hanya mendukung encode, tetapi juga mendukung decode.

pertukaran.IO ((key,...)


exchange.IO(k, key)

```k```参数用于设置```exchange.IO()```函数的功能,设置为```"key"```表示该函数用于切换私钥。
k
true
string
```key```参数用于设置私钥。
key
true
string

```javascript
function main() {
    exchange.IO("key", "Private Key")   // "Private Key"代表私钥字符串,需要具体填写
}

### exchange.IO("api", ...)

```exchange.IO("api", ...)```函数的调用方式用于调用智能合约的方法。

```exchange.IO("api", ...)```函数返回所调用的智能合约方法的返回值。
string、number、bool、object、array、空值等系统支持的所有类型

exchange.IO(k, address, method)
exchange.IO(k, address, method, ...args)
exchange.IO(k, address, method, value, ...args)

```k```参数用于设置```exchange.IO()```函数的功能,设置为```"api"```表示该函数用于扩展调用请求。
k
true
string
```address```参数用于指定智能合约的地址。
address
true
string
```method```参数用于指定所要调用的智能合约的方法。
method
true
string
```value```参数用于设置发送的ETH数量。 所要执行的智能合约方法的```stateMutability```属性是```payable```,则需要传```value```参数。 ```"stateMutability":"payable"```属性可以从ABI中查看,```exchange.IO()```函数会根据已经注册的ABI中的```stateMutability```属性判断所需要的参数, 如果```stateMutability```属性是```nonpayable```则不需要传```value```参数。
value
false
number、string
```arg```参数用于指定所要调用智能合约的方法的参数。 ```arg```参数可能有多个,```arg```参数的类型与个数根据所要调用的智能合约的方法而定。
arg
false
string、number、bool等系统支持的所有类型

```javascript
function main(){
    var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"    // 代币的合约地址,例子中的代币为1INCH
    Log(exchange.IO("api", tokenAddress, "decimals"))                  // 查询,打印1INCH代币的精度指数为18
}
```javascript
function main(){
    // 代币的合约地址,例子中的代币为1INCH
    var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"                          

    // 例如查询得出1000000000000000000,除以该token的精度单位1e18,得出当前交易所对象绑定的钱包给spender地址授权了1个1INCH数量
    Log(exchange.IO("api", tokenAddress, "allowance", "owner", "spender"))   
}
```owner```:钱包地址,例子中以字符串"owner"代替,实际使用需要具体填写地址。 ```spender```:被授权的合约地址,例子中以字符串"spender"代替,实际使用需要具体填写地址,例如可以是```Uniswap V3 router v1```地址。
```javascript
function main(){
    // 代币的合约地址,例子中的代币为1INCH
    var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"                 

    // 授权量的十六进制字符串: 0xde0b6b3a7640000 , 对应的十进制字符串: 1e18 , 1e18除以该token的精度单位,即1个代币数量 , 所以这里指授权一个代币
    Log(exchange.IO("api", tokenAddress, "approve", "spender", "0xde0b6b3a7640000"))  
}
```spender```:被授权的合约地址,例子中以字符串"spender"代替,实际使用需要具体填写地址,例如可以是```Uniswap V3 router v1```地址。 ```0xde0b6b3a7640000```:授权数量,这里使用的是十六进制字符串表示,对应的十进制数值为1e18,除以例子中的token精度单位(即1e18), 得出授权了1个token。 ```exchange.IO()```函数的第三个参数传入方法名```approve```,也可以写methodId的形式,例如:"0x571ac8b0"。 也可以写完整标准方法名,例如:"approve(address,uint256)"。
```javascript
function main() {
    var ContractV3SwapRouterV2 = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
    var tokenInName = "ETH"
    var amountIn = 0.01
    var options = {gasPrice: 5000000000, gasLimit: 21000, nonce: 100}   // 此处为举例,具体要根据实际场景设置
    var data = ""                                                       // 编码后的数据,此处为空字符串,具体要根据实际场景设置
    var tx = exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", (tokenInName == 'ETH' ? amountIn : 0), (new Date().getTime() / 1000) + 3600, data, options || {})
}
```multicall```方法可能有多种传参方式,具体可以查询包含该方法的ABI,调用该方法之前需要先注册ABI。返回值:txid。  

具体的```multicall```方法调用例子,可以参考平台公开的[「Uniswap V3 交易类库」模板](https://www.fmz.com/strategy/397260)  

这里使用伪代码来描述一些细节:

exchange.IO ((api, ContractV3SwapRouterV2, multicall(uint256,byte[]), nilai, tenggat waktu, data)



```ContractV3SwapRouterV2```:Uniswap V3的router v2地址。
```value```:转账的ETH数量,如果兑换操作的tokenIn代币不是ETH,则设置为0。
```deadline```:```deadline```是```multicall```方法的参数,可以设置为(new Date().getTime() / 1000) + 3600,表示一小时内有效。
```data```:```data```是```multicall```方法的参数,需要执行的打包操作数据。  

与```exchange.IO("api", "eth", "send", "toAddress", toAmount)```类似,在调用```multicall```方法时也可以指定方法调用的```gasLimit/gasPrice/nonce```设置,
同样使用伪代码来描述:

exchange.IO ((api, ContractV3SwapRouterV2, multicall ((uint256,byte[]), nilai, tenggat waktu, data, {gasPrice: 123456, gasLimit: 21000})


可以根据具体需求设置```{gasPrice: 11, gasLimit: 111, nonce: 111}```参数,该参数设置在```exchange.IO()```函数的最后一个参数上。
可以省略其中的```nonce```使用系统默认的值,或者不设置```gasLimit/gasPrice/nonce```,全部使用系统默认值。


### exchange.IO("address")

```exchange.IO("address")```函数的调用方式用于获取{@var/EXCHANGE exchange}交易所对象配置的钱包的地址。

```exchange.IO("address")```函数返回配置的钱包地址。
string

exchange.IO(k)

```k```参数用于设置```exchange.IO()```函数的功能,设置为```"address"```表示该函数用于获取配置的钱包地址。
k
true
string

```javascript
function main() {
    Log(exchange.IO("address"))         // 打印exchange交易所对象上配置的私钥的钱包地址
}

pertukaran.IO ((base,...)


exchange.IO(k, address)

```k```参数用于设置```exchange.IO()```函数的功能,设置为```"base"```表示该函数用于切换RPC节点。
k
true
string
```address```参数用于设置RPC节点地址。
address
true
string

```javascript
function main() {
    var chainRpc = "https://bsc-dataseed.binance.org"
    e.IO("base", chainRpc)    // 切换到BSC链
}
Benang TA