发起交易

在下文中,我们将以如下钱包为例:

Address: 0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF
Private Key: 0x1c1a49fea9a4ede1dc8e582639f498d41fa3c4a9e2ab2b9d740a4a3ec14e1cbf

Layer-1

Layer-1 上进行的唯一交易是充值。充值有两个类型,分别是 DepositETHDepositERC20

ABIs

[
{
"constant": false,
"inputs": [
{
"internalType": "contract IERC20",
"name": "_token",
"type": "address"
},
{
"internalType": "uint104",
"name": "_amount",
"type": "uint104"
},
{
"internalType": "address",
"name": "_franklinAddr",
"type": "address"
}
],
"name": "depositERC20",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "_franklinAddr",
"type": "address"
}
],
"name": "depositETH",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
}
]

充值ETH

代码示例:

import { Wallet, Contract, utils } from 'ethers'
const contract = new Contract('0x8ECa806Aecc86CE90Da803b080Ca4E3A9b8097ad', ABI, wallet)
const wallet = new Wallet('0x1c1a49fea9a4ede1dc8e582639f498d41fa3c4a9e2ab2b9d740a4a3ec14e1cbf')
async function depositETH(amount) {
const tx = await contract.depositETH(wallet.address, {
value: utils.parse(amount)
})
return tx
}
// deposit 1 ETH
depositETH('1').then(console.log)

充值 ERC20 代币

与其他项目一样,需要您允许 ZKSwap 的主合约地址使用 ERC20 代币进行充值。但需要注意部分限制兑换额的代币(参见 https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729)

代码示例:

