zkLink X Documentaion
HomeGitHubBlogExplorer
  • 🙂Welcome
    • Introduction
  • ⚖️Architecture
    • Overview
    • Settlement Layer
      • Working Principal of A Multi-Chain ZK-Rollup
      • Nexus: Settlement on ETH L2s
      • Origin: Settlement on ETH and Alt-L1s
      • Multi-Chain State Synchronization
        • In-Detail: Nexus Multi-Chain State Synchronization
      • Supported Networks of zkLink Nexus and Origin
      • Security Assumptions of zkLink Nexus and Origin
    • Execution Layer
      • TS-zkVM for App Rollup
    • Sequencing Layer
    • DA Layer
  • 🛠️Developer
    • Developer Overview
    • Get Started
    • Examples
      • Base Demo
    • JSON RPC & Websocket & Kafka
      • JSON-RPC API
      • JSON-RPC Errors
      • Websocket
      • Kafka
    • Transactions
      • Basic Types
      • State Update
      • Transaction
        • Deposit
        • FullExit
        • ChangePubKey
        • Withdraw
        • Transfer
        • ForcedExit
        • OrderMatching
        • AutoDeleveraging
        • ContractMatching
        • Funding
        • Liquidation
        • UpdateGlobalVar
      • Private Key & Signature
        • Algorithm
        • ChangePubKey
        • Withdraw
        • Transfer
        • ForcedExit
        • OrderMatching
        • ContractMatching
        • Funding
        • Liquidation
        • AutoDeleveraging
        • UpdateGlobalVar
    • SDK
      • Go
        • Types
        • Signature
        • Utils
        • Transactions
          • ChangePubKey
          • Withdraw
          • Transfer
          • ForcedExit
          • OrderMatching
          • ContractMatching
          • AutoDeleveraging
          • Funding
          • Liquidation
          • UpdateGlobalVar
      • Js
        • Signature
        • Utils
        • Transactions
          • ChangePubKey
          • Withdraw
          • Transfer
          • ForcedExit
          • OrderMatching
          • ContractMatching
          • AutoDeleveraging
          • Funding
          • Liquidation
          • UpdateGlobalVar
      • Dart
        • Signature
        • Utils
        • Transactions
          • ChangePubKey
          • Withdraw
          • Transfer
          • ForcedExit
          • OrderMatching
          • ContractMatching
          • AutoDeleveraging
          • Funding
          • Liquidation
          • UpdateGlobalVar
  • ⚙️Network Information
    • Connected Networks
      • Mainnet
      • Testnet
    • DApps & Deployment Addresses
      • Mainnet
      • Testnet
  • Wallet & User Fund Streamline
    • Withdraw
    • Wallet Integration & AA Wallet
    • Deposit
  • Integration Cases
    • Heavyweight Integration (Multi-Chain Derivatives & Spot Exchange)
    • Simple Integration (Multi-Chain Spot Exchange)
  • Appendix
    • Audits
    • FAQ
    • glossary
Powered by GitBook
On this page

Was this helpful?

  1. Developer
  2. Transactions
  3. Transaction

ChangePubKey

PreviousFullExitNextWithdraw

Last updated 11 months ago

Was this helpful?

Modifies the public key hash of the Layer3 account.

Name
Type
Required
Description

type

String

yes

The value is "ChangePubKey"

chainId

yes

ID defined by zkLink, for example, when the user performs ChangePubKey on ETH, the front-end needs to set this value to the Ethereum ID defined by zkLink on Layer3

accountId

yes

Target account ID of ChangePubKey

subAccountId

yes

Target subaccount ID of ChangePubKey, the fee will be deducted from this subaccount

newPkHash

yes

New public key hash

nonce

yes

Current nonce of the target account

feeToken

yes

The token used as the fee token

fee

yes

Fee obtained via estimateTransactionFee API, the value should be packable

ethAuthData

yes

ChangePubKeyAuthData to set the public key

signature

yes

the public key hash corresponding to the signature must be aligned with the newPkHash

ts

u32

yes

Timestamp of the API call, used as front-end request id to generate transaction hash

where the ChangePubKeyAuthData is an Enum which contains 3 types: EthECDSA, EthCreate2, Onchain

Name
Type
Required
Description

type

String

yes

The value is "EthECDSA"

ethSignature

String

yes

eth signature with 0x prefix

Refer to to create the signature content in this way, where the domain is:

{
  "name":"ZkLink", // constaint
  "version":"1", // constaint
  "chainId":13, // this this the L1 chain id, not the one defined by zkLink
  "verifyingContract":"0x388c818ca8b9251b393131c08a736a67ccb19297" // this is the zkLink contract address on L1
}

Note: Different chain has different chainId and verifyingContract, you can get the chain information from rpc interface getSupportChains.

For Example:

{
  "type": "ChangePubKey",
  "chainId": 1,
  "accountId": 39,
  "subAccountId": 1,
  "newPkHash": "0xbfb4f4a68dc9e49f7785082a8c12354ed663b6e0",
  "feeToken": 1,
  "fee": "1285000000000000",
  "nonce": 0,
  "signature": {
    "pubKey": "0xed53a138751ed1e456f46e74eff3463d2420e488a4f608bde0f28d13c7104d29",
    "signature": "3b91c0421df4295281596746722ae20ccf270c5fc0561f93a0219db1faea6518f033e778dd552f90a9a6afd06427428b2ac4ea6f6893a3f162b32683d1108a02"
  },
  "ethAuthData": {
    "type": "EthECDSA",
    "ethSignature": "0x8e548e3727a94533b3963877b87966e308e6eef7762f78de567ff14b4e0e87780d37a845501ffd2cdbc7d6f0d620c14589212761f1637ea8214b0b6bac10aa9b1b"
  },
  "ts": 1675650037
}
Name
Type
Required
Description

type

String

yes

The value is "EthCreate2"

creatorAddress

String

yes

creator address

saltArg

String

yes

The salt argument when create address, H256 hex string

codeHash

String

yes

code hash, H256 hex string

For Example:

{
  "type": "ChangePubKey",
  "chainId": 1,
  "accountId": 39,
  "subAccountId": 1,
  "newPkHash": "0xbfb4f4a68dc9e49f7785082a8c12354ed663b6e0",
  "feeToken": 1,
  "fee": "1285000000000000",
  "nonce": 0,
  "signature": {
    "pubKey": "0xed53a138751ed1e456f46e74eff3463d2420e488a4f608bde0f28d13c7104d29",
    "signature": "3b91c0421df4295281596746722ae20ccf270c5fc0561f93a0219db1faea6518f033e778dd552f90a9a6afd06427428b2ac4ea6f6893a3f162b32683d1108a02"
  },
  "ethAuthData": {
    "type":"EthCreate2",
    "creatorAddress":"0x388c818ca8b9251b393131c08a736a67ccb19297",
    "saltArg":"0x66b8e2fa879542a0c32c77e137ab830c3345788a2696999afbd07acabab8ad81",
    "codeHash":"0xfb57f5a066444ff426f4433344fd2e179843fd9069c06eb3b4ecc74e8b599410"
  },
  "ts": 1675650037
}
Name
Type
Required
Description

type

String

yes

The value is "Onchain"

Before sending the transaction, you must use the layer1 address of the account to call the setAuthPubkeyHash interface(by call the setAuthPubkeyHash function of Wallet in sdk) of the ZkLink contract to pre-set the PubkeyHash for your layer2 account (the ChangePubKey tx will be checked against the ZkLink contract after on-chain).

For Example:

