Skip to content

numbersprotocol/nit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nit

Nit is git for web3 digital asset and helps user to commit an asset's activities (chronicle) to blockchain. Please note, this repository is for nit open-source tools. If you are looking for accessing nit via API services, please visit here for more details.

Why Nit

To make digital assets trustworthy and traceable, Nit leverages web3 technologies and Git core concepts. Everyone can chronicle their assets by creating on-chain records so that we can productively debate, narrate, and analyse. All asset histories are written on chain and are searchable by asset CID. A sample transaction can be found here.

Case study

  1. A crypto-based dossier could help prove Russia committed war crimes, CNN
  2. Starling Lab and Hala Systems file Cryptographic Submission of Evidence of War Crimes in Ukraine to the International Criminal Court, CAGR

Commit & Asset Tree

nit adopt similar design as git.

  • When there is an update to the asset, such as updating creator information or updating content itself to create a child asset, there should be a new commit attach the asset itself.

  • Every asset has a Tree file in IPFS to describe the property of the asset, including creator, creation time, license, etc. The asset tree CID is included in the on-chain message. Here is the example of the asset tree.

The db diagram can be found here. In this diagram, you will find tables of commit and assetTree with the explanation of each data field

Installation

yarn global add @numbersprotocol/nit

Example: Initial Registration

If it's your first time to run nit, initialize Nit with default configuration:

nit init

and provide personal information. The details of the Nit configuration format is in the Configuration section below.

nit config -e

The default integrity register (smart contract) is running on Avalanche Fuji (Testnet) and will migrate to Numbers mainnet in the future. You need to get some testing tokens from the Fuji faucet for paying transaction fee.

Create a working directory for the targeting asset:

mkdir ~/temp && cd ~/temp

Create the Asset Tree of the targeting asset. Example:

nit add <asset-filepath> -m "First registration."

To access the file of the CID, you can use browser to open the URL: https://<cid>.ipfs.dweb.link

Double check the Commit information meets your expectation:

nit status

Register the Commit on blockchain:

nit commit -m "commit description"

You can check the Commit on blockchain by following the explorer URL returned by Nit.

Get On-Chain Information

Get on-chain block numbers of an Asset

nit log <asset-cid> --blocks

Example command of the mockup Asset

nit log aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --blocks

Commit block numbers and indices

Total Commit number: 74
Index: 0, Block number: 7236185
Index: 1, Block number: 7236445
...
Index: 71, Block number: 10849040
Index: 72, Block number: 10849133
Index: 73, Block number: 11040035

Get Commits of an Asset

You can specify the starting and ending indices of block numbers:

nit log <asset-cid> --from-index 3 --to-index 5

You will get the Commits from the block numbers associated to index 3 & 4.

Example command of the mockup Asset

nit log aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --from-index 71 --to-index 73
Commits in block 71 & 72 (exclude block 73)
Total Commit number: 74

block number: 10849040
tx: 0x6d5902173255afe379cc4ae934a6c684ecfd865679286665622de3cf10eddcbe
{
  "assetTreeCid": "bafkreifnpykuw5g2m4k5k5wf55zxtzjmcftstzhtsarlkqytimajj3ntlq",
  "assetTreeSha256": "ad7e154b74da6715d576c5ef7379e52c116729e4f39022b54313430094edb35c",
  "assetTreeSignature": "0x9faf5c9d13b8d90a7a8e88aa6daf089ca89593c28dc241347c4756e83c2f1ea53ed1cb9e189f7ab81c81327527c97595f44ed71dda8e5d78ebe0dccfe9dd27081c",
  "author": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
  "committer": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
  "provider": "bafkreigtmno2wacf4ldb6ewbkboe7oojedsp3dky35djytor6guwzhbdpa",
  "timestampCreated": 1655720482,
  "action": "bafkreiavifzn7ntlb6p2lr55k3oezo6pofwvknecukc5auhng4miowcte4",
  "actionResult": "https://bafkreifnpykuw5g2m4k5k5wf55zxtzjmcftstzhtsarlkqytimajj3ntlq.ipfs.dweb.link",
  "abstract": "Action action-initial-registration."
}

block number: 10849133
tx: 0xe383fdc0f4eaf44e8bde4737f33bcd45742dcb846f3beb890976793d7cc9358e
{
  "assetTreeCid": "bafkreidptwydheqfybug4mmnzwzdg4rqxjvg4akl2pwjmrfxhqz33qv4tu",
  "assetTreeSha256": "6f9db0339205c0686e318dcdb2337230ba6a6e014bd3ec9644b73c33bdc2bc9d",
  "assetTreeSignature": "0xef547e124a9904dbdb5a418022ad03c621201b74111a3b4c5fac61b1d82350170766cef8a27737d21ca9b1bd4e04f7cdea460706b68b14e0ed17f2a3de83f9131b",
  "author": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
  "committer": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
  "provider": "bafkreigtmno2wacf4ldb6ewbkboe7oojedsp3dky35djytor6guwzhbdpa",
  "timestampCreated": 1655720763,
  "action": "bafkreiavifzn7ntlb6p2lr55k3oezo6pofwvknecukc5auhng4miowcte4",
  "actionResult": "https://bafkreidptwydheqfybug4mmnzwzdg4rqxjvg4akl2pwjmrfxhqz33qv4tu.ipfs.dweb.link",
  "abstract": "Action action-initial-registration."
}

Get difference of Commits and Asset Trees of an Asset

nit diff <asset-cid> --from-index 3 --to-index 5

Example command of the mockup Asset

nit diff aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --from-index 71 --to-index 73
Diff of Commits and Asset Trees in block 71 & 72 (exclude block 73)
from: block 10849040, tx 0x6d5902173255afe379cc4ae934a6c684ecfd865679286665622de3cf10eddcbe
  to: block 10849133, tx 0xe383fdc0f4eaf44e8bde4737f33bcd45742dcb846f3beb890976793d7cc9358e

Commit difference
{
  "abstract": "Action action-initial-registration.",
  "action": "bafkreiavifzn7ntlb6p2lr55k3oezo6pofwvknecukc5auhng4miowcte4",
 -"actionResult": "https://bafkreifnpykuw5g2m4k5k5wf55zxtzjmcftstzhtsarlkqytimajj3ntlq.ipfs.dweb.link",
 -"assetTreeCid": "bafkreifnpykuw5g2m4k5k5wf55zxtzjmcftstzhtsarlkqytimajj3ntlq",
 -"assetTreeSha256": "ad7e154b74da6715d576c5ef7379e52c116729e4f39022b54313430094edb35c",
 -"assetTreeSignature": "0x9faf5c9d13b8d90a7a8e88aa6daf089ca89593c28dc241347c4756e83c2f1ea53ed1cb9e189f7ab81c81327527c97595f44ed71dda8e5d78ebe0dccfe9dd27081c",
 +"actionResult": "https://bafkreidptwydheqfybug4mmnzwzdg4rqxjvg4akl2pwjmrfxhqz33qv4tu.ipfs.dweb.link",
 +"assetTreeCid": "bafkreidptwydheqfybug4mmnzwzdg4rqxjvg4akl2pwjmrfxhqz33qv4tu",
 +"assetTreeSha256": "6f9db0339205c0686e318dcdb2337230ba6a6e014bd3ec9644b73c33bdc2bc9d",
 +"assetTreeSignature": "0xef547e124a9904dbdb5a418022ad03c621201b74111a3b4c5fac61b1d82350170766cef8a27737d21ca9b1bd4e04f7cdea460706b68b14e0ed17f2a3de83f9131b",
  "author": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
  "committer": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
  "provider": "bafkreigtmno2wacf4ldb6ewbkboe7oojedsp3dky35djytor6guwzhbdpa",
 -"timestampCreated": 1655720482
 +"timestampCreated": 1655720763
}

Asset Tree difference
{
  "abstract": "",
  "assetCid": "bafybeif3ctgbmiso4oykvwj6jebyrkjxqr26bfrkesla5yr2ypgx47wgle",
  "assetCreator": null,
  "assetSha256": null,
  "assetTimestampCreated": null,
  "assetTreeCustomKey1": "foo",
  "assetTreeCustomKey2": "bar",
  "encodingFormat": "application/zip",
  "license": {
    "document": "https://starlinglab.org",
    "name": "Starling License"
  },
 +"nftRecord": "bafkreielfjf7sfxigb4r7tejt7jhl6kthxoujwziywixlwxjjho32may7y"
}

Configuration

The Nit configuration mimics the Hardhat configuration with additional fields.

The Nit configuration is at ~/.nitconfig.json. Linux users can open the default editor by the command below:

nit config -e
Example of a Nit configuration:
{
  // CID of the author's profile of original Assets
  "author": "bafkreihkrnjvjeijjhalozcfpgrgb46673dlt4e3qm5bmvzzb4if423wse",
  // CID of the committer's profile who creates Asset Trees and Commits
  "committer": "bafkreihkrnjvjeijjhalozcfpgrgb46673dlt4e3qm5bmvzzb4if423wse",
  // CID of the service provider who hosts the integrity registration service
  "provider": "bafkreido4zu743f6isb5wninfkedvbirj2ngb5fkivrpdijh2xtd3s6rnu",
  "defaultNetwork": "fuji",
  "network": {
    "rinkeby": {
      "url": "https://eth-rinkeby.alchemyapi.io/v2/UO5kfog_UDJgGCuqeaSJmnE95_gKOnFN",
      "gasLimit": 200000,
      "accounts": [
        "<private-key>",
      ],
      // integrity record contract address
      "contract": "0x2Aa4e29872DE77E1Bc6cF310d647F9cB0f9a073B",
      "explorerBaseUrl": "https://rinkeby.etherscan.io/tx"
    },
    "avalanche": {
      "chainId": 43114,
      "url": "https://api.avax.network/ext/bc/C/rpc",
      "accounts": [
        "<private-key>",
      ],
      "contract": "0x1970aFD0831E9233667fb9484910926c2b18BCb4",
      "explorerBaseUrl": "https://snowtrace.io/tx"
    },
    "fuji": {
      "url": "https://api.avax-test.network/ext/bc/C/rpc",
      "chainId": 43113,
      "gasLimit": 200000,
      "accounts": [
        "<private-key>",
      ],
      "contract": "0xA2De03bee39Fa637440909abC5621063bC5DA926",
      "explorerBaseUrl": "https://testnet.snowtrace.io/tx"
    },
    "polygon": {
      "url": "https://polygon-rpc.com/",
      "gasPrice": 60000000000,
      "accounts": [
        "<private-key>",
      ],
      "contract": "0x2094747c6c870f20E38f701116CBb46845b5E5c1",
      "explorerBaseUrl": "https://polygonscan.com/tx"
    },
    "moonbase": {
      "url": "https://rpc.api.moonbase.moonbeam.network",
      "accounts": [
        "<private-key>",
      ],
      "contract": "0xfbeA33fe2b266697404Dc5D1dC0A4ee9D0eDED23",
      "explorerBaseUrl": "https://moonbase.moonscan.io/tx"
    },
    "aurora_testnet": {
      "url": "https://testnet.aurora.dev/",
      "chainId": 1313161555,
      "accounts": [
        "<private-key>",
      ],
      "contract": "0x8e1bF90681C672e25aE880767d57f0552f6F5Cd1",
      "explorerBaseUrl": "https://testnet.aurorascan.dev/tx"
    }
  },
  // For the ipfsadd command. We will support web3.storage soon
  "infura": {
    "projectId": "aaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "projectSecret": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  }
}

Verification

Verify the integrity of an Asset Tree

nit verify --integrity-hash <assetTreeSha256> --signature <assetTreeSignature>

Example

nit verify --integrity-hash 6f9db0339205c0686e318dcdb2337230ba6a6e014bd3ec9644b73c33bdc2bc9d --signature 0xef547e124a9904dbdb5a418022ad03c621201b74111a3b4c5fac61b1d82350170766cef8a27737d21ca9b1bd4e04f7cdea460706b68b14e0ed17f2a3de83f9131b

Verification result

Signer address: 0x63B7076FC0A914Af543C2e5c201df6C29FCC18c5

If the signer address is different from the Committer's wallet address, you can treat this Commit as not trustworthy.