import { Wallet, Contract, utils } from 'ethers'
const contract = new Contract('0x8ECa806Aecc86CE90Da803b080Ca4E3A9b8097ad', ABI, wallet)
const wallet = new Wallet('0x1c1a49fea9a4ede1dc8e582639f498d41fa3c4a9e2ab2b9d740a4a3ec14e1cbf')
async function depositERC20(amount, tokenAddress) {
const tokenContract = new Contract(tokenAddress, ERC20_ABI, wallet)
// check allowance
const allowance = await tokenContract.allowance(wallet.address, MAIN_CONTRACT_ADDRESS)
let nonce
if (allowance.lt(utils.parse(amount)) {
// approve
const MAX_AMOUNT = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
const approveTx = await tokenContract.allow(MAIN_CONTRACT_ADDRESS, MAX_AMOUNT)
nonce = approveTx.nonce + 1
}
const tx = await contract.depositERC20(tokenAddress, utils.parse(amount), wallet.address, {
nonce
})
return tx
}
// deposit 100 ZKS
depositERC20('100', '0xe4815ae53b124e7263f08dcdbbb757d41ed658c6').then(console.log)

Layer-2

向 ZKSwap 发起交易时,API 需传入 3 个必要参数:txsignaturefastProcessing,在后文中,Signed Transaction 指的是 tx 字段,ETH Signature指的是 signature 字段。

私钥

用 Layer-1 的私钥对以下信息进行签名以获取 Layer-2 的种子。使用 zkSync's crypto libraries 获取私钥。

Plain Text
JavaScript
Plain Text
Access ZKSwap account.
Only sign this message for a trusted client!
JavaScript
const msg = 'Access ZKSwap account.\n\nOnly sign this message for a trusted client!'

以下是一个完整的在 JavaScript 中使用 zksync-crypto 获取私钥的例子。

import { Wallet, Contract, utils } from 'ethers'
import { privateKeyFromSeed, private_key_to_pubkey_hash } from 'zksync-crypto'
const wallet = new Wallet('0x1c1a49fea9a4ede1dc8e582639f498d41fa3c4a9e2ab2b9d740a4a3ec14e1cbf')
async function getPrivateKey() {
const msg = 'Access ZKSwap account.\n\nOnly sign this message for a trusted client!'
const signature = await wallet.signMessage(msg)
const seed = utils.arrayify(signature)
// Get private key
const privateKey = privateKeyFromSeed(seed)
return privateKey
}
getPrivateKey().then(console.log)

公钥哈希(Public Key Hash)

获取私钥后,需要您将 publick key hash 注册到 ZKSwap,以验证您发出的交易。

import { utils } from 'ethers'
import { private_key_to_pubkey_hash } from 'zksync-crypto'
const pubKeyHash = `sync:${utils.hexlify(private_key_to_pubkey_hash(privateKey)).substr(2)}`

签名(Signature)

向 ZKSwap 发起交易前,需要您对交易信息进行签名。

import { utils } from 'ethers'
import { sign_musig } from 'zksync-crypto'
function signMessage(privateKey, msgBytes) {
const signaturePacked = sign_musig(privateKey, msgBytes)
const pubKey = utils.hexlify(signaturePacked.slice(0, 32)).substr(2)
const signature = utils.hexlify(signaturePacked.slice(32)).substr(2)
return {
pubKey,
signature
}
}
const msgBytes = utils.concat([type, accountId, ...etc])
const signature = signMessage(privateKey, msgBytes)

修改公钥(Change Public Key)

帐户在 ZKSwap 上注册后(通过转账 或 充值),您可以更改帐户的 pubKeyHash 以便在 Layer-2 上进行任何其他类型的交易。这是一个特殊操作,无须使用 Layer-2 的私钥进行签名。

交易信息

Field

Type

Comment

type

string

ChangePubKey

accountId

number

您的账户 ID

account

address

您的账户地址

newPkHash

number

公钥哈希值

nonce

number

您当前的 nonce

ethSignature

string

Layer-1 签名

签名交易示例

{
"type": "ChangePubKey",
"accountId": 83670,
"account": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
"newPkHash": "sync:83f62ba777515089eb905a375f77f59ddfada116",
"nonce": 0,
"ethSignature": "0x66c1ef3611a634e400301375b291a0835b0e31237273e1bdab45acc3ef27c761674fd5e5a706566e5175e8e18306f5b8d1d36016f3894e84d527c3c97e92bcf71c"
}

ETH 签名

Message Template
Message to sign
Signature
Message Template
Register ZKSwap pubkey:
{pubKeyHash}
nonce: {hexlifiedNonce}
account id: {hexlifiedAccountId}
Only sign this message for a trusted client!
Message to sign
Register ZKSwap pubkey:
83f62ba777515089eb905a375f77f59ddfada116
nonce: 0x00000000
account id: 0x000146d6
Only sign this message for a trusted client!
Signature
0x66c1ef3611a634e400301375b291a0835b0e31237273e1bdab45acc3ef27c761674fd5e5a706566e5175e8e18306f5b8d1d36016f3894e84d527c3c97e92bcf71c

转账

交易信息

Bytes Order

Field

Type

Comment

Bytes Examplle

0

type

string

转账

0x05

1

accountId

number

您的账户 ID

0x000146d6

2

from

address

您的账户地址

0x026a25efbcefb2e481d005e4f00ccced0af511ff

3

to

address

收款人账户地址

0x961b513dfd3e363c238e0f98219ee02552a847bd

4

token

number

代币ID

0x0001

5

amount

string

转账数额

0x4a817c8008

6

fee

string

手续费

0x0000

7

chainId

number

10 对应主网,

3 对应 ropsten 测试网

0x0a

8

nonce

number

当前 nonce

0x00000001

-

signature

object

包含您的公钥和签名

完整的字节码示例

0x05000146d6026a25efbcefb2e481d005e4f00ccced0af511ff961b513dfd3e363c238e0f98219ee02552a847bd00014a817c800800000a00000001

签名交易示例

{
"type": "Transfer",
"accountId": 83670,
"from": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
"to": "0x961b513dfd3e363c238e0f98219ee02552a847bd",
"token": 1,
"amount": "1000000000000000000",
"fee": "0",
"chainId": 10,
"nonce": 1,
"signature": {
"pubKey": "110ffd569daaee30068fc3c85922d1237f63a41d4749d464b883131e92369204",
"signature": "4aaf03004e24973dbf418e1eb389aa540e41a119ec9908d270682ee32a260caef082b63dd5ec1a466b0011040fb3d7704c0fe0550108c0ffd5866021f1fbb004"
}
}

ETH 签名

Message Template
Message Example
Signature
Message Template
Transfer {readableAmount} {tokenSymbol}
To: {to}
ChainId {chainId}
Nonce: {nonce}
Fee: {readableFee} {tokenSymbol}
Account Id: {accountId}
Message Example
Transfer 1.0 ZKS
To: 0x961b513dfd3e363c238e0f98219ee02552a847bd
ChainId 10
Nonce: 1
Fee: 0.0 ZKS
Account Id: 83670
Signature
{
"type": "EthereumSignature",
"signature": "0xd5d40b48c7f4f8448b2bacdfe5e828bcfd0b0a68e5c895318139a2428a19f3417f65b305b0fbb8c6b5416a101d6b68c7160fe5174caf9d181039fd77d853430f1c"
}

提现

交易信息

Bytes Order

Field

Type

Comment

Bytes Examplle

0

type

string

提现

0x03

1

accountId

number

您的账户 ID

0x000146d6

2

from

address

您的账户地址

0x026a25efbcefb2e481d005e4f00ccced0af511ff

3

to

address

提现账户地址

0x026a25efbcefb2e481d005e4f00ccced0af511ff

4

token

number

提现的代币ID

0x0001

5

amount

string

提现数额

0x00000000000000002f7fb72c1003e100

6

fee

string

手续费

0xc52f

7

chainId

number

10 对应主网, 3 对应 ropsten 测试网

0x0a

8

nonce

number

当前 nonce

0x00000002

-

signature

object

包含您的公钥和签名

完整的字节码示例

0x03000146d6026a25efbcefb2e481d005e4f00ccced0af511ff026a25efbcefb2e481d005e4f00ccced0af511ff000100000000000000002f7fb72c1003e100c52f0a00000002

签名交易示例

{
"type": "Withdraw",
"accountId": 83670,
"from": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
"to": "0x026a25efbcefb2e481d005e4f00ccced0af511ff",
"token": 1,
"amount": "3422655641700000000",
"fee": "1577000000000000000",
"chainId": 10,
"nonce": 2,
"signature": {
"pubKey": "110ffd569daaee30068fc3c85922d1237f63a41d4749d464b883131e92369204",
"signature": "b983234033e17cb3552a7253bec8c7fab7af7c63d06d1d328dac2d377a2440a0af18238b560c73e7274583b65887b59315fc3f87d9505146df7030dd45ee6801"
}
}

ETH 签名

Message Template
Message Example
Signature
Message Template
Withdraw {readableAmount} {tokenSymbol}
To: {to}
ChainId {chainId}
Nonce: {nonce}
Fee: {readableFee} {tokenSymbol}
Account Id: {accountId}
Message Example
Withdraw 3.4226556417 ZKS
To: 0x026a25efbcefb2e481d005e4f00ccced0af511ff
ChainId 10
Nonce: 2
Fee: 1.577 ZKS
Account Id: 83670
Signature
{
"type": "EthereumSignature",
"signature": "0x2c1d029ef846ef1643db63660834537d1b6c255050125c663df55ad51925786d070c450af9719d17ae14c86b9987871cbf7e8cca6177ded0a9d42aa5e6190bbc1b"
}

兑换

交易信息

Bytes Order

Field

Type

Comment

Bytes Examplle

0

type

string

兑换

0x0b

1

accountId

number

您的账户ID

0x000146d6

2

from

address

您的账户地址

0x026a25efbcefb2e481d005e4f00ccced0af511ff

3

to

address

交易对地址

0xf005ab93a5ede376de898f0980cc63b460273e3d

4

tokenIn

number

兑换时的输入代币ID

0x0001

5

amountIn

string

兑换输入代币数量

0x4a817c8009

6

tokenOut

number

兑换时的输出代币ID

0x001d

7

amountOutMin

string

兑换输出代币的最小数量

0x003bfab660

8

feeIn

string

等于 "0"

0x0000

9

chainId

number

10 对应主网, 3 对应 ropsten 测试网

0x0a

10

nonce

number

当前 nonce

0x00000003

-

signature

object

包含您的公钥和签名

完整字节码示例

0x0b000146d6026a25efbcefb2e481d005e4f00ccced0af511fff005ab93a5ede376de898f0980cc63b460273e3d00014a817c8009001d003bfab66000000a00000003

签名交易示例

{
"type": "Swap",
"accountId": 83670,
"from": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
"to": "0xf005ab93a5ede376de898f0980cc63b460273e3d",
"tokenIn": 1,
"tokenOut": 29,
"amountIn": "10000000000000000000",
"amountOutMin": "31446451",
"feeIn": "0",
"chainId": 10,
"nonce": 3,
"signature": {
"pubKey": "110ffd569daaee30068fc3c85922d1237f63a41d4749d464b883131e92369204",
"signature": "8883428c7787ca9e92dda23c6161293acc4cd9b07b480b11021a54a229bd942ae2e3e95f8963ed6403395020487a1c176cddfa69abe8c48c00e0a52b25971f02"
}
}

ETH 签名

Message Template
Message Example
Signature
Message Template
Swap {readableAmontIn} {tokenInSymbol}
Minimum: {readableAmontOutMin} {tokenOutSymbol}
To: {pairAddress}
ChainId {chainId}
Nonce: {nonce}
Fee: 0.0 {tokenInSymbol}
Account Id: {accountId}
Message Example
Swap 10.0 ZKS
Minimum: 31.446451 USDT
To: 0xf005ab93a5ede376de898f0980cc63b460273e3d
ChainId 10
Nonce: 3
Fee: 0.0 ZKS
Account Id: 83670
Signature
{
"type": "EthereumSignature",
"signature": "0x18eefc084207b628945b98d30d051965a616c9d7af65e6475444b50870a98fec3277d82259e24d832f50a512475e795b284ccbac8c128ba82aa269849c4262bf1c"
}

添加流动性

交易信息

Bytes Order

Field

Type

Comment

Bytes Examplle

0

type

string

添加流动性

0x09

1

accountId

number

您的账户ID

0x000146d6

2

from

address

您的账户地址

0x026a25efbcefb2e481d005e4f00ccced0af511ff

3

to

address

交易对地址

0xf005ab93a5ede376de898f0980cc63b460273e3d

4

tokenA

number

您想要添加的A代币ID

0x0001

5

amountADesired

number

您想要添加的A代币的数量

0x4a817c8009

6

amountAMin

string

您想要添加到交易对中去的A代币的最小数量

0x4a221e7009

7

tokenB

number

您想要添加的B代币ID

0x001d

8

amountBDesired

string

您想要添加的B代币的数量

0x003b9049e0

9

amountBMin

string

您想要添加的B代币的最小数量

0x003b440c00

10

tokenLiquidity

number

交易对 ID.

0x0080

11

feeA

string

A代币的手续费

0x0000

12

feeB

string

B代币的手续费

0x0000

13

chainId

number

10 对应主网, 3 对应 ropsten 测试网

0x0a

14

nonce

number

您的当前nonce

0x00000003

-

signature

object

包含您的公钥和签名

完整字节码示例

0x09000146d6026a25efbcefb2e481d005e4f00ccced0af511fff005ab93a5ede376de898f0980cc63b460273e3d00014a817c80094a221e7009001d003b9049e0003b440c000080000000000a00000004

签名交易示例

{
"type": "AddLiquidity",
"accountId": 83670,
"from": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
"to": "0xf005ab93a5ede376de898f0980cc63b460273e3d",
"tokenA": 1,
"tokenB": 29,
"tokenLiquidity": 128,
"amountADesired": "10000000000000000000",
"amountBDesired": "31228495",
"amountAMin": "9950000000000000000",
"amountBMin": "31072352",
"feeA": "0",
"feeB": "0",
"chainId": 10,
"nonce": 4,
"signature": {
"pubKey": "110ffd569daaee30068fc3c85922d1237f63a41d4749d464b883131e92369204",
"signature": "40474f11c8c5826473969ffb6f8a4c5c15df8875c24faf07ee1f749d97f66e06dc1672a70ab79469affa953e3a37199725cf423929489ef99ae1b9293a771b01"
}
}

ETH 签名

Message Template
Message Example
Signature
Message Template
AddLiquidity {pairSymbol}
Desired: {readableAmontA} {tokenASymbol} {readableAmontB} {tokenBSymbol}
Minimum: {readableAmontAMin} {tokenASymbol} {readableAmontBMin} {tokenBSymbol}
To: {pairAddress}
ChainId {chainId}
Nonce: {nonce}
Fee: {readableFeeA} {tokenASymbol} {readableFeeB} {tokenBSymbol}
Account Id: {accountId}
Message Example
AddLiquidity liquidity_1_29
Desired: 10.0 ZKS 31.228495 USDT
Minimum: 9.95 ZKS 31.072352 USDT
To: 0xf005ab93a5ede376de898f0980cc63b460273e3d
ChainId 10
Nonce: 4
Fee: 0.0 ZKS 0.0 USDT
Account Id: 83670
Signature
{
"type": "EthereumSignature",
"signature": "0x365b5c64738f425743728b5615f6e428d9a6c3ca333cf9630602e283e2efaadf26194be778fe7a15532b4768b385b4339c739ac22cffba4f94ef8d594f415d021b"
}

移除流动性

交易信息

Bytes Order

Field

Type

Comment

Bytes Examplle

0

type

string

移除流动性

0x0a

1

accountId

number

你的账户ID

0x000146d6

2

from

address

你的账户地址

0x026a25efbcefb2e481d005e4f00ccced0af511ff

3

to

address

交易对地址

0xf005ab93a5ede376de898f0980cc63b460273e3d

4

tokenA

number

A代币ID

0x0001

5

amountAMin

string

您想要移除的A代币的最小数量

0x4a221e68e9

6

feeA

string

A代币手续费

0x0000

7

tokenB

number

B代币ID

0x001d

8

amountBMin

string

您想要移除的B代币的最小数量

0x003b440c00

9

feeB

string

B代币手续费

0x0000

10

tokenLiquidity

number

交易对 ID.

0x0080

11

amountLiquidity

string

您想要移除的 LP token 的数量

0x1da59cc1a3

12

chainId

number

10 对应主网, 3 对应 ropsten 测试网

0x0a

13

nonce

number

您的当前nonce

0x00000005

-

signature

object

包含您的公钥和签名

完整字节码示例

0x0a000146d6026a25efbcefb2e481d005e4f00ccced0af511fff005ab93a5ede376de898f0980cc63b460273e3d00014a221e68e90000001d003b440c00000000801da59cc1a30a00000005

交易签名示例

{
"type": "RemoveLiquidity",
"accountId": 83670,
"from": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
"to": "0xf005ab93a5ede376de898f0980cc63b460273e3d",
"tokenA": 1,
"tokenB": 29,
"amountAMin": "9949999943000000000",
"amountBMin": "31072352",
"tokenLiquidity": 128,
"amountLiquidity": "3979142669000",
"feeA": "0",
"feeB": "0",
"chainId": 10,
"nonce": 5,
"signature": {
"pubKey": "110ffd569daaee30068fc3c85922d1237f63a41d4749d464b883131e92369204",
"signature": "5d55820bbe5101f6c389789b59468a07b31ca3e8c19142835c1b4b44761d55ac9f5bcad78e2c97054a9ad70bceb7b5387c73983590282101ca230bbf5a2a5305"
}
}

ETH 签名

Message Template
Message Example
Signature
Message Template
RemoveLiquidity {readableLiquidityAmount} {pairSymbol}
Minimum: {readableAmontAMin} {tokenASymbol} {readableAmontBMin} {tokenBSymbol}
To: {pairAddress}
ChainId {chainId}
Nonce: {nonce}
Fee: {readableFeeA} {tokenASymbol} {readableFeeB} {tokenBSymbol}
Account Id: {accountId}
Message Example
RemoveLiquidity 0.000003979142669 liquidity_1_29
Minimum: 9.949999943 ZKS 31.072352 USDT
To: 0xf005ab93a5ede376de898f0980cc63b460273e3d
ChainId 10
Nonce: 5
Fee: 0.0 ZKS 0.0 USDT
Account Id: 83670
Signature
{
"type": "EthereumSignature",
"signature": "0x595f8efca127d15b5bb36e84aad96e0629b4894e68bbc8918e789f15f85a8a0d6e573c66281ecad182c57cd027d21d9a83cf289ca505128152e58e95bde2e0531b"
}