{
  "type": "ChangePubKey",
  "chainId": 1,
  "accountId": 39,
  "subAccountId": 1,
  "newPkHash": "0xbfb4f4a68dc9e49f7785082a8c12354ed663b6e0",
  "feeToken": 1,
  "fee": "1285000000000000",
  "nonce": 0,
  "signature": {
    "pubKey": "0xed53a138751ed1e456f46e74eff3463d2420e488a4f608bde0f28d13c7104d29",
    "signature": "3b91c0421df4295281596746722ae20ccf270c5fc0561f93a0219db1faea6518f033e778dd552f90a9a6afd06427428b2ac4ea6f6893a3f162b32683d1108a02"
  },
  "ethAuthData": {
      "type": "Onchain"
  },
  "ts": 1675650037
}

sign

import (
    time
    fmt
    sdk "github.com/zkLinkProtocol/zklink_sdk/generated/uniffi/zklink_sdk"
)

func SignChangePubkey {
    ethSignature := sdk.PackedEthSignature("0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b")
    // get current timestamp
    now := time.Now()
    timeStamp := sdk.TimeStamp(now.Unix())
    mainContract := sdk.ZkLinkAddress("0x5505a8cD4594Dbf79d8C59C0Df1414AB871CA896")

    // create ChangePubKey transaction type without signed
    builder := sdk.ChangePubKeyBuilder{
		ChainId: sdk.ChainId(1),
		AccountId: sdk.AccountId(1),
		SubAccountId: sdk.SubAccountId(4),
		NewPubkeyHash: sdk.PubKeyHash("0xd8d5fb6a6caef06aa3dc2abdcdc240987e5330fe"),
		FeeToken: sdk.TokenId(1),
		Fee: *big.NewInt(100),
		Nonce: sdk.Nonce(100),
		EthSignature: &ethSignature,
		Timestamp: timeStamp,
    }
    tx := sdk.NewChangePubKey(builder)
    l1ClientId := uint32(1)
    privateKey := "0xbe725250b123a39dab5b7579334d5888987c72a58f4508062545fe6e08ca94f4"
    signer, err := sdk.NewSigner(privateKey)
    if err != nil {
        return
    }
    txSignature, err := signer.SignChangePubkeyWithEthEcdsaAuth(tx, l1ClientId, mainContract)
    fmt.Println("L1 signature: %s", txSignature.Layer1Signature)
    fmt.Println("signed Tx: %s", txSignature.Tx)
    submitterSignature, err := signer.SubmitterSignature(txSignature.Tx)
    fmt.Println("submitter signature: %s, %s", submitterSignature.PubKey, submitterSignature.Signature)
}
import init, *  as wasm  from "/path/to/zklink-sdk-web.js";

async function testEcdsaAuth() {
    await init();
    const main_contract = "0x5505a8cD4594Dbf79d8C59C0Df1414AB871CA896";
    const l1_client_id = 80001;
    const new_pubkey_hash = "0xd8d5fb6a6caef06aa3dc2abdcdc240987e5330fe";
    const ts  = Math.floor(Date.now() / 1000);
    try {
        let tx_builder = new wasm.ChangePubKeyBuilder(
            1,5,1,new_pubkey_hash,18,"100000000000000",
            1,"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b",
            ts);
        let tx = wasm.newChangePubkey(tx_builder);
        const signer = new wasm.JsonRpcSigner();
        await signer.initZklinkSigner();
        let tx_signature = await signer.signChangePubkeyWithEthEcdsaAuth(tx,l1_client_id,main_contract);
        console.log(tx_signature);
        let submitter_signature = signer.submitterSignature(tx_signature.tx);
        console.log(submitter_signature);
        //send to zklink
        let rpc_client = new wasm.RpcClient("testnet");
        let tx_hash = await rpc_client.sendTransaction(tx_signature.tx,null,submitter_signature);
        console.log(tx_hash);

    } catch (error) {
        console.error(error);
    }
}

Refer to to create a contract address, then the ChangePubKey is executed by the account that can successfully call the contract's isValidSignature method.

For more detail please refer to in SDK

For more detail please refer to

🛠️
EIP712
EIP1271
Golang example
javascript example
BigUint
ChangePubKeyAuthData
ChainId
AccountId
SubAccountId
PubkeyHash
Nonce
TokenId
ZkLinkSignatur