3. SDK Signature

✅User signature required

❌ No user signature required

Transactions that change blockchain status

  • Register L2 accounts

  • Create NFT-related transactions

  • Transfer assets between accounts

  • Use Zecrey-Dex for token swap

  • Deposit assets to Zecrey L2

  • Withdraw assets to BNB L1

  • Get the account information on Zecrey

  • Get the details of L2 assets

  • Get the details of the NFT Marketplace

In Zecrey-Marketplace-SDK, in order to make it easy for developers to register and send transactions, the private key signing process is encapsulated inside the SDK methods. Thus, developers do not need to understand the principle and process of signing, just use the SDK-client to make method calls to complete the required functions.

In order to provide developers with a deeper understanding of the process of signing transactions by the SDK, in the following section, we will explain the process of user signature transactions and related function methods. This section is only intended to give developers a deeper understanding of Zecrey and Zecrey SDK.

Due to the difference in the signature algorithms (ecdsa/eddsa) between L1 and L2 account systems, they use different private keys for transaction signatures:

  • A transaction occurring on L1 requires the transaction to be signed on L1. For example, depositing assets from an L1 wallet to an L2 wallet uses the L1 private key.

  • Transactions occurring on Zecrey (L2) require the transaction to be signed on L2. For example, all transactions initiated on L2 need to be signed using L2's private key.

Note that the L2 private key is derived from the L1 private key signature, which means that there is a one-to-one correspondence between the L1 and L2 private keys. If you generate your own Zecrey (L2) private key, you can make it permanent to avoid repeated operations. There will be no need to regenerate the seed with the private key of L1 in the future.

The following examples show how to use the SDK for account creation, L2 private key generation and transaction signature respectively.

Create an account:

  • Use the client to generate an L1 account and private key, then generate an L2 seed (private key) and public key



package main

import (

func main() {
    l1Addr, privateKeyStr, l2pk, seed, err := sdk.CreateL1Account()
    if err != nil { panic(err) }
    fmt.Println("l1Addr:", l1Addr) //l1 account
    fmt.Println("privateKeyStr:", privateKeyStr)//l1 private key
    fmt.Println("l2pk:", l2pk)     //l2 public key
    fmt.Println("seed:", seed)     //l2 private key

Example result

l1Addr: 0xD207262DEA01aE806fA2dCaEdd489Bd2f5FABcFE
seed: 0x6a1a320d14790f2d9aa9a37769f4833d583a3f7f974fd452a3990aeb0e7a6052
privateKeyStr: 1a061a8e74cee1ce2e2ddd29f5afea99ecfbaf1998b6d349a8c09a368e637b8e
l2pk: 06278b99871f1d64fcc83bd27713cbf743d957c510a245d6bfb0eae888e35452274a2b4c8c7b7424f25d7d187661225111753197248fa045fd872aa662fdcb24

Generate L2 private key

  • Generate L2 public and private keys with the user's L1 private key



package main

import (

func main() {
    privateKey := "0xe94a8b4ddd33b2865a89bb764d70a0c3e3276007ece8f114a47a4e9581ec3567"
    l2pk, seed, err := sdk.GetSeedAndL2Pk(privateKey)
    if err != nil { panic(err) }
    fmt.Println("seed:", seed)//l2 private key
    fmt.Println("l2pk:", l2pk)//l2 public key

Example result

seed: 0x7ea589236ac7e6034a40ad31f27a6ea1bbaeb7746ba5e8d3408a3abb480a8688
l2pk: 22fc6f5d74c8639245462a0af6b5c931bd209c04034b28421a60336635ab85950a3163e68ec29319ca200fac009408369b0a1f75200a118aded920cd240e1358

Signature by the signer

  • Transaction signature process

    • Encapsulate the transaction bodies

    • Calculate transaction hashes

    • Sign



  • Sign the CreateCollectionTx

package main

import (

func main() {
   accountName := "Alice"
   seed := "28e1a3762ff9944e9a4ad79477b756ef0aff3d2af76f0f40a0c3ec6ca76cf24b"
   c, err := sdk.NewClient(accountName, seed)
   if err != nil {
   expiredAt := time.Now().Add(time.Hour * 24 * 2).UnixMilli()
   accountIndex, _ := sdk.GetAccountIndex(accountName)
   accountNonce, _ := sdk.GetNextNonce(accountIndex)
   txInfo := &sdk.CreateCollectionTxInfo{
      AccountIndex:      accountIndex,
      Name:              fmt.Sprintf("Nft Collection - %d", accountNonce),
      Introduction:      "Great Nft!",
      GasAccountIndex:   1,
      GasFeeAssetId:     0,
      GasFeeAssetAmount: big.NewInt(5000),
      ExpiredAt:         expiredAt,
      Nonce:             accountNonce,
      Sig:               nil,
   hFunc := mimc.NewMiMC()
   convertedTx := sdk.ConvertCreateCollectionTxInfo(txInfo)
   msgHash, _ := legendTxTypes.ComputeCreateCollectionMsgHash(convertedTx, hFunc)
   signature, _ := sdk.SignMessage(c.keyManager,msgHash)
   txInfo.Sig = signature


Example result

    "Name":"Nft Collection - 1",
    "Introduction":"Great Nft!",

Last updated