Skip to content

Chaincode first setps

Assuming a brand new channel in the environment

How to create keys

Use the chain-cli command to generate a secp256k1 key pair (or alternatively, use a Node.js library such as @noble/secp256k1 or ethers).

galachain keygen file_name

Using the command above both public and private key will be generated in the provided path. The public key will have the suffix .pub.

Details on how to install the chain-cli can be found in getting-started.md.

How to generate a new encryption key

Choose one of the options below.

  1. Generate a strong password using a password vault (e.g. Bitwarden, LastPass, KeepassXC).

  2. Hash the generated private key.

The encryption key is used as the x-user-encryption-key header, and is an important part of GalaChain authorization flow. Security best practices dictate that it should be a strong key.

How to create a new curator user

Use GC_ADMIN to create at least one new account (e.g. GAME_ADMIN) in the curator org.

curl --location 'http://{CHAINCODE_URL}/api/identity/curator-user' \
--header 'accept: application/json' \
--header 'Content-Type: application/json' \
--header 'x-identity-user-id: GC_ADMIN' \
--header 'x-user-encryption-key: GC_ADMIN' \
--data '{
  "userId": "GAME_ADMIN",
  "identityEncryptionKey": "strong-generated-key"
}'

How to save the generated public key for the new curator user

Substitute the placeholder values in the sample curl command below with the generated curator user id, encryption key and public key to make a successful request.

curl --location 'http://{CHAINCODE_URL}/api/{CHAINCODE_NAME}/public-key-contract/RegisterUser' \
--header 'accept: application/json' \
--header 'Content-Type: application/json' \
--header 'x-identity-lookup-key: GC_ADMIN' \
--header 'x-user-encryption-key: GC_ADMIN' \
--data '{
    "publicKey": "0454d15528f41819cb77816ddd7f76f753de0ae425680d1055c043d18be0eebf369e122e3b44e1c0184619754ffa23c2d3f1945cee8e7b46f95b401b1fe69baefb",
    "signature": "MEYCIQDf3m2pVAcm2CBmev3070TPu+FQZhMlqRGzVCGkUGvOlwIhALFlzbamcGArO4AeALTmAKqGPxklnobLMwFX+VoiDbOB",
    "user": "service|GAME_ADMIN"
}'

The signature should be generated using the private key of the GC_ADMIN in this case because the signer has to already be registered. See how to sign a DTO here.

Note that the user requires a prefix of service| for curator users.

How to add the new curator user as an authority on a token

curl --location 'http://{CHAINCODE_URL}/api/{CHAINCODE_NAME}/token-contract/CreateTokenClass' \
--header 'accept: application/json' \
--header 'Content-Type: application/json' \
--header 'x-identity-lookup-key: service|GAME_ADMIN' \
--header 'x-user-encryption-key: strong-generated-key' \
--data '{
    "tokenClass": {
        "collection": "ChainCli2",
        "category": "Sample2",
        "type": "ffxc7xyh2",
        "additionalKey": "v9dbrgop2"
    },
    "name": "ChainCliSampleToken1234",
    "symbol": "CHCHCHAINSS",
    "description": "Mostly-randomly generated sample DTO created with chain dto generate.",
    "image": "http://app.gala.games/chain-cli-test-data",
    "metadataAddress": "qui",
    "totalBurned": "0",
    "maxCapacity": "100000000",
    "contractAddress": "deserunt incididunt",
    "totalSupply": "0",
    "maxSupply": "1000000000",
    "isNonFungible": false,
    "rarity": "IWiSx",
    "authorities": [
        "client|GAME_ADMIN",
        "client|GC_ADMIN"
    ],
    "totalMintAllowance": "0",
    "network": "GC",
    "decimals": 1,
    "signature": "MEQCIFyNwLSoFTdPjjlvt9m9M/1v9lele696/SP9GLbrcPOzAiBe3K+6iOwYlOOhNb+pAfnolY6o12gT+4QRSfOqDnoI4Q=="
}'

Note that while the signature field is optional for the DTO class definition generally, it is required for this Write/Submit transaction to be executed on chain.

It is strongly recommended to save at least two users as authorities on every token class. Only token authorities have the ability to update existing TokenClass objects on chain, so create at least two to have a backup in case of private key loss.

How to sign a DTO

It's necessary to have a private key generated by galachain keygen to use this command. Leave the signature field in the provided DTO empty - the convenience of this command is that it will sign the DTO, generate the signature, and populate the field for you.

Then you can use the command galachain dto:sign to get the response with your DTO containing the signature field.

Example:

galachain dto:sign data/privateKey '{
  "tokenClass": {
    "collection": "CLITest",
    "category": "Currency",
  }
}'

or

galachain dto:sign data/privateKey dto.json

The command will normalize your private key and create a signature based on the DTO and the normilized private key using the secp256k1 cryptography. The signature is encoded to base64 and added to the signature field.

Note that if you like to sign DTOs on your on, it's important to know the DTO should be deterministic, so different peers will always interpret them the same. The reason and the solution for that can be found